From nobody Fri Sep 09 21:30:59 2022 X-Original-To: dev-commits-src-main@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4MPTgm0Wjqz4cN6S; Fri, 9 Sep 2022 21:31:00 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4MPTgm02SDz3YHy; Fri, 9 Sep 2022 21:31:00 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1662759060; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=BR162fypvGISJy8BaixnPlYzd6IFvflezfzOncHCJwQ=; b=DBTckU+MSiISl0bwKd0WP+luvOm2IBBkeMfnO1iOvsCBPuL6M6BqdYv9iyiuf6B6XqWiMr dOk4cKA1Hkz1a5XmsyFizkKGYY4YXOfrE/NiXrcz0dlDuiILD4i+Ty/1ZXOcA66YKcoAHF ndtGQLIpvhqaLwXrVoGyn4RKeUa18o/gvR7Ts/50FecDGPx0QIGRzf6A5f99aPNgSbJCCl apnuEeV/7TjfjOMTEMsq1Hig24Oz5ORVJhxGXgkp3WSULTiatZ0Zf5+TxKCsc9aLx7y22S TyqsOlEeboTmYVLhqXuJfn+Asf4//XUjC4B2O+ajD2YXyccEvKaMQiY4mjjOeg== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 4MPTgl6C6qz1Kfd; Fri, 9 Sep 2022 21:30:59 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.16.1/8.16.1) with ESMTP id 289LUxc7066516; Fri, 9 Sep 2022 21:30:59 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.16.1/8.16.1/Submit) id 289LUxU6066515; Fri, 9 Sep 2022 21:30:59 GMT (envelope-from git) Date: Fri, 9 Sep 2022 21:30:59 GMT Message-Id: <202209092130.289LUxU6066515@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: Kirk McKusick Subject: git: 927f8d8bbbed - main - Handle NULL return from localtime(3) in ls(1) and find(1) List-Id: Commit messages for the main branch of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-main List-Help: List-Post: List-Subscribe: List-Unsubscribe: Sender: owner-dev-commits-src-main@freebsd.org X-BeenThere: dev-commits-src-main@freebsd.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: mckusick X-Git-Repository: src X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: 927f8d8bbbed70f6c88d05c19b5b366f8e7532c9 Auto-Submitted: auto-generated ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1662759060; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=BR162fypvGISJy8BaixnPlYzd6IFvflezfzOncHCJwQ=; b=kUbtxpq8WT6tLZ1O4dXqJwZVi3fTNB/xDyPeRPSx+5CnHnvFtO1wDUs6L6SNiSAFueklQY 3ePD18Fu0iOmkfgg1G0apiOK4F9/nCv5SfjU76baT8E+EQLoEDrLTznzInexNJ31FBGgkx 2C3Vtos/suYAfZLuq0Yc6kl8hXcK4T6cpJI6PulNn6/Qg81+zVb4PvLuT1WXC/f7kwn7df /VLwmGNJylH2m658abR/aipHFpIrkk8oOUdn+coLF7TzmTRI6JhsKDcpEvP6i4yem0QfPL PCFx2lviyBEZ3Lc1EI171iwuu/o7cXYdkeXgjrgkoOeUfX0YvO/S7ubwV92KMg== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1662759060; a=rsa-sha256; cv=none; b=b1JFffIGk7NAxlu4reIB43Yt88wUi/6o7TFBg+lL5gxFGFexZBktIq0TOtZawzRHv2PNiU Zs7i+SO6XI3c0rQF9PuyCmEc2nHY7zvZi30Kpo72GoqWBd8dCmb2+31RnISxm2Tfs1fT7X 2PcfymV4n73HC8SfNHbjFns8Ouc6rJYZ5GsSGt4Pj2q980eY+a7eiZVV3iXdpbGgCnA85W RTGYyz0lvqhfQjL8nAEPNqr4YJF7P13V1ChBQsXpRHz6feYEGDMXb28s/3wklcxkL+Nj1O nHwUyoOv7kzKuUxniBYvVQCzKEsrny5KeZD+jAG1wCOVu6KBN6w4xeXMLH/hJA== ARC-Authentication-Results: i=1; mx1.freebsd.org; none X-ThisMailContainsUnwantedMimeParts: N The branch main has been updated by mckusick: URL: https://cgit.FreeBSD.org/src/commit/?id=927f8d8bbbed70f6c88d05c19b5b366f8e7532c9 commit 927f8d8bbbed70f6c88d05c19b5b366f8e7532c9 Author: Kirk McKusick AuthorDate: 2022-09-09 21:29:53 +0000 Commit: Kirk McKusick CommitDate: 2022-09-09 21:30:42 +0000 Handle NULL return from localtime(3) in ls(1) and find(1) The ls(1) (with -l option) and find(1) (with -ls option) utilties segment fault when operating on files with very large modification times. A recent disk corruption set a spurious bit in the mtime field of one of my files to 0x8000000630b0167 (576460753965089127) which is in year 18,266,940,962. I discovered the problem when running fsck_ffs(8) which uses ctime(3) to convert it to a readable format. Ctime cannot fit the year into its four character field, so returns ??? ??? ?? ??:??:?? ???? (typically Thu Nov 24 18:22:48 2021). With the filesystem mounted, I used `ls -l' to see how it would report the modification time and it segment faulted. The find(1) program also segment faulted (see script below). Both these utilities call the localtime(3) function to decode the modification time. Localtime(3) returns a pointer to a struct tm (which breaks things out into its component pieces: year, month, day, hour, minute, second). The ls(1) and find(1) utilities then print out the date based on the appropriate fields in the returned tm structure. Although not documented in the localtime(3) manual page, localtime(3) returns a NULL pointer if the passed in time translates to a year that will not fit in an "int" (which if "int" is 32-bits cannot hold the year 18,266,940,962). Since ls(1) and find(1) do not check for a NULL struct tm * return from localtime(3), they segment fault when they try to dereference it. When localtime(3) returns NULL, the attached patches produce a date string of "bad date val". This string is chosen because it has the same number of characters (12) and white spaces (2) as the usual date string, for example "Sep 3 22:06" or "May 15 2017". The most recent ANSI standard for localtime(3) does say that localtime(3) can return NULL (see https://pubs.opengroup.org/onlinepubs/9699919799/ and enter localtime in the search box). Our localtime(3) man page should be updated to indicate that NULL is a possible return. More importantly, there are over 100 uses of localtime(3) in the FreeBSD source tree (see Differential Revision D36474 for the list). Most do not check for a NULL return from localtime(3). Reported by: Peter Holm Reviewed by: kib, Chuck Silvers, Warner Losh MFC after: 2 weeks Sponsored by: The FreeBSD Foundation Differential Revision: https://reviews.freebsd.org/D36474 --- bin/ls/print.c | 11 ++++++----- usr.bin/find/ls.c | 6 +++++- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/bin/ls/print.c b/bin/ls/print.c index bbe5c6f8a6f6..5e8a54ca0620 100644 --- a/bin/ls/print.c +++ b/bin/ls/print.c @@ -432,18 +432,17 @@ printdev(size_t width, dev_t dev) (void)printf("%#*jx ", (u_int)width, (uintmax_t)dev); } -static size_t +static void ls_strftime(char *str, size_t len, const char *fmt, const struct tm *tm) { char *posb, nfmt[BUFSIZ]; const char *format = fmt; - size_t ret; if ((posb = strstr(fmt, "%b")) != NULL) { if (month_max_size == 0) { compute_abbreviated_month_size(); } - if (month_max_size > 0) { + if (month_max_size > 0 && tm != NULL) { snprintf(nfmt, sizeof(nfmt), "%.*s%s%*s%s", (int)(posb - fmt), fmt, get_abmon(tm->tm_mon), @@ -453,8 +452,10 @@ ls_strftime(char *str, size_t len, const char *fmt, const struct tm *tm) format = nfmt; } } - ret = strftime(str, len, format, tm); - return (ret); + if (tm != NULL) + strftime(str, len, format, tm); + else + strlcpy(str, "bad date val", len); } static void diff --git a/usr.bin/find/ls.c b/usr.bin/find/ls.c index 8c4c16ed3461..8d7406216256 100644 --- a/usr.bin/find/ls.c +++ b/usr.bin/find/ls.c @@ -88,6 +88,7 @@ printtime(time_t ftime) static time_t lnow; const char *format; static int d_first = -1; + struct tm *tm; #ifdef D_MD_ORDER if (d_first < 0) @@ -103,7 +104,10 @@ printtime(time_t ftime) else /* mmm dd yyyy || dd mmm yyyy */ format = d_first ? "%e %b %Y " : "%b %e %Y "; - strftime(longstring, sizeof(longstring), format, localtime(&ftime)); + if ((tm = localtime(&ftime)) != NULL) + strftime(longstring, sizeof(longstring), format, tm); + else + strlcpy(longstring, "bad date val ", sizeof(longstring)); fputs(longstring, stdout); }