From patchwork Fri Apr 9 23:43:31 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Rosen Penev X-Patchwork-Id: 1464566 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (no SPF record) smtp.mailfrom=lists.openwrt.org (client-ip=2001:8b0:10b:1:d65d:64ff:fe57:4e05; helo=desiato.infradead.org; envelope-from=openwrt-devel-bounces+incoming=patchwork.ozlabs.org@lists.openwrt.org; receiver=) Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; secure) header.d=lists.infradead.org header.i=@lists.infradead.org header.a=rsa-sha256 header.s=desiato.20200630 header.b=Y4CrkA4T; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20161025 header.b=O+MwZGIq; dkim-atps=neutral Received: from desiato.infradead.org (desiato.infradead.org [IPv6:2001:8b0:10b:1:d65d:64ff:fe57:4e05]) (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) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4FHFDF26s1z9sWH for ; Sat, 10 Apr 2021 09:47:24 +1000 (AEST) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=desiato.20200630; h=Sender:Content-Transfer-Encoding :Content-Type:List-Subscribe:List-Help:List-Post:List-Archive: List-Unsubscribe:List-Id:MIME-Version:Message-Id:Date:Subject:Cc:To:From: Reply-To:Content-ID:Content-Description:Resent-Date:Resent-From:Resent-Sender :Resent-To:Resent-Cc:Resent-Message-ID:In-Reply-To:References:List-Owner; bh=1gQ7tE1SqZE0gge2OzKS0jj0u8Y0C7pdMOPSbccuNwM=; b=Y4CrkA4Tm/w5/oVMzjYfzkUcV/ dXzqWNk3bJ1uQhSovYnWwEfx/d7f7MyrWTf4PxwIfW18nIPqBHVRjKb1YeWlUT2Q49YYpnsB44c7l N1Y3+4NuMWpOilJyBEPIepIqAzt4G9LQV6OxzxZ7WybgfO6X661oeSVbtt/Ml0iz66xCC4LWjqQtY HG2WMRKphW4n9JtIR8AG5hxcxszzqCrEjmNMJE1S3O/qpdnV51W4OQCybuPSy2wFHKpwQZgNtM2ee RNIyylZ2tvGk8QuaNX2ktuQJ4ZuADyGvA9V2Qcc3VMnBmRIezYXvqkwF9CGIYZ5ntMB1drw13Mwfi y3/8692w==; Received: from localhost ([::1] helo=desiato.infradead.org) by desiato.infradead.org with esmtp (Exim 4.94 #2 (Red Hat Linux)) id 1lV0ng-001mKs-Mo; Fri, 09 Apr 2021 23:44:34 +0000 Received: from mail-pj1-x102c.google.com ([2607:f8b0:4864:20::102c]) by desiato.infradead.org with esmtps (Exim 4.94 #2 (Red Hat Linux)) id 1lV0mo-001mG1-1g for openwrt-devel@lists.openwrt.org; Fri, 09 Apr 2021 23:44:11 +0000 Received: by mail-pj1-x102c.google.com with SMTP id kk2-20020a17090b4a02b02900c777aa746fso3959521pjb.3 for ; Fri, 09 Apr 2021 16:43:35 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:mime-version :content-transfer-encoding; bh=5gF8xsNPe/cyx+l8+Fr8CKyrILlcRVrjbZ0+8xx8h74=; b=O+MwZGIqOjhYnV/Cil6qNQjnkPXEQrbd37mEFLq6WXHIdRWaF3zSr5BQ9LDDZnBudK k8f3U+EPPHvZ+XJJ6KmC+/fPzcW+o22F3ieNDe71CyUe6UiZkntcy7ld7lyVDA+IsGnJ l8SYaiuqyPKLg1rqWLI2rndxgB8Goes0UJCcj16ZX8eCXYPJrNPOV91sJjAU0A3hzUhg +RzuAX6i9wTsNVfkdbn6FVMectu6dmKk0XII9eTdX6PJGGIIO2bYLiaNr9aWNOBLqIj7 glZ3kJdghGp4VPhd2FsskakrVruDKqSohFsxANVGLvuvoBIYF3ShmjjQHXZeulem/uhF unZA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:mime-version :content-transfer-encoding; bh=5gF8xsNPe/cyx+l8+Fr8CKyrILlcRVrjbZ0+8xx8h74=; b=jw6rF3ENQYbS4dmdtbcCxABGh9hyJ7iGliZAWmBcMathl7h343Ezpe5ZXKFySF3B0b QZR3eDj9a5KxlHGQ6YxRYv4mDcG3wRLfBvK6u9YU5oKD21g0pONvrD5loN/r3ts2H9K8 mG9BRDoqaQP8Dezh1Ax81k4xgvRJoFm4JYlL/reWT/3YuN2G8rnb4QMHnpdBDhB1dpPp Ioj+4HQjjbr3CEKpxR44qYmUfeDjN4H77v45/atrhmQNKRd10fc/fIWa7+HCXRLftNem 6QOi1Ho+VSzNPpOmXA0spkXH/XiMd8oXuhcuoTIMpfGqaSrUTEu5oQxhbPxu+BcV2SsG g2EA== X-Gm-Message-State: AOAM5325KXCJNrv8XWiPTd7HhTPrdFrdpj77pjVFsNuARVMSfbkU2EYQ UjJX4jrtEu4H6jKFGffcOJa/JqtoR0k= X-Google-Smtp-Source: ABdhPJz6LKoXs5XdoC9O0cftRtVLw7Fh0bYszAnYjkG3JflRjcL/6E/WCVFi1hA4qFB+jsle+Z88Zw== X-Received: by 2002:a17:902:ea10:b029:e8:e2e9:d9a5 with SMTP id s16-20020a170902ea10b02900e8e2e9d9a5mr15392303plg.22.1618011813440; Fri, 09 Apr 2021 16:43:33 -0700 (PDT) Received: from mangix-trapnet.lan ([2001:470:1f05:79e::a89]) by smtp.gmail.com with ESMTPSA id d8sm3371331pfq.27.2021.04.09.16.43.32 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 09 Apr 2021 16:43:32 -0700 (PDT) From: Rosen Penev To: openwrt-devel@lists.openwrt.org Cc: pepe.schlehofer@gmail.com Subject: [PATCH]-19.07 busybox: backport hwclock fixes Date: Fri, 9 Apr 2021 16:43:31 -0700 Message-Id: <20210409234331.723573-1-rosenp@gmail.com> X-Mailer: git-send-email 2.30.2 MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20210410_004409_361833_38943868 X-CRM114-Status: GOOD ( 25.34 ) X-Spam-Score: -0.2 (/) X-Spam-Report: Spam detection software, running on the system "desiato.infradead.org", has NOT identified this incoming email as spam. The original message has been attached to this so you can view it or label similar future email. If you have any questions, see the administrator of that system for details. Content preview: Currently on devices with an RTC, sysfixtime uses busybox' hwclock to set the RTC time. Unfortunately, g/settimeofday on musl completely ignore the second parameter which forces users to use the sysca [...] Content analysis details: (-0.2 points, 5.0 required) pts rule name description ---- ---------------------- -------------------------------------------------- 0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record -0.0 SPF_PASS SPF: sender matches SPF record 0.0 FREEMAIL_FROM Sender email is commonly abused enduser mail provider [rosenp[at]gmail.com] -0.0 RCVD_IN_DNSWL_NONE RBL: Sender listed at https://www.dnswl.org/, no trust [2607:f8b0:4864:20:0:0:0:102c listed in] [list.dnswl.org] 0.1 DKIM_SIGNED Message has a DKIM or DK signature, not necessarily valid -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature -0.1 DKIM_VALID_AU Message has a valid DKIM or DK signature from author's domain -0.1 DKIM_VALID_EF Message has a valid DKIM or DK signature from envelope-from domain X-BeenThere: openwrt-devel@lists.openwrt.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: OpenWrt Development List List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "openwrt-devel" Errors-To: openwrt-devel-bounces+incoming=patchwork.ozlabs.org@lists.openwrt.org Currently on devices with an RTC, sysfixtime uses busybox' hwclock to set the RTC time. Unfortunately, g/settimeofday on musl completely ignore the second parameter which forces users to use the syscall directly. Backport two patches to fix hwclock's support for timezones. Signed-off-by: Rosen Penev Tested-by: Josef Schlehofer --- Note: this is already fixed in master and 21.02. package/utils/busybox/Makefile | 2 +- ...ock-Fix-settimeofday-for-glibc-v2.31.patch | 53 +++++ ...fix-musl-breakage-of-settimeofday-tz.patch | 195 ++++++++++++++++++ 3 files changed, 249 insertions(+), 1 deletion(-) create mode 100644 package/utils/busybox/patches/010-hwclock-Fix-settimeofday-for-glibc-v2.31.patch create mode 100644 package/utils/busybox/patches/020-hwclock-fix-musl-breakage-of-settimeofday-tz.patch diff --git a/package/utils/busybox/Makefile b/package/utils/busybox/Makefile index 23dd5498a1..a12401ff30 100644 --- a/package/utils/busybox/Makefile +++ b/package/utils/busybox/Makefile @@ -9,7 +9,7 @@ include $(TOPDIR)/rules.mk PKG_NAME:=busybox PKG_VERSION:=1.30.1 -PKG_RELEASE:=6 +PKG_RELEASE:=7 PKG_FLAGS:=essential PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2 diff --git a/package/utils/busybox/patches/010-hwclock-Fix-settimeofday-for-glibc-v2.31.patch b/package/utils/busybox/patches/010-hwclock-Fix-settimeofday-for-glibc-v2.31.patch new file mode 100644 index 0000000000..c6dd897b78 --- /dev/null +++ b/package/utils/busybox/patches/010-hwclock-Fix-settimeofday-for-glibc-v2.31.patch @@ -0,0 +1,53 @@ +From 38b8f0a91a786f42531b1e27746060377fbdcaba Mon Sep 17 00:00:00 2001 +From: Eddie James +Date: Mon, 10 Aug 2020 09:59:02 -0500 +Subject: [PATCH 1/2] hwclock: Fix settimeofday for glibc v2.31+ + +The glibc implementation changed for settimeofday, resulting in "invalid +argument" error when attempting to set both timezone and time with a single +call. Fix this by calling settimeofday twice + +Signed-off-by: Eddie James +Signed-off-by: Denys Vlasenko +--- + util-linux/hwclock.c | 14 +++++++++++--- + 1 file changed, 11 insertions(+), 3 deletions(-) + +--- a/util-linux/hwclock.c ++++ b/util-linux/hwclock.c +@@ -122,16 +122,20 @@ static void to_sys_clock(const char **pp + struct timeval tv; + struct timezone tz; + +- tz.tz_minuteswest = timezone/60; ++ tz.tz_minuteswest = timezone / 60; + /* ^^^ used to also subtract 60*daylight, but it's wrong: + * daylight!=0 means "this timezone has some DST + * during the year", not "DST is in effect now". + */ + tz.tz_dsttime = 0; + ++ /* glibc v2.31+ returns an error if both args are non-NULL */ ++ if (settimeofday(NULL, &tz)) ++ bb_simple_perror_msg_and_die("settimeofday"); ++ + tv.tv_sec = read_rtc(pp_rtcname, NULL, utc); + tv.tv_usec = 0; +- if (settimeofday(&tv, &tz)) ++ if (settimeofday(&tv, NULL)) + bb_perror_msg_and_die("settimeofday"); + } + +@@ -283,7 +287,11 @@ static void set_system_clock_timezone(in + gettimeofday(&tv, NULL); + if (!utc) + tv.tv_sec += tz.tz_minuteswest * 60; +- if (settimeofday(&tv, &tz)) ++ ++ /* glibc v2.31+ returns an error if both args are non-NULL */ ++ if (settimeofday(NULL, &tz)) ++ bb_perror_msg_and_die("settimeofday"); ++ if (settimeofday(&tv, NULL)) + bb_perror_msg_and_die("settimeofday"); + } + diff --git a/package/utils/busybox/patches/020-hwclock-fix-musl-breakage-of-settimeofday-tz.patch b/package/utils/busybox/patches/020-hwclock-fix-musl-breakage-of-settimeofday-tz.patch new file mode 100644 index 0000000000..88ab9f7b18 --- /dev/null +++ b/package/utils/busybox/patches/020-hwclock-fix-musl-breakage-of-settimeofday-tz.patch @@ -0,0 +1,195 @@ +From 54644059ef984727168c124858448ec66f4ecb5f Mon Sep 17 00:00:00 2001 +From: Denys Vlasenko +Date: Wed, 16 Dec 2020 13:49:10 +0100 +Subject: [PATCH 2/2] hwclock: fix musl breakage of settimeofday(tz) + +function old new delta +set_kernel_timezone_and_clock - 119 +119 +set_kernel_tz - 28 +28 +hwclock_main 480 301 -179 +------------------------------------------------------------------------------ +(add/remove: 2/0 grow/shrink: 0/1 up/down: 147/-179) Total: -32 bytes + +Signed-off-by: Denys Vlasenko +--- + util-linux/hwclock.c | 128 +++++++++++++++++++++++++------------------ + 1 file changed, 75 insertions(+), 53 deletions(-) + +--- a/util-linux/hwclock.c ++++ b/util-linux/hwclock.c +@@ -37,6 +37,19 @@ + #include + #include "rtc_.h" + ++ ++//musl has no __MUSL__ or similar define to check for, ++//but its has these lines: ++// #define __NEED_fsblkcnt_t ++// #define __NEED_fsfilcnt_t ++#if defined(__linux__) && defined(__NEED_fsblkcnt_t) && defined(__NEED_fsfilcnt_t) ++# define LIBC_IS_MUSL 1 ++# include ++#else ++# define LIBC_IS_MUSL 0 ++#endif ++ ++ + /* diff code is disabled: it's not sys/hw clock diff, it's some useless + * "time between hwclock was started and we saw CMOS tick" quantity. + * It's useless since hwclock is started at a random moment, +@@ -117,26 +130,73 @@ static void show_clock(const char **pp_r + #endif + } + +-static void to_sys_clock(const char **pp_rtcname, int utc) ++static void set_kernel_tz(const struct timezone *tz) + { +- struct timeval tv; +- struct timezone tz; +- +- tz.tz_minuteswest = timezone / 60; +- /* ^^^ used to also subtract 60*daylight, but it's wrong: +- * daylight!=0 means "this timezone has some DST +- * during the year", not "DST is in effect now". ++#if LIBC_IS_MUSL ++ /* musl libc does not pass tz argument to syscall ++ * because "it's deprecated by POSIX, therefore it's fine ++ * if we gratuitously break stuff" :( + */ +- tz.tz_dsttime = 0; +- +- /* glibc v2.31+ returns an error if both args are non-NULL */ +- if (settimeofday(NULL, &tz)) ++#if !defined(SYS_settimeofday) && defined(SYS_settimeofday_time32) ++# define SYS_settimeofday SYS_settimeofday_time32 ++#endif ++ int ret = syscall(SYS_settimeofday, NULL, tz); ++#else ++ int ret = settimeofday(NULL, tz); ++#endif ++ if (ret) + bb_simple_perror_msg_and_die("settimeofday"); ++} ++ ++/* ++ * At system boot, kernel may set system time from RTC, ++ * but it knows nothing about timezones. If RTC is in local time, ++ * then system time is wrong - it is offset by timezone. ++ * --systz option corrects system time if RTC is in local time, ++ * and (always) sets in-kernel timezone. ++ * ++ * This is an alternate option to --hctosys that does not read the ++ * hardware clock. ++ * ++ * util-linux's code has this comment: ++ * RTC | settimeofday calls ++ * ------|------------------------------------------------- ++ * Local | 1) warps system time*, sets PCIL* and kernel tz ++ * UTC | 1st) locks warp_clock 2nd) sets kernel tz ++ * * only on first call after boot ++ * (PCIL is "persistent_clock_is_local" kernel internal flag, ++ * it makes kernel save RTC in local time, not UTC.) ++ */ ++static void set_kernel_timezone_and_clock(int utc, const struct timeval *hctosys) ++{ ++ time_t cur; ++ struct tm *broken; ++ struct timezone tz = { 0 }; ++ ++ /* if --utc, prevent kernel's warp_clock() with a dummy call */ ++ if (utc) ++ set_kernel_tz(&tz); ++ ++ /* Set kernel's timezone offset based on userspace one */ ++ cur = time(NULL); ++ broken = localtime(&cur); ++ tz.tz_minuteswest = -broken->tm_gmtoff / 60; ++ /*tz.tz_dsttime = 0; already is */ ++ set_kernel_tz(&tz); /* MIGHT warp_clock() if 1st call since boot */ ++ ++ if (hctosys) { /* it's --hctosys: set time too */ ++ if (settimeofday(hctosys, NULL)) ++ bb_simple_perror_msg_and_die("settimeofday"); ++ } ++} ++ ++static void to_sys_clock(const char **pp_rtcname, int utc) ++{ ++ struct timeval tv; + + tv.tv_sec = read_rtc(pp_rtcname, NULL, utc); + tv.tv_usec = 0; +- if (settimeofday(&tv, NULL)) +- bb_perror_msg_and_die("settimeofday"); ++ return set_kernel_timezone_and_clock(utc, &tv); + } + + static void from_sys_clock(const char **pp_rtcname, int utc) +@@ -262,39 +322,6 @@ static void from_sys_clock(const char ** + close(rtc); + } + +-/* +- * At system boot, kernel may set system time from RTC, +- * but it knows nothing about timezones. If RTC is in local time, +- * then system time is wrong - it is offset by timezone. +- * This option corrects system time if RTC is in local time, +- * and (always) sets in-kernel timezone. +- * +- * This is an alternate option to --hctosys that does not read the +- * hardware clock. +- */ +-static void set_system_clock_timezone(int utc) +-{ +- struct timeval tv; +- struct tm *broken; +- struct timezone tz; +- +- gettimeofday(&tv, NULL); +- broken = localtime(&tv.tv_sec); +- tz.tz_minuteswest = timezone / 60; +- if (broken->tm_isdst > 0) +- tz.tz_minuteswest -= 60; +- tz.tz_dsttime = 0; +- gettimeofday(&tv, NULL); +- if (!utc) +- tv.tv_sec += tz.tz_minuteswest * 60; +- +- /* glibc v2.31+ returns an error if both args are non-NULL */ +- if (settimeofday(NULL, &tz)) +- bb_perror_msg_and_die("settimeofday"); +- if (settimeofday(&tv, NULL)) +- bb_perror_msg_and_die("settimeofday"); +-} +- + //usage:#define hwclock_trivial_usage + //usage: IF_LONG_OPTS( + //usage: "[-r|--show] [-s|--hctosys] [-w|--systohc] [--systz]" +@@ -335,7 +362,6 @@ int hwclock_main(int argc UNUSED_PARAM, + const char *rtcname = NULL; + unsigned opt; + int utc; +- + #if ENABLE_LONG_OPTS + static const char hwclock_longopts[] ALIGN1 = + "localtime\0" No_argument "l" /* short opt is non-standard */ +@@ -347,10 +373,6 @@ int hwclock_main(int argc UNUSED_PARAM, + "rtc\0" Required_argument "f" + ; + #endif +- +- /* Initialize "timezone" (libc global variable) */ +- tzset(); +- + opt = getopt32long(argv, + "^lurswtf:" "\0" "r--wst:w--rst:s--wrt:t--rsw:l--u:u--l", + hwclock_longopts, +@@ -368,7 +390,7 @@ int hwclock_main(int argc UNUSED_PARAM, + else if (opt & HWCLOCK_OPT_SYSTOHC) + from_sys_clock(&rtcname, utc); + else if (opt & HWCLOCK_OPT_SYSTZ) +- set_system_clock_timezone(utc); ++ set_kernel_timezone_and_clock(utc, NULL); + else + /* default HWCLOCK_OPT_SHOW */ + show_clock(&rtcname, utc);