netfilter: nft_meta: use 64-bit time arithmetic
authorArnd Bergmann <arnd@arndb.de>
Fri, 8 Nov 2019 21:32:47 +0000 (22:32 +0100)
committerPablo Neira Ayuso <pablo@netfilter.org>
Fri, 15 Nov 2019 22:44:45 +0000 (23:44 +0100)
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>
net/netfilter/nft_meta.c

index 8fd21f436347331af0423b4622f310ee496a385e..8fbea031bd4a746604c2082c7eeb969a37cec912 100644 (file)
 
 static DEFINE_PER_CPU(struct rnd_state, nft_prandom_state);
 
-static u8 nft_meta_weekday(unsigned long secs)
+static u8 nft_meta_weekday(time64_t secs)
 {
        unsigned int dse;
        u8 wday;
 
        secs -= NFT_META_SECS_PER_MINUTE * sys_tz.tz_minuteswest;
-       dse = secs / NFT_META_SECS_PER_DAY;
+       dse = div_u64(secs, NFT_META_SECS_PER_DAY);
        wday = (4 + dse) % NFT_META_DAYS_PER_WEEK;
 
        return wday;
 }
 
-static u32 nft_meta_hour(unsigned long secs)
+static u32 nft_meta_hour(time64_t secs)
 {
        struct tm tm;
 
@@ -250,10 +250,10 @@ void nft_meta_get_eval(const struct nft_expr *expr,
                nft_reg_store64(dest, ktime_get_real_ns());
                break;
        case NFT_META_TIME_DAY:
-               nft_reg_store8(dest, nft_meta_weekday(get_seconds()));
+               nft_reg_store8(dest, nft_meta_weekday(ktime_get_real_seconds()));
                break;
        case NFT_META_TIME_HOUR:
-               *dest = nft_meta_hour(get_seconds());
+               *dest = nft_meta_hour(ktime_get_real_seconds());
                break;
        default:
                WARN_ON(1);