Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

netfilter: nft_meta: use 64-bit time arithmetic

On 32-bit architectures, get_seconds() returns an unsigned 32-bit
time value, which also matches the type used in the nft_meta
code. This will not overflow in year 2038 as a time_t would, but
it still suffers from the overflow problem later on in year 2106.

Change this instance to use the time64_t type consistently
and avoid the deprecated get_seconds().

The nft_meta_weekday() calculation potentially gets a little slower
on 32-bit architectures, but now it has the same behavior as on
64-bit architectures and does not overflow.

Fixes: 63d10e12b00d ("netfilter: nft_meta: support for time matching")
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
Acked-by: Phil Sutter <phil@nwl.cc>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>

authored by

Arnd Bergmann and committed by
Pablo Neira Ayuso
6408c40c fcbad829

+5 -5
+5 -5
net/netfilter/nft_meta.c
··· 33 33 34 34 static DEFINE_PER_CPU(struct rnd_state, nft_prandom_state); 35 35 36 - static u8 nft_meta_weekday(unsigned long secs) 36 + static u8 nft_meta_weekday(time64_t secs) 37 37 { 38 38 unsigned int dse; 39 39 u8 wday; 40 40 41 41 secs -= NFT_META_SECS_PER_MINUTE * sys_tz.tz_minuteswest; 42 - dse = secs / NFT_META_SECS_PER_DAY; 42 + dse = div_u64(secs, NFT_META_SECS_PER_DAY); 43 43 wday = (4 + dse) % NFT_META_DAYS_PER_WEEK; 44 44 45 45 return wday; 46 46 } 47 47 48 - static u32 nft_meta_hour(unsigned long secs) 48 + static u32 nft_meta_hour(time64_t secs) 49 49 { 50 50 struct tm tm; 51 51 ··· 250 250 nft_reg_store64(dest, ktime_get_real_ns()); 251 251 break; 252 252 case NFT_META_TIME_DAY: 253 - nft_reg_store8(dest, nft_meta_weekday(get_seconds())); 253 + nft_reg_store8(dest, nft_meta_weekday(ktime_get_real_seconds())); 254 254 break; 255 255 case NFT_META_TIME_HOUR: 256 - *dest = nft_meta_hour(get_seconds()); 256 + *dest = nft_meta_hour(ktime_get_real_seconds()); 257 257 break; 258 258 default: 259 259 WARN_ON(1);