|
|
6ec062 |
diff --git a/proc/sysinfo.c b/proc/sysinfo.c
|
|
|
6ec062 |
index 1435de1..1d2b8e2 100644
|
|
|
6ec062 |
--- a/proc/sysinfo.c
|
|
|
6ec062 |
+++ b/proc/sysinfo.c
|
|
|
6ec062 |
@@ -36,6 +36,9 @@
|
|
|
6ec062 |
#include <netinet/in.h> /* htons */
|
|
|
6ec062 |
#endif
|
|
|
6ec062 |
|
|
|
6ec062 |
+#include <link.h>
|
|
|
6ec062 |
+#include <elf.h>
|
|
|
6ec062 |
+
|
|
|
6ec062 |
long smp_num_cpus; /* number of CPUs */
|
|
|
6ec062 |
long page_bytes; /* this architecture's page size */
|
|
|
6ec062 |
|
|
|
6ec062 |
@@ -249,15 +252,67 @@ static void old_Hertz_hack(void){
|
|
|
6ec062 |
|
|
|
6ec062 |
extern char** environ;
|
|
|
6ec062 |
|
|
|
6ec062 |
-/* for ELF executables, notes are pushed before environment and args */
|
|
|
6ec062 |
-static unsigned long find_elf_note(unsigned long findme){
|
|
|
6ec062 |
+static unsigned long find_elf_note(unsigned long type)
|
|
|
6ec062 |
+{
|
|
|
6ec062 |
+ ElfW(auxv_t) auxv_struct;
|
|
|
6ec062 |
+ ElfW(auxv_t) *auxv_temp;
|
|
|
6ec062 |
+ FILE *fd;
|
|
|
6ec062 |
+ int i;
|
|
|
6ec062 |
+ static ElfW(auxv_t) *auxv = NULL;
|
|
|
6ec062 |
unsigned long *ep = (unsigned long *)environ;
|
|
|
6ec062 |
- while(*ep++);
|
|
|
6ec062 |
- while(*ep){
|
|
|
6ec062 |
- if(ep[0]==findme) return ep[1];
|
|
|
6ec062 |
- ep+=2;
|
|
|
6ec062 |
+ unsigned long ret_val = NOTE_NOT_FOUND;
|
|
|
6ec062 |
+
|
|
|
6ec062 |
+
|
|
|
6ec062 |
+ if(!auxv) {
|
|
|
6ec062 |
+
|
|
|
6ec062 |
+ fd = fopen("/proc/self/auxv", "rb");
|
|
|
6ec062 |
+
|
|
|
6ec062 |
+ if(!fd) { // can't open auxv? that could be caused by euid change
|
|
|
6ec062 |
+ // ... and we need to fall back to the old and unsafe
|
|
|
6ec062 |
+ // ... method that doesn't work when calling library
|
|
|
6ec062 |
+ // ... functions with dlopen -> FIXME :(
|
|
|
6ec062 |
+
|
|
|
6ec062 |
+ while(*ep++); // for ELF executables, notes are pushed
|
|
|
6ec062 |
+ while(*ep){ // ... before environment and args
|
|
|
6ec062 |
+ if(ep[0]==type) return ep[1];
|
|
|
6ec062 |
+ ep+=2;
|
|
|
6ec062 |
+ }
|
|
|
6ec062 |
+ return NOTE_NOT_FOUND;
|
|
|
6ec062 |
+ }
|
|
|
6ec062 |
+
|
|
|
6ec062 |
+ auxv = (ElfW(auxv_t) *) malloc(getpagesize());
|
|
|
6ec062 |
+ if (!auxv) {
|
|
|
6ec062 |
+ perror("malloc");
|
|
|
6ec062 |
+ exit(EXIT_FAILURE);
|
|
|
6ec062 |
+ }
|
|
|
6ec062 |
+
|
|
|
6ec062 |
+ i = 0;
|
|
|
6ec062 |
+ do {
|
|
|
6ec062 |
+ fread(&auxv_struct, sizeof(ElfW(auxv_t)), 1, fd);
|
|
|
6ec062 |
+ auxv[i] = auxv_struct;
|
|
|
6ec062 |
+ i++;
|
|
|
6ec062 |
+ } while (auxv_struct.a_type != AT_NULL);
|
|
|
6ec062 |
+
|
|
|
6ec062 |
+ fclose(fd);
|
|
|
6ec062 |
+
|
|
|
6ec062 |
+ }
|
|
|
6ec062 |
+
|
|
|
6ec062 |
+ auxv_temp = auxv;
|
|
|
6ec062 |
+ i = 0;
|
|
|
6ec062 |
+ do {
|
|
|
6ec062 |
+ if(auxv_temp[i].a_type == type) {
|
|
|
6ec062 |
+ ret_val = (unsigned long)auxv_temp[i].a_un.a_val;
|
|
|
6ec062 |
+ break;
|
|
|
6ec062 |
+ }
|
|
|
6ec062 |
+ i++;
|
|
|
6ec062 |
+ } while (auxv_temp[i].a_type != AT_NULL);
|
|
|
6ec062 |
+
|
|
|
6ec062 |
+ if (auxv){
|
|
|
6ec062 |
+ auxv_temp = NULL;
|
|
|
6ec062 |
+ free(auxv);
|
|
|
6ec062 |
+ auxv = NULL;
|
|
|
6ec062 |
}
|
|
|
6ec062 |
- return NOTE_NOT_FOUND;
|
|
|
6ec062 |
+ return ret_val;
|
|
|
6ec062 |
}
|
|
|
6ec062 |
|
|
|
6ec062 |
int have_privs;
|