Blame SOURCES/0001-netfilter-xt_time-use-time64_t.patch

Kmods SIG 8d16be
From fcbad8293d52864d87d0b9f6035fd87a049d59d8 Mon Sep 17 00:00:00 2001
Kmods SIG 8d16be
From: Arnd Bergmann <arnd@arndb.de>
Kmods SIG 8d16be
Date: Fri, 8 Nov 2019 21:34:28 +0100
Kmods SIG 8d16be
Subject: [Backport fcbad8293d52] netfilter: xt_time: use time64_t
Kmods SIG 8d16be
Kmods SIG 8d16be
The current xt_time driver suffers from the y2038 overflow on 32-bit
Kmods SIG 8d16be
architectures, when the time of day calculations break.
Kmods SIG 8d16be
Kmods SIG 8d16be
Also, on both 32-bit and 64-bit architectures, there is a problem with
Kmods SIG 8d16be
info->date_start/stop, which is part of the user ABI and overflows in
Kmods SIG 8d16be
in 2106.
Kmods SIG 8d16be
Kmods SIG 8d16be
Fix the first issue by using time64_t and explicit calls to div_u64()
Kmods SIG 8d16be
and div_u64_rem(), and document the seconds issue.
Kmods SIG 8d16be
Kmods SIG 8d16be
The explicit 64-bit division is unfortunately slower on 32-bit
Kmods SIG 8d16be
architectures, but doing it as unsigned lets us use the optimized
Kmods SIG 8d16be
division-through-multiplication path in most configurations.  This should
Kmods SIG 8d16be
be fine, as the code already does not allow any negative time of day
Kmods SIG 8d16be
values.
Kmods SIG 8d16be
Kmods SIG 8d16be
Using u32 seconds values consistently would probably also work and
Kmods SIG 8d16be
be a little more efficient, but that doesn't feel right as it would
Kmods SIG 8d16be
propagate the y2106 overflow to more place rather than fewer.
Kmods SIG 8d16be
Kmods SIG 8d16be
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
Kmods SIG 8d16be
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Kmods SIG 8d16be
---
Kmods SIG 8d16be
 src/xt_time.c | 19 +++++++++++--------
Kmods SIG 8d16be
 1 file changed, 11 insertions(+), 8 deletions(-)
Kmods SIG 8d16be
Kmods SIG 8d16be
diff --git a/src/xt_time.c b/src/xt_time.c
Kmods SIG 8d16be
index 8dbb4d48f2ed5995dedaa8eb4f4b18a0ba91acb2..67cb984894153d5db895e104adacf51422926e34 100644
Kmods SIG 8d16be
--- a/src/xt_time.c
Kmods SIG 8d16be
+++ b/src/xt_time.c
Kmods SIG 8d16be
@@ -77,12 +77,12 @@ static inline bool is_leap(unsigned int y)
Kmods SIG 8d16be
  * This is done in three separate functions so that the most expensive
Kmods SIG 8d16be
  * calculations are done last, in case a "simple match" can be found earlier.
Kmods SIG 8d16be
  */
Kmods SIG 8d16be
-static inline unsigned int localtime_1(struct xtm *r, time_t time)
Kmods SIG 8d16be
+static inline unsigned int localtime_1(struct xtm *r, time64_t time)
Kmods SIG 8d16be
 {
Kmods SIG 8d16be
 	unsigned int v, w;
Kmods SIG 8d16be
 
Kmods SIG 8d16be
 	/* Each day has 86400s, so finding the hour/minute is actually easy. */
Kmods SIG 8d16be
-	v         = time % SECONDS_PER_DAY;
Kmods SIG 8d16be
+	div_u64_rem(time, SECONDS_PER_DAY, &v);
Kmods SIG 8d16be
 	r->second = v % 60;
Kmods SIG 8d16be
 	w         = v / 60;
Kmods SIG 8d16be
 	r->minute = w % 60;
Kmods SIG 8d16be
@@ -90,13 +90,13 @@ static inline unsigned int localtime_1(struct xtm *r, time_t time)
Kmods SIG 8d16be
 	return v;
Kmods SIG 8d16be
 }
Kmods SIG 8d16be
 
Kmods SIG 8d16be
-static inline void localtime_2(struct xtm *r, time_t time)
Kmods SIG 8d16be
+static inline void localtime_2(struct xtm *r, time64_t time)
Kmods SIG 8d16be
 {
Kmods SIG 8d16be
 	/*
Kmods SIG 8d16be
 	 * Here comes the rest (weekday, monthday). First, divide the SSTE
Kmods SIG 8d16be
 	 * by seconds-per-day to get the number of _days_ since the epoch.
Kmods SIG 8d16be
 	 */
Kmods SIG 8d16be
-	r->dse = time / 86400;
Kmods SIG 8d16be
+	r->dse = div_u64(time, SECONDS_PER_DAY);
Kmods SIG 8d16be
 
Kmods SIG 8d16be
 	/*
Kmods SIG 8d16be
 	 * 1970-01-01 (w=0) was a Thursday (4).
Kmods SIG 8d16be
@@ -105,7 +105,7 @@ static inline void localtime_2(struct xtm *r, time_t time)
Kmods SIG 8d16be
 	r->weekday = (4 + r->dse - 1) % 7 + 1;
Kmods SIG 8d16be
 }
Kmods SIG 8d16be
 
Kmods SIG 8d16be
-static void localtime_3(struct xtm *r, time_t time)
Kmods SIG 8d16be
+static void localtime_3(struct xtm *r, time64_t time)
Kmods SIG 8d16be
 {
Kmods SIG 8d16be
 	unsigned int year, i, w = r->dse;
Kmods SIG 8d16be
 
Kmods SIG 8d16be
@@ -160,7 +160,7 @@ time_mt(const struct sk_buff *skb, struct xt_action_param *par)
Kmods SIG 8d16be
 	const struct xt_time_info *info = par->matchinfo;
Kmods SIG 8d16be
 	unsigned int packet_time;
Kmods SIG 8d16be
 	struct xtm current_time;
Kmods SIG 8d16be
-	s64 stamp;
Kmods SIG 8d16be
+	time64_t stamp;
Kmods SIG 8d16be
 
Kmods SIG 8d16be
 	/*
Kmods SIG 8d16be
 	 * We need real time here, but we can neither use skb->tstamp
Kmods SIG 8d16be
@@ -173,14 +173,14 @@ time_mt(const struct sk_buff *skb, struct xt_action_param *par)
Kmods SIG 8d16be
 	 *	1. match before 13:00
Kmods SIG 8d16be
 	 *	2. match after 13:00
Kmods SIG 8d16be
 	 *
Kmods SIG 8d16be
-	 * If you match against processing time (get_seconds) it
Kmods SIG 8d16be
+	 * If you match against processing time (ktime_get_real_seconds) it
Kmods SIG 8d16be
 	 * may happen that the same packet matches both rules if
Kmods SIG 8d16be
 	 * it arrived at the right moment before 13:00, so it would be
Kmods SIG 8d16be
 	 * better to check skb->tstamp and set it via __net_timestamp()
Kmods SIG 8d16be
 	 * if needed.  This however breaks outgoing packets tx timestamp,
Kmods SIG 8d16be
 	 * and causes them to get delayed forever by fq packet scheduler.
Kmods SIG 8d16be
 	 */
Kmods SIG 8d16be
-	stamp = get_seconds();
Kmods SIG 8d16be
+	stamp = ktime_get_real_seconds();
Kmods SIG 8d16be
 
Kmods SIG 8d16be
 	if (info->flags & XT_TIME_LOCAL_TZ)
Kmods SIG 8d16be
 		/* Adjust for local timezone */
Kmods SIG 8d16be
@@ -193,6 +193,9 @@ time_mt(const struct sk_buff *skb, struct xt_action_param *par)
Kmods SIG 8d16be
 	 *   - 'now' is in the weekday mask
Kmods SIG 8d16be
 	 *   - 'now' is in the daytime range time_start..time_end
Kmods SIG 8d16be
 	 * (and by default, libxt_time will set these so as to match)
Kmods SIG 8d16be
+	 *
Kmods SIG 8d16be
+	 * note: info->date_start/stop are unsigned 32-bit values that
Kmods SIG 8d16be
+	 *	 can hold values beyond y2038, but not after y2106.
Kmods SIG 8d16be
 	 */
Kmods SIG 8d16be
 
Kmods SIG 8d16be
 	if (stamp < info->date_start || stamp > info->date_stop)
Kmods SIG 8d16be
-- 
Kmods SIG 8d16be
2.31.1
Kmods SIG 8d16be