malloc() + gpg
Γιώργος Κεραμίδας
keramida at ceid.upatras.gr
Tue Mar 11 18:28:01 EET 2003
On 2003-03-11 09:28, Alexandros Papadopoulos <apapadop at cmu.edu> wrote:
> On Tuesday 11 March 2003 06:48, Γιώργος Κεραμίδας wrote:
> > > To gpg είναι suid root. Υποτίθεται ότι αν δεν μπορεί να
> > > lockάρει τη μνήμη, παραπονιέται με το γνωστό "WARNING: Using
> > > insecure memory".
> >
> > Υποτίθεται ότι η mlock() είναι μόνο για τον superuser. Εδώ που το
> > gpg δεν είναι setuid root, όταν τρέχω το gpg από απλό χρήστη
> > παίρνω το "insecure memory" warning. Όταν το τρέχω από root όμως
> > όχι.
>
> Μάλλον δεν ήμουν ξεκάθαρος. Το gpg είναι suid root, και δεν παίρνω
> warning για insecure memory, *αλλά* το strace μου έδειξε εκείνο το
> μήνυμα που μοιάζει με αποτυχία κλειδώματος της μνήμης.
>
> Αυτό που προσπαθώ να κάνω είναι να δω ότι όντως το gpg καλεί
> επιτυχώς την mlock().
Εδώ είναι λίγο περίεργα τα πράγματα. Το ktrace στο BSD μου, έχει
συμπεριφορά που μοιάζει να είναι 'προστασία' των setuid προγραμμάτων
από tracing/debugging. Τα παρακάτω είναι ότι ξέρω για το FreeBSD αλλά
αντίστοιχα πράγματα είμαι σίγουρος ότι μπορούν να βρεθούν και για το
Linux με λίγο ψάξιμο στο kernel source.
Όταν το gpg δεν είναι setuid, και τρέξω το ktrace για να κρατήσει log
από όλα τα system calls του προγράμματος, βλέπω:
: giorgos at gothmog[16:49]/home/giorgos$ kdump -f gpg.trace | grep mlock
: 34753 gpg CALL mlock(0x2829a000,0x4000)
: 34753 gpg RET mlock -1 errno 1 Operation not permitted
Αυτό είναι αναμενόμενο, αφού το gpg δεν είναι setuid root. Όταν το
αλλάξω σε setuid, το ktrace μετά το exec του gpg σταματάει να μου
δείχνει τα events:
: giorgos at gothmog[16:55]/home/giorgos$ kdump -f gpg.trace | more
: 34850 ktrace RET ktrace 0
: 34850 ktrace CALL execve(0xbfbff360,0xbfbff880,0xbfbff88c)
: 34850 ktrace NAMI "/sbin/gpg"
: 34850 ktrace RET execve -1 errno 2 No such file or directory
: 34850 ktrace CALL execve(0xbfbff360,0xbfbff880,0xbfbff88c)
: 34850 ktrace NAMI "/bin/gpg"
: 34850 ktrace RET execve -1 errno 2 No such file or directory
: 34850 ktrace CALL execve(0xbfbff360,0xbfbff880,0xbfbff88c)
: 34850 ktrace NAMI "/usr/sbin/gpg"
: 34850 ktrace RET execve -1 errno 2 No such file or directory
: 34850 ktrace CALL execve(0xbfbff360,0xbfbff880,0xbfbff88c)
: 34850 ktrace NAMI "/usr/bin/gpg"
: 34850 ktrace RET execve -1 errno 2 No such file or directory
: 34850 ktrace CALL execve(0xbfbff360,0xbfbff880,0xbfbff88c)
: 34850 ktrace NAMI "/usr/games/gpg"
: 34850 ktrace RET execve -1 errno 2 No such file or directory
: 34850 ktrace CALL execve(0xbfbff360,0xbfbff880,0xbfbff88c)
: 34850 ktrace NAMI "/usr/local/bin/gpg"
: 34850 ktrace NAMI "/usr/libexec/ld-elf.so.1"
: giorgos at gothmog[16:55]/home/giorgos$
Πλέον το gpg τρέχει με δικαιώματα root και δεν επιτρέπεται σαν
'giorgos' να μπορώ να βλέπω τι κάνει ενα setuid πρόγραμμα.
Αντίθετα, σαν superuser, μπορώ να συνεχίσω το tracing κανονικά:
: sysop at gothmog[16:51]/home/giorgos# kdump -f gpg.trace | grep mlock
: 34781 gpg CALL mlock(0x2829a000,0x4000)
: 34781 gpg RET mlock 0
Ο περιορισμός αυτός επιβάλλεται από τον ίδιο τον πυρήνα του FreeBSD,
στο αρχείο kern_ktrace[1]. Η ktrace() ψάχνει πρώτα να βρει στο
process list το struct proc *p το οποίο προσπαθεί ο user να κάνει
trace. 'Υστερα καλείται το p_candebug() από το kern_prot.c[2].
Οι έλεγχοι που κάνει το p_candebug() είναι οι εξής:
- Αν δεν είναι ενεργοποιημένο το superuser policy (ο χρήστης root
όντως έχει περισσότερα δικαιώματα) ή είναι το calling thread
περιορισμένο σε κάποιο jail (jail == chroot on steroids), τότε η
πρόσβαση απαγορεύεται.
- Αν υπάρχει κάποιος άλλος περιορισμός λόγω jail (η function
prison_check() αποτύχει), τότε η πρόσβαση απαγορεύεται.
- Αν το sysctl security.bsd.see_other_uids είναι μηδέν ή το real uid
του caller είναι διαφορετικό από το real uid του proc *p, τότε η
πρόσβαση απαγορεύεται.
- Οι τελευταίοι έλεγχοι είναι που μας ενδιαφέρουν όμως. Τρεις
διαφορετικοί έλεγχοι ενώνονται σε ένα if { ... } block.
1591 /*
1592 * Is p's group set a subset of td's effective group set? This
1593 * includes p's egid, group access list, rgid, and svgid.
1594 */
...
1606 /*
1607 * Are the uids present in p's credential equal to td's
1608 * effective uid? This includes p's euid, svuid, and ruid.
1609 */
...
1619 /*
1620 * If p's gids aren't a subset, or the uids aren't a subset,
1621 * or the credential has changed, require appropriate privilege
1622 * for td to debug p. For POSIX.1e capabilities, this will
1623 * require CAP_SYS_PTRACE.
1624 */
1625 if (!grpsubset || !uidsubset || credentialchanged) {
1626 error = suser_cred(td->td_ucred, PRISON_ROOT);
1627 if (error)
1628 return (error);
1629 }
Αυτό είναι που με περιορίζει εμένα να κάνω ktrace σε setuid
προγράμματα από απλό user. Και τώρα που διάβασα τι γίνεται και
κυρίως πως, μπορώ να πω ότι καταλαβαίνω γιατί το κάνουν αυτό :)
=== Αναφορές
[1] http://cvsweb.freebsd.org/src/sys/kern/kern_ktrace.c
[2] http://cvsweb.freebsd.org/src/sys/kern/kern_prot.c
More information about the Linux-greek-users
mailing list