summaryrefslogtreecommitdiff
path: root/backport-Avoid-use-of-atoi-in-some-places-in-libc.patch
diff options
context:
space:
mode:
Diffstat (limited to 'backport-Avoid-use-of-atoi-in-some-places-in-libc.patch')
-rw-r--r--backport-Avoid-use-of-atoi-in-some-places-in-libc.patch120
1 files changed, 120 insertions, 0 deletions
diff --git a/backport-Avoid-use-of-atoi-in-some-places-in-libc.patch b/backport-Avoid-use-of-atoi-in-some-places-in-libc.patch
new file mode 100644
index 0000000..c991622
--- /dev/null
+++ b/backport-Avoid-use-of-atoi-in-some-places-in-libc.patch
@@ -0,0 +1,120 @@
+From a3708cf6b0a5a68e2ed1ce3db28a03ed21d368d2 Mon Sep 17 00:00:00 2001
+From: Joseph Myers <joseph@codesourcery.com>
+Date: Mon, 19 Dec 2022 14:45:44 +0000
+Subject: [PATCH] Avoid use of atoi in some places in libc
+
+This patch is split out of
+<https://sourceware.org/pipermail/libc-alpha/2022-December/144122.html>.
+
+atoi has undefined behavior on out-of-range input, which makes it
+problematic to use anywhere in glibc that might be processing input
+out-of-range for atoi but not specified to produce undefined behavior
+for the function calling atoi. Change some uses of atoi to call
+strtol instead; this avoids the undefined behavior, though there is no
+guarantee that the overflow handling of strtol is really right in
+those places either. This also serves to avoid localplt test failures
+given an installed header redirection for strtol (which means that the
+call from the inline atoi implementation doesn't end up at a hidden
+alias from libc_hidden_proto).
+
+Certainly, the use of atoi is questionable in argp-help.c (shared with
+gnulib, so shouldn't depend on glibc implementation details, and
+processing user-provided input), and maybe also in argp-parse.c (I'm
+not sure what that code in argp-parse.c is meant to be used for). I
+also changed inet/rexec.c and resolv/res_init.c similarly to use
+strtol to avoid such localplt failures, although given those files (in
+those versions) are only used in glibc it's not problematic for them
+to rely on the specific behavior of glibc's atoi on out-of-range input
+(in the absence of compiler optimizations based on the undefined
+behavior) in the same way it's problematic for gnulib code to do so.
+
+There may be other uses of atoi (or atol or atoll), in any of glibc's
+installed code, for which it would also be appropriate to avoid the
+undefined behavior on out-of-range input; this patch only fixes the
+specific cases needed to avoid localplt failures.
+
+Tested for x86_64.
+---
+ argp/argp-help.c | 6 +++---
+ argp/argp-parse.c | 2 +-
+ inet/rexec.c | 2 +-
+ resolv/res_init.c | 6 +++---
+ 4 files changed, 8 insertions(+), 8 deletions(-)
+
+diff --git a/argp/argp-help.c b/argp/argp-help.c
+index 90a2795cef..f7f1134c80 100644
+--- a/argp/argp-help.c
++++ b/argp/argp-help.c
+@@ -210,9 +210,9 @@ fill_in_uparams (const struct argp_state *state)
+ }
+ else if (isdigit ((unsigned char) *arg))
+ {
+- val = atoi (arg);
+- while (isdigit ((unsigned char) *arg))
+- arg++;
++ char *ep;
++ val = strtol (arg, &ep, 10);
++ arg = ep;
+ SKIPWS (arg);
+ }
+
+diff --git a/argp/argp-parse.c b/argp/argp-parse.c
+index 68dc45417b..1533b43aaf 100644
+--- a/argp/argp-parse.c
++++ b/argp/argp-parse.c
+@@ -147,7 +147,7 @@ argp_default_parser (int key, char *arg, struct argp_state *state)
+ break;
+
+ case OPT_HANG:
+- _argp_hang = atoi (arg ? arg : "3600");
++ _argp_hang = arg ? strtol (arg, NULL, 10) : 3600;
+ while (_argp_hang-- > 0)
+ __sleep (1);
+ break;
+diff --git a/inet/rexec.c b/inet/rexec.c
+index 064e979d68..c647b7ac34 100644
+--- a/inet/rexec.c
++++ b/inet/rexec.c
+@@ -134,7 +134,7 @@ retry:
+ if (!getnameinfo(&sa2.sa, sa2len,
+ NULL, 0, servbuff, sizeof(servbuff),
+ NI_NUMERICSERV))
+- port = atoi(servbuff);
++ port = strtol(servbuff, NULL, 10);
+ (void) sprintf(num, "%u", port);
+ (void) __write(s, num, strlen(num)+1);
+ { socklen_t len = sizeof (from);
+diff --git a/resolv/res_init.c b/resolv/res_init.c
+index 2c0bea658e..61b958a437 100644
+--- a/resolv/res_init.c
++++ b/resolv/res_init.c
+@@ -654,7 +654,7 @@ res_setoptions (struct resolv_conf_parser *parser, const char *options)
+ /* Search for and process individual options. */
+ if (!strncmp (cp, "ndots:", sizeof ("ndots:") - 1))
+ {
+- int i = atoi (cp + sizeof ("ndots:") - 1);
++ int i = strtol (cp + sizeof ("ndots:") - 1, NULL, 10);
+ if (i <= RES_MAXNDOTS)
+ parser->template.ndots = i;
+ else
+@@ -662,7 +662,7 @@ res_setoptions (struct resolv_conf_parser *parser, const char *options)
+ }
+ else if (!strncmp (cp, "timeout:", sizeof ("timeout:") - 1))
+ {
+- int i = atoi (cp + sizeof ("timeout:") - 1);
++ int i = strtol (cp + sizeof ("timeout:") - 1, NULL, 10);
+ if (i <= RES_MAXRETRANS)
+ parser->template.retrans = i;
+ else
+@@ -670,7 +670,7 @@ res_setoptions (struct resolv_conf_parser *parser, const char *options)
+ }
+ else if (!strncmp (cp, "attempts:", sizeof ("attempts:") - 1))
+ {
+- int i = atoi (cp + sizeof ("attempts:") - 1);
++ int i = strtol (cp + sizeof ("attempts:") - 1, NULL, 10);
+ if (i <= RES_MAXRETRY)
+ parser->template.retry = i;
+ else
+--
+2.33.0
+