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

2015-08-01 Thread Bruce Evans

On Sat, 1 Aug 2015, Jilles Tjoelker wrote:


On Wed, Jul 29, 2015 at 08:52:52AM +1000, Bruce Evans wrote:

On Tue, 28 Jul 2015, Baptiste Daroussin wrote:

Added: head/usr.sbin/pw/tests/pw_groupadd.sh
==
--- /dev/null   00:00:00 1970   (empty, because file is newly added)
+++ head/usr.sbin/pw/tests/pw_groupadd.sh   Tue Jul 28 21:10:58 2015
(r285985)
@@ -0,0 +1,15 @@
+# $FreeBSD$
+
+# Import helper functions
+. $(atf_get_srcdir)/helper_functions.shin
+
+atf_test_case group_add_gid_too_large
+group_add_gid_too_large_body() {
+   populate_etc_skel
+   atf_check -s exit:64 -e inline:pw: Bad id '9': too 
large\n \
+   ${PW} groupadd -n test1 -g 9
+}



Check for large valid ids on i386 (should succeed, but currently fail),
negative ids (require failure), magic ids like (uid_t)-1 and (uid_t)-2
(should fail, but currently succeed on amd64), and the hex ids (should
succeed, but currently fail).  (uid_t)-1 is special for some syscalls,
so shouldn't be permitted for users.  (uid_t)-2 special for nfs (see
exports(5)).  The magic ids are hard to spell without using hex, but
pw is too broken to accept that.  For 32-bit ids, the above number
should be replaced by 0x1 when pw supports hex.  Also check
that 0x and 0xfffe are not too large, but reserved, and
that 0xfffd is not too large and not reserved.


These values are easily written using arithmetic expansion, for example
largeid=$((0x1)).


Not really.  Shells are also very buggy or limited in this area.  I
often use old versions of sh and bash that only support up to INT32_MAX
and have broken overflow handling.  /bin/sh in -current only supports
up to INT64_MAX (or maybe INTMAX_MAX) and has broken overflow handling
(it clamps to INT64_MAX).  Not so old versions of bash only support
up to INT64_MAX and have differently broken overflow handling (4.3.99
blindly assigns to int64_t, so $((0x8000)) becomes
-0x8000.

expr is also limited to INT64_MAX, but attempts to have non-broken
overflow handling.


When using strtol() or similar functions, accepting hex typically
implies accepting octal as well, which causes confusing and
POSIX-violating results like 010 interpreted as eight.


This is a problem.  strtonum could accept hex but not octal by calling
strtoimax() twice for bases 10 and 16.  Also dehumanized formats like
1k and 1K.  It should also actually accept numbers as input.  1.1e1 if
not I * Pi.

Bruce
___
svn-src-head@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to svn-src-head-unsubscr...@freebsd.org


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

2015-08-01 Thread Jilles Tjoelker
On Wed, Jul 29, 2015 at 08:52:52AM +1000, Bruce Evans wrote:
 On Tue, 28 Jul 2015, Baptiste Daroussin wrote:
  Added: head/usr.sbin/pw/tests/pw_groupadd.sh
  ==
  --- /dev/null   00:00:00 1970   (empty, because file is newly added)
  +++ head/usr.sbin/pw/tests/pw_groupadd.sh   Tue Jul 28 21:10:58 2015
  (r285985)
  @@ -0,0 +1,15 @@
  +# $FreeBSD$
  +
  +# Import helper functions
  +. $(atf_get_srcdir)/helper_functions.shin
  +
  +atf_test_case group_add_gid_too_large
  +group_add_gid_too_large_body() {
  +   populate_etc_skel
  +   atf_check -s exit:64 -e inline:pw: Bad id '9': too 
  large\n \
  +   ${PW} groupadd -n test1 -g 9
  +}

 Check for large valid ids on i386 (should succeed, but currently fail),
 negative ids (require failure), magic ids like (uid_t)-1 and (uid_t)-2
 (should fail, but currently succeed on amd64), and the hex ids (should
 succeed, but currently fail).  (uid_t)-1 is special for some syscalls,
 so shouldn't be permitted for users.  (uid_t)-2 special for nfs (see
 exports(5)).  The magic ids are hard to spell without using hex, but
 pw is too broken to accept that.  For 32-bit ids, the above number
 should be replaced by 0x1 when pw supports hex.  Also check
 that 0x and 0xfffe are not too large, but reserved, and
 that 0xfffd is not too large and not reserved.

These values are easily written using arithmetic expansion, for example
largeid=$((0x1)).

When using strtol() or similar functions, accepting hex typically
implies accepting octal as well, which causes confusing and
POSIX-violating results like 010 interpreted as eight.

-- 
Jilles Tjoelker
___
svn-src-head@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to svn-src-head-unsubscr...@freebsd.org


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

2015-08-01 Thread Bruce Evans

On Sat, 1 Aug 2015, Jilles Tjoelker wrote:


On Sun, Aug 02, 2015 at 02:59:00AM +1000, Bruce Evans wrote:

On Sat, 1 Aug 2015, Jilles Tjoelker wrote:

These values are easily written using arithmetic expansion, for example
largeid=$((0x1)).



Not really.  Shells are also very buggy or limited in this area.  I
often use old versions of sh and bash that only support up to INT32_MAX
and have broken overflow handling.  /bin/sh in -current only supports
up to INT64_MAX (or maybe INTMAX_MAX) and has broken overflow handling
(it clamps to INT64_MAX).  Not so old versions of bash only support
up to INT64_MAX and have differently broken overflow handling (4.3.99
blindly assigns to int64_t, so $((0x8000)) becomes
-0x8000.



expr is also limited to INT64_MAX, but attempts to have non-broken
overflow handling.


The tests need not work with old versions of sh and bash (they already
rely on many more recent features and bugfixes). The broken overflow
handling in parsing literals does not affect the given example.


But I complained about the example being deficient.  It only needs to
test up to UINT32_MAX now, but that may change.  A similar test in
dd already needs to go up to UINT64_MAX.  dd does support hex numbers,
and is suppose to support offsets about OFF_MAX, but this is broken
by excessive support for the signedness of off_t.  All kernel addresses
in /dev/kmem are above 0x on amd64.  I tried to get
green@ to fix this in Y2K, but the result was a larger mess.


When using strtol() or similar functions, accepting hex typically
implies accepting octal as well, which causes confusing and
POSIX-violating results like 010 interpreted as eight.



This is a problem.  strtonum could accept hex but not octal by calling
strtoimax() twice for bases 10 and 16.  Also dehumanized formats like
1k and 1K.  It should also actually accept numbers as input.  1.1e1 if
not I * Pi.


Silently expanding what strtonum() accepts might cause breakage or even
security vulnerabilities.


It is hard to fix broken APIs/UIs once they are used.

strtonum() is not used often in /usr/src.  Its main use is in openssh,
and that is hard to fix since both strtonum and opensh are from OpenBSD.
Using names in the reserved namespace causes portability problems.
FreeBSD's expand_number() is a much worse name, but at least it doesn't
conflict with better future uses of a reserved name.

Bruce
___
svn-src-head@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to svn-src-head-unsubscr...@freebsd.org


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

2015-08-01 Thread Jilles Tjoelker
On Sun, Aug 02, 2015 at 02:59:00AM +1000, Bruce Evans wrote:
 On Sat, 1 Aug 2015, Jilles Tjoelker wrote:
  These values are easily written using arithmetic expansion, for example
  largeid=$((0x1)).

 Not really.  Shells are also very buggy or limited in this area.  I
 often use old versions of sh and bash that only support up to INT32_MAX
 and have broken overflow handling.  /bin/sh in -current only supports
 up to INT64_MAX (or maybe INTMAX_MAX) and has broken overflow handling
 (it clamps to INT64_MAX).  Not so old versions of bash only support
 up to INT64_MAX and have differently broken overflow handling (4.3.99
 blindly assigns to int64_t, so $((0x8000)) becomes
 -0x8000.

 expr is also limited to INT64_MAX, but attempts to have non-broken
 overflow handling.

The tests need not work with old versions of sh and bash (they already
rely on many more recent features and bugfixes). The broken overflow
handling in parsing literals does not affect the given example.

  When using strtol() or similar functions, accepting hex typically
  implies accepting octal as well, which causes confusing and
  POSIX-violating results like 010 interpreted as eight.

 This is a problem.  strtonum could accept hex but not octal by calling
 strtoimax() twice for bases 10 and 16.  Also dehumanized formats like
 1k and 1K.  It should also actually accept numbers as input.  1.1e1 if
 not I * Pi.

Silently expanding what strtonum() accepts might cause breakage or even
security vulnerabilities.

-- 
Jilles Tjoelker
___
svn-src-head@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to svn-src-head-unsubscr...@freebsd.org


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

2015-07-28 Thread Bruce Evans

On Wed, 29 Jul 2015, Baptiste Daroussin wrote:


On Wed, Jul 29, 2015 at 08:52:52AM +1000, Bruce Evans wrote:

On Tue, 28 Jul 2015, Baptiste Daroussin wrote:


Log:
 Check uid/gid used when creating a user/group are not larger than 
UID_MAX/GID_MAX

 PR:173977
 Reported by:   nv...@gmx.com


This is broken in a different way than before.


Modified: head/usr.sbin/pw/pw.c
==
--- head/usr.sbin/pw/pw.c   Tue Jul 28 20:52:10 2015(r285984)
+++ head/usr.sbin/pw/pw.c   Tue Jul 28 21:10:58 2015(r285985)
@@ -269,7 +269,7 @@ main(int argc, char *argv[])
}
if (strspn(optarg, 0123456789) != strlen(optarg))
errx(EX_USAGE, -g expects a number);
-   id = strtonum(optarg, 0, LONG_MAX, errstr);
+   id = strtonum(optarg, 0, GID_MAX, errstr);


`id' still has type long.  The assignment overflows on 32-bit arches when
the value exceeds 0x7fff.  That is for half of all valid values.  pw
is broken in not supporting these values, but at least it detected them
as errors in the previous version.  Old versions implemented this bug
using atoi() with no error checking.


So writting a function like strtonum like function with that prototype
intmax_t strtonumber(const char *, intmax_t min, intmax_t max, const char **);
and an unsigned equivalent
uintmax_t strtonumber(const char *, uintmax_t min, uintmax_t max, const char 
**);


Not completely, since this would restore some of the complications of the
strto*() family (there is API explosion, and types to match).  These 2
functions don't even handle all the integer ranges (with assymmetric
signedness), or hex numbers, or floating point).

To match the types for gid_t's with these APIs, you could write:

gid_t id = strtounum(optarg, 0, GID_MAX, errstr);

or

uintmax_t id = strtounum(optarg, 0, GID_MAX, errstr);

but can't mix these id types with others that need different signedness..
or use plain int/long/u_long for anything.  This is not a problem for
uids and gids since they usually have the same underlying type.

POSIX (XSI) made a mess of this for waitid(idtype_t idtype, id_t id,
...).  id can be either a pid, a uid, a gid or a session id.  So id_t
is specified as an integer type that can contain all of these.
Representing all of these is generally impossible due to the sign
differences, and the conversions made to contain seem to be
unspecified.  FreeBSD actually uses int64_t for id_t and an enum
for idtype_t, so simple conversions preserve the value at the cost
of bloat.  This wouldn't work with 64-bit uid_t.

A similar mess can be made for strto*num() by specifying it to work
with a container type num_t and making this type opaque so that it
is hard to use :-), except there no strict container exists for int64_t
and uint64_t.

Bruce
___
svn-src-head@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to svn-src-head-unsubscr...@freebsd.org


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

2015-07-28 Thread Baptiste Daroussin
On Wed, Jul 29, 2015 at 08:52:52AM +1000, Bruce Evans wrote:
 On Tue, 28 Jul 2015, Baptiste Daroussin wrote:
 
  Log:
   Check uid/gid used when creating a user/group are not larger than 
  UID_MAX/GID_MAX
 
   PR:173977
   Reported by:   nv...@gmx.com
 
 This is broken in a different way than before.
 
  Modified: head/usr.sbin/pw/pw.c
  ==
  --- head/usr.sbin/pw/pw.c   Tue Jul 28 20:52:10 2015(r285984)
  +++ head/usr.sbin/pw/pw.c   Tue Jul 28 21:10:58 2015(r285985)
  @@ -269,7 +269,7 @@ main(int argc, char *argv[])
  }
  if (strspn(optarg, 0123456789) != strlen(optarg))
  errx(EX_USAGE, -g expects a number);
  -   id = strtonum(optarg, 0, LONG_MAX, errstr);
  +   id = strtonum(optarg, 0, GID_MAX, errstr);
 
 `id' still has type long.  The assignment overflows on 32-bit arches when
 the value exceeds 0x7fff.  That is for half of all valid values.  pw
 is broken in not supporting these values, but at least it detected them
 as errors in the previous version.  Old versions implemented this bug
 using atoi() with no error checking.

So writting a function like strtonum like function with that prototype
intmax_t strtonumber(const char *, intmax_t min, intmax_t max, const char **);
and an unsigned equivalent
uintmax_t strtonumber(const char *, uintmax_t min, uintmax_t max, const char 
**);

would do the right thing?

Best regards,
Bapt


pgpHeRbuvPuy0.pgp
Description: PGP signature


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

2015-07-28 Thread Bruce Evans

On Tue, 28 Jul 2015, Baptiste Daroussin wrote:


Log:
 Check uid/gid used when creating a user/group are not larger than 
UID_MAX/GID_MAX

 PR:173977
 Reported by:   nv...@gmx.com


This is broken in a different way than before.


Modified: head/usr.sbin/pw/pw.c
==
--- head/usr.sbin/pw/pw.c   Tue Jul 28 20:52:10 2015(r285984)
+++ head/usr.sbin/pw/pw.c   Tue Jul 28 21:10:58 2015(r285985)
@@ -269,7 +269,7 @@ main(int argc, char *argv[])
}
if (strspn(optarg, 0123456789) != strlen(optarg))
errx(EX_USAGE, -g expects a number);
-   id = strtonum(optarg, 0, LONG_MAX, errstr);
+   id = strtonum(optarg, 0, GID_MAX, errstr);


`id' still has type long.  The assignment overflows on 32-bit arches when
the value exceeds 0x7fff.  That is for half of all valid values.  pw
is broken in not supporting these values, but at least it detected them
as errors in the previous version.  Old versions implemented this bug
using atoi() with no error checking.

The behaviour in the overflowing cases is implementation-defined.
Normally this converts large values to negative ones.  This defeats
the lower limit of 0.

The change works accidentally on 64-bit arches.  It is assumed that
GID_MAX is representable as long long (since strtonum()'s API is too
broken to use even intmax_t, and uintmax_t is needed).  This assumption
is satisfied now.  It would break if someone expands gid_t to uint64_t.
without expandling long long to int65_t or larger.  Then passing GID_MAX
would change it to an implementation-defined value.  Normally to
INT64_MIN.  This negative, so there are no values in the range.

Similarly for uids.


Added: head/usr.sbin/pw/tests/pw_groupadd.sh
==
--- /dev/null   00:00:00 1970   (empty, because file is newly added)
+++ head/usr.sbin/pw/tests/pw_groupadd.sh   Tue Jul 28 21:10:58 2015
(r285985)
@@ -0,0 +1,15 @@
+# $FreeBSD$
+
+# Import helper functions
+. $(atf_get_srcdir)/helper_functions.shin
+
+atf_test_case group_add_gid_too_large
+group_add_gid_too_large_body() {
+   populate_etc_skel
+   atf_check -s exit:64 -e inline:pw: Bad id '9': too 
large\n \
+   ${PW} groupadd -n test1 -g 9
+}


Check for large valid ids on i386 (should succeed, but currently fail),
negative ids (require failure), magic ids like (uid_t)-1 and (uid_t)-2
(should fail, but currently succeed on amd64), and the hex ids (should
succeed, but currently fail).  (uid_t)-1 is special for some syscalls,
so shouldn't be permitted for users.  (uid_t)-2 special for nfs (see
exports(5)).  The magic ids are hard to spell without using hex, but
pw is too broken to accept that.  For 32-bit ids, the above number
should be replaced by 0x1 when pw supports hex.  Also check
that 0x and 0xfffe are not too large, but reserved, and
that 0xfffd is not too large and not reserved.

Bruce
___
svn-src-head@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to svn-src-head-unsubscr...@freebsd.org


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

2015-07-28 Thread Baptiste Daroussin
Author: bapt
Date: Tue Jul 28 21:10:58 2015
New Revision: 285985
URL: https://svnweb.freebsd.org/changeset/base/285985

Log:
  Check uid/gid used when creating a user/group are not larger than 
UID_MAX/GID_MAX
  
  PR:   173977
  Reported by:  nv...@gmx.com

Added:
  head/usr.sbin/pw/tests/pw_groupadd.sh   (contents, props changed)
Modified:
  head/usr.sbin/pw/pw.c
  head/usr.sbin/pw/tests/Makefile
  head/usr.sbin/pw/tests/pw_useradd.sh

Modified: head/usr.sbin/pw/pw.c
==
--- head/usr.sbin/pw/pw.c   Tue Jul 28 20:52:10 2015(r285984)
+++ head/usr.sbin/pw/pw.c   Tue Jul 28 21:10:58 2015(r285985)
@@ -269,7 +269,7 @@ main(int argc, char *argv[])
}
if (strspn(optarg, 0123456789) != strlen(optarg))
errx(EX_USAGE, -g expects a number);
-   id = strtonum(optarg, 0, LONG_MAX, errstr);
+   id = strtonum(optarg, 0, GID_MAX, errstr);
if (errstr != NULL)
errx(EX_USAGE, Bad id '%s': %s, optarg,
errstr);
@@ -281,7 +281,7 @@ main(int argc, char *argv[])
addarg(arglist, 'u', optarg);
break;
}
-   id = strtonum(optarg, 0, LONG_MAX, errstr);
+   id = strtonum(optarg, 0, UID_MAX, errstr);
if (errstr != NULL)
errx(EX_USAGE, Bad id '%s': %s, optarg,
errstr);

Modified: head/usr.sbin/pw/tests/Makefile
==
--- head/usr.sbin/pw/tests/Makefile Tue Jul 28 20:52:10 2015
(r285984)
+++ head/usr.sbin/pw/tests/Makefile Tue Jul 28 21:10:58 2015
(r285985)
@@ -8,6 +8,7 @@ TESTSDIR=   ${TESTSBASE}/usr.sbin/pw
 ATF_TESTS_SH=  pw_etcdir \
pw_lock \
pw_config \
+   pw_groupadd \
pw_groupdel \
pw_groupmod \
pw_useradd \

Added: head/usr.sbin/pw/tests/pw_groupadd.sh
==
--- /dev/null   00:00:00 1970   (empty, because file is newly added)
+++ head/usr.sbin/pw/tests/pw_groupadd.sh   Tue Jul 28 21:10:58 2015
(r285985)
@@ -0,0 +1,15 @@
+# $FreeBSD$
+
+# Import helper functions
+. $(atf_get_srcdir)/helper_functions.shin
+
+atf_test_case group_add_gid_too_large
+group_add_gid_too_large_body() {
+   populate_etc_skel
+   atf_check -s exit:64 -e inline:pw: Bad id '9': too 
large\n \
+   ${PW} groupadd -n test1 -g 9
+}
+
+atf_init_test_cases() {
+   atf_add_test_case group_add_gid_too_large
+}

Modified: head/usr.sbin/pw/tests/pw_useradd.sh
==
--- head/usr.sbin/pw/tests/pw_useradd.shTue Jul 28 20:52:10 2015
(r285984)
+++ head/usr.sbin/pw/tests/pw_useradd.shTue Jul 28 21:10:58 2015
(r285985)
@@ -289,6 +289,13 @@ user_add_uid0_body() {
-s exit:0 ${PW} usershow foo
 }
 
+atf_test_case user_add_uid_too_large
+user_add_uid_too_large_body() {
+   populate_etc_skel
+   atf_check -s exit:64 -e inline:pw: Bad id '9': too 
large\n \
+   ${PW} useradd -n test1 -u 9
+}
+
 atf_init_test_cases() {
atf_add_test_case user_add
atf_add_test_case user_add_noupdate
@@ -313,4 +320,5 @@ atf_init_test_cases() {
atf_add_test_case user_add_R
atf_add_test_case user_add_skel
atf_add_test_case user_add_uid0
+   atf_add_test_case user_add_uid_too_large
 }
___
svn-src-head@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to svn-src-head-unsubscr...@freebsd.org