<html><head><meta name="qrichtext" content="1" /></head><body style="font-size:10pt;font-family:Bitstream Vera Sans">
<p>On Tuesday 01 May 2007 09:12:18 Jan Evert van Grootheest wrote:</p>
<p>> > On Friday 27 April 2007 13:44:46 Jan Evert van Grootheest wrote:</p>
<p>> > > </p>
<p>> > > > > All,</p>
<p>> > > > > </p>
<p>> > > > > I think this got introduced in applets.c:check_suid with 17508 </p>
<p>> > > > > 'accumulated post-1.4.0 fixes'.</p>
<p>> > > > > </p>
<p>> > > > > This part of the diff seems responsible.</p>
<p>> > > > > -                        if ((sct->m_mode & (S_ISGID | S_IXGRP)) </p>
<p>> > > > > == (S_ISGID | S_IXGRP)) { /* *both* have to be set </p>
<p>> > for sgid */</p>
<p>> > > > > -                                xsetgid(sct->m_gid);</p>
<p>> > > > > -                        } else xsetgid(rgid); /* </p>
<p>> > > > > no sgid -> drop */</p>
<p>> > > > > -</p>
<p>> > > > > -                        if (sct->m_mode & S_ISUID) </p>
<p>> > xsetuid(sct->m_uid);</p>
<p>> > > > > -                        else xsetuid(ruid); /* </p>
<p>> > > > > no suid -> drop */</p>
<p>> > > > > +                        if (sct->m_gid != 0) {</p>
<p>> > > > > +                                /* _both_ have to be </p>
<p>> > set for sgid */</p>
<p>> > > > > +                                if ((sct->m_mode & (S_ISGID |</p>
<p>> > > > > S_IXGRP)) == (S_ISGID | S_IXGRP)) {</p>
<p>> > > > > +                                        xsetgid(sct->m_gid);</p>
<p>> > > > > +                                } else xsetgid(rgid); /* no</p>
<p>> > > > > sgid -> drop */</p>
<p>> > > > > +                        }</p>
<p>> > > > > +                        if (sct->m_uid != 0) {</p>
<p>> > > > > +                                if (sct->m_mode & S_ISUID)</p>
<p>> > > > > xsetuid(sct->m_uid);</p>
<p>> > > > > +                                else xsetuid(ruid); /* no suid</p>
<p>> > > > > -> drop */</p>
<p>> > > > > +                        }</p>
<p>> > > > > </p>
<p>> > > > > Previously if there was no sgid/suid, privileges would </p>
<p>> > always be </p>
<p>> > > > > dropped. Now they're only dropped if the uid/gid in </p>
<p>> > bb.conf is not </p>
<p>> > > > > 0.</p>
<p>> > > > > </p>
<p>> > > > > I would propose to revert this part of the patch.</p>
<p>> > > > > Adding an else to call xsetuid/xsetgid would seem to do </p>
<p>> > the right </p>
<p>> > > > > thing but, I guess, would only increase the size of the </p>
<p>> > > > > executable.</p>
<p>> > > > > </p>
<p>> > > > > This seems, by the way, to be a security bug? It leaves </p>
<p>> > processes </p>
<p>> > > > > with effective root all over!</p>
<p>> > > > > </p>
<p>> > > > > -- Jan Evert</p>
<p>> > > > > </p>
<p>> > > > > </p>
<p>> > > > > > -----Oorspronkelijk bericht-----</p>
<p>> > > > > > Van: busybox-bounces@busybox.net</p>
<p>> > > > > > [mailto:busybox-bounces@busybox.net] Namens Jan Evert van </p>
<p>> > > > Grootheest</p>
<p>> > > > > > Verzonden: vrijdag 27 april 2007 9:07</p>
<p>> > > > > > Aan: busybox@busybox.net</p>
<p>> > > > > > Onderwerp: /etc/busybox.conf confusion</p>
<p>> > > > > > </p>
<p>> > > > > > </p>
<p>> > > > > > Hi,</p>
<p>> > > > > > </p>
<p>> > > > > > The confusion is mine (not bb).</p>
<p>> > > > > > </p>
<p>> > > > > > If I have sh not in /etc/busybox.conf and I login as user</p>
<p>> > > > > mysql I get</p>
<p>> > > > > > this:</p>
<p>> > > > > > </p>
<p>> > > > > > viking-be# cat /proc/self/status | egrep "id:|Name"</p>
<p>> > > > > > Name: sh</p>
<p>> > > > > > Tgid: 1192</p>
<p>> > > > > > Pid: 1192</p>
<p>> > > > > > PPid: 1173</p>
<p>> > > > > > TracerPid: 0</p>
<p>> > > > > > Uid: 500 500 500 500</p>
<p>> > > > > > Gid: 500 500 500 500</p>
<p>> > > > > > viking-be# cat /proc/1173/status | egrep "id:|Name"</p>
<p>> > > > > > Name: sh</p>
<p>> > > > > > Tgid: 1173</p>
<p>> > > > > > Pid: 1173</p>
<p>> > > > > > PPid: 1064</p>
<p>> > > > > > TracerPid: 0</p>
<p>> > > > > > Uid: 500 500 500 500</p>
<p>> > > > > > Gid: 500 500 500 500</p>
<p>> > > > > > </p>
<p>> > > > > > </p>
<p>> > > > > > Now, when I put sh in the busybox.conf file as using</p>
<p>> > > > > > sh = xxx 0.0</p>
<p>> > > > > > And login again and try the same this is the result </p>
<p>> > viking-be# </p>
<p>> > > > > > cat /proc/self/status | egrep "id:|Name"</p>
<p>> > > > > > Name: sh</p>
<p>> > > > > > Tgid: 1206</p>
<p>> > > > > > Pid: 1206</p>
<p>> > > > > > PPid: 1203</p>
<p>> > > > > > TracerPid: 0</p>
<p>> > > > > > Uid: 500 0 0 0</p>
<p>> > > > > > Gid: 500 0 0 0</p>
<p>> > > > > > viking-be# cat /proc/1203/status | egrep "id:|Name"</p>
<p>> > > > > > Name: sh</p>
<p>> > > > > > Tgid: 1203</p>
<p>> > > > > > Pid: 1203</p>
<p>> > > > > > PPid: 1064</p>
<p>> > > > > > TracerPid: 0</p>
<p>> > > > > > Uid: 500 0 0 0</p>
<p>> > > > > > Gid: 500 0 0 0</p>
<p>> > > > > > </p>
<p>> > > > > > </p>
<p>> > > > > > I am confused, because I was expecting the same output. I </p>
<p>> > > > > > thought</p>
<p>> > > > > > that xxx meant that the applet is a regular executable </p>
<p>> > > > that doesn't</p>
<p>> > > > > > change effective uid and gid. But apparently it does?</p>
<p>> > > > > > </p>
<p>> > > > > > So can anyone explain this?</p>
<p>> > > > > > Which part of the process do I not understand?</p>
<p>> > > > > > My guess would be that the problem, if at all, is with</p>
<p>> > > > the starting</p>
<p>> > > > > > shell, because busybox is suid root and bb.conf is read during</p>
<p>> > > > > > startup.</p>
<p>> > > > > > </p>
<p>> > > > > > This is a login via the bb telnetd (which is, of course,</p>
<p>> > > > running as</p>
<p>> > > > > > root) and using the bb login (which is xxx in</p>
<p>> > > > busybox.conf). And it</p>
<p>> > > > > > concerns bb 1.4.1 (with all patches, as far as I know)</p>
<p>> > > > using glibc</p>
<p>> > > > > > 2.3.6 on i386.</p>
<p>> > > > > > </p>
<p>> > > > > > Also note the 'Name' of cat. It is 'sh'. I would </p>
<p>> > guess this to </p>
<p>> > > > > > be</p>
<p>> > > > > > due to cat being a safe applet.</p>
<p>> > > > > > </p>
<p>> > > > > > Many thanks,</p>
<p>> > > > > > Jan Evert</p>
<p>> > > > > > </p>
<p>> > > > </p>
<p>> > > > </p>
<p>> > > > I think more changes are needed. Passwd and su are not really</p>
<p>> > > > behaving well:</p>
<p>> > > > </p>
<p>> > > > I'm now trying to change the password of a regular user</p>
<p>> > > > (mysql). If I have the passwd applet in bb.conf as xxx it, </p>
<p>> > > > obviously, is not able to read /etc/shadow. If I have the </p>
<p>> > > > passwd applet in bb.conf as sxx then it attempts to change </p>
<p>> > > > the password of root. If I have the passwd applet in bb.conf </p>
<p>> > > > as sxx and attempt 'passwd mysql' when logged in as mysql, </p>
<p>> > > > then the correct password is changed, but without asking for </p>
<p>> > > > the old password!</p>
<p>> > > > </p>
<p>> > > > Something comparable is happening to the su applet. When</p>
<p>> > > > executed as a regular user: With su as xxx, it asks for the </p>
<p>> > > > password and then fails to set groups. With su as sxx, it </p>
<p>> > > > doesn't ask for the password and drops straight into a shell </p>
<p>> > > > with the correct user (just as if root had executed it).</p>
<p>> > > > </p>
<p>> > > > Any ideas?</p>
<p>> > > > </p>
<p>> > > > Thanks,</p>
<p>> > > > Jan Evert</p>
<p>> > > </p>
<p>> > > I think I figured it out.</p>
<p>> > > </p>
<p>> > > A suid program has effective uid of the owner of the </p>
<p>> > program (usually </p>
<p>> > > that will be root). And the real uid is the uid of the </p>
<p>> > logged in user </p>
<p>> > > (for example, mysql). If a suid root program executes </p>
<p>> > setuid(x), the </p>
<p>> > > real and effective uids are changed to become x. Same goes for gid.</p>
<p>> > > </p>
<p>> > > And that is the bug. Busybox is suid root. If an applet is </p>
<p>> > supposed to </p>
<p>> > > be suid, a setuid is done changing the real uid to root. Thus, for </p>
<p>> > > example, su and passwd think they are executed by root and behave </p>
<p>> > > differently! However, bb doesn't need to setuid because the </p>
<p>> > effective </p>
<p>> > > uid is already root because the program is suid root.</p>
<p>> > > </p>
<p>> > > So I came up with this patch which I think does the right </p>
<p>> > thing. This </p>
<p>> > > is against 1.4.1.</p>
<p>> > > </p>
<p>> > > Thanks,</p>
<p>> > > Jan Evert</p>
<p>> > > </p>
<p>> > </p>
<p>> > Hi,</p>
<p>> > this seems to work for me:</p>
<p>> > busybox.conf is</p>
<p>> > </p>
<p>> > [SUID]</p>
<p>> > passwd = ssx 0.0</p>
<p>> > # applet su can be run by anyone and runs with euid=0/egid=0</p>
<p>> > su = ssx root.0 </p>
<p>> > # applet su can be run by anyone and runs with euid=0/egid=0</p>
<p>> > </p>
<p>> > </p>
<p>> > root@localhost:~/Desktop/busybox# chown 0.0 /etc/busybox.conf</p>
<p>> > root@localhost:~/Desktop/busybox# chmod 600 /etc/busybox.conf </p>
<p>> > </p>
<p>> > root@localhost:~/Desktop/busybox# cp busybox /usr/bin/passwd</p>
<p>> > root@localhost:~/Desktop/busybox# chown 0.0 /usr/bin/passwd</p>
<p>> > root@localhost:~/Desktop/busybox# chmod 4755 /usr/bin/passwd</p>
<p>> > </p>
<p>> > Running as normal user:</p>
<p>> > </p>
<p>> > root@localhost:~/Desktop/busybox# cat /proc/18601/status</p>
<p>> > Name: passwd</p>
<p>> > State: S (sleeping)</p>
<p>> > SleepAVG: 88%</p>
<p>> > Tgid: 18601</p>
<p>> > Pid: 18601</p>
<p>> > PPid: 15912</p>
<p>> > TracerPid: 0</p>
<p>> > Uid: 1000 0 0 0</p>
<p>> > Gid: 1000 1000 1000 1000</p>
<p>> > FDSize: 256</p>
<p>> > Groups: 7 20 24 25 29 46 111 113 1000 1002 1003</p>
<p>> > </p>
<p>> > tito@localhost:~$ id</p>
<p>> > uid=1000(tito) gid=1000(tito) </p>
<p>> > groups=7(lp),20(dip),24(cdrom),25(floppy),29(audio),46(plugdev</p>
<p>> > ),111(admin),113(fuse),1000(tito),1002(vboxusers),1003(halt)</p>
<p>> > tito@localhost:~$ /usr/bin/passwd</p>
<p>> > ruid = 1000 /*debug */</p>
<p>> > busybox.conf readable /*debug */</p>
<p>> > found su /*debug */</p>
<p>> > found passwd /*debug */</p>
<p>> > requested uid 0 gid 0 /*debug */</p>
<p>> > Changing password for tito</p>
<p>> > Old password:</p>
<p>> > New password:</p>
<p>> > Bad password: too weak</p>
<p>> > passwd: password for tito is unchanged</p>
<p>> > </p>
<p>> > then changing busybox.conf to</p>
<p>> > </p>
<p>> > [SUID]</p>
<p>> > passwd = ssx 0.0</p>
<p>> > </p>
<p>> > tito@localhost:~$ /usr/bin/passwd</p>
<p>> > ruid = 1000</p>
<p>> > busybox.conf readable</p>
<p>> > found su</p>
<p>> > found passwd</p>
<p>> > requested uid 0 gid 0</p>
<p>> > Changing password for tito</p>
<p>> > Old password:</p>
<p>> > Incorrect password</p>
<p>> > passwd: password for tito is unchanged</p>
<p>> > tito@localhost:~$ </p>
<p>> > </p>
<p>> > </p>
<p>> > it is not possible to change password.</p>
<p>> > </p>
<p>> > Running as root:</p>
<p>> > </p>
<p>> > root@localhost:~/Desktop# cat /proc/18582/status</p>
<p>> > Name: passwd</p>
<p>> > State: S (sleeping)</p>
<p>> > SleepAVG: 58%</p>
<p>> > Tgid: 18582</p>
<p>> > Pid: 18582</p>
<p>> > PPid: 12012</p>
<p>> > TracerPid: 0</p>
<p>> > Uid: 0 0 0 0</p>
<p>> > Gid: 0 0 0 0</p>
<p>> > </p>
<p>> > root@localhost:~/Desktop# /usr/bin/passwd</p>
<p>> > ruid = 0 /* debug */</p>
<p>> > Changing password for root</p>
<p>> > New password:</p>
<p>> > Bad password: too weak</p>
<p>> > Retype password:</p>
<p>> > Passwords don't match</p>
<p>> > passwd: password for root is unchanged</p>
<p>> > root@localhost:~/Desktop#</p>
<p>> </p>
<p>> Tito, others,</p>
<p>> </p>
<p>> Sorry about this, but those su and passwd comments were with my initial</p>
<p>> patch applied.</p>
<p>> </p>
<p>> With original code, it is easiest to demonstrate using 'cat</p>
<p>> /proc/self/status' with a suid root bbox and as a regular user. Try both</p>
<p>> with cat in bbox.conf as xxx and cat not present in bbox.conf.</p>
<p>> When cat is present as xxx, privileges are not dropped.</p>
<p>> </p>
<p>> I ran into this because my environment had ash and sh as ssx in</p>
<p>> bbox.conf. Which I changed to xxx. And then still had not proper</p>
<p>> uids/gids.</p>
<p>> </p>
<p>> -- Jan Evert </p>
<p>Hi,</p>
<p>mv busybox /bin/busybox</p>
<p>chown 0.0 /bin/busybox</p>
<p>chmod 4755 /bin/busybox</p>
<p></p>
<p>1 ) not in busybox.conf:</p>
<p>        as normal user /bin/busybox cat /proc/self/status does not work</p>
<p></p>
<p>2) in busybox.conf</p>
<p>2a)        as normal user and cat = ssx 0.0 in busybox.conf </p>
<p>        /bin/busybox cat /proc/self/status works</p>
<p>        Name: busybox</p>
<p>        State: R (running)</p>
<p>        SleepAVG: 88%</p>
<p>        Tgid: 6937</p>
<p>        Pid: 6937</p>
<p>        PPid: 6416</p>
<p>        TracerPid: 0</p>
<p>        Uid: 1000 0 0 0</p>
<p>        Gid: 1000 1000 1000 1000</p>
<p></p>
<p>2b) as normal user and cat = xxx 0.0 in busybox.conf </p>
<p>        /bin/busybox cat /proc/self/status does not work</p>
<p></p>
<p>        if in [SUID] stanza alphabetical order is respected</p>
<p>        [SUID]</p>
<p>        cat = xxx 0.0</p>
<p>        passwd = ssx 0.0</p>
<p>        # applet su can be run by anyone and runs with euid=0/egid=0</p>
<p>        su = ssx root.0</p>
<p>        # applet su can be run by anyone and runs with euid=0/egid=0</p>
<p></p>
<p>2c) as normal user and cat = xxx 0.0 in busybox.conf it works</p>
<p>        </p>
<p>        /bin/busybox cat /proc/self/status works</p>
<p></p>
<p>        if in [SUID] stanza alphabetical order is not respected</p>
<p>        [SUID]</p>
<p>        passwd = ssx 0.0</p>
<p>        # applet su can be run by anyone and runs with euid=0/egid=0</p>
<p>        su = ssx root.0</p>
<p>        # applet su can be run by anyone and runs with euid=0/egid=0</p>
<p>        cat = xxx 0.0</p>
<p></p>
<p>        Name: busybox</p>
<p>        State: R (running)</p>
<p>        SleepAVG: 58%</p>
<p>        Tgid: 6953</p>
<p>        Pid: 6953</p>
<p>        PPid: 6416</p>
<p>        TracerPid: 0</p>
<p>        Uid: 1000 0 0 0</p>
<p>        Gid: 1000 1000 1000 1000</p>
<p></p>
<p>Seems that there is really something wrong here....</p>
<p></p>
<p>IMHO check_suid and parse_config_file should be totally rewritten,</p>
<p>the first to make it more readable and the second to reduce the bloat as most of its features </p>
<p>are unused at the moment.</p>
<p></p>
<p>Ciao,</p>
<p>Tito</p>
<p></p>
</body></html>