From owner-freebsd-hackers  Fri Feb 28 08:52:00 1997
Return-Path: <owner-hackers>
Received: (from root@localhost)
          by freefall.freebsd.org (8.8.5/8.8.5) id IAA05221
          for hackers-outgoing; Fri, 28 Feb 1997 08:52:00 -0800 (PST)
Received: from godzilla.zeta.org.au (godzilla.zeta.org.au [203.2.228.19])
          by freefall.freebsd.org (8.8.5/8.8.5) with ESMTP id IAA05212;
          Fri, 28 Feb 1997 08:51:43 -0800 (PST)
Received: (from bde@localhost) by godzilla.zeta.org.au (8.8.3/8.6.9) id DAA20965; Sat, 1 Mar 1997 03:47:38 +1100
Date: Sat, 1 Mar 1997 03:47:38 +1100
From: Bruce Evans <bde@zeta.org.au>
Message-Id: <199702281647.DAA20965@godzilla.zeta.org.au>
To: bde@freebsd.org, jkh@time.cdrom.com
Subject: Re: Will the real uid_t please stand up?
Cc: hackers@freebsd.org
Sender: owner-hackers@freebsd.org
X-Loop: FreeBSD.org
Precedence: bulk

>Following some of the discussion in port-i386@NetBSD.org about this,
>I decided to look into FreeBSD's own uid_t situation and noticed the
>following "interesting things" in 2.2 and -current:
>
>/usr/include/g++/_G_config.h:typedef unsigned int _G_uid_t;
>
>OK, one vote for unsigned int.
>
>/usr/include/kerberosIV/krb.h:typedef unsigned short uid_t;
>
>Ooh, and one for unsigned short!  Fortunately, this one is disabled
>by an ifdef but it probably should still be changed.
>
>/usr/include/sys/types.h:typedef        u_int32_t       uid_t;          /* user 

Ony <sys/types.h> is authoritative.

>And the check in /usr/src/usr.sbin/pwd_mkdb/pw_scan.c does indeed say:
>
>        if (id > USHRT_MAX) {
>                warnx("%s > max uid value (%d)", p, USHRT_MAX);
>                /*return (0);*/ /* THIS SHOULD NOT BE FATAL! */
>        }
>
>(same mistake made for gid_t).  It's not fatal, but it certainly doesn't
>seem right.

We decided not to change this, partly because large ids cause problems.
E.g., the quota system attempts to create a 256GB (?) sparse file to
hold data for uid 0xfffffffe.  It fails due to overflow bugs and creates
a measly 4GB file.

>Does the following patch seem appropriate or are there reasons
>for artificially limiting uid_t to a ushort which I still don't
>know about?

>--- /usr/src/usr.sbin/pwd_mkdb/pw_scan.c.orig	Fri Feb 28 07:37:48 1997
>+++ /usr/src/usr.sbin/pwd_mkdb/pw_scan.c	Fri Feb 28 07:37:49 1997
>@@ -81,8 +81,8 @@
> 		warnx("root uid should be 0");
> 		return (0);
> 	}
>-	if (id > USHRT_MAX) {
>-		warnx("%s > max uid value (%d)", p, USHRT_MAX);
>+	if (id > UINT_MAX) {
>+		warnx("%s > max uid value (%d)", p, UINT_MAX);
> 		/*return (0);*/ /* THIS SHOULD NOT BE FATAL! */
> 	}
> 	pw->pw_uid = id;

Both versions are quite buggy.  `id' has type long.  On i386's, USHRT_MAX
has type int, so the first test fails to detect negative ids.  On i386's
sizeof(long) == sizeof(int), so the second test never succeeds.  If
longs are larger than ints, then the second test has the same bug as
the first test.  The second warning uses the wrong format specifier for
printing an unsigned int and would usually say that the max is -1.  If
sizeof(short) == sizeof(int), then USHRT_MAX has type unsigned int and
the first warning has the same bug.

Bruce