On Thu, 1 Sep 2016, Edho Arief wrote:> Date: Thu, 1 Sep 2016 15:43:58 > From: Edho Arief <me at myconan.net> > To: freebsd-security at freebsd.org > Subject: Re: edit others user crontab, security bug > > Hi, > > On Thu, Sep 1, 2016, at 21:47, Andrii Kuzik wrote: > > Probably a lot of freebsd servers affected > > > > Security bug allows to edit other users crontab > > > > root# pw useradd -n www.promspecbud.com -g nobody -s /bin/sh -d /tmp > > root# pw useradd -n www.promspecbud.com.other -g nobody -s /bin/sh -d > > /tmp > > root# echo @daily doit baby > /tmp/test > > root# crontab -u www.promspecbud.com.other /tmp/test > > root# crontab -u www.promspecbud.com -l > > > > =====output ====> > @daily doit baby > > ================> > > > root#echo @daily doit baby one more time>> /tmp/test > > root#sudo -u www.promspecbud.com.other crontab /tmp/test > > root#sudo -u www.promspecbud.com crontab -l > > =====output ====> > @daily doit baby > > @daily doit baby one more time > > ================> > > > > to be more specific, the bug is crontab truncates usernames to 19 > characters as defined in cron.h: > > #define MAX_UNAME 20 /* max length of username, should be > overkill */ > > > # pw useradd users12345names67890 > # crontab -u users12345names67890 -l > crontab: no crontab for users12345names6789 > ^-- cut offapart from the crontab user length there seem to be quite a lot of possible values to choose from (MAXLOGNAME being the FreeBSD standard, right?) $ cd /usr/include $ egrep "^#define.*(USER|LOG)" */*h *.h| grep MAX |grep NAME bsm/libbsm.h:#define AU_USER_NAME_MAX 50 netsmb/smb.h:#define SMB_MAXUSERNAMELEN 128 sys/param.h:#define MAXLOGNAME 33 /* max login name length (incl. NUL) */ sys/sysctl.h:#define USER_TZNAME_MAX 20 /* int: POSIX2_TZNAME_MA X */ limits.h:#define _POSIX_LOGIN_NAME_MAX 9 stdio.h:#define L_cuserid 17 /* size for cuserid(3); MAXLOGNAME, lega cy */ unistd.h:#define _SC_LOGIN_NAME_MAX 73 -- Damian Weber
<<On Thu, 1 Sep 2016 18:56:04 +0200 (CEST), Damian Weber <dweber at htwsaar.de> said:> bsm/libbsm.h:#define AU_USER_NAME_MAX 50That's fine, since it means that the user name in an audit record (i.e., output data) is bigger than what FreeBSD needs.> netsmb/smb.h:#define SMB_MAXUSERNAMELEN 128Not sure that this matters for anything.> sys/param.h:#define MAXLOGNAME 33 /* max login name length > (incl. NUL) */This is the one that matters.> sys/sysctl.h:#define USER_TZNAME_MAX 20 /* int: POSIX2_TZNAME_MA > X */Not relevant.> limits.h:#define _POSIX_LOGIN_NAME_MAX 9This is the POSIX "minimum maximum" -- i.e., all POSIX systems must support at least this value.> stdio.h:#define L_cuserid 17 /* size for cuserid(3); MAXLOGNAME, lega > cy */Legacy interface that should not be used.> unistd.h:#define _SC_LOGIN_NAME_MAX 73Because we do not define LOGIN_NAME_MAX, portable applications are required to use sysconf(3) to find out what {LOGIN_NAME_MAX} (i.e., the parameter, not the C-language macro) in the running system actually is. This is the "key" which allows them to retrieve that value; it is just an arbitrary integer (could be an enum if we went in for that sort of thing). I see now that this was fixed by emaste@ yesterday (r305269). I'm a bit disappointed that it was done using MAXLOGNAME, but looking at the way it's used in the code, fixing it to use the proper POSIX parameter {LOGIN_NAME_MAX} would require significant restructuring, since the arrays that are currently statically allocated would have to be replaced with dynamic allocations. There are other static limits in this old code that should probably also be replaced, for safety, but don't represent a problem currently. -GAWollman