]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
3.18-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 10 Jan 2019 16:10:46 +0000 (17:10 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 10 Jan 2019 16:10:46 +0000 (17:10 +0100)
added patches:
fork-record-start_time-late.patch
sunrpc-fix-cache_head-leak-due-to-queued-request.patch
sunrpc-use-svc_net-in-svcauth_gss_-functions.patch

queue-3.18/fork-record-start_time-late.patch [new file with mode: 0644]
queue-3.18/series
queue-3.18/sunrpc-fix-cache_head-leak-due-to-queued-request.patch [new file with mode: 0644]
queue-3.18/sunrpc-use-svc_net-in-svcauth_gss_-functions.patch [new file with mode: 0644]

diff --git a/queue-3.18/fork-record-start_time-late.patch b/queue-3.18/fork-record-start_time-late.patch
new file mode 100644 (file)
index 0000000..1ea70bc
--- /dev/null
@@ -0,0 +1,78 @@
+From 7b55851367136b1efd84d98fea81ba57a98304cf Mon Sep 17 00:00:00 2001
+From: David Herrmann <dh.herrmann@gmail.com>
+Date: Tue, 8 Jan 2019 13:58:52 +0100
+Subject: fork: record start_time late
+
+From: David Herrmann <dh.herrmann@gmail.com>
+
+commit 7b55851367136b1efd84d98fea81ba57a98304cf upstream.
+
+This changes the fork(2) syscall to record the process start_time after
+initializing the basic task structure but still before making the new
+process visible to user-space.
+
+Technically, we could record the start_time anytime during fork(2).  But
+this might lead to scenarios where a start_time is recorded long before
+a process becomes visible to user-space.  For instance, with
+userfaultfd(2) and TLS, user-space can delay the execution of fork(2)
+for an indefinite amount of time (and will, if this causes network
+access, or similar).
+
+By recording the start_time late, it much closer reflects the point in
+time where the process becomes live and can be observed by other
+processes.
+
+Lastly, this makes it much harder for user-space to predict and control
+the start_time they get assigned.  Previously, user-space could fork a
+process and stall it in copy_thread_tls() before its pid is allocated,
+but after its start_time is recorded.  This can be misused to later-on
+cycle through PIDs and resume the stalled fork(2) yielding a process
+that has the same pid and start_time as a process that existed before.
+This can be used to circumvent security systems that identify processes
+by their pid+start_time combination.
+
+Even though user-space was always aware that start_time recording is
+flaky (but several projects are known to still rely on start_time-based
+identification), changing the start_time to be recorded late will help
+mitigate existing attacks and make it much harder for user-space to
+control the start_time a process gets assigned.
+
+Reported-by: Jann Horn <jannh@google.com>
+Signed-off-by: Tom Gundersen <teg@jklm.no>
+Signed-off-by: David Herrmann <dh.herrmann@gmail.com>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ kernel/fork.c |   13 +++++++++++--
+ 1 file changed, 11 insertions(+), 2 deletions(-)
+
+--- a/kernel/fork.c
++++ b/kernel/fork.c
+@@ -1321,8 +1321,6 @@ static struct task_struct *copy_process(
+       posix_cpu_timers_init(p);
+-      p->start_time = ktime_get_ns();
+-      p->real_start_time = ktime_get_boot_ns();
+       p->io_context = NULL;
+       p->audit_context = NULL;
+       if (clone_flags & CLONE_THREAD)
+@@ -1487,6 +1485,17 @@ static struct task_struct *copy_process(
+       spin_lock(&current->sighand->siglock);
+       /*
++       * From this point on we must avoid any synchronous user-space
++       * communication until we take the tasklist-lock. In particular, we do
++       * not want user-space to be able to predict the process start-time by
++       * stalling fork(2) after we recorded the start_time but before it is
++       * visible to the system.
++       */
++
++      p->start_time = ktime_get_ns();
++      p->real_start_time = ktime_get_boot_ns();
++
++      /*
+        * Copy seccomp details explicitly here, in case they were changed
+        * before holding sighand lock.
+        */
index 5c4ed8730786bf33eacbf58070008db5ecfbc72c..7f377fa51d657356ab2dc78803b452442e2ed0df 100644 (file)
@@ -29,3 +29,6 @@ mips-ensure-pmd_present-returns-false-after-pmd_mknotpresent.patch
 mips-align-kernel-load-address-to-64kb.patch
 cifs-fix-error-mapping-for-smb2_lock-command-which-caused-ofd-lock-problem.patch
 scsi-zfcp-fix-posting-too-many-status-read-buffers-leading-to-adapter-shutdown.patch
+fork-record-start_time-late.patch
+sunrpc-fix-cache_head-leak-due-to-queued-request.patch
+sunrpc-use-svc_net-in-svcauth_gss_-functions.patch
diff --git a/queue-3.18/sunrpc-fix-cache_head-leak-due-to-queued-request.patch b/queue-3.18/sunrpc-fix-cache_head-leak-due-to-queued-request.patch
new file mode 100644 (file)
index 0000000..27be9ac
--- /dev/null
@@ -0,0 +1,68 @@
+From 4ecd55ea074217473f94cfee21bb72864d39f8d7 Mon Sep 17 00:00:00 2001
+From: Vasily Averin <vvs@virtuozzo.com>
+Date: Wed, 28 Nov 2018 11:45:57 +0300
+Subject: sunrpc: fix cache_head leak due to queued request
+
+From: Vasily Averin <vvs@virtuozzo.com>
+
+commit 4ecd55ea074217473f94cfee21bb72864d39f8d7 upstream.
+
+After commit d202cce8963d, an expired cache_head can be removed from the
+cache_detail's hash.
+
+However, the expired cache_head may be waiting for a reply from a
+previously submitted request. Such a cache_head has an increased
+refcounter and therefore it won't be freed after cache_put(freeme).
+
+Because the cache_head was removed from the hash it cannot be found
+during cache_clean() and can be leaked forever, together with stalled
+cache_request and other taken resources.
+
+In our case we noticed it because an entry in the export cache was
+holding a reference on a filesystem.
+
+Fixes d202cce8963d ("sunrpc: never return expired entries in sunrpc_cache_lookup")
+Cc: Pavel Tikhomirov <ptikhomirov@virtuozzo.com>
+Cc: stable@kernel.org # 2.6.35
+Signed-off-by: Vasily Averin <vvs@virtuozzo.com>
+Reviewed-by: NeilBrown <neilb@suse.com>
+Signed-off-by: J. Bruce Fields <bfields@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ net/sunrpc/cache.c |    9 ++++++++-
+ 1 file changed, 8 insertions(+), 1 deletion(-)
+
+--- a/net/sunrpc/cache.c
++++ b/net/sunrpc/cache.c
+@@ -50,6 +50,10 @@ static void cache_init(struct cache_head
+       h->last_refresh = now;
+ }
++static void cache_fresh_locked(struct cache_head *head, time_t expiry);
++static void cache_fresh_unlocked(struct cache_head *head,
++                              struct cache_detail *detail);
++
+ struct cache_head *sunrpc_cache_lookup(struct cache_detail *detail,
+                                      struct cache_head *key, int hash)
+ {
+@@ -94,6 +98,7 @@ struct cache_head *sunrpc_cache_lookup(s
+                               *hp = tmp->next;
+                               tmp->next = NULL;
+                               detail->entries --;
++                              cache_fresh_locked(tmp, 0);
+                               freeme = tmp;
+                               break;
+                       }
+@@ -109,8 +114,10 @@ struct cache_head *sunrpc_cache_lookup(s
+       cache_get(new);
+       write_unlock(&detail->hash_lock);
+-      if (freeme)
++      if (freeme) {
++              cache_fresh_unlocked(freeme, detail);
+               cache_put(freeme, detail);
++      }
+       return new;
+ }
+ EXPORT_SYMBOL_GPL(sunrpc_cache_lookup);
diff --git a/queue-3.18/sunrpc-use-svc_net-in-svcauth_gss_-functions.patch b/queue-3.18/sunrpc-use-svc_net-in-svcauth_gss_-functions.patch
new file mode 100644 (file)
index 0000000..4fa9ecf
--- /dev/null
@@ -0,0 +1,56 @@
+From b8be5674fa9a6f3677865ea93f7803c4212f3e10 Mon Sep 17 00:00:00 2001
+From: Vasily Averin <vvs@virtuozzo.com>
+Date: Mon, 24 Dec 2018 14:44:42 +0300
+Subject: sunrpc: use SVC_NET() in svcauth_gss_* functions
+
+From: Vasily Averin <vvs@virtuozzo.com>
+
+commit b8be5674fa9a6f3677865ea93f7803c4212f3e10 upstream.
+
+Signed-off-by: Vasily Averin <vvs@virtuozzo.com>
+Cc: stable@vger.kernel.org
+Signed-off-by: J. Bruce Fields <bfields@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ net/sunrpc/auth_gss/svcauth_gss.c |    8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+--- a/net/sunrpc/auth_gss/svcauth_gss.c
++++ b/net/sunrpc/auth_gss/svcauth_gss.c
+@@ -1102,7 +1102,7 @@ static int svcauth_gss_legacy_init(struc
+       struct kvec *resv = &rqstp->rq_res.head[0];
+       struct rsi *rsip, rsikey;
+       int ret;
+-      struct sunrpc_net *sn = net_generic(rqstp->rq_xprt->xpt_net, sunrpc_net_id);
++      struct sunrpc_net *sn = net_generic(SVC_NET(rqstp), sunrpc_net_id);
+       memset(&rsikey, 0, sizeof(rsikey));
+       ret = gss_read_verf(gc, argv, authp,
+@@ -1213,7 +1213,7 @@ static int svcauth_gss_proxy_init(struct
+       uint64_t handle;
+       int status;
+       int ret;
+-      struct net *net = rqstp->rq_xprt->xpt_net;
++      struct net *net = SVC_NET(rqstp);
+       struct sunrpc_net *sn = net_generic(net, sunrpc_net_id);
+       memset(&ud, 0, sizeof(ud));
+@@ -1403,7 +1403,7 @@ svcauth_gss_accept(struct svc_rqst *rqst
+       __be32          *rpcstart;
+       __be32          *reject_stat = resv->iov_base + resv->iov_len;
+       int             ret;
+-      struct sunrpc_net *sn = net_generic(rqstp->rq_xprt->xpt_net, sunrpc_net_id);
++      struct sunrpc_net *sn = net_generic(SVC_NET(rqstp), sunrpc_net_id);
+       dprintk("RPC:       svcauth_gss: argv->iov_len = %zd\n",
+                       argv->iov_len);
+@@ -1691,7 +1691,7 @@ svcauth_gss_release(struct svc_rqst *rqs
+       struct rpc_gss_wire_cred *gc = &gsd->clcred;
+       struct xdr_buf *resbuf = &rqstp->rq_res;
+       int stat = -EINVAL;
+-      struct sunrpc_net *sn = net_generic(rqstp->rq_xprt->xpt_net, sunrpc_net_id);
++      struct sunrpc_net *sn = net_generic(SVC_NET(rqstp), sunrpc_net_id);
+       if (gc->gc_proc != RPC_GSS_PROC_DATA)
+               goto out;