chroot, exec problem



  • Guten Morgen,

    ich habe wieder mal ein Problem, ich möchte ein Programm schreiben welches auf meinem V-Server(Ubuntu) ein Programm als anderen User, in einer Chroot Umgebung startet.

    Wenn ich das Programm von mir starte, welches als root ausgeführt wird, funktioniert es nur wenn ich den Parameter für die Chroot Umgebung weglasse.

    Das Filesystem funktioniert auch in der Chroot Umgebung welches ich durch auflisten des Wurzelverzeichnisses im Programm festgestellt habe, aber wenn ich mittels exec ein Programm starten will findet er dieses nicht.

    Und hier mein Vollständiges Programm mit debug anweisungen, wobei die Letzte ausgabe wenn exec nicht funktionierte auch im neuem Wurzelverzeichnis landet.

    Edit:(Problembeschreibung nochmals mit Zeilennummer im übernächsten post)

    #include <stdio.h>
    #include <unistd.h>
    #include <stdlib.h>
    #include <dirent.h>
    #include <errno.h>
    #include <sys/time.h>
    #include <sys/resource.h>
    #include <string.h>
    #include <sys/types.h>
    #include <dirent.h>
    
    #define debug
    
    int main(int argc,char *argv[], char *env[]){
    int a=0;
    int ex=0;
    int user=getuid();
    int group=getgid();
    int i=1;
    int ch=0;
    int arg=0;
    
    printf("uid:%i, euid:%i\n",getuid(),geteuid());
    
    if((user>=1000)||(group>=1000)){
       return 100;
    }
    
    char *args[22];
    
    long lwert=0;
    
    struct rlimit limit;
    
    #ifdef debug
    FILE *wdebug=fopen("wrapper.dbg","a+");
    #endif 
    
    int uid=getuid();
    
    i=1;
    
    //Parameter Auswerten
    while(argv[i]){
       fprintf(wdebug,"arg[%i]:%s\n",i,argv[i]);
       if(!strcmp(argv[i],"-e")){
          i++;
          ex=i;
          #ifdef debug
          fprintf(wdebug,"-e %s\n",argv[i]);
          #endif
       }else if(!strcmp(argv[i],"-c")){
          i++;
          ch=i;
          #ifdef debug
          fprintf(wdebug,"-c %s\n",argv[i]);
          #endif
       }else if(!strcmp(argv[i],"-u")){
          i++;
          user=atoi(argv[i]);
          #ifdef debug
          fprintf(wdebug,"-u %s\n",argv[i]);
          #endif
          if(user<=1000){
             #ifdef debug
             fprintf(wdebug,"error uid<=1000");
             #endif
             return 1;
          }
       }else if(!strcmp(argv[i],"-g")){
          i++;
          group=atoi(argv[i]);
          #ifdef debug
          fprintf(wdebug,"-g %s\n",argv[i]);
          #endif
    
          if(group<=1000){
             #ifdef debug
             fprintf(wdebug,"error gid<=1000");
             #endif
             return 2;
          }
       }else if(!strcmp(argv[i],"-a")){
          i++;
          a=i;
          #ifdef debug
          fprintf(wdebug,"-a %s\n",argv[i]);
          #endif
       }else if(!strcmp(argv[i],"-arg")){
          i++;
          arg=i;
       }else{
          #ifdef debug
          fprintf(wdebug,"error parameter existiert nicht");
          #endif
          return 3;
       }
    i++;
    }
    
    //Umsetzen der Parameter
    if(ch){
       if(chdir(argv[ch])){
          return 10;
       }
       if(chroot(".")){
          #ifdef debug
          fprintf(wdebug,"error chroot");
          #endif
          return 8;
       }else{
       if(chdir("/")){
          #ifdef debug
          fprintf(wdebug,"error chroot");
          #endif
       }
    
       DIR *dir;
       struct dirent *dirzeiger;
    
       if((dir=opendir("/")) == NULL) {
          fprintf(stderr,"Fehler bei opendir ...\n");
          return EXIT_FAILURE;
       }
       /* das komplette Verzeichnis auslesen */
       while((dirzeiger=readdir(dir)) != NULL)
          printf("%s\n",(*dirzeiger).d_name);
       /* Lesezeiger wieder schließen */
       if(closedir(dir) == -1)
          printf("Fehler beim Schließen von %s\n", "/");
       }
    }
    if(group){
       if(setgid(group)||setegid(group)){
          #ifdef debug
          fprintf(wdebug,"error setgid");
          #endif
          return 7;
       }
    }
    if(user){
       if(setuid(user)||seteuid(user)){
          #ifdef debug
          fprintf(wdebug,"error setuid");
          #endif
          return 6;
       }
    }
    if(a){
       if(chdir(argv[a])){
          #ifdef debug
          fprintf(wdebug,"error setdir");
          #endif
          return 5;
       }
    }
    if(ex){
       int j=1;
       args[0]=argv[ex];
       if(arg){
       char *tmp=malloc(strlen(argv[arg])+1);
       strcpy(tmp,argv[arg]);
       char *tmp1=tmp;
       while((tmp=strchr(tmp,' '))&&j<21){
          *tmp=0;
          args[j]=tmp1;
          tmp++;
          tmp1=tmp;
          j++;
       }
    args[j]=tmp1;
    j++;	
    }
    args[j]=(char*)0;
    #ifdef debug
    fclose(wdebug);
    #endif
    execvp(args[0],args);
    #ifdef debug
    if(wdebug=fopen("/wrapper.dbg","a+")){
       fprintf(wdebug,"error exec: %i",errno);
       perror((char*)NULL);
       fclose(wdebug);
    }
    #endif
    return 4;
    }
    }
    

    Danke für eure Hilfe.



  • 190 Zeilen Code mit kaputter Einrückung ist etwas viel. Bitte versuch, den Fehler auf die relevanten Zeilen einzugrenzen.

    Antikalas schrieb:

    Das Filesystem funktioniert auch in der Chroot Umgebung welches ich durch auflisten des Wurzelverzeichnisses im Programm festgestellt habe

    Damit man in einer chroot-Umgebung sinnvoll arbeiten kann, muss die chroot-Umgebung alles enthalten, was benötigt wird, insbesondere also alle shared libraries, die deine executables laden wollen.



  • Wenn ich das compilierte Programm so starte,
    /Programmpfad/Programmname -c /chrootpfad -e /zu_chrootendes_Programm -u 1006 -g 1006
    bekomme ich von meiner errorausgabe in Zeile 183 die Ausgabe, dass das zu_chrootendes_Programm nicht existiert.

    Aber meine Kontroll Ausgabe des neuen Wurzelvezeichnisses(Zeile 127) Listet das
    zu_chrootendes_Programm mit auf.

    Wenn ich mein programm ohne den Parameter zur setzen der Chroot Umgebung ausführe dann funktioniert es.
    /Programmpfad/Programmname -e /chrootpfad/zu_chrootendes_Programm -u 1006 -g 1006

    Also muss der fehler irgenwo beim chroot befehl(Zeile 107) oder beim exec befehl(Zeile 179) liegen.

    Ich weiß wie man eine Chrootumgebung aufbaut mit dem Program Chroot bekomme ich auch die Programm darin gestartet,
    aber ich muss es über mein Programm hinbekommen.


Anmelden zum Antworten