Re: svn commit: r345853 - head/usr.bin/rctl

2019-09-03 Thread Mateusz Guzik
On 4/4/19, Enji Cooper  wrote:
>
>> On Apr 3, 2019, at 1:37 PM, Mateusz Guzik  wrote:
>>
>> Author: mjg
>> Date: Wed Apr  3 20:37:14 2019
>> New Revision: 345853
>> URL: https://svnweb.freebsd.org/changeset/base/345853
>>
>> Log:
>>  rctl: fix sysctl kern.racct.enable use after r341182
>>
>>  The value was changed from int to bool. Since the new type
>>  is smaller, the rest of the variable in the caller was left
>>  unitialized.
>
> I hit a bug like this recently with capsicum-test. Do you think it makes
> sense to purge all of the memory or return -1/set EINVAL for reasons similar
> to this for newp?
>
>  [EINVAL]   A non-null newp is given and its specified length
> in
> newlen is too large or too small.
>

There is most likely code which always passed oversized bufs. This change
would break it.

-- 
Mateusz Guzik 


___
svn-src-all@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"


Re: svn commit: r345853 - head/usr.bin/rctl

2019-09-03 Thread Enji Cooper


> On Apr 3, 2019, at 1:37 PM, Mateusz Guzik  wrote:
> 
> Author: mjg
> Date: Wed Apr  3 20:37:14 2019
> New Revision: 345853
> URL: https://svnweb.freebsd.org/changeset/base/345853
> 
> Log:
>  rctl: fix sysctl kern.racct.enable use after r341182
> 
>  The value was changed from int to bool. Since the new type
>  is smaller, the rest of the variable in the caller was left
>  unitialized.

I hit a bug like this recently with capsicum-test. Do you think it makes sense 
to purge all of the memory or return -1/set EINVAL for reasons similar to this 
for newp?

 [EINVAL]   A non-null newp is given and its specified length in
newlen is too large or too small.

Thanks!
-Enji

___
svn-src-all@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"


Re: svn commit: r345853 - head/usr.bin/rctl

2019-09-03 Thread Bruce Evans

On Wed, 3 Apr 2019, Enji Cooper wrote:


On Apr 3, 2019, at 1:37 PM, Mateusz Guzik  wrote:

Author: mjg
Date: Wed Apr  3 20:37:14 2019
New Revision: 345853
URL: https://svnweb.freebsd.org/changeset/base/345853

Log:
 rctl: fix sysctl kern.racct.enable use after r341182

 The value was changed from int to bool. Since the new type
 is smaller, the rest of the variable in the caller was left
 unitialized.


Why not fix the bug?  It it was breaking the ABI by changing int to bool.
Churning int to bool is bad enough even when it doesn't break ABIs.


I hit a bug like this recently with capsicum-test. Do you think it makes sense 
to purge all of the memory or return -1/set EINVAL for reasons similar to this 
for newp?

[EINVAL]   A non-null newp is given and its specified length in
   newlen is too large or too small.


Purge?  That would break correct programs to not detect ABI mismatches
and kernel bugs.

One direction of this was broken almost 25 years ago in phk's rewrite
of sysctl.  I use the following fix (edited from my 16 year old 1483
line patch for mostly style bugs in kern_sysctl.c,  There are many
more now).

XX Index: kern_sysctl.c
XX ===
XX RCS file: /home/ncvs/src/sys/kern/kern_sysctl.c,v
XX retrieving revision 1.157
XX diff -u -2 -r1.157 kern_sysctl.c
XX --- kern_sysctl.c11 Jun 2004 02:20:37 -  1.157
XX +++ kern_sysctl.c11 Jun 2004 07:58:23 -
XX @@ -957,6 +949,13 @@
XX  if (!req->newptr)
XX  return 0;
XX -if (req->newlen - req->newidx < l)
XX +if (req->newlen - req->newidx != l) {
XX +if (req->newlen - req->newidx > l) {
XX +printf(
XX +"sysctl_new_kernel -- short write: %zu - %zu > %zu\n",
XX +req->newlen, req->newidx, l);
XX +Debugger("sysctl_new_kernel: short write");
XX +}
XX  return (EINVAL);
XX +}
XX  bcopy((char *)req->newptr + req->newidx, p, l);
XX  req->newidx += l;
XX @@ -1075,6 +1073,13 @@
XX  if (!req->newptr)
XX  return 0;
XX -if (req->newlen - req->newidx < l)
XX +if (req->newlen - req->newidx != l) {
XX +if (req->newlen - req->newidx > l) {
XX +printf(
XX +"sysctl_new_user -- short write: %zu - %zu > %zu\n",
XX +req->newlen, req->newidx, l);
XX +Debugger("sysctl_new_user: short write");
XX +}
XX  return (EINVAL);
XX +}
XX  error = copyin((char *)req->newptr + req->newidx, p, l);
XX  req->newidx += l;

IIRC, the error is still detected for short reads.  This seems to be the
case here.

More recently, I tried to fix the sysctl ABI so that applications don't
need to hard-code or probe for the size of integer variables to match
the size used by the current kernel.  Any size large enough to represent
the value should work.  E.g., for this bool, applications that use the
unchurned ABI write an int, and everything works provided the int can
be represented as a bool.

In the opposite direction, larger kernel variables can easily represent
smaller application variables, so there is no problem provided the
kernel does the correct conversions.  Currently it doesn't.  For short
writes, it writes to the lower bits and leaves garbage in the top bits.
Or maybe the reverse for big-endian.  Then it succeeds and doesn't
return the documented error -1/EINVAL.

My fix would break some probes.  It seems to be neccessary to probe using
reads, since writes would be destructive.  The application might try to
read into an int8_t variable.  This would succeed if the kernel variable
is intmax_t, provided the current value is between 0 and 127.  But
writing 128 or larger later won't work.  The applications can start the
probe with the maximum type intmax_t, but that will always work
(except for unsigned values), so the application might as well hard-code
use of intmax_t and waste a lot of space.

Most applications are currently broken by not probing at all.  This often
breaks ones like systat and top which report kernel variables whose size
often increases.  Errror handling in systat and top is still very broken:
- getsysctl() in systat detects all size mismatches but mishandles them
  by printing an error message and returning garbage.  It mishandles
  even errors detected by the kernel similarly, except the garbage is
  less processed if sysctlbyname() fails.  It also has many style bugs
  (function type on the same line as the function name; initialization
  in declaration; no blank line after declaration; excessive braces;
  casts to unsigned long to print size_t's since %zu has only been
  standard for 20 years; not using the BSD spelling u_long in these
  casts).
- top uses the same getsysctl() wrapper as systat, but quits after an
  error and is missing the style bugs except for the the 

svn commit: r345853 - head/usr.bin/rctl

2019-09-03 Thread Mateusz Guzik
Author: mjg
Date: Wed Apr  3 20:37:14 2019
New Revision: 345853
URL: https://svnweb.freebsd.org/changeset/base/345853

Log:
  rctl: fix sysctl kern.racct.enable use after r341182
  
  The value was changed from int to bool. Since the new type
  is smaller, the rest of the variable in the caller was left
  unitialized.
  
  PR:   236714
  Reported by:  trasz
  Diagnosed by: markj
  Sponsored by: The FreeBSD Foundation

Modified:
  head/usr.bin/rctl/rctl.c

Modified: head/usr.bin/rctl/rctl.c
==
--- head/usr.bin/rctl/rctl.cWed Apr  3 19:59:45 2019(r345852)
+++ head/usr.bin/rctl/rctl.cWed Apr  3 20:37:14 2019(r345853)
@@ -378,8 +378,9 @@ print_rules(char *rules, int hflag, int nflag)
 static void
 enosys(void)
 {
-   int error, racct_enable;
size_t racct_enable_len;
+   int error;
+   bool racct_enable;
 
racct_enable_len = sizeof(racct_enable);
error = sysctlbyname("kern.racct.enable",
@@ -392,7 +393,7 @@ enosys(void)
err(1, "sysctlbyname");
}
 
-   if (racct_enable == 0)
+   if (!racct_enable)
errx(1, "RACCT/RCTL present, but disabled; enable using 
kern.racct.enable=1 tunable");
 }
 


___
svn-src-all@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"


Re: svn commit: r345853 - head/usr.bin/rctl

2019-04-04 Thread Bruce Evans

On Wed, 3 Apr 2019, Enji Cooper wrote:


On Apr 3, 2019, at 1:37 PM, Mateusz Guzik  wrote:

Author: mjg
Date: Wed Apr  3 20:37:14 2019
New Revision: 345853
URL: https://svnweb.freebsd.org/changeset/base/345853

Log:
 rctl: fix sysctl kern.racct.enable use after r341182

 The value was changed from int to bool. Since the new type
 is smaller, the rest of the variable in the caller was left
 unitialized.


Why not fix the bug?  It it was breaking the ABI by changing int to bool.
Churning int to bool is bad enough even when it doesn't break ABIs.


I hit a bug like this recently with capsicum-test. Do you think it makes sense 
to purge all of the memory or return -1/set EINVAL for reasons similar to this 
for newp?

[EINVAL]   A non-null newp is given and its specified length in
   newlen is too large or too small.


Purge?  That would break correct programs to not detect ABI mismatches
and kernel bugs.

One direction of this was broken almost 25 years ago in phk's rewrite
of sysctl.  I use the following fix (edited from my 16 year old 1483
line patch for mostly style bugs in kern_sysctl.c,  There are many
more now).

XX Index: kern_sysctl.c
XX ===
XX RCS file: /home/ncvs/src/sys/kern/kern_sysctl.c,v
XX retrieving revision 1.157
XX diff -u -2 -r1.157 kern_sysctl.c
XX --- kern_sysctl.c11 Jun 2004 02:20:37 -  1.157
XX +++ kern_sysctl.c11 Jun 2004 07:58:23 -
XX @@ -957,6 +949,13 @@
XX  if (!req->newptr)
XX  return 0;
XX -if (req->newlen - req->newidx < l)
XX +if (req->newlen - req->newidx != l) {
XX +if (req->newlen - req->newidx > l) {
XX +printf(
XX +"sysctl_new_kernel -- short write: %zu - %zu > %zu\n",
XX +req->newlen, req->newidx, l);
XX +Debugger("sysctl_new_kernel: short write");
XX +}
XX  return (EINVAL);
XX +}
XX  bcopy((char *)req->newptr + req->newidx, p, l);
XX  req->newidx += l;
XX @@ -1075,6 +1073,13 @@
XX  if (!req->newptr)
XX  return 0;
XX -if (req->newlen - req->newidx < l)
XX +if (req->newlen - req->newidx != l) {
XX +if (req->newlen - req->newidx > l) {
XX +printf(
XX +"sysctl_new_user -- short write: %zu - %zu > %zu\n",
XX +req->newlen, req->newidx, l);
XX +Debugger("sysctl_new_user: short write");
XX +}
XX  return (EINVAL);
XX +}
XX  error = copyin((char *)req->newptr + req->newidx, p, l);
XX  req->newidx += l;

IIRC, the error is still detected for short reads.  This seems to be the
case here.

More recently, I tried to fix the sysctl ABI so that applications don't
need to hard-code or probe for the size of integer variables to match
the size used by the current kernel.  Any size large enough to represent
the value should work.  E.g., for this bool, applications that use the
unchurned ABI write an int, and everything works provided the int can
be represented as a bool.

In the opposite direction, larger kernel variables can easily represent
smaller application variables, so there is no problem provided the
kernel does the correct conversions.  Currently it doesn't.  For short
writes, it writes to the lower bits and leaves garbage in the top bits.
Or maybe the reverse for big-endian.  Then it succeeds and doesn't
return the documented error -1/EINVAL.

My fix would break some probes.  It seems to be neccessary to probe using
reads, since writes would be destructive.  The application might try to
read into an int8_t variable.  This would succeed if the kernel variable
is intmax_t, provided the current value is between 0 and 127.  But
writing 128 or larger later won't work.  The applications can start the
probe with the maximum type intmax_t, but that will always work
(except for unsigned values), so the application might as well hard-code
use of intmax_t and waste a lot of space.

Most applications are currently broken by not probing at all.  This often
breaks ones like systat and top which report kernel variables whose size
often increases.  Errror handling in systat and top is still very broken:
- getsysctl() in systat detects all size mismatches but mishandles them
  by printing an error message and returning garbage.  It mishandles
  even errors detected by the kernel similarly, except the garbage is
  less processed if sysctlbyname() fails.  It also has many style bugs
  (function type on the same line as the function name; initialization
  in declaration; no blank line after declaration; excessive braces;
  casts to unsigned long to print size_t's since %zu has only been
  standard for 20 years; not using the BSD spelling u_long in these
  casts).
- top uses the same getsysctl() wrapper as systat, but quits after an
  error and is missing the style bugs except for the the 

Re: svn commit: r345853 - head/usr.bin/rctl

2019-04-03 Thread Mateusz Guzik
On 4/4/19, Enji Cooper  wrote:
>
>> On Apr 3, 2019, at 1:37 PM, Mateusz Guzik  wrote:
>>
>> Author: mjg
>> Date: Wed Apr  3 20:37:14 2019
>> New Revision: 345853
>> URL: https://svnweb.freebsd.org/changeset/base/345853
>>
>> Log:
>>  rctl: fix sysctl kern.racct.enable use after r341182
>>
>>  The value was changed from int to bool. Since the new type
>>  is smaller, the rest of the variable in the caller was left
>>  unitialized.
>
> I hit a bug like this recently with capsicum-test. Do you think it makes
> sense to purge all of the memory or return -1/set EINVAL for reasons similar
> to this for newp?
>
>  [EINVAL]   A non-null newp is given and its specified length
> in
> newlen is too large or too small.
>

There is most likely code which always passed oversized bufs. This change
would break it.

-- 
Mateusz Guzik 
___
svn-src-all@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"


Re: svn commit: r345853 - head/usr.bin/rctl

2019-04-03 Thread Enji Cooper


> On Apr 3, 2019, at 1:37 PM, Mateusz Guzik  wrote:
> 
> Author: mjg
> Date: Wed Apr  3 20:37:14 2019
> New Revision: 345853
> URL: https://svnweb.freebsd.org/changeset/base/345853
> 
> Log:
>  rctl: fix sysctl kern.racct.enable use after r341182
> 
>  The value was changed from int to bool. Since the new type
>  is smaller, the rest of the variable in the caller was left
>  unitialized.

I hit a bug like this recently with capsicum-test. Do you think it makes sense 
to purge all of the memory or return -1/set EINVAL for reasons similar to this 
for newp?

 [EINVAL]   A non-null newp is given and its specified length in
newlen is too large or too small.

Thanks!
-Enji
___
svn-src-all@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"


svn commit: r345853 - head/usr.bin/rctl

2019-04-03 Thread Mateusz Guzik
Author: mjg
Date: Wed Apr  3 20:37:14 2019
New Revision: 345853
URL: https://svnweb.freebsd.org/changeset/base/345853

Log:
  rctl: fix sysctl kern.racct.enable use after r341182
  
  The value was changed from int to bool. Since the new type
  is smaller, the rest of the variable in the caller was left
  unitialized.
  
  PR:   236714
  Reported by:  trasz
  Diagnosed by: markj
  Sponsored by: The FreeBSD Foundation

Modified:
  head/usr.bin/rctl/rctl.c

Modified: head/usr.bin/rctl/rctl.c
==
--- head/usr.bin/rctl/rctl.cWed Apr  3 19:59:45 2019(r345852)
+++ head/usr.bin/rctl/rctl.cWed Apr  3 20:37:14 2019(r345853)
@@ -378,8 +378,9 @@ print_rules(char *rules, int hflag, int nflag)
 static void
 enosys(void)
 {
-   int error, racct_enable;
size_t racct_enable_len;
+   int error;
+   bool racct_enable;
 
racct_enable_len = sizeof(racct_enable);
error = sysctlbyname("kern.racct.enable",
@@ -392,7 +393,7 @@ enosys(void)
err(1, "sysctlbyname");
}
 
-   if (racct_enable == 0)
+   if (!racct_enable)
errx(1, "RACCT/RCTL present, but disabled; enable using 
kern.racct.enable=1 tunable");
 }
 
___
svn-src-all@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"