NetBSD Problem Report #57828

From www@netbsd.org  Sun Jan  7 22:27:11 2024
Return-Path: <www@netbsd.org>
Received: from mail.netbsd.org (mail.netbsd.org [199.233.217.200])
	(using TLSv1.3 with cipher TLS_AES_256_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 6AB1F1A9238
	for <gnats-bugs@gnats.NetBSD.org>; Sun,  7 Jan 2024 22:27:11 +0000 (UTC)
Message-Id: <20240107222640.3D5861A9239@mollari.NetBSD.org>
Date: Sun,  7 Jan 2024 22:26:40 +0000 (UTC)
From: alx@kernel.org
Reply-To: alx@kernel.org
To: gnats-bugs@NetBSD.org
Subject: strtoi(3), strtou(3): When both ERANGE and ENOTSUP conditions happen, ERANGE should be more important
X-Send-Pr-Version: www-1.0

>Number:         57828
>Category:       lib
>Synopsis:       strtoi(3), strtou(3): When both ERANGE and ENOTSUP conditions happen, ERANGE should be more important
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    lib-bug-people
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Sun Jan 07 22:30:01 +0000 2024
>Last-Modified:  Sat Jan 20 16:15:02 +0000 2024
>Originator:     Alejandro Colomar
>Release:        9.3
>Organization:
Linux man-pages
>Environment:
N/A
>Description:
In strtoi(3) and strtou(3), the conditions for both ERANGE and
ENOTSUP can ahppen at in the same call.  Consider the following:

    strtoi("42z", &end, 0, 3, 7, &status);

From ERANGE, or ENOTSUP, I argue it should return ERANGE.

-  The information about ENOTSUP can be extracted from 'end', as
   (*end != '\0').  So if we report ERANGE, a caller can still
   check for trailing text easily.  However, there's no secondary
   way to check ERANGE; if it's shadowed by ENOTSUP, that vital
   information is completely lost.
-  It is usual to expect trailing text after the number, as
   when parsing some formatted text, where numbers are mixed with
   other text.  On the other hand, out-of-range values should
   usually be rejected as invalid input, and also warned about.
   If ENOTSUP shadows ERANGE, we're in a bad position.

The following two calls are currently equivalent:

    strtoi("7z", &end, 0, 3, 7, &status);
    strtoi("42z", &end, 0, 3, 7, &status);

I argue they shouldn't; there should be a way to distinguish them.


Here's a discussion in the shadow mailing list, where I originally reported this bug:
<https://lists.sr.ht/~hallyn/shadow/%3CZZoQDms6Sv6e5SPE%40debian%3E>
>How-To-Repeat:
Call strtoi(3) or strtou(3) with a string that overflows or underflows the [min, max] range, *and* contains trailing text.
>Fix:
I've implemented my own strtoi() and strtou(), using GNU C11, which report ERANGE if both ERANGE and ENOTSUP happen:


alx@debian:~/src/shadow/shadow/getlong$ grepc -tfd shadow_strtoi .
./lib/atoi/strtoi.c:intmax_t
shadow_strtoi(const char *str, char **restrict endptr, int base,
    intmax_t min, intmax_t max, int *restrict status)
{
	return strtoN(str, endptr, base, min, max, status, intmax_t);
}
alx@debian:~/src/shadow/shadow/getlong$ grepc -tfd shadow_strtou .
./lib/atoi/strtoi.c:uintmax_t
shadow_strtou(const char *str, char **restrict endptr, int base,
    uintmax_t min, uintmax_t max, int *restrict status)
{
	return strtoN(str, endptr, base, min, max, status, uintmax_t);
}
alx@debian:~/src/shadow/shadow/getlong$ grepc strtoN .
./lib/atoi/strtoi.c:#define strtoN(str, endptr, base, min, max, status, TYPE)                     \
({                                                                            \
	const char  *str_ = str;                                              \
	char        **endptr_ = endptr;                                       \
	int         base_ = base;                                             \
	TYPE        min_ = min;                                               \
	TYPE        max_ = max;                                               \
	int         *status_ = status;                                        \
                                                                              \
	int         errno_saved_, s_;                                         \
	char        *e_;                                                      \
	TYPE        n_;                                                       \
                                                                              \
	if (endptr_ == NULL)                                                  \
		endptr_ = &e_;                                                \
	if (status_ == NULL)                                                  \
		status_ = &s_;                                                \
                                                                              \
	if (base_ < 0 || base_ > 36) {                                        \
		*status_ = EINVAL;                                            \
		n_ = 0;                                                       \
                                                                              \
	} else {                                                              \
		errno_saved_ = errno;                                         \
		errno = 0;                                                    \
		n_ = strtoNmax(TYPE, str_, endptr_, base_);                   \
                                                                              \
		if (*endptr_ == str_)                                         \
			*status_ = ECANCELED;                                 \
		else if (errno == ERANGE)                                     \
			*status_ = ERANGE;                                    \
		else if (n_ < min_ || n_ > max_)                              \
			*status_ = ERANGE;                                    \
		else if (**endptr_ != '\0')                                   \
			*status_ = ENOTSUP;                                   \
		else                                                          \
			*status_ = 0;                                         \
                                                                              \
		errno = errno_saved_;                                         \
	}                                                                     \
	SATURATE(min_, max_, n_);                                             \
})
alx@debian:~/src/shadow/shadow/getlong$ grepc strtoNmax .
./lib/atoi/strtoi.c:#define strtoNmax(TYPE, ...)                                                  \
(                                                                             \
	_Generic((TYPE) 0,                                                    \
		intmax_t:  strtoimax,                                         \
		uintmax_t: strtoumax                                          \
	)(__VA_ARGS__)                                                        \
)
alx@debian:~/src/shadow/shadow/getlong$ grepc SATURATE .
./lib/atoi/strtoi.h:#define SATURATE(min, max, n)  MAX(min, MIN(max, n))

>Audit-Trail:
From: Alejandro Colomar <alx@kernel.org>
To: gnats-bugs@netbsd.org
Cc: 
Subject: Re: lib/57828: strtoi(3), strtou(3): When both ERANGE and ENOTSUP
 conditions happen, ERANGE should be more important
Date: Tue, 9 Jan 2024 14:30:23 +0100

 --oYlthqTVVSHtac1b
 Content-Type: text/plain; protected-headers=v1; charset=utf-8
 Content-Disposition: inline
 Content-Transfer-Encoding: quoted-printable
 Date: Tue, 9 Jan 2024 14:30:23 +0100
 From: Alejandro Colomar <alx@kernel.org>
 To: gnats-bugs@netbsd.org
 Subject: Re: lib/57828: strtoi(3), strtou(3): When both ERANGE and ENOTSUP
  conditions happen, ERANGE should be more important

 On Sun, Jan 07, 2024 at 10:30:01PM +0000, gnats-admin@netbsd.org wrote:
 > Thank you very much for your problem report.
 > It has the internal identification `lib/57828'.
 > The individual assigned to look at your
 > report is: lib-bug-people.=20
 >=20
 > >Category:       lib
 > >Responsible:    lib-bug-people
 > >Synopsis:       strtoi(3), strtou(3): When both ERANGE and ENOTSUP condi=
 tions happen, ERANGE should be more important
 > >Arrival-Date:   Sun Jan 07 22:30:01 +0000 2024

 Hi,

 Here's an analysis of the implications that changing strto[iu](3) would
 have in the entire NetBSD tree (unless I missed anything):

 <https://lists.sr.ht/~hallyn/shadow/%3CZZoQDms6Sv6e5SPE%40debian%3E#%3CZZsY=
 ZJaG2wn-WLEy@debian%3E>
 with a small correction here:
 <https://lists.sr.ht/~hallyn/shadow/%3CZZoQDms6Sv6e5SPE%40debian%3E#%3CZZs1=
 os0iaHxTJffh@debian%3E>

 And here's an analysis of the implications that changing strto[iu](3)
 would have in the Debian sources (unless I missed anything):

 <https://lists.sr.ht/~hallyn/shadow/%3CZZoQDms6Sv6e5SPE%40debian%3E#%3CZZ1I=
 4s5fT7kyrpN3@debian%3E>

 Have a lovely day,
 Alex

 --=20
 <https://www.alejandro-colomar.es/>
 Looking for a remote C programming job at the moment.

 --oYlthqTVVSHtac1b
 Content-Type: application/pgp-signature; name="signature.asc"

 -----BEGIN PGP SIGNATURE-----

 iQIzBAABCgAdFiEE6jqH8KTroDDkXfJAnowa+77/2zIFAmWdSm8ACgkQnowa+77/
 2zI1LRAAiocN1dgkXgdpX0ziWoBUcl7QPrJ6xPfz7N2MpsF2awktJKkyb2b1AW3v
 eG2RaF7qDOmINlZgS5mnQOtfgENdqH+z9G8H4a+RsmXNbfYrvgkKH1RpX++fOUe8
 bMkx2c58KWo8g2+T0avDT1Tou28OMCu6/q+/NAPMVi947Mjp0JzP+8bVoTlwGy0U
 zY/t4rIVjxt51qvnf0G5n0s5eauetoCyYk7GSDq8gYBgR9MZ/UWp3H2gbQhxMxCz
 phz+nXv5TrXoAPYpdzhMUIMeis4WwA9qo+83h/Lx1bWmj15bpLoSZV37t2T/GIOF
 dzh+lzMGMA/YlVczLfe9aQhiuNf7Fc7p3wvSOWsd1HILTKqeny8QwrX4MNAA04lC
 7IIqGhui4SEw7KEbNNbFGtnNQgIZ4XT9dnCkoF2dPIO2hQ/t7PnTA9WuY+9LpdjQ
 lUekBoE/3r4RoNBLSFJrxUJHuoVjnmzsRX8WFnRS5G9Gln4byt4uK6eilO4HigB1
 Cj0E0fhDvPaMhZrggIx1UBmCpuRLJo7j1bqtNZdGXaHHgvcWG4QdmNOHsrocuUHS
 I0NLmu10ZWkH9v8H7nyLqduNCAxpfvInC9uKeiG3h/GPjpj7WzPs4WBz+sPthZ5G
 +Jy9Dah40EBmWHnbCqm4G1LgmpNnPHay5vk/nq7QRDhLpIcX1EE=
 =dQm6
 -----END PGP SIGNATURE-----

 --oYlthqTVVSHtac1b--

From: Alejandro Colomar <alx@kernel.org>
To: gnats-bugs@netbsd.org
Cc: 
Subject: Re: lib/57828: strtoi(3), strtou(3): When both ERANGE and ENOTSUP
 conditions happen, ERANGE should be more important
Date: Tue, 9 Jan 2024 14:33:06 +0100

 --5sGvpjti7fmlimHD
 Content-Type: text/plain; protected-headers=v1; charset=utf-8
 Content-Disposition: inline
 Content-Transfer-Encoding: quoted-printable
 Date: Tue, 9 Jan 2024 14:33:06 +0100
 From: Alejandro Colomar <alx@kernel.org>
 To: gnats-bugs@netbsd.org
 Subject: Re: lib/57828: strtoi(3), strtou(3): When both ERANGE and ENOTSUP
  conditions happen, ERANGE should be more important

 On Sun, Jan 07, 2024 at 10:30:01PM +0000, gnats-admin@netbsd.org wrote:
 > Thank you very much for your problem report.
 > It has the internal identification `lib/57828'.
 > The individual assigned to look at your
 > report is: lib-bug-people.=20
 >=20
 > >Category:       lib
 > >Responsible:    lib-bug-people
 > >Synopsis:       strtoi(3), strtou(3): When both ERANGE and ENOTSUP condi=
 tions happen, ERANGE should be more important
 > >Arrival-Date:   Sun Jan 07 22:30:01 +0000 2024

 Here's an analysis of the implications that changing strto[iu](3) would
 have in the entire NetBSD tree (unless I missed anything):

 <https://lists.sr.ht/~hallyn/shadow/%3CZZoQDms6Sv6e5SPE%40debian%3E#%3CZZsY=
 ZJaG2wn-WLEy@debian%3E>
 with a small correction here:
 <https://lists.sr.ht/~hallyn/shadow/%3CZZoQDms6Sv6e5SPE%40debian%3E#%3CZZs1=
 os0iaHxTJffh@debian%3E>

 And here's an analysis of the implications that changing strto[iu](3)
 would have in the Debian sources (unless I missed anything):

 <https://lists.sr.ht/~hallyn/shadow/%3CZZoQDms6Sv6e5SPE%40debian%3E#%3CZZ1I=
 4s5fT7kyrpN3@debian%3E>

 Have a lovely day,
 Alex

 --=20
 <https://www.alejandro-colomar.es/>
 Looking for a remote C programming job at the moment.

 --5sGvpjti7fmlimHD
 Content-Type: application/pgp-signature; name="signature.asc"

 -----BEGIN PGP SIGNATURE-----

 iQIzBAABCgAdFiEE6jqH8KTroDDkXfJAnowa+77/2zIFAmWdSxIACgkQnowa+77/
 2zJ4MQ/+JWmjv9gV7axwoMa2mO2Vyrmp6iK9Jj2LrfcCEDQJUSHlFI63xnvMQvh4
 Rpi+yvZIPOyS6M5Hq7ref02wRgUHMduyf/Q3M0xCxpGcaVGvhR9N6MHwkJfTI0iK
 S9yuK85Z4OWXGoN/ShbY7mt7IULSxvdcnO/kcokKdZE5kNNW1njgUAHuCJzBIlas
 qCW862CRfjXv6/5KyA8xpyqFIrhZ4kpxd9AQI3lo6f/5/ZU7Vvs7JF9x2FF/phcg
 xE2A1bRrk54ODgNamCvlgvgOgY1H2D0nUhJibl21hUglrMFUae9P7Vq24iuPn7gQ
 /ZcgIOf2s1XaJ6jyEu4vza939P6OD3n9kBmH+dquwDM6/QO8UxXbS2RJOQXXrEqh
 9Oazu66Zi1JBthT8/dZGkX7BlXZgC61PppYVxk0QP5M8LnP1/yBA4xcmlKfcn0N1
 PAdtgcqVl80Hy9Ex4NklqcmwzEnKivaZccgVraEdcPuP9EFufIvFm3wywaRCF6V+
 /E7Ng5gvwXSZNQGYJYQP6PZhuBQTF9QpIbcrpJpIKNze79hI27axvfvrrNZcOkDa
 mS6HmgRakzh4QFs10Iwu/OXwf+2i3+jiBLcLHEB2cNsJ7AbrkacUpfQlysCSstwz
 HIsigEne3VANFKBRyWcVzKsCp+oE+JyqnIlYLnjkAdvr7d+Q9v0=
 =SA8c
 -----END PGP SIGNATURE-----

 --5sGvpjti7fmlimHD--

From: "Christos Zoulas" <christos@netbsd.org>
To: gnats-bugs@gnats.NetBSD.org
Cc: 
Subject: PR/57828 CVS commit: src
Date: Sat, 20 Jan 2024 11:13:39 -0500

 Module Name:	src
 Committed By:	christos
 Date:		Sat Jan 20 16:13:39 UTC 2024

 Modified Files:
 	src/common/lib/libc/stdlib: _strtoi.h
 	src/lib/libc/stdlib: strtoi.3 strtonum.c strtou.3

 Log Message:
 PR/57828: Alejandro Colomar: Prioritize test for ERANGE before testing for
 fully consuming the string. Adjust strtonum(3) to behave as before. Document
 the order of the tests and sync the man pages (I should really autogenerate
 one of the two man pages...)


 To generate a diff of this commit:
 cvs rdiff -u -r1.2 -r1.3 src/common/lib/libc/stdlib/_strtoi.h
 cvs rdiff -u -r1.7 -r1.8 src/lib/libc/stdlib/strtoi.3 \
     src/lib/libc/stdlib/strtou.3
 cvs rdiff -u -r1.6 -r1.7 src/lib/libc/stdlib/strtonum.c

 Please note that diffs are not public domain; they are subject to the
 copyright notices on the relevant files.

NetBSD Home
NetBSD PR Database Search

(Contact us) $NetBSD: query-full-pr,v 1.47 2022/09/11 19:34:41 kim Exp $
$NetBSD: gnats_config.sh,v 1.9 2014/08/02 14:16:04 spz Exp $
Copyright © 1994-2024 The NetBSD Foundation, Inc. ALL RIGHTS RESERVED.