Fixing invalid reads in find_elf_note due to setenv invocation
Resolves issue on mailing list and Red Hat Bugzilla 1163404.
This commit is contained in:
parent
b4fdb27a05
commit
ecabdaca41
@ -36,6 +36,9 @@
|
|||||||
#include <netinet/in.h> /* htons */
|
#include <netinet/in.h> /* htons */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include <link.h>
|
||||||
|
#include <elf.h>
|
||||||
|
|
||||||
long smp_num_cpus; /* number of CPUs */
|
long smp_num_cpus; /* number of CPUs */
|
||||||
long page_bytes; /* this architecture's page size */
|
long page_bytes; /* this architecture's page size */
|
||||||
|
|
||||||
@ -249,15 +252,67 @@ static void old_Hertz_hack(void){
|
|||||||
|
|
||||||
extern char** environ;
|
extern char** environ;
|
||||||
|
|
||||||
/* for ELF executables, notes are pushed before environment and args */
|
static unsigned long find_elf_note(unsigned long type)
|
||||||
static unsigned long find_elf_note(unsigned long findme){
|
{
|
||||||
|
ElfW(auxv_t) auxv_struct;
|
||||||
|
ElfW(auxv_t) *auxv_temp;
|
||||||
|
FILE *fd;
|
||||||
|
int i;
|
||||||
|
static ElfW(auxv_t) *auxv = NULL;
|
||||||
unsigned long *ep = (unsigned long *)environ;
|
unsigned long *ep = (unsigned long *)environ;
|
||||||
while(*ep++);
|
unsigned long ret_val = NOTE_NOT_FOUND;
|
||||||
while(*ep){
|
|
||||||
if(ep[0]==findme) return ep[1];
|
|
||||||
|
if(!auxv) {
|
||||||
|
|
||||||
|
fd = fopen("/proc/self/auxv", "rb");
|
||||||
|
|
||||||
|
if(!fd) { // can't open auxv? that could be caused by euid change
|
||||||
|
// ... and we need to fall back to the old and unsafe
|
||||||
|
// ... method that doesn't work when calling library
|
||||||
|
// ... functions with dlopen -> FIXME :(
|
||||||
|
|
||||||
|
while(*ep++); // for ELF executables, notes are pushed
|
||||||
|
while(*ep){ // ... before environment and args
|
||||||
|
if(ep[0]==type) return ep[1];
|
||||||
ep+=2;
|
ep+=2;
|
||||||
}
|
}
|
||||||
return NOTE_NOT_FOUND;
|
return NOTE_NOT_FOUND;
|
||||||
|
}
|
||||||
|
|
||||||
|
auxv = (ElfW(auxv_t) *) malloc(getpagesize());
|
||||||
|
if (!auxv) {
|
||||||
|
perror("malloc");
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
i = 0;
|
||||||
|
do {
|
||||||
|
fread(&auxv_struct, sizeof(ElfW(auxv_t)), 1, fd);
|
||||||
|
auxv[i] = auxv_struct;
|
||||||
|
i++;
|
||||||
|
} while (auxv_struct.a_type != AT_NULL);
|
||||||
|
|
||||||
|
fclose(fd);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
auxv_temp = auxv;
|
||||||
|
i = 0;
|
||||||
|
do {
|
||||||
|
if(auxv_temp[i].a_type == type) {
|
||||||
|
ret_val = (unsigned long)auxv_temp[i].a_un.a_val;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
} while (auxv_temp[i].a_type != AT_NULL);
|
||||||
|
|
||||||
|
if (auxv){
|
||||||
|
auxv_temp = NULL;
|
||||||
|
free(auxv);
|
||||||
|
auxv = NULL;
|
||||||
|
}
|
||||||
|
return ret_val;
|
||||||
}
|
}
|
||||||
|
|
||||||
int have_privs;
|
int have_privs;
|
||||||
|
Loading…
Reference in New Issue
Block a user