Я пытаюсь написать LD_PRELOAD
способную библиотеку, которая не позволяет процессам удалять себя из этой переменной (чтобы дети ее наследовали).Пока я успешно завернул putenv
, setenv
и clearenv
, но execve
вызывает у меня проблемы.
Мой код пока:
int (*real_execve)(const char *filename, char *const argv[], char *const envp[]);
int execve(const char *filename, char *const argv[], char *const envp[]){
real_execve = dlsym(RTLD_NEXT,"execve");
char *path = getenv("LD_PRELOAD");
fprintf(stderr, "INTERCEPTED execve, env:\n");
int i;
for(i=0;envp[i]!=NULL;i++);
char *nenvp[i+1];
nenvp[i]=NULL;
for(i=0;envp[i]!=NULL;i++){
char *string = envp[i];
char *buf = malloc((strlen(string)+1)*sizeof(char));
strcpy(buf,string);
char *name = strtok(buf,"=");
char *value = strtok(NULL,"=");
if(0==strcmp(name,"LD_PRELOAD")){
fprintf(stderr," FIXING '%s'\n",string);
char * nstring = malloc((strlen(name)+strlen(path)+strlen(value)+3)*sizeof(char));
strcpy(nstring,name);
strcat(nstring,"=");
strcat(nstring,path);
strcat(nstring,":");
strcat(nstring,value);
nenvp[i]=nstring;
fprintf(stderr," TO '%s'\n",nenvp[i]);
free(string);
}else{
nenvp[i]=envp[i];
fprintf(stderr," LEFT '%s'\n",nenvp[i]);
}
free(buf);
}
fprintf(stderr, " CALLING %s\n", filename);
return real_execve(filename,argv,nenvp);
}
Я сталкиваюсь с 2проблемы:
он регистрирует такие вещи как:
FIXING 'LD_PRELOAD=/usr/$LIB/libstdc++.so.6 /usr/$LIB/libgcc_s.so.1 /usr/$LIB/libxcb.so.1'
TO 'LD_PRELOAD=/usr/$LIB/libstdc++.so.6 /usr/$LIB/libgcc_s.so.1 /usr/$LIB/libxcb.so.1:/usr/$LIB/libstdc++.so.6 /usr/$LIB/libgcc_s.so.1 /usr/$LIB/libxcb.so.1'
вместо ожидаемого предопределения пути к себе, так что я думаю, что я каким-то образом испортил strtok.
Я получаю много ошибок, подобных этим:
Error in 'sh': munmap_chunk(): invalid pointer: 0x00007fff3888af4a
, что для меня звучит так, будто я освобождаю слишком много, но яЯ не могу найти виновного.
Надеюсь, это звучит не слишком похоже на пост "Эй, исправь это для меня", но я вроде как бьюсь об стену здесь и помогубудет очень признателен.