diff --git a/NEWS b/NEWS index ed14c574..4edaa8bf 100644 --- a/NEWS +++ b/NEWS @@ -1,6 +1,7 @@ procps-3.2.5 --> procps-3.2.6 more MIPS crud -- thanks Jim Gifford and Ryan Oliver +begin prep for setuid procps-3.2.4 --> procps-3.2.5 diff --git a/proc/ksym.c b/proc/ksym.c index 2b9cf591..a336686b 100644 --- a/proc/ksym.c +++ b/proc/ksym.c @@ -509,8 +509,10 @@ int open_psdb_message(const char *restrict override, void (*message)(const char || (sm=getenv("PS_SYSTEM_MAP")) ){ - read_and_parse(); - if(sysmap_mmap(sm, message)) return 0; + if(!have_privs){ + read_and_parse(); + if(sysmap_mmap(sm, message)) return 0; + } /* failure is better than ignoring the user & using bad data */ return -1; /* ought to return "Namelist not found." */ } diff --git a/proc/library.map b/proc/library.map index f8cf9c7e..a38627b7 100644 --- a/proc/library.map +++ b/proc/library.map @@ -1,7 +1,7 @@ # for --version-script # WTF is the syntax for this file? # Give me a BNF, man! -_3_2_4 { +_3_2_5 { global: __cyg_profile_func_enter; __cyg_profile_func_exit; main; @@ -10,7 +10,7 @@ global: openproc; closeproc; tty_to_dev; dev_to_tty; open_psdb_message; open_psdb; lookup_wchan; display_version; procps_version; linux_version_code; - Hertz; smp_num_cpus; + Hertz; smp_num_cpus; have_privs; sprint_uptime; uptime; user_from_uid; print_uptime; loadavg; pretty_print_signals; print_given_signals; unix_print_signals; signal_name_to_number; signal_number_to_name; meminfo; vminfo; getstat; getdiskstat; getpartitions_num; getslabinfo; get_pid_digits; diff --git a/proc/sysinfo.c b/proc/sysinfo.c index f46b5c28..8265dd37 100644 --- a/proc/sysinfo.c +++ b/proc/sysinfo.c @@ -170,8 +170,13 @@ static void old_Hertz_hack(void){ } } +// same as: euid != uid || egid != gid +#ifndef AT_SECURE +#define AT_SECURE 23 // secure mode boolean (true if setuid, etc.) +#endif + #ifndef AT_CLKTCK -#define AT_CLKTCK 17 /* frequency of times() */ +#define AT_CLKTCK 17 // frequency of times() #endif #define NOTE_NOT_FOUND 42 @@ -189,8 +194,21 @@ static unsigned long find_elf_note(unsigned long findme){ return NOTE_NOT_FOUND; } +int have_privs; + +static int check_for_privs(void){ + unsigned long rc = find_elf_note(AT_SECURE); + if(rc==NOTE_NOT_FOUND){ + // not valid to run this code after UID or GID change! + // (if needed, may use AT_UID and friends instead) + rc = geteuid() != getuid() || getegid() != getgid(); + } + return !!rc; +} + static void init_libproc(void) __attribute__((constructor)); static void init_libproc(void){ + have_privs = check_for_privs(); // ought to count CPUs in /proc/stat instead of relying // on glibc, which foolishly tries to parse /proc/cpuinfo // diff --git a/proc/sysinfo.h b/proc/sysinfo.h index 4063f371..02c88ee0 100644 --- a/proc/sysinfo.h +++ b/proc/sysinfo.h @@ -8,6 +8,7 @@ EXTERN_C_BEGIN extern unsigned long long Hertz; /* clock tick frequency */ extern long smp_num_cpus; /* number of CPUs */ +extern int have_privs; /* boolean, true if setuid or similar */ #if 0 #define JT double