[Bug 486944] Re: Different permission denied errors

Roger Leigh rleigh at codelibre.net
Sun Mar 7 01:07:22 UTC 2010


[GnuTLS maintainers: I'd appreciate some input on this regarding gcrypt
dropping root privs inappropriately, which causes massive breakage]

original report came from https://bugs.launchpad.net/ubuntu/+source/schroot/+bug/486944

On Sun, Mar 07, 2010 at 10:57:44AM +1100, Brian May wrote:
> You previous email didn't seem to come out on Launchpad, so I will
> just reply here.

No problem (the Debian BTS is rather easier to deal with--I only
noticed this bug by random chance).  From the log below, it's showing
entry into the pam_ldap module.  This was triggered by a call to
pam_acct_mgmt() in libpam from within schroot following successful
authentication:

> #25 0x00007fc554eb5cc1 in pam_sm_acct_mgmt () from /lib/security/pam_ldap.so

it then enters libldap with this call

> #21 0x00007fc554c9c58e in ldap_start_tls_s () from /usr/lib/libldap_r-2.4.so.2

and then into gnutls until this call

> #9  0x00007fc5543c09af in wrap_gcry_mac_init (algo=<value optimized
> out>, ctx=0x2713) at mac-libgcrypt.c:42

at which point we go into libgcrypt and then the buggy setuid call
comes from lock_pool in src/secmem.c:

  if (uid && ! geteuid ())
    {
      /* check that we really dropped the privs.
       * Note: setuid(0) should always fail */
      if (setuid (uid) || getuid () != geteuid () || !setuid (0))
        log_fatal ("failed to reset uid: %s\n", strerror (errno));
    }

So from the information we have, I'd blame this upon libgcrypt.
It's using root privs if available to lock memory pages into core,
but makes the assumption that if we aren't root we want to drop root
privileges.  For a setuid program, this assumption is incorrect.

To be honest, this looks completely wrong.  There are three cases:
1) running as normal user
   - we never enter the block
2) running as root
   - we never enter the block
3) running setuid root where uid != 0 and geteuid() == 0
   - here we break things

So the entire block looks completely pointless.  Any setuid program
calling into libgcrypt will break.  And due to using PAM, we don't
even know it's going to happen!  It's up to the setuid program
code to drop privs, not a random library.  As we've seen, in our
case we would have dropped the privs much later, and dropping them
at this point results in the program being completely broken due to
not having the privileges to complete its setup tasks.


Regards,
Roger

> On 7 March 2010 06:59, Roger Leigh <rleigh at codelibre.net> wrote:
> > This seems rather more likely than something intrinsic to schroot.
> > You should be able to confirm this with gdb by breaking on calls
> > to setuid and then doing a backtrace.  schroot itself only calls
> > setuid() prior to invoking the command in the chroot, and then again to
> > check that privs were dropped correctly.  This should tell us which
> > library/function called it.
> 
> What gdb shows me seems just so weird, I am just going to print the
> results here, without trying to make sense of them.
> 
> Note I installed the -dbg packages for libgcrypt and libgnutls.
> 
> GNU gdb (GDB) 7.0-ubuntu
> Copyright (C) 2009 Free Software Foundation, Inc.
> License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
> This is free software: you are free to change and redistribute it.
> There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
> and "show warranty" for details.
> This GDB was configured as "x86_64-linux-gnu".
> For bug reporting instructions, please see:
> <http://www.gnu.org/software/gdb/bugs/>...
> Reading symbols from /usr/bin/schroot...(no debugging symbols found)...done.
> (gdb) set args -c lenny
> (gdb) r
> Starting program: /usr/bin/schroot -c lenny
> [Thread debugging using libthread_db enabled]
> E: /dev/vg/schroot-lenny: Failed to stat file: Permission denied
> 
> Program exited normally.
> (gdb) break setuid
> Breakpoint 1 at 0x7f0fb948ae80
> (gdb) r
> Starting program: /usr/bin/schroot -c lenny
> [Thread debugging using libthread_db enabled]
> 
> Breakpoint 1, 0x00007fc557984e80 in setuid () from /lib/libc.so.6
> (gdb) bt
> #0  0x00007fc557984e80 in setuid () from /lib/libc.so.6
> #1  0x00007fc553cf3004 in lock_pool (n=<value optimized out>) at secmem.c:296
> #2  secmem_init (n=<value optimized out>) at secmem.c:477
> #3  0x00007fc553cf31ba in _gcry_secmem_malloc_internal (size=128) at
> secmem.c:509
> #4  0x00007fc553cf3248 in _gcry_secmem_malloc (size=128) at secmem.c:544
> #5  0x00007fc553cee74d in do_malloc (n=10003, flags=32768,
> mem=0x7fff1951a9a8) at global.c:730
> #6  0x00007fc553cee77c in _gcry_malloc_secure (n=10003) at global.c:769
> #7  0x00007fc553d00fd0 in md_open (h=0x7fff1951aa18, algo=1,
> secure=<value optimized out>, hmac=<value optimized out>) at md.c:487
> #8  0x00007fc553d010fa in _gcry_md_open (h=0x7fff1951ab08, algo=32768,
> flags=<value optimized out>) at md.c:530
> #9  0x00007fc5543c09af in wrap_gcry_mac_init (algo=<value optimized
> out>, ctx=0x2713) at mac-libgcrypt.c:42
> #10 0x00007fc5543a6ee7 in _gnutls_hmac_init (dig=0x7fff1951ab00,
> algorithm=GNUTLS_MAC_MD5, key=0x2112350, keylen=24) at
> gnutls_hash_int.c:277
> #11 0x00007fc5543b7b38 in _gnutls_P_hash (algorithm=<value optimized
> out>, secret=<value optimized out>, secret_size=<value optimized out>,
> seed=<value optimized out>, seed_size=<value optimized out>,
> total_bytes=<value optimized out>, ret=0x7fff1951ad60
> "\354\255Q\031\377\177") at gnutls_state.c:811
> #12 0x00007fc5543b7d8a in _gnutls_PRF (session=<value optimized out>,
> secret=<value optimized out>, secret_size=<value optimized out>,
> label=<value optimized out>, label_size=<value optimized out>,
>     seed=0x7fff1951b160
> "K\222\352\274\311\367\273\213Y\314\356\252Lu-\325y\341\265\300,\t\311/\342\237\066\v\025\031l\373K\222\352\274/g\363\270\370\020\037[:\347b\037\033\223\322\070\257bɊ\271\340\f\342]\030\212=\001",
> seed_size=<value optimized out>, total_bytes=48, ret=0x210c692) at
> gnutls_state.c:926
> #13 0x00007fc5543a55ff in generate_normal_master (session=0x210c670,
> keep_premaster=0) at gnutls_kx.c:155
> #14 0x00007fc5543b037b in _gnutls_connection_state_init
> (session=0x2713) at gnutls_constate.c:434
> #15 0x00007fc5543a11c8 in _gnutls_send_handshake_final
> (session=0x210c670, init=1) at gnutls_handshake.c:2472
> #16 0x00007fc5543a13a5 in _gnutls_handshake_common (session=0x210c670)
> at gnutls_handshake.c:2693
> #17 0x00007fc5543a2a37 in gnutls_handshake (session=0x210c670) at
> gnutls_handshake.c:2297
> #18 0x00007fc554c9d40e in ?? () from /usr/lib/libldap_r-2.4.so.2
> #19 0x00007fc554c9c1d2 in ?? () from /usr/lib/libldap_r-2.4.so.2
> #20 0x00007fc554c9c433 in ldap_int_tls_start () from /usr/lib/libldap_r-2.4.so.2
> #21 0x00007fc554c9c58e in ldap_start_tls_s () from /usr/lib/libldap_r-2.4.so.2
> #22 0x00007fc554eb2b84 in ?? () from /lib/security/pam_ldap.so
> #23 0x00007fc554eb4f37 in ?? () from /lib/security/pam_ldap.so
> #24 0x00007fc554eb51a1 in ?? () from /lib/security/pam_ldap.so
> #25 0x00007fc554eb5cc1 in pam_sm_acct_mgmt () from /lib/security/pam_ldap.so
> #26 0x00007fc558f71bde in ?? () from /lib/libpam.so.0
> #27 0x000000000048d7a0 in ?? ()
> #28 0x0000000000477f56 in ?? ()
> #29 0x000000000042cabb in ?? ()
> #30 0x0000000000422ef7 in ?? ()
> #31 0x0000000000414089 in ?? ()
> #32 0x00007fc5578feabd in __libc_start_main () from /lib/libc.so.6
> #33 0x0000000000411b29 in ?? ()
> #34 0x00007fff1951cda8 in ?? ()
> #35 0x000000000000001c in ?? ()
> #36 0x0000000000000003 in ?? ()
> #37 0x00007fff1951e6df in ?? ()
> #38 0x00007fff1951e6f0 in ?? ()
> #39 0x00007fff1951e6f3 in ?? ()
> #40 0x0000000000000000 in ?? ()
> (gdb) c
> Continuing.
> 
> Breakpoint 1, 0x00007fc557984e80 in setuid () from /lib/libc.so.6
> (gdb) bt
> #0  0x00007fc557984e80 in setuid () from /lib/libc.so.6
> #1  0x00007fc553cf301f in lock_pool (n=<value optimized out>) at secmem.c:296
> #2  secmem_init (n=<value optimized out>) at secmem.c:477
> #3  0x00007fc553cf31ba in _gcry_secmem_malloc_internal (size=128) at
> secmem.c:509
> #4  0x00007fc553cf3248 in _gcry_secmem_malloc (size=128) at secmem.c:544
> #5  0x00007fc553cee74d in do_malloc (n=0, flags=0, mem=0x7fff1951a9a8)
> at global.c:730
> #6  0x00007fc553cee77c in _gcry_malloc_secure (n=0) at global.c:769
> #7  0x00007fc553d00fd0 in md_open (h=0x7fff1951aa18, algo=1,
> secure=<value optimized out>, hmac=<value optimized out>) at md.c:487
> #8  0x00007fc553d010fa in _gcry_md_open (h=0x7fff1951ab08, algo=0,
> flags=<value optimized out>) at md.c:530
> #9  0x00007fc5543c09af in wrap_gcry_mac_init (algo=<value optimized
> out>, ctx=0x0) at mac-libgcrypt.c:42
> #10 0x00007fc5543a6ee7 in _gnutls_hmac_init (dig=0x7fff1951ab00,
> algorithm=GNUTLS_MAC_MD5, key=0x2112350, keylen=24) at
> gnutls_hash_int.c:277
> #11 0x00007fc5543b7b38 in _gnutls_P_hash (algorithm=<value optimized
> out>, secret=<value optimized out>, secret_size=<value optimized out>,
> seed=<value optimized out>, seed_size=<value optimized out>,
> total_bytes=<value optimized out>, ret=0x7fff1951ad60
> "\354\255Q\031\377\177") at gnutls_state.c:811
> #12 0x00007fc5543b7d8a in _gnutls_PRF (session=<value optimized out>,
> secret=<value optimized out>, secret_size=<value optimized out>,
> label=<value optimized out>, label_size=<value optimized out>,
>     seed=0x7fff1951b160
> "K\222\352\274\311\367\273\213Y\314\356\252Lu-\325y\341\265\300,\t\311/\342\237\066\v\025\031l\373K\222\352\274/g\363\270\370\020\037[:\347b\037\033\223\322\070\257bɊ\271\340\f\342]\030\212=\001",
> seed_size=<value optimized out>, total_bytes=48, ret=0x210c692) at
> gnutls_state.c:926
> #13 0x00007fc5543a55ff in generate_normal_master (session=0x210c670,
> keep_premaster=0) at gnutls_kx.c:155
> #14 0x00007fc5543b037b in _gnutls_connection_state_init (session=0x0)
> at gnutls_constate.c:434
> #15 0x00007fc5543a11c8 in _gnutls_send_handshake_final
> (session=0x210c670, init=1) at gnutls_handshake.c:2472
> #16 0x00007fc5543a13a5 in _gnutls_handshake_common (session=0x210c670)
> at gnutls_handshake.c:2693
> #17 0x00007fc5543a2a37 in gnutls_handshake (session=0x210c670) at
> gnutls_handshake.c:2297
> #18 0x00007fc554c9d40e in ?? () from /usr/lib/libldap_r-2.4.so.2
> #19 0x00007fc554c9c1d2 in ?? () from /usr/lib/libldap_r-2.4.so.2
> #20 0x00007fc554c9c433 in ldap_int_tls_start () from /usr/lib/libldap_r-2.4.so.2
> #21 0x00007fc554c9c58e in ldap_start_tls_s () from /usr/lib/libldap_r-2.4.so.2
> #22 0x00007fc554eb2b84 in ?? () from /lib/security/pam_ldap.so
> #23 0x00007fc554eb4f37 in ?? () from /lib/security/pam_ldap.so
> #24 0x00007fc554eb51a1 in ?? () from /lib/security/pam_ldap.so
> #25 0x00007fc554eb5cc1 in pam_sm_acct_mgmt () from /lib/security/pam_ldap.so
> #26 0x00007fc558f71bde in ?? () from /lib/libpam.so.0
> #27 0x000000000048d7a0 in ?? ()
> #28 0x0000000000477f56 in ?? ()
> #29 0x000000000042cabb in ?? ()
> #30 0x0000000000422ef7 in ?? ()
> #31 0x0000000000414089 in ?? ()
> #32 0x00007fc5578feabd in __libc_start_main () from /lib/libc.so.6
> #33 0x0000000000411b29 in ?? ()
> #34 0x00007fff1951cda8 in ?? ()
> #35 0x000000000000001c in ?? ()
> #36 0x0000000000000003 in ?? ()
> #37 0x00007fff1951e6df in ?? ()
> #38 0x00007fff1951e6f0 in ?? ()
> #39 0x00007fff1951e6f3 in ?? ()
> #40 0x0000000000000000 in ?? ()
> (gdb) r
> The program being debugged has been started already.
> Start it from the beginning? (y or n) n
> Program not restarted.
> (gdb) c
> Continuing.
> E: /dev/vg/schroot-lenny: Failed to stat file: Permission denied
> 
> Program exited normally.
> 
> -- 
> Brian May <brian at microcomaustralia.com.au>

-- 
  .''`.  Roger Leigh
 : :' :  Debian GNU/Linux             http://people.debian.org/~rleigh/
 `. `'   Printing on GNU/Linux?       http://gutenprint.sourceforge.net/
   `-    GPG Public Key: 0x25BFB848   Please GPG sign your mail.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 197 bytes
Desc: Digital signature
URL: <http://lists.alioth.debian.org/pipermail/pkg-gnutls-maint/attachments/20100307/d16f5b26/attachment.pgp>


More information about the Pkg-gnutls-maint mailing list