NetBSD Problem Report #54053
From msaitoh@five.execsw.org Mon Mar 11 06:20:07 2019
Return-Path: <msaitoh@five.execsw.org>
Received: from mail.netbsd.org (mail.netbsd.org [199.233.217.200])
(using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits))
(Client CN "mail.NetBSD.org", Issuer "mail.NetBSD.org CA" (not verified))
by mollari.NetBSD.org (Postfix) with ESMTPS id 27C137A1A2
for <gnats-bugs@gnats.NetBSD.org>; Mon, 11 Mar 2019 06:20:07 +0000 (UTC)
Message-Id: <20190311062004.8358788612A@five.execsw.org>
Date: Mon, 11 Mar 2019 15:20:04 +0900 (JST)
From: msaitoh@execsw.org
Reply-To: msaitoh@execsw.org
To: gnats-bugs@NetBSD.org
Subject: humanize_number(HN_AUTOSCALE) with big buffer doesn't work.
X-Send-Pr-Version: 3.95
>Number: 54053
>Category: lib
>Synopsis: humanize_number(HN_AUTOSCALE) with big buffer doesn't work.
>Confidential: no
>Severity: non-critical
>Priority: low
>Responsible: kre
>State: closed
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Mon Mar 11 06:25:00 +0000 2019
>Closed-Date: Wed Mar 13 05:46:29 +0000 2019
>Last-Modified: Wed Mar 13 05:46:29 +0000 2019
>Originator: msaitoh@execsw.org
>Release: Any?
>Organization:
>Environment:
>Description:
It seems using humanize_number(HN_AUTOSCALE) with big buffer doesn't work as expected.
------------------ test program ---------------
#include <assert.h>
#include <inttypes.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#ifdef __FreeBSD__
#include <libutil.h>
#endif
/*
* bufsize bps result
*
* 40 1000000000 0 Ebps
* 39 1000000000 1000000000 bps
*/
int
main(int argc, char *argv[])
{
char buf[40];
int64_t bps = 1000000000;
int rv;
rv = humanize_number(buf, sizeof(buf), bps, "bps",
HN_AUTOSCALE, HN_DIVISOR_1000);
printf("\tbaudrate %s\n", buf);
return rv;
}
-----------------------------------------
1000000000 with buffer size 39 works:
1000000000 bps
1000000000 with buffer size 40 doesn't work:
0 Ebps
I added debug printf into humanize_number.c like below:
-------------------------------------
/* Check if enough room for `x y' + suffix + `\0' */
if (len < baselen + 1)
return (-1);
#if 1
printf("divisor = %ld\n", divisor);
printf(" len = %ld\n", len);
printf("baselen = %ld\n", baselen);
printf("bytes = %ld\n", bytes);
#endif
if (scale & (HN_AUTOSCALE | HN_GETSCALE)) {
/* See if there is additional columns can be used. */
for (max = 100, i = len - baselen; i-- > 0;) {
printf("i = %zu, max = %ld\n", i, max);
max *= 10;
}
-------------------------------------
The output was:
./humanize_number
divisor = 1000
len = 40
baselen = 6
bytes = 100000000000
i = 33, max = 100
i = 32, max = 1000
i = 31, max = 10000
i = 30, max = 100000
i = 29, max = 1000000
i = 28, max = 10000000
i = 27, max = 100000000
i = 26, max = 1000000000
i = 25, max = 10000000000
i = 24, max = 100000000000
i = 23, max = 1000000000000
i = 22, max = 10000000000000
i = 21, max = 100000000000000
i = 20, max = 1000000000000000
i = 19, max = 10000000000000000
i = 18, max = 100000000000000000
i = 17, max = 1000000000000000000
i = 16, max = -8446744073709551616
i = 15, max = 7766279631452241920
i = 14, max = 3875820019684212736
i = 13, max = 1864712049423024128
i = 12, max = 200376420520689664
i = 11, max = 2003764205206896640
i = 10, max = 1590897978359414784
i = 9, max = -2537764290115403776
i = 8, max = -6930898827444486144
i = 7, max = 4477988020393345024
i = 6, max = 7886392056514347008
i = 5, max = 5076944270305263616
i = 4, max = -4570789518076018688
i = 3, max = -8814407033341083648
i = 2, max = 4089650035136921600
i = 1, max = 4003012203950112768
i = 0, max = 3136633892082024448
baudrate 0 Ebps
Overflow?
>How-To-Repeat:
See above.
>Fix:
I don't know.
>Release-Note:
>Audit-Trail:
Responsible-Changed-From-To: lib-bug-people->kre
Responsible-Changed-By: kre@NetBSD.org
Responsible-Changed-When: Mon, 11 Mar 2019 08:52:05 +0000
Responsible-Changed-Why:
I am looking into this PR
From: "Robert Elz" <kre@netbsd.org>
To: gnats-bugs@gnats.NetBSD.org
Cc:
Subject: PR/54053 CVS commit: src/lib/libc/gen
Date: Mon, 11 Mar 2019 15:10:52 +0000
Module Name: src
Committed By: kre
Date: Mon Mar 11 15:10:51 UTC 2019
Modified Files:
src/lib/libc/gen: humanize_number.3 humanize_number.c
Log Message:
PR lib/54053
When auto scaling, and the buffer is bigger than big enough
for the biggest possible number, don't try and calculate
the max value that will fit in the buffer - that calc
will overflow (guaranteed) and is useless, the value
we're formatting cannot possibly be bigger. So simply
use the unscaled value (the raw number).
While here, also avoid returning values that are larger
than the buffer len ... while it would be nice to be able
to find out how big the buffer should be so the data will
fit, the interface doesn't really allow that (the buffer
length passed in controls the scaling - at least when
auto scaling) and the code already does "return -1" when
it detects the buffer length is too small, even before
it works out how much would have been needed. So, rather
than returning a value > len (while truncating the result
to fit in len ... all courtesy of snprintf()) return -1
in this case as well.
Also, allow suffix==NULL (meaning "") - there's no reason
not to, and requiring users to pass in an explicit "" is
not useful.
To generate a diff of this commit:
cvs rdiff -u -r1.11 -r1.12 src/lib/libc/gen/humanize_number.3
cvs rdiff -u -r1.17 -r1.18 src/lib/libc/gen/humanize_number.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
State-Changed-From-To: open->feedback
State-Changed-By: kre@NetBSD.org
State-Changed-When: Mon, 11 Mar 2019 15:15:52 +0000
State-Changed-Why:
Can you verify if this is fixed OK now (in HEAD, as of a minute ago...)
Also, do you need this pulled up to -8 ? humanize_number() seems to
have been untouched in any signifigant way in a very long time, and
while this was a fairly blatant bug, it had not previously been noticed.
From: "Robert Elz" <kre@netbsd.org>
To: gnats-bugs@gnats.NetBSD.org
Cc:
Subject: PR/54053 CVS commit: src/tests/lib/libc/gen
Date: Mon, 11 Mar 2019 17:45:12 +0000
Module Name: src
Committed By: kre
Date: Mon Mar 11 17:45:12 UTC 2019
Modified Files:
src/tests/lib/libc/gen: t_humanize_number.c
Log Message:
Explicitly test for PR lib/54053
A suitable test was actually there already - but the results
were not verified. So just add a test that the result string
is what is expected. (Previously for len==128 and bytes==10000
it would have returned "0E" now it returns 10000 as it should.)
To generate a diff of this commit:
cvs rdiff -u -r1.9 -r1.10 src/tests/lib/libc/gen/t_humanize_number.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
From: "Robert Elz" <kre@netbsd.org>
To: gnats-bugs@gnats.NetBSD.org
Cc:
Subject: PR/54053 CVS commit: src/sys/kern
Date: Tue, 12 Mar 2019 00:25:44 +0000
Module Name: src
Committed By: kre
Date: Tue Mar 12 00:25:44 UTC 2019
Modified Files:
src/sys/kern: subr_humanize.c
Log Message:
This had a similar problem to that reported in PR lib/54053
for the userland (libc) version of humanize_number(),
except in a much more limited, and less harmful, way ...
If the value to be printed was > ~0/10 (eg ~0 itself) and
the buffer given was big enough to hold it, "umax" would overflow,
and the expected result was not produced (here at least the effect was
simply to scale the result for huge values by one unnecessary step,
rather than maximally scale all values usually generating 0E, but
incorrect nonetheless.)
To generate a diff of this commit:
cvs rdiff -u -r1.1 -r1.2 src/sys/kern/subr_humanize.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
From: Masanobu SAITOH <msaitoh@execsw.org>
To: gnats-bugs@NetBSD.org, kre@NetBSD.org, netbsd-bugs@netbsd.org,
gnats-admin@netbsd.org
Cc: msaitoh@execsw.org
Subject: Re: lib/54053 (humanize_number(HN_AUTOSCALE) with big buffer doesn't
work.)
Date: Wed, 13 Mar 2019 14:10:15 +0900
On 2019/03/12 0:15, kre@NetBSD.org wrote:
> Synopsis: humanize_number(HN_AUTOSCALE) with big buffer doesn't work.
>
> State-Changed-From-To: open->feedback
> State-Changed-By: kre@NetBSD.org
> State-Changed-When: Mon, 11 Mar 2019 15:15:52 +0000
> State-Changed-Why:
> Can you verify if this is fixed OK now (in HEAD, as of a minute ago...)
Yes. It's fixed!
> Also, do you need this pulled up to -8 ? humanize_number() seems to
> have been untouched in any signifigant way in a very long time, and
> while this was a fairly blatant bug, it had not previously been noticed.
This bug is not serious and it's not required for me to pullup to -8.
But, another person might get the same problem and might waste the time.
It would be good to pullup to avoid it and reduce diff between
-current and netbsd-[78].
--
-----------------------------------------------
SAITOH Masanobu (msaitoh@execsw.org
msaitoh@netbsd.org)
From: Robert Elz <kre@munnari.OZ.AU>
To: Masanobu SAITOH <msaitoh@execsw.org>
Cc: gnats-bugs@NetBSD.org, netbsd-bugs@netbsd.org
Subject: Re: lib/54053 (humanize_number(HN_AUTOSCALE) with big buffer doesn't work.)
Date: Wed, 13 Mar 2019 12:34:50 +0700
Date: Wed, 13 Mar 2019 14:10:15 +0900
From: Masanobu SAITOH <msaitoh@execsw.org>
Message-ID: <11147520-0be5-fb8a-aa5f-aa4aff29dca9@execsw.org>
| Yes. It's fixed!
Thanks for confirming.
| This bug is not serious and it's not required for me to pullup to -8.
OK, in that case I think I won't bother as ...
| But, another person might get the same problem and might waste the time.
| It would be good to pullup to avoid it and reduce diff between
| -current and netbsd-[78].
First I think it better to reduce the diff between 8.0 and 8_STABLE
(and 8.1 when it happens) than between 8 and CURRENT (or 9). The latter
is pretty much a waste of time (there's LOTS of diff).
Second, I think it's unlikely that anyone else will ever see this
problem (and I wonder at just what you were really doing - other than
the illustration demo included in the PR - when you experienced this
problem.) HN_AUTOSCALE and a big buffer together do not really make
sense - HN_AUTOSCALE is intended to make the number fit in a limited
field width, if all possible - if the buffer is any larger than (about)
20 + the length of the suffix to be added, you might just as well simply
do snprintf() and be done with it, as that is all that humanize_number()
does in that case.
That will be why, that even though this bug had been there essentially
forever (decades...) no-one had previously noticed.
I wouldn't bother with a pullup to -7 in any case. I doubt at this stage
that there will ever be a new point release for that, and this issue just
isn't important enough. It would only get to those running 7_STABLE
(and upgrading that from time to time) which are a set of people who at
this stage are probably much better off running 8_STABLE instead.
But if you really want to request a pullup to -8 by all means go ahead.
(I can supply the needed source-changes message if you don't still have it).
The patch should apply easily enogh I'd think (and if there were any other
changes, simply including all of them - pulling -8 up to the same as HEAD
would not be unreasonable.)
For now, I will just close this though.
kre
State-Changed-From-To: feedback->closed
State-Changed-By: kre@NetBSD.org
State-Changed-When: Wed, 13 Mar 2019 05:46:29 +0000
State-Changed-Why:
Submitter confirms that problem is fixed
>Unformatted:
(Contact us)
$NetBSD: query-full-pr,v 1.43 2018/01/16 07:36:43 maya Exp $
$NetBSD: gnats_config.sh,v 1.9 2014/08/02 14:16:04 spz Exp $
Copyright © 1994-2017
The NetBSD Foundation, Inc. ALL RIGHTS RESERVED.