aboutsummaryrefslogtreecommitdiffstats
path: root/net/xfrm/xfrm_policy.c
diff options
context:
space:
mode:
authorArnd Bergmann <arnd@arndb.de>2018-07-11 06:19:13 -0400
committerSteffen Klassert <steffen.klassert@secunet.com>2018-07-11 09:25:30 -0400
commit386c5680e2e80b012de557cf8326962070e0897b (patch)
tree3daeb6c7a2943f19b531a89e23ae917990d6f4ac /net/xfrm/xfrm_policy.c
parent6d8e85ffe17895d7bc632dfbaa9e2e33b22fe873 (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.c24
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)
189static void xfrm_policy_timer(struct timer_list *t) 189static 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 }