diff options
author | Arnd Bergmann <arnd@arndb.de> | 2018-07-11 06:19:13 -0400 |
---|---|---|
committer | Steffen Klassert <steffen.klassert@secunet.com> | 2018-07-11 09:25:30 -0400 |
commit | 386c5680e2e80b012de557cf8326962070e0897b (patch) | |
tree | 3daeb6c7a2943f19b531a89e23ae917990d6f4ac /net/xfrm/xfrm_policy.c | |
parent | 6d8e85ffe17895d7bc632dfbaa9e2e33b22fe873 (diff) |
xfrm: use time64_t for in-kernel timestamps
The lifetime managment uses '__u64' timestamps on the user space
interface, but 'unsigned long' for reading the current time in the kernel
with get_seconds().
While this is probably safe beyond y2038, it will still overflow in 2106,
and the get_seconds() call is deprecated because fo that.
This changes the xfrm time handling to use time64_t consistently, along
with reading the time using the safer ktime_get_real_seconds(). It still
suffers from problems that can happen from a concurrent settimeofday()
call or (to a lesser degree) a leap second update, but since the time
stamps are part of the user API, there is nothing we can do to prevent
that.
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
Diffstat (limited to 'net/xfrm/xfrm_policy.c')
-rw-r--r-- | net/xfrm/xfrm_policy.c | 24 |
1 files changed, 12 insertions, 12 deletions
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c index ef75891450e7..5d2f734f4309 100644 --- a/net/xfrm/xfrm_policy.c +++ b/net/xfrm/xfrm_policy.c | |||
@@ -189,8 +189,8 @@ static inline unsigned long make_jiffies(long secs) | |||
189 | static void xfrm_policy_timer(struct timer_list *t) | 189 | static void xfrm_policy_timer(struct timer_list *t) |
190 | { | 190 | { |
191 | struct xfrm_policy *xp = from_timer(xp, t, timer); | 191 | struct xfrm_policy *xp = from_timer(xp, t, timer); |
192 | unsigned long now = get_seconds(); | 192 | time64_t now = ktime_get_real_seconds(); |
193 | long next = LONG_MAX; | 193 | time64_t next = TIME64_MAX; |
194 | int warn = 0; | 194 | int warn = 0; |
195 | int dir; | 195 | int dir; |
196 | 196 | ||
@@ -202,7 +202,7 @@ static void xfrm_policy_timer(struct timer_list *t) | |||
202 | dir = xfrm_policy_id2dir(xp->index); | 202 | dir = xfrm_policy_id2dir(xp->index); |
203 | 203 | ||
204 | if (xp->lft.hard_add_expires_seconds) { | 204 | if (xp->lft.hard_add_expires_seconds) { |
205 | long tmo = xp->lft.hard_add_expires_seconds + | 205 | time64_t tmo = xp->lft.hard_add_expires_seconds + |
206 | xp->curlft.add_time - now; | 206 | xp->curlft.add_time - now; |
207 | if (tmo <= 0) | 207 | if (tmo <= 0) |
208 | goto expired; | 208 | goto expired; |
@@ -210,7 +210,7 @@ static void xfrm_policy_timer(struct timer_list *t) | |||
210 | next = tmo; | 210 | next = tmo; |
211 | } | 211 | } |
212 | if (xp->lft.hard_use_expires_seconds) { | 212 | if (xp->lft.hard_use_expires_seconds) { |
213 | long tmo = xp->lft.hard_use_expires_seconds + | 213 | time64_t tmo = xp->lft.hard_use_expires_seconds + |
214 | (xp->curlft.use_time ? : xp->curlft.add_time) - now; | 214 | (xp->curlft.use_time ? : xp->curlft.add_time) - now; |
215 | if (tmo <= 0) | 215 | if (tmo <= 0) |
216 | goto expired; | 216 | goto expired; |
@@ -218,7 +218,7 @@ static void xfrm_policy_timer(struct timer_list *t) | |||
218 | next = tmo; | 218 | next = tmo; |
219 | } | 219 | } |
220 | if (xp->lft.soft_add_expires_seconds) { | 220 | if (xp->lft.soft_add_expires_seconds) { |
221 | long tmo = xp->lft.soft_add_expires_seconds + | 221 | time64_t tmo = xp->lft.soft_add_expires_seconds + |
222 | xp->curlft.add_time - now; | 222 | xp->curlft.add_time - now; |
223 | if (tmo <= 0) { | 223 | if (tmo <= 0) { |
224 | warn = 1; | 224 | warn = 1; |
@@ -228,7 +228,7 @@ static void xfrm_policy_timer(struct timer_list *t) | |||
228 | next = tmo; | 228 | next = tmo; |
229 | } | 229 | } |
230 | if (xp->lft.soft_use_expires_seconds) { | 230 | if (xp->lft.soft_use_expires_seconds) { |
231 | long tmo = xp->lft.soft_use_expires_seconds + | 231 | time64_t tmo = xp->lft.soft_use_expires_seconds + |
232 | (xp->curlft.use_time ? : xp->curlft.add_time) - now; | 232 | (xp->curlft.use_time ? : xp->curlft.add_time) - now; |
233 | if (tmo <= 0) { | 233 | if (tmo <= 0) { |
234 | warn = 1; | 234 | warn = 1; |
@@ -240,7 +240,7 @@ static void xfrm_policy_timer(struct timer_list *t) | |||
240 | 240 | ||
241 | if (warn) | 241 | if (warn) |
242 | km_policy_expired(xp, dir, 0, 0); | 242 | km_policy_expired(xp, dir, 0, 0); |
243 | if (next != LONG_MAX && | 243 | if (next != TIME64_MAX && |
244 | !mod_timer(&xp->timer, jiffies + make_jiffies(next))) | 244 | !mod_timer(&xp->timer, jiffies + make_jiffies(next))) |
245 | xfrm_pol_hold(xp); | 245 | xfrm_pol_hold(xp); |
246 | 246 | ||
@@ -791,7 +791,7 @@ int xfrm_policy_insert(int dir, struct xfrm_policy *policy, int excl) | |||
791 | } | 791 | } |
792 | policy->index = delpol ? delpol->index : xfrm_gen_index(net, dir, policy->index); | 792 | policy->index = delpol ? delpol->index : xfrm_gen_index(net, dir, policy->index); |
793 | hlist_add_head(&policy->byidx, net->xfrm.policy_byidx+idx_hash(net, policy->index)); | 793 | hlist_add_head(&policy->byidx, net->xfrm.policy_byidx+idx_hash(net, policy->index)); |
794 | policy->curlft.add_time = get_seconds(); | 794 | policy->curlft.add_time = ktime_get_real_seconds(); |
795 | policy->curlft.use_time = 0; | 795 | policy->curlft.use_time = 0; |
796 | if (!mod_timer(&policy->timer, jiffies + HZ)) | 796 | if (!mod_timer(&policy->timer, jiffies + HZ)) |
797 | xfrm_pol_hold(policy); | 797 | xfrm_pol_hold(policy); |
@@ -1282,7 +1282,7 @@ int xfrm_sk_policy_insert(struct sock *sk, int dir, struct xfrm_policy *pol) | |||
1282 | old_pol = rcu_dereference_protected(sk->sk_policy[dir], | 1282 | old_pol = rcu_dereference_protected(sk->sk_policy[dir], |
1283 | lockdep_is_held(&net->xfrm.xfrm_policy_lock)); | 1283 | lockdep_is_held(&net->xfrm.xfrm_policy_lock)); |
1284 | if (pol) { | 1284 | if (pol) { |
1285 | pol->curlft.add_time = get_seconds(); | 1285 | pol->curlft.add_time = ktime_get_real_seconds(); |
1286 | pol->index = xfrm_gen_index(net, XFRM_POLICY_MAX+dir, 0); | 1286 | pol->index = xfrm_gen_index(net, XFRM_POLICY_MAX+dir, 0); |
1287 | xfrm_sk_policy_link(pol, dir); | 1287 | xfrm_sk_policy_link(pol, dir); |
1288 | } | 1288 | } |
@@ -2132,7 +2132,7 @@ no_transform: | |||
2132 | } | 2132 | } |
2133 | 2133 | ||
2134 | for (i = 0; i < num_pols; i++) | 2134 | for (i = 0; i < num_pols; i++) |
2135 | pols[i]->curlft.use_time = get_seconds(); | 2135 | pols[i]->curlft.use_time = ktime_get_real_seconds(); |
2136 | 2136 | ||
2137 | if (num_xfrms < 0) { | 2137 | if (num_xfrms < 0) { |
2138 | /* Prohibit the flow */ | 2138 | /* Prohibit the flow */ |
@@ -2352,7 +2352,7 @@ int __xfrm_policy_check(struct sock *sk, int dir, struct sk_buff *skb, | |||
2352 | return 1; | 2352 | return 1; |
2353 | } | 2353 | } |
2354 | 2354 | ||
2355 | pol->curlft.use_time = get_seconds(); | 2355 | pol->curlft.use_time = ktime_get_real_seconds(); |
2356 | 2356 | ||
2357 | pols[0] = pol; | 2357 | pols[0] = pol; |
2358 | npols++; | 2358 | npols++; |
@@ -2366,7 +2366,7 @@ int __xfrm_policy_check(struct sock *sk, int dir, struct sk_buff *skb, | |||
2366 | XFRM_INC_STATS(net, LINUX_MIB_XFRMINPOLERROR); | 2366 | XFRM_INC_STATS(net, LINUX_MIB_XFRMINPOLERROR); |
2367 | return 0; | 2367 | return 0; |
2368 | } | 2368 | } |
2369 | pols[1]->curlft.use_time = get_seconds(); | 2369 | pols[1]->curlft.use_time = ktime_get_real_seconds(); |
2370 | npols++; | 2370 | npols++; |
2371 | } | 2371 | } |
2372 | } | 2372 | } |