From patchwork Thu Dec 15 21:13:43 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Joseph Myers X-Patchwork-Id: 61984 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id E62573896C36 for ; Thu, 15 Dec 2022 21:14:02 +0000 (GMT) X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from esa2.mentor.iphmx.com (esa2.mentor.iphmx.com [68.232.141.98]) by sourceware.org (Postfix) with ESMTPS id AE979389634D for ; Thu, 15 Dec 2022 21:13:48 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org AE979389634D Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=codesourcery.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=mentor.com X-IronPort-AV: E=Sophos;i="5.96,248,1665475200"; d="scan'208";a="90415665" Received: from orw-gwy-01-in.mentorg.com ([192.94.38.165]) by esa2.mentor.iphmx.com with ESMTP; 15 Dec 2022 13:13:47 -0800 IronPort-SDR: ASnabGSSuzIhg6+mtKnckqydk2dkZR51eyuVjaAc++zT34Tx5AhFkF0IOnqjvOgoOH6M/mRGHR pd5d5UaGVLo3N0ii3lUMRLZ6Sx6b4ZV8l0czIhz9a3rKJAh79tb+xWJP8TbSLRSE8gP8Fbi7xu u88IVMBwwWu3UDKfX40RIbwhlkvJefjqhKF5UGCjE0dDiqy+RXpsf0Gfm5ntrCrT5GYk2YXu27 JE7hpY5J+d8L/u/y2XHHUp1uvCjjfDwYol5j0jjm+S6iE6XjvM5+YP8xQcRMO4wPIvEbWluqMM Lk8= Date: Thu, 15 Dec 2022 21:13:43 +0000 From: Joseph Myers To: Subject: Avoid use of atoi in some places in libc Message-ID: <166040fa-841-ae72-4dc8-3233a43ded1@codesourcery.com> MIME-Version: 1.0 X-Originating-IP: [137.202.0.90] X-ClientProxiedBy: svr-ies-mbx-11.mgc.mentorg.com (139.181.222.11) To svr-ies-mbx-10.mgc.mentorg.com (139.181.222.10) X-Spam-Status: No, score=-3115.5 required=5.0 tests=BAYES_00, GIT_PATCH_0, HEADER_FROM_DIFFERENT_DOMAINS, KAM_DMARC_STATUS, RCVD_IN_MSPIKE_H2, SPF_HELO_PASS, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: libc-alpha@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Libc-alpha mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: libc-alpha-bounces+patchwork=sourceware.org@sourceware.org Sender: "Libc-alpha" This patch is split out of . 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. Reviewed-by: Noah Goldstein diff --git a/argp/argp-help.c b/argp/argp-help.c index 90a2795cef..328b981374 100644 --- a/argp/argp-help.c +++ b/argp/argp-help.c @@ -210,7 +210,7 @@ fill_in_uparams (const struct argp_state *state) } else if (isdigit ((unsigned char) *arg)) { - val = atoi (arg); + val = strtol (arg, NULL, 10); while (isdigit ((unsigned char) *arg)) arg++; 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