bin/173977: pw(8) does not do range-checking on UIDs/GUIs from user's input, passwd DB becomes inconsistent
Nikos Vassiliadis
nvass at gmx.com
Wed Nov 28 18:50:01 UTC 2012
>Number: 173977
>Category: bin
>Synopsis: pw(8) does not do range-checking on UIDs/GUIs from user's input, passwd DB becomes inconsistent
>Confidential: no
>Severity: non-critical
>Priority: low
>Responsible: freebsd-bugs
>State: open
>Quarter:
>Keywords:
>Date-Required:
>Class: sw-bug
>Submitter-Id: current-users
>Arrival-Date: Wed Nov 28 18:50:00 UTC 2012
>Closed-Date:
>Last-Modified:
>Originator: Nikos Vassiliadis
>Release: FreeBSD 10.0-CURRENT
>Organization:
>Environment:
FreeBSD lab.local 10.0-CURRENT FreeBSD 10.0-CURRENT #3 r243503: Sun Nov 25 11:44:20 EET 2012 root at lab.local:/usr/obj/usr/src/sys/RCTLLAB i386
>Description:
pw(8) command does not do any range checking on the uid and gid input, resulting in inconsistencies in the password database.
>How-To-Repeat:
Try adding a too big uid:
> root at lab:~ # pw user add -n test1 -u 9999999999999
> root at lab:~ # id test1
> uid=2147483647(test1) gid=1004(test1) groups=1004(test1)
An invalid number is also accepted and is interpreted as 0:
> root at lab:~ # pw user add -n test2 -u asd9999999999999
> pw: uid `0' has already been allocated
The password database can become inconsistent because "pw user del" does not really delete the user:
> root at lab:~ # pw user add -n test0 -u 9999999999999999999
> root at lab:~ # id test0
> uid=2147483647(test0) gid=2147483647(test0) groups=2147483647(test0)
> root at lab:~ # pw user del test0
> root at lab:~ # pw user del test0
> pw: pw_copy(): No such file or directory
> root at lab:~ # id test0
> uid=2147483647(test0) gid=2147483647 groups=2147483647
/etc/passwd does not contain the user test0 but /etc/pwd.db is.
>Fix:
Patch attached with submission follows:
Index: usr.sbin/pw/pw_group.c
===================================================================
--- usr.sbin/pw/pw_group.c (revision 243652)
+++ usr.sbin/pw/pw_group.c (working copy)
@@ -350,6 +350,8 @@
*/
if (a_gid != NULL) {
gid = (gid_t) atol(a_gid->val);
+ if (errno == ERANGE || errno == EINVAL)
+ errx(EX_DATAERR, "gid %s is invalid", a_gid->val);
if ((grp = GETGRGID(gid)) != NULL && getarg(args, 'o') == NULL)
errx(EX_DATAERR, "gid `%ld' has already been allocated", (long) grp->gr_gid);
Index: usr.sbin/pw/pw_user.c
===================================================================
--- usr.sbin/pw/pw_user.c (revision 243652)
+++ usr.sbin/pw/pw_user.c (working copy)
@@ -849,6 +849,8 @@
*/
if (a_uid != NULL) {
uid = (uid_t) atol(a_uid->val);
+ if (errno == ERANGE || errno == EINVAL)
+ errx(EX_DATAERR, "uid %s is invalid", a_uid->val);
if ((pwd = GETPWUID(uid)) != NULL && getarg(args, 'o') == NULL)
errx(EX_DATAERR, "uid `%ld' has already been allocated", (long) pwd->pw_uid);
>Release-Note:
>Audit-Trail:
>Unformatted:
More information about the freebsd-bugs
mailing list