правильный способ фильтрации execve среды - PullRequest
0 голосов
/ 19 мая 2018

Я пытаюсь написать 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

    , что для меня звучит так, будто я освобождаю слишком много, но яЯ не могу найти виновного.

Надеюсь, это звучит не слишком похоже на пост "Эй, исправь это для меня", но я вроде как бьюсь об стену здесь и помогубудет очень признателен.

Ответы [ 2 ]

0 голосов
/ 19 мая 2018

Сделайте это прямо:

  • Создайте новый массив указателей с размером, необходимым для хранения нового env / var / s
  • strdup()все необходимые элементы от старого до нового массива.
  • При необходимости добавьте новый материал.
  • Убедитесь, что последний указатель в массиве равен NULL.
  • Passновый массив указателей на исходные execve().

Не не изменять или даже (пытаться) free() записи старой среды.

0 голосов
/ 19 мая 2018

Нельзя предполагать, что отдельная строка в envp была выделена с malloc, поэтому free(string) может быть неопределенным поведением.Практически невозможно вызвать exec* с полностью пустой кучей, и все изображение будет заменено в любом случае, поэтому не стоит беспокоиться.

Ваш второй strtok вызов должен предоставить NULL в качестве первогоаргумент.См. man strtok для объяснения и примеров.

...