chmod +s



  • Hallo,

    habe da ein Verständnisproblem.

    $ chown user1:user1 a.out
    $ chmod +s a.out
    $ ls -l a.out
    -rwsr-sr-x    1 user1      user1         11520 2004-02-19 12:06 a.out
    

    Wenn ich jetzt das Programm als user2 starte, läuft es mit den Gruppenrechten von user2 und nicht von user1.
    In dem Testprogramm führe ich ls aus und ich bekomme den Inhalt des Verzeichnises angezeigt, wobei das Verzeichnis so aussieht:

    $ ls -ld .
    drwxr-x---    2 user2    user2        4096 2004-02-19 12:09 .
    

    user1 ist nicht in der Gruppe von user2.

    Wieso wird hier die Gruppe vom ausführenden Benutzer "vererbt"?



  • Wie testest Du das?

    uo@uo tmp $ cat foo.c
    #include <stdio.h>
    #include <unistd.h>
    
    int main(void) {
      printf("uid: %i, gid: %i\n", getuid(), getgid());
      printf("euid: %i, egid: %i\n", geteuid(), getegid());
    }
    uo@uo tmp $ gcc foo.c
    uo@uo tmp $ sudo chown apache:apache a.out
    uo@uo tmp $ sudo chmod +s a.out
    uo@uo tmp $ ls -l a.out
    -rwsr-sr-x    1 apache   apache       7309 Feb 19 15:07 a.out
    uo@uo tmp $ ./a.out
    uid: 1000, gid: 100
    euid: 81, egid: 81
    

    Du siehst, der Code laeuft unter Gruppe 81.



  • Ja, die Ausgaben bekomme ich auch. Aber wieso gibt mir der ls-Aufruf in folgendem Beispiel kein "permission denied", obwohl nur root und die Gruppe root lesen darf?

    root@denis:~/tmp$ cat a.c
    int main()
    {
        printf("uid: %i, gid: %i\n", getuid(), getgid());
        printf("euid: %i, egid: %i\n", geteuid(), getegid());
        printf("\n--- ls ---\n");
        system("ls"); 
    }
    
    root@denis:~/tmp$ gcc a.c
    root@denis:~/tmp$ chown denis:denis a.out
    root@denis:~/tmp$ chmod +s a.out 
    root@denis:~/tmp$ chmod ug=rwx,o= .
    root@denis:~/tmp$ ls -ld a.out .   
    drwxrwx---    2 root     root         4096 2004-02-19 16:16 .
    -rwsr-sr-x    1 denis    denis       12084 2004-02-19 16:16 a.out
    root@denis:~/tmp$ ./a.out
    uid: 0, gid: 0
    euid: 1000, egid: 1000
    
    --- ls ---
    a.c  a.out
    

    Wenn ich auch der Gruppe root die Lese-Berechtigung für das Verzeichnis entziehe, bekomme ich auch das erwartete permission denied.



  • Ergaenze das Programm mal um ein

    system("id")
    

    und Du siehst: id wird wieder als root ausgefuehrt.

    Warum das? system() verhaelt sich per Definition wie fork() gefolgt von execl(<shell path>, "sh", "-c", command, (char *)0);. sh ist auf den meisten Linux-Systemen die Bash 2, und diese setzt uid und gid auf die gespeicherten Werte zurueck, bevor sie den Befehl ausfuehrt.



  • Ah danke, jetzt verstehe ich.

    Ich wusste nicht, dass ein Prozess die Möglichkeit hat, seine effektive userid einfach wieder zurück zu setzen.

    Ursprünglich wollte ich damit die Rechte eines Programms einschränken, aber so ist dieses uid/gid-Bit ja nur zu gebrauchen, wenn man einem Programm mehr Rechte geben will 😕



  • Schau Dir mal setresuid() an. Damit kannst Du im aufgerufenen Prozess alle Spuren der alten uid loeschen. Wenn Du keinen Zugriff auf den Source des zu beschraenkenden Programms hast, musst Du einen kleinen Wrapper schreiben.


Anmelden zum Antworten