From owner-svn-src-head@FreeBSD.ORG Mon Jun 1 18:05:06 2015 Return-Path: Delivered-To: svn-src-head@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id C1F22830; Mon, 1 Jun 2015 18:05:06 +0000 (UTC) (envelope-from baptiste.daroussin@gmail.com) Received: from mail-wi0-x22e.google.com (mail-wi0-x22e.google.com [IPv6:2a00:1450:400c:c05::22e]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (Client CN "smtp.gmail.com", Issuer "Google Internet Authority G2" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 55EEC1AEC; Mon, 1 Jun 2015 18:05:06 +0000 (UTC) (envelope-from baptiste.daroussin@gmail.com) Received: by wizo1 with SMTP id o1so115230673wiz.1; Mon, 01 Jun 2015 11:05:05 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=sender:date:from:to:cc:subject:message-id:references:mime-version :content-type:content-disposition:in-reply-to:user-agent; bh=2rMCil1UyGo/Y4gBwgRqYcJinf4iH8qxZWO7sC8BlQM=; b=bBFE9s8JMmPVkb1/rqhfq4Xo0AI3RRkXBNxD4LfYech65V8LfWsNwDcOMe66S5eNES WIucB60viWI84USuEmNwLZWKbEr5gubUTnIkSVYwIixCuOv3/dmDSpjkTla+0M/1PNIr aoMBOkSHkzvsgd5Yrqo6yIMJsImhbq2NYcLHaqhIaQRjD8ef/kSztmiWX3T+0GKao1nJ T5+G7Dcw4VcL9AJOSZW0jlyrNcazhl0JUTcczuITyeSf0w4f3bZx9WIYM9+lQMQcFkKL l7hGO6xkGJQSLux4f5JiBqXkVwAl6gcD4iOh3MBB6Ns+nfMmpuB64jL0fTkxlI/KfQfI Z+4A== X-Received: by 10.194.110.100 with SMTP id hz4mr43885585wjb.6.1433181904870; Mon, 01 Jun 2015 11:05:04 -0700 (PDT) Received: from ivaldir.etoilebsd.net ([2001:41d0:8:db4c::1]) by mx.google.com with ESMTPSA id ch2sm17751242wib.18.2015.06.01.11.05.03 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 01 Jun 2015 11:05:03 -0700 (PDT) Sender: Baptiste Daroussin Date: Mon, 1 Jun 2015 20:05:01 +0200 From: Baptiste Daroussin To: Bruce Evans Cc: svn-src-head@freebsd.org, svn-src-all@freebsd.org, src-committers@freebsd.org Subject: Re: svn commit: r283842 - head/usr.sbin/pw Message-ID: <20150601180501.GA7523@ivaldir.etoilebsd.net> References: <201505312207.t4VM73Vh015383@svn.freebsd.org> <20150601143951.J863@besplex.bde.org> MIME-Version: 1.0 Content-Type: multipart/signed; micalg=pgp-sha1; protocol="application/pgp-signature"; boundary="tKW2IUtsqtDRztdT" Content-Disposition: inline In-Reply-To: <20150601143951.J863@besplex.bde.org> User-Agent: Mutt/1.5.23 (2014-03-12) X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 01 Jun 2015 18:05:06 -0000 --tKW2IUtsqtDRztdT Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Content-Transfer-Encoding: quoted-printable On Mon, Jun 01, 2015 at 03:36:58PM +1000, Bruce Evans wrote: > On Sun, 31 May 2015, Baptiste Daroussin wrote: >=20 > > Log: > > Remove useless cast in printf and printf-like functions: > > use %u for uid_t and gid_t >=20 > The cast was not useless. It was to avoid the assumption that the default > promotion of uid_t and gid_t is anything in particular. Now it is assumed > that the default promotion is unsigned (int works too, but this is subtle= r). >=20 > uids and gids are only guaranteed to have non-negative values. In > POSIX before about 2001, uid_t and gid_t can be any type that can > represent all the values taken on, so can be floating point. Floating > point was rarely used for POSIX types, and most programs make too many > assumptions about types, so POSIX now requires uid_t and gid_t to be > integer types. Then can still be signed integer types IIRC. Nornally > it is a bug to print signed integer types with unsigned integer formats, > but since uids and gids are guaranteed to be non-negative both formats > work. (pids require different handling since they are overloaded to > hold process group ids as negative values, so pid_t is signed and %u > format is very broken for printing general pids.) Well uid_t is defined as an unsigned int (__uint32_t actually) if it is ever going to be changed to something else they at least it will now raise a war= ning. I consider using %u here is less buggy than the previous casts. >=20 > The program assumed that uids and gids are not too large to be represented > by unsigned long. This was the only way to print them in C90 and before. > C99 broke this by breaking the promise that unsigned long is the largest > unsigned integer type. This broke all code that does careful casts to > unsigned long. However, unsigned long is usually large enough in practic= e. > Careful code now has to cast to uintmax_t, but that is usually excessive > (but doesn't actually work for __uint128_t). Even plain unsigned usually > works on vaxes. >=20 > > Modified: > > head/usr.sbin/pw/pw_conf.c > > head/usr.sbin/pw/pw_group.c > > head/usr.sbin/pw/pw_user.c > > > > Modified: head/usr.sbin/pw/pw_conf.c > > =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D > > --- head/usr.sbin/pw/pw_conf.c Sun May 31 21:44:09 2015 (r283841) > > +++ head/usr.sbin/pw/pw_conf.c Sun May 31 22:07:03 2015 (r283842) > > @@ -453,19 +453,19 @@ write_userconfig(char const * file) > > config.default_class : ""); > > break; > > case _UC_MINUID: > > - sbuf_printf(buf, "%lu", (unsigned long) config.min_uid); > > + sbuf_printf(buf, "%u", config.min_uid); >=20 > This works accidentally even on some non-vaxes. All supported arches in > FreeBSD have 32-bit unsigned's, and POSIX was broken in about 2007 to > disallow 16-bit unsigned's. uid_t is uint32_t in FreeBSD. However, it > is planned to change ino_t and some other types to 64 bits. I forget if > the plans include uid_t. Even 64-bit ino_t is too large for me. >=20 > The version with the cast to unsigned long is not really better. Suppose > uid_t is expanded to 16 bits. Then without the cast, the size mismatch > is detected. With it, everything still works if unsigned long is 64 bits, > but if unsigned long is 32 bits then the cast just breaks detection of > the mismatch and gives wrong results for values that actually need 64 bit= s. >=20 > > Modified: head/usr.sbin/pw/pw_group.c > > =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D > > --- head/usr.sbin/pw/pw_group.c Sun May 31 21:44:09 2015 (r283841) > > +++ head/usr.sbin/pw/pw_group.c Sun May 31 22:07:03 2015 (r283842) > > @@ -83,7 +83,7 @@ pw_group(struct userconf * cnf, int mode > > gid_t next =3D gr_gidpolicy(cnf, args); > > if (getarg(args, 'q')) > > return next; > > - printf("%ld\n", (long)next); > > + printf("%u\n", next); > > return EXIT_SUCCESS; > > } > > >=20 > This also has sign changes. gids are supposed to be non-negative, so > using signed long was probably a bug. >=20 > However, the program is elsewhere clueless about types, and I think you > did't change the parts where it uses atol() to misparse input. atol() > can't even handle 32-bit uids on 32-bit arches. It truncates large > positive ones to LONG_MAX. It returns negative values (truncated to > LONG_MIN if necessary). The misparsing then doesn't detect the error > of negative ids, but blindly casts to uid_t or gid_t, of course using > lexical style bugs in the casts. The magic ids -1 and -2 are sometimes > needed (perhaps not as input in pw, but -1 is used as an error value > and this value can be input). These values don't really exist as ids. > They must be cast before use. The actual values just cannot be entered, > since atol() misparses them (it truncates large values, and also doesn't > support hex, so (uid_t)-2 must be written as a long decimal number to > input it for misparsing. I do plan to work on those atol as well, but I try to be very careful with pw(8). So I make small modifications one by one. >=20 > > @@ -137,7 +137,7 @@ pw_group(struct userconf * cnf, int mode > > else if (rc !=3D 0) { > > err(EX_IOERR, "group update"); > > } > > - pw_log(cnf, mode, W_GROUP, "%s(%ld) removed", a_name->val, (long) g= id); > > + pw_log(cnf, mode, W_GROUP, "%s(%u) removed", a_name->val, gid); > > return EXIT_SUCCESS; > > } else if (mode =3D=3D M_PRINT) > > return print_group(grp, getarg(args, 'P') !=3D NULL); >=20 > If the error gid (gid_t)-1 is ever printed, now %u format prints it as a > cryptic decimal number where %ld format printed it as -1. well actually this code was actually used, and I checked the output before = and after the change and it printed the same output 4294967295. Best regards, Bapt --tKW2IUtsqtDRztdT Content-Type: application/pgp-signature -----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iEYEARECAAYFAlVsns0ACgkQ8kTtMUmk6ExM/wCgnqGE+gb3+K6o8x8qWsIpuibc JmIAnR31xOghBTsEQ83xNzIECu2OI7rA =ZPS8 -----END PGP SIGNATURE----- --tKW2IUtsqtDRztdT--