]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blob - releases/4.4.140/netfilter-nf_log-don-t-hold-nf_log_mutex-during-user-access.patch
4.14-stable patches
[thirdparty/kernel/stable-queue.git] / releases / 4.4.140 / netfilter-nf_log-don-t-hold-nf_log_mutex-during-user-access.patch
1 From ce00bf07cc95a57cd20b208e02b3c2604e532ae8 Mon Sep 17 00:00:00 2001
2 From: Jann Horn <jannh@google.com>
3 Date: Mon, 25 Jun 2018 17:22:00 +0200
4 Subject: netfilter: nf_log: don't hold nf_log_mutex during user access
5
6 From: Jann Horn <jannh@google.com>
7
8 commit ce00bf07cc95a57cd20b208e02b3c2604e532ae8 upstream.
9
10 The old code would indefinitely block other users of nf_log_mutex if
11 a userspace access in proc_dostring() blocked e.g. due to a userfaultfd
12 region. Fix it by moving proc_dostring() out of the locked region.
13
14 This is a followup to commit 266d07cb1c9a ("netfilter: nf_log: fix
15 sleeping function called from invalid context"), which changed this code
16 from using rcu_read_lock() to taking nf_log_mutex.
17
18 Fixes: 266d07cb1c9a ("netfilter: nf_log: fix sleeping function calle[...]")
19 Signed-off-by: Jann Horn <jannh@google.com>
20 Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
21 Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
22
23 ---
24 net/netfilter/nf_log.c | 9 ++++++---
25 1 file changed, 6 insertions(+), 3 deletions(-)
26
27 --- a/net/netfilter/nf_log.c
28 +++ b/net/netfilter/nf_log.c
29 @@ -422,14 +422,17 @@ static int nf_log_proc_dostring(struct c
30 rcu_assign_pointer(net->nf.nf_loggers[tindex], logger);
31 mutex_unlock(&nf_log_mutex);
32 } else {
33 + struct ctl_table tmp = *table;
34 +
35 + tmp.data = buf;
36 mutex_lock(&nf_log_mutex);
37 logger = nft_log_dereference(net->nf.nf_loggers[tindex]);
38 if (!logger)
39 - table->data = "NONE";
40 + strlcpy(buf, "NONE", sizeof(buf));
41 else
42 - table->data = logger->name;
43 - r = proc_dostring(table, write, buffer, lenp, ppos);
44 + strlcpy(buf, logger->name, sizeof(buf));
45 mutex_unlock(&nf_log_mutex);
46 + r = proc_dostring(&tmp, write, buffer, lenp, ppos);
47 }
48
49 return r;