From patchwork Mon Nov 27 16:19:24 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Arnd Bergmann X-Patchwork-Id: 119741 Delivered-To: patch@linaro.org Received: by 10.140.22.227 with SMTP id 90csp488636qgn; Mon, 27 Nov 2017 08:20:33 -0800 (PST) X-Google-Smtp-Source: AGs4zMZ6XuQr+vEaLPXPx9xiXdA2paU4ns5ahTida+BKojsUNOFr4ZhutiuVGR5mJfgaDKEFprnq X-Received: by 10.84.172.1 with SMTP id m1mr39707047plb.174.1511799632949; Mon, 27 Nov 2017 08:20:32 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1511799632; cv=none; d=google.com; s=arc-20160816; b=yOEMp8lLqN4tnmb2eN7+IpCLBLrntOuYpUXm7vPalkGr92S7ByAO1upK0mVYvPznGe JR9GLdMEekK0FGBWe+vjiA/Qj02wiSq2HKGO0Uv4xDgWrck0AH3fjbRrP7g0C6XC9RxD 6lDbQP2/Cl+gUcWvDZvxlTRO9wLVQA6T3F6yoof7YShIO4WepiykDVPxRb/3ReSlahA0 WttdBCqW8ee1epW287RdPTiqbt5EYZi5xFMmbMARXi8K6VTN0j1pNW84acZvs5bNmfhy FAjTZBbIxFqUS/tRgJSlLws8bDL73ddmvpaC2ftmUMsnVmv9y3Vl3/x/AtNIloGliPvF oA7g== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:message-id:date:subject:cc:to:from :arc-authentication-results; bh=jMDF0W5jdEJnYatO7P9mdlhNkK89J2VNSe8WclAixQs=; b=ZYlr0ho1+4MgfaLgdVRwAAXb0ln1mFDzuhrVRW3ntG6sKWV6FvsEPp0kqdlQ3v13FP bxaPUbOG1hADfAxD1Tl7o4yYm3uVk+D1O8To64GW7s9dqudFYAzj9I2EuN/YojnfclSc YIGVg+vrpJauD4HvXHMfKI6unUvAsi4ZF1mwGoWt4HBJrs9OJpUOtU8eM/In5KO85HbA TbOTTlOlnQLp3DmQGghAvuv+E13AisL3ID5vXWdoJvsc+I49nFcqp/vpUN2jKxHzH2rw LvRzs9s+jiQ6+9GU2VhrfLcqKvPrX6Ck2p0jV1GAln/MFskLEKo+tPBE5CnnHhG4wqFX N7FQ== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id f1si4952981pgt.806.2017.11.27.08.20.32; Mon, 27 Nov 2017 08:20:32 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753507AbdK0QUb (ORCPT + 28 others); Mon, 27 Nov 2017 11:20:31 -0500 Received: from mout.kundenserver.de ([212.227.126.131]:50876 "EHLO mout.kundenserver.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753320AbdK0QU3 (ORCPT ); Mon, 27 Nov 2017 11:20:29 -0500 Received: from wuerfel.lan ([109.193.157.232]) by mrelayeu.kundenserver.de (mreue006 [212.227.15.129]) with ESMTPA (Nemesis) id 0MJIXG-1eHhB63WqA-002ra0; Mon, 27 Nov 2017 17:20:15 +0100 From: Arnd Bergmann To: "David S. Miller" Cc: y2038@lists.linaro.org, Arnd Bergmann , Eric Dumazet , Willem de Bruijn , "Rosen, Rami" , Andrey Konovalov , "Reshetova, Elena" , Mike Maloney , Sowmini Varadhan , netdev@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH 1/2] [net-next] packet: clarify timestamp overflow Date: Mon, 27 Nov 2017 17:19:24 +0100 Message-Id: <20171127162001.4055813-1-arnd@arndb.de> X-Mailer: git-send-email 2.9.0 X-Provags-ID: V03:K0:f9NuAXPM1QuK5pFkJWgrtIdqsibbqaROZUWTUZa9ZvTQ3wnkXEW OlLnm2VO5WAcxmtFq9wwKggJ6Ia8cUusqcMNAfj+LMKWbdEUEmvvYm8pp9zqFgWba04Aw44 dM4K/x0OOshT0jP3qnxhaW/0kMXkMXF15oyZh/j9cMK9oUsLBnsKarEA7v0rseNEv7ZJwvM QoOa4UdDNilzES81f1wsw== X-UI-Out-Filterresults: notjunk:1; V01:K0:CWj6BVP+hs8=:zyVhJOzT6jtzvqGOhWvvB6 CX8N2IiQaYb2bgw0majS/UvAvwAsoVNQbaK0SIP/q8Ndl1uSZLIY+S0W7FPApRvcubHbAXJHp tjSUtR+6aO7AA9yJhRSVTJMv2tn1JnqLMKHphBeHT0CepsQm8z+KTsgmpXYEIWSZF1cjevHLV L0hW++BMOIrnvtPzXxoo0AknaGO43Di7oWrjquzFB6CnwGZre6xQ2IWpcHdRz0f3jPr2oP10H 573PhKFg0NMT9mKJvAql1T63AYAL2k5VIEzRUeK/wS+wLuhBh9fZyrAW9YtDmIq0Wq8Pfi9vy klOZsEKS2zO1/1kJ3GmbJUXreCp0jI9STQ+guVNuBRN2bf0RqcfCDwNKwjQ2qEzh0cZxkUur7 CJUuGjE3tfx3luB9zNcprQ+4BHE8HP1vTO4kQyB4DB5G2aDU31nOQH5ZMN5ZDZPf2OxtrMXNd pIxW/5E4xjsqOLYiFV6m111iqYRycf36PR+eJBnpGnckYGmKDtpyMZ2wLd4rjOmK5M84EOpDx 3V05mA/Vw+ngUqSJihEt1MymSMuKszbd6baNd2jo4MCKjMEtVAhTiu333OYvcKU8S4REVDu6m V5f1UjME2cF+xC7c9hsKAsyzGWoHFIPgKoXbjQd3r3IIDStieivhwXguW7DfnT94hZ7DtJqCx RN06vLG/1F028uRittum6x3ZLY4xXAyQi9gQqNiM2znbAgqTvB+9votg4r7ElG8eYqVKyV3/g SYbJz3IANzk/3f41sRV17mB8yT19BsJey6cgQg== Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org The memory mapped packet socket data structure in version 1 through 3 all contain 32-bit second values for the packet time stamps, which makes them suffer from the overflow of time_t in y2038 or y2106 (depending on whether user space interprets the value as signed or unsigned). The implementation uses the deprecated getnstimeofday() function. In order to get rid of that, this changes the code to use ktime_get_real_ts64() as a replacement, documenting the nature of the overflow. As long as the user applications treat the timestamps as unsigned, or only use the difference between timestamps, they are fine, and changing the timestamps to 64-bit wouldn't require a more invasive user space API change. Note: a lot of other APIs suffer from incompatible structures when time_t gets redefined to 64-bit in 32-bit user space, but this one does not. Signed-off-by: Arnd Bergmann --- net/packet/af_packet.c | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-) -- 2.9.0 diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c index 737092ca9b4e..7432c6699818 100644 --- a/net/packet/af_packet.c +++ b/net/packet/af_packet.c @@ -439,17 +439,17 @@ static int __packet_get_status(struct packet_sock *po, void *frame) } } -static __u32 tpacket_get_timestamp(struct sk_buff *skb, struct timespec *ts, +static __u32 tpacket_get_timestamp(struct sk_buff *skb, struct timespec64 *ts, unsigned int flags) { struct skb_shared_hwtstamps *shhwtstamps = skb_hwtstamps(skb); if (shhwtstamps && (flags & SOF_TIMESTAMPING_RAW_HARDWARE) && - ktime_to_timespec_cond(shhwtstamps->hwtstamp, ts)) + ktime_to_timespec64_cond(shhwtstamps->hwtstamp, ts)) return TP_STATUS_TS_RAW_HARDWARE; - if (ktime_to_timespec_cond(skb->tstamp, ts)) + if (ktime_to_timespec64_cond(skb->tstamp, ts)) return TP_STATUS_TS_SOFTWARE; return 0; @@ -459,13 +459,20 @@ static __u32 __packet_set_timestamp(struct packet_sock *po, void *frame, struct sk_buff *skb) { union tpacket_uhdr h; - struct timespec ts; + struct timespec64 ts; __u32 ts_status; if (!(ts_status = tpacket_get_timestamp(skb, &ts, po->tp_tstamp))) return 0; h.raw = frame; + /* + * versions 1 through 3 overflow the timestamps in y2106, since they + * all store the seconds in a 32-bit unsigned integer. + * If we create a version 4, that should have a 64-bit timestamp, + * either 64-bit seconds + 32-bit nanoseconds, or just 64-bit + * nanoseconds. + */ switch (po->tp_version) { case TPACKET_V1: h.h1->tp_sec = ts.tv_sec; @@ -805,8 +812,8 @@ static void prb_close_block(struct tpacket_kbdq_core *pkc1, * It shouldn't really happen as we don't close empty * blocks. See prb_retire_rx_blk_timer_expired(). */ - struct timespec ts; - getnstimeofday(&ts); + struct timespec64 ts; + ktime_get_real_ts64(&ts); h1->ts_last_pkt.ts_sec = ts.tv_sec; h1->ts_last_pkt.ts_nsec = ts.tv_nsec; } @@ -836,7 +843,7 @@ static void prb_thaw_queue(struct tpacket_kbdq_core *pkc) static void prb_open_block(struct tpacket_kbdq_core *pkc1, struct tpacket_block_desc *pbd1) { - struct timespec ts; + struct timespec64 ts; struct tpacket_hdr_v1 *h1 = &pbd1->hdr.bh1; smp_rmb(); @@ -849,7 +856,7 @@ static void prb_open_block(struct tpacket_kbdq_core *pkc1, BLOCK_NUM_PKTS(pbd1) = 0; BLOCK_LEN(pbd1) = BLK_PLUS_PRIV(pkc1->blk_sizeof_priv); - getnstimeofday(&ts); + ktime_get_real_ts64(&ts); h1->ts_first_pkt.ts_sec = ts.tv_sec; h1->ts_first_pkt.ts_nsec = ts.tv_nsec; @@ -2184,7 +2191,7 @@ static int tpacket_rcv(struct sk_buff *skb, struct net_device *dev, unsigned long status = TP_STATUS_USER; unsigned short macoff, netoff, hdrlen; struct sk_buff *copy_skb = NULL; - struct timespec ts; + struct timespec64 ts; __u32 ts_status; bool is_drop_n_account = false; bool do_vnet = false; @@ -2312,7 +2319,7 @@ static int tpacket_rcv(struct sk_buff *skb, struct net_device *dev, skb_copy_bits(skb, 0, h.raw + macoff, snaplen); if (!(ts_status = tpacket_get_timestamp(skb, &ts, po->tp_tstamp))) - getnstimeofday(&ts); + ktime_get_real_ts64(&ts); status |= ts_status;