>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@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@lab:~ # pw user add -n test1 -u 9999999999999
> root@lab:~ # id test1
> uid=2147483647(test1) gid=1004(test1) groups=1004(test1)

An invalid number is also accepted and is interpreted as 0:
> root@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@lab:~ # pw user add -n test0 -u 9999999999999999999
> root@lab:~ # id test0
> uid=2147483647(test0) gid=2147483647(test0) groups=2147483647(test0)
> root@lab:~ # pw user del test0
> root@lab:~ # pw user del test0
> pw: pw_copy(): No such file or directory
> root@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:
_______________________________________________
freebsd-bugs@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-bugs
To unsubscribe, send any mail to "freebsd-bugs-unsubscr...@freebsd.org"

Reply via email to