aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRoberto Bergantinos Corpas <rbergant@redhat.com>2020-02-04 11:32:56 +0100
committerBen Hutchings <ben@decadent.org.uk>2020-05-22 21:19:44 +0100
commit4d91d2ab7288808df5e434a93f12d26de86d4101 (patch)
treeb9dcf0de747f72d155606d90d2f2efd76e7772b9
parent888865cfee84dbf800fb174cfa70ec58bf326578 (diff)
downloadlinux-stable-4d91d2ab7288808df5e434a93f12d26de86d4101.tar.gz
sunrpc: expiry_time should be seconds not timeval
commit 3d96208c30f84d6edf9ab4fac813306ac0d20c10 upstream. When upcalling gssproxy, cache_head.expiry_time is set as a timeval, not seconds since boot. As such, RPC cache expiry logic will not clean expired objects created under auth.rpcsec.context cache. This has proven to cause kernel memory leaks on field. Using 64 bit variants of getboottime/timespec Expiration times have worked this way since 2010's c5b29f885afe "sunrpc: use seconds since boot in expiry cache". The gssproxy code introduced in 2012 added gss_proxy_save_rsc and introduced the bug. That's a while for this to lurk, but it required a bit of an extreme case to make it obvious. Signed-off-by: Roberto Bergantinos Corpas <rbergant@redhat.com> Fixes: 030d794bf498 "SUNRPC: Use gssproxy upcall for server..." Tested-By: Frank Sorenson <sorenson@redhat.com> Signed-off-by: J. Bruce Fields <bfields@redhat.com> [bwh: Backported to 3.16: Use struct timespec and getboottime()] Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
-rw-r--r--net/sunrpc/auth_gss/svcauth_gss.c4
1 files changed, 4 insertions, 0 deletions
diff --git a/net/sunrpc/auth_gss/svcauth_gss.c b/net/sunrpc/auth_gss/svcauth_gss.c
index 03000a10983d02..09c2f8c27ec4c6 100644
--- a/net/sunrpc/auth_gss/svcauth_gss.c
+++ b/net/sunrpc/auth_gss/svcauth_gss.c
@@ -1171,6 +1171,7 @@ static int gss_proxy_save_rsc(struct cache_detail *cd,
dprintk("RPC: No creds found!\n");
goto out;
} else {
+ struct timespec boot;
/* steal creds */
rsci.cred = ud->creds;
@@ -1191,6 +1192,9 @@ static int gss_proxy_save_rsc(struct cache_detail *cd,
&expiry, GFP_KERNEL);
if (status)
goto out;
+
+ getboottime(&boot);
+ expiry -= boot.tv_sec;
}
rsci.h.expiry_time = expiry;