svn commit: r277652 - in head/usr.sbin/pw: . tests

Bruce Evans brde at optusnet.com.au
Sun Jan 25 15:31:29 UTC 2015


On Sun, 25 Jan 2015, Slawa Olhovchenkov wrote:

> On Sun, Jan 25, 2015 at 04:56:24PM +1100, Bruce Evans wrote:
>
>> Negative ids have historical abuses in places like mountd.  mountd still
>> hard-codes -2 and -2 for the default uid and gid of an unprivileged user.
>> It at least casts these values to uid_t and gid_t before using them.
>> This gives the ids the non-random values of UINT32_MAX-1 if uid_t and
>> gid_t are uint32_t.  (If uid_t and gid_t were signed, then it would
>> leave the values as negative, so invalid.)  These magic values may work
>> better than when ids were 16 bits, since there is less risk of them
>> conflicting with a normal id.  However, the non-conflict is probably
>> a bug.  FreeBSD uses the magic ids of 65534 for user nobody: group
>> nobody.  These would have been (id_t)-2 with 16-bit ids.  They no
>> longer match, so ls displays (id_t)-2 numerically.  FreeBSD also has
>> a group nogroup = 65553 that doesn't match the nfs usage.  However2,
>> in FreeBSD-1 wher ids were 16-bits, nobody was 32767 and nogroup was
>> 32766. so they didn't match nfs for other reasons.  The 2 non-groups
>> now seem to be just a bug -- FreeBSD-1 didn't have group nobody.
>> 4.4BSD-Lite2 has the same values as FreeBSD-1.
>
> This is not full true for ZFS case.
> On ZFS nobody is 2^32-2.

File systems don't get to decide this.  zfs actually uses 2^16-2.  It
claims to use the standard POSIX id for the user nobody, but there are
no such thing in POSIX (except (*id_t)-1 means "no value" for some
syscalls) so it must not be used otherwise).  zfs actually uses the
FreeBSD values UID_NOBODY and GID_NOBODY, so it is at least consistent
with the default /etc/passwd and /etc/group, unlike nfs.  I added the
hard-coded UID_* and GID_* as quick fixes for devfs in 1996, since
parsing the password database to get them in the correct way is too
hard.  This hack is still used today :-(.  Except, I didn't add the
NOBODY ids.  These are not used by any file system.  They are hacks
for devfs alone, mislayered into a devfs (device-specific) header.
The sysadmin can easily break all these hard-coded values by editing
the password database, but shouldn't.

Googling "POSIX uid nobody" finds no early POSIX hits, but some warnings
that the magic ids are non-POSIX.  Wikipedia gives the following magic
ids:
   0: normally the superuser.  This is probably still hard-coded in many
      places in FreeBSD, though many places were fixed in the conversion
      from suser() to priv_check().
   (uid_t)-1: POSIX standard for omitted arg
   -2: historical nobody
   32767: another historical nobody, still used by OpenBSD
   65534: another nobody, now used by many Linux distributions for
 	 compatibilty betwen 16-bit and 32-bit ids.  Default Linux
 	 return value for the id returned by 16-bit syscalls when
 	 the value is too large.  [Linux switched to 32-bit ids much
 	 later than FreeBSD, so it has to be more careful with
 	 compatibility.  The Linux emulator in FreeBSD is both
 	 incompatible and insecure here -- it doesn't return 65534,
 	 but truncates using blind assignment.]
   99: statically allocate 0-99 for system use and use the last value
       in the range for nobody.

Bruce


More information about the svn-src-head mailing list