From: Greg Kroah-Hartman Date: Wed, 3 Jul 2019 12:22:35 +0000 (+0200) Subject: 5.1-stable patches X-Git-Tag: v5.1.17~54 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=d7c3fd7f8da87c75babd7397893cb73181941de0;p=thirdparty%2Fkernel%2Fstable-queue.git 5.1-stable patches added patches: bluetooth-fix-faulty-expression-for-minimum-encryption-key-size-check.patch netfilter-nf_flow_table-ignore-df-bit-setting.patch netfilter-nft_flow_offload-don-t-offload-when-sequence-numbers-need-adjustment.patch netfilter-nft_flow_offload-ipcb-is-only-valid-for-ipv4-family.patch netfilter-nft_flow_offload-set-liberal-tracking-mode-for-tcp.patch signal-remove-the-wrong-signal_pending-check-in-restore_user_sigmask.patch --- diff --git a/queue-5.1/bluetooth-fix-faulty-expression-for-minimum-encryption-key-size-check.patch b/queue-5.1/bluetooth-fix-faulty-expression-for-minimum-encryption-key-size-check.patch new file mode 100644 index 00000000000..b0ec204a562 --- /dev/null +++ b/queue-5.1/bluetooth-fix-faulty-expression-for-minimum-encryption-key-size-check.patch @@ -0,0 +1,38 @@ +From eca94432934fe5f141d084f2e36ee2c0e614cc04 Mon Sep 17 00:00:00 2001 +From: Matias Karhumaa +Date: Tue, 2 Jul 2019 16:35:09 +0200 +Subject: Bluetooth: Fix faulty expression for minimum encryption key size check + +From: Matias Karhumaa + +commit eca94432934fe5f141d084f2e36ee2c0e614cc04 upstream. + +Fix minimum encryption key size check so that HCI_MIN_ENC_KEY_SIZE is +also allowed as stated in the comment. + +This bug caused connection problems with devices having maximum +encryption key size of 7 octets (56-bit). + +Fixes: 693cd8ce3f88 ("Bluetooth: Fix regression with minimum encryption key size alignment") +Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=203997 +Signed-off-by: Matias Karhumaa +Cc: stable@vger.kernel.org +Signed-off-by: Marcel Holtmann +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + net/bluetooth/l2cap_core.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/net/bluetooth/l2cap_core.c ++++ b/net/bluetooth/l2cap_core.c +@@ -1353,7 +1353,7 @@ static bool l2cap_check_enc_key_size(str + * actually encrypted before enforcing a key size. + */ + return (!test_bit(HCI_CONN_ENCRYPT, &hcon->flags) || +- hcon->enc_key_size > HCI_MIN_ENC_KEY_SIZE); ++ hcon->enc_key_size >= HCI_MIN_ENC_KEY_SIZE); + } + + static void l2cap_do_start(struct l2cap_chan *chan) diff --git a/queue-5.1/netfilter-nf_flow_table-ignore-df-bit-setting.patch b/queue-5.1/netfilter-nf_flow_table-ignore-df-bit-setting.patch new file mode 100644 index 00000000000..92f92149748 --- /dev/null +++ b/queue-5.1/netfilter-nf_flow_table-ignore-df-bit-setting.patch @@ -0,0 +1,37 @@ +From e75b3e1c9bc5b997d09bdf8eb72ab3dd3c1a7072 Mon Sep 17 00:00:00 2001 +From: Florian Westphal +Date: Tue, 21 May 2019 13:24:30 +0200 +Subject: netfilter: nf_flow_table: ignore DF bit setting + +From: Florian Westphal + +commit e75b3e1c9bc5b997d09bdf8eb72ab3dd3c1a7072 upstream. + +Its irrelevant if the DF bit is set or not, we must pass packet to +stack in either case. + +If the DF bit is set, we must pass it to stack so the appropriate +ICMP error can be generated. + +If the DF is not set, we must pass it to stack for fragmentation. + +Signed-off-by: Florian Westphal +Signed-off-by: Pablo Neira Ayuso +Signed-off-by: Greg Kroah-Hartman + +--- + net/netfilter/nf_flow_table_ip.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +--- a/net/netfilter/nf_flow_table_ip.c ++++ b/net/netfilter/nf_flow_table_ip.c +@@ -246,8 +246,7 @@ nf_flow_offload_ip_hook(void *priv, stru + flow = container_of(tuplehash, struct flow_offload, tuplehash[dir]); + rt = (struct rtable *)flow->tuplehash[dir].tuple.dst_cache; + +- if (unlikely(nf_flow_exceeds_mtu(skb, flow->tuplehash[dir].tuple.mtu)) && +- (ip_hdr(skb)->frag_off & htons(IP_DF)) != 0) ++ if (unlikely(nf_flow_exceeds_mtu(skb, flow->tuplehash[dir].tuple.mtu))) + return NF_ACCEPT; + + if (skb_try_make_writable(skb, sizeof(*iph))) diff --git a/queue-5.1/netfilter-nft_flow_offload-don-t-offload-when-sequence-numbers-need-adjustment.patch b/queue-5.1/netfilter-nft_flow_offload-don-t-offload-when-sequence-numbers-need-adjustment.patch new file mode 100644 index 00000000000..087b9dc422d --- /dev/null +++ b/queue-5.1/netfilter-nft_flow_offload-don-t-offload-when-sequence-numbers-need-adjustment.patch @@ -0,0 +1,50 @@ +From 91a9048f238063dde7feea752b9dd386f7e3808b Mon Sep 17 00:00:00 2001 +From: Florian Westphal +Date: Tue, 21 May 2019 13:24:32 +0200 +Subject: netfilter: nft_flow_offload: don't offload when sequence numbers need adjustment + +From: Florian Westphal + +commit 91a9048f238063dde7feea752b9dd386f7e3808b upstream. + +We can't deal with tcp sequence number rewrite in flow_offload. +While at it, simplify helper check, we only need to know if the extension +is present, we don't need the helper data. + +Signed-off-by: Florian Westphal +Signed-off-by: Pablo Neira Ayuso +Signed-off-by: Greg Kroah-Hartman + +--- + net/netfilter/nft_flow_offload.c | 6 ++---- + 1 file changed, 2 insertions(+), 4 deletions(-) + +--- a/net/netfilter/nft_flow_offload.c ++++ b/net/netfilter/nft_flow_offload.c +@@ -12,7 +12,6 @@ + #include + #include + #include +-#include + + struct nft_flow_offload { + struct nft_flowtable *flowtable; +@@ -67,7 +66,6 @@ static void nft_flow_offload_eval(const + { + struct nft_flow_offload *priv = nft_expr_priv(expr); + struct nf_flowtable *flowtable = &priv->flowtable->data; +- const struct nf_conn_help *help; + enum ip_conntrack_info ctinfo; + struct nf_flow_route route; + struct flow_offload *flow; +@@ -93,8 +91,8 @@ static void nft_flow_offload_eval(const + goto out; + } + +- help = nfct_help(ct); +- if (help) ++ if (nf_ct_ext_exist(ct, NF_CT_EXT_HELPER) || ++ ct->status & IPS_SEQ_ADJUST) + goto out; + + if (ctinfo == IP_CT_NEW || diff --git a/queue-5.1/netfilter-nft_flow_offload-ipcb-is-only-valid-for-ipv4-family.patch b/queue-5.1/netfilter-nft_flow_offload-ipcb-is-only-valid-for-ipv4-family.patch new file mode 100644 index 00000000000..96043d90931 --- /dev/null +++ b/queue-5.1/netfilter-nft_flow_offload-ipcb-is-only-valid-for-ipv4-family.patch @@ -0,0 +1,56 @@ +From 69aeb538587e087bfc81dd1f465eab3558ff3158 Mon Sep 17 00:00:00 2001 +From: Florian Westphal +Date: Tue, 21 May 2019 13:24:33 +0200 +Subject: netfilter: nft_flow_offload: IPCB is only valid for ipv4 family + +From: Florian Westphal + +commit 69aeb538587e087bfc81dd1f465eab3558ff3158 upstream. + +Guard this with a check vs. ipv4, IPCB isn't valid in ipv6 case. + +Signed-off-by: Florian Westphal +Signed-off-by: Pablo Neira Ayuso +Signed-off-by: Greg Kroah-Hartman + +--- + net/netfilter/nft_flow_offload.c | 17 +++++++++++------ + 1 file changed, 11 insertions(+), 6 deletions(-) + +--- a/net/netfilter/nft_flow_offload.c ++++ b/net/netfilter/nft_flow_offload.c +@@ -48,15 +48,20 @@ static int nft_flow_route(const struct n + return 0; + } + +-static bool nft_flow_offload_skip(struct sk_buff *skb) ++static bool nft_flow_offload_skip(struct sk_buff *skb, int family) + { +- struct ip_options *opt = &(IPCB(skb)->opt); +- +- if (unlikely(opt->optlen)) +- return true; + if (skb_sec_path(skb)) + return true; + ++ if (family == NFPROTO_IPV4) { ++ const struct ip_options *opt; ++ ++ opt = &(IPCB(skb)->opt); ++ ++ if (unlikely(opt->optlen)) ++ return true; ++ } ++ + return false; + } + +@@ -74,7 +79,7 @@ static void nft_flow_offload_eval(const + struct nf_conn *ct; + int ret; + +- if (nft_flow_offload_skip(pkt->skb)) ++ if (nft_flow_offload_skip(pkt->skb, nft_pf(pkt))) + goto out; + + ct = nf_ct_get(pkt->skb, &ctinfo); diff --git a/queue-5.1/netfilter-nft_flow_offload-set-liberal-tracking-mode-for-tcp.patch b/queue-5.1/netfilter-nft_flow_offload-set-liberal-tracking-mode-for-tcp.patch new file mode 100644 index 00000000000..7df08710e1f --- /dev/null +++ b/queue-5.1/netfilter-nft_flow_offload-set-liberal-tracking-mode-for-tcp.patch @@ -0,0 +1,52 @@ +From 8437a6209f76f85a2db1abb12a9bde2170801617 Mon Sep 17 00:00:00 2001 +From: Florian Westphal +Date: Tue, 21 May 2019 13:24:31 +0200 +Subject: netfilter: nft_flow_offload: set liberal tracking mode for tcp + +From: Florian Westphal + +commit 8437a6209f76f85a2db1abb12a9bde2170801617 upstream. + +Without it, whenever a packet has to be pushed up the stack (e.g. because +of mtu mismatch), then conntrack will flag packets as invalid, which in +turn breaks NAT. + +Signed-off-by: Florian Westphal +Signed-off-by: Pablo Neira Ayuso +Signed-off-by: Greg Kroah-Hartman + +--- + net/netfilter/nft_flow_offload.c | 8 ++++++++ + 1 file changed, 8 insertions(+) + +--- a/net/netfilter/nft_flow_offload.c ++++ b/net/netfilter/nft_flow_offload.c +@@ -72,6 +72,7 @@ static void nft_flow_offload_eval(const + struct nf_flow_route route; + struct flow_offload *flow; + enum ip_conntrack_dir dir; ++ bool is_tcp = false; + struct nf_conn *ct; + int ret; + +@@ -84,6 +85,8 @@ static void nft_flow_offload_eval(const + + switch (ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.protonum) { + case IPPROTO_TCP: ++ is_tcp = true; ++ break; + case IPPROTO_UDP: + break; + default: +@@ -109,6 +112,11 @@ static void nft_flow_offload_eval(const + if (!flow) + goto err_flow_alloc; + ++ if (is_tcp) { ++ ct->proto.tcp.seen[0].flags |= IP_CT_TCP_FLAG_BE_LIBERAL; ++ ct->proto.tcp.seen[1].flags |= IP_CT_TCP_FLAG_BE_LIBERAL; ++ } ++ + ret = flow_offload_add(flowtable, flow); + if (ret < 0) + goto err_flow_add; diff --git a/queue-5.1/signal-remove-the-wrong-signal_pending-check-in-restore_user_sigmask.patch b/queue-5.1/signal-remove-the-wrong-signal_pending-check-in-restore_user_sigmask.patch new file mode 100644 index 00000000000..ac5c86ff2be --- /dev/null +++ b/queue-5.1/signal-remove-the-wrong-signal_pending-check-in-restore_user_sigmask.patch @@ -0,0 +1,280 @@ +From 97abc889ee296faf95ca0e978340fb7b942a3e32 Mon Sep 17 00:00:00 2001 +From: Oleg Nesterov +Date: Fri, 28 Jun 2019 12:06:50 -0700 +Subject: signal: remove the wrong signal_pending() check in restore_user_sigmask() + +From: Oleg Nesterov + +commit 97abc889ee296faf95ca0e978340fb7b942a3e32 upstream. + +This is the minimal fix for stable, I'll send cleanups later. + +Commit 854a6ed56839 ("signal: Add restore_user_sigmask()") introduced +the visible change which breaks user-space: a signal temporary unblocked +by set_user_sigmask() can be delivered even if the caller returns +success or timeout. + +Change restore_user_sigmask() to accept the additional "interrupted" +argument which should be used instead of signal_pending() check, and +update the callers. + +Eric said: + +: For clarity. I don't think this is required by posix, or fundamentally to +: remove the races in select. It is what linux has always done and we have +: applications who care so I agree this fix is needed. +: +: Further in any case where the semantic change that this patch rolls back +: (aka where allowing a signal to be delivered and the select like call to +: complete) would be advantage we can do as well if not better by using +: signalfd. +: +: Michael is there any chance we can get this guarantee of the linux +: implementation of pselect and friends clearly documented. The guarantee +: that if the system call completes successfully we are guaranteed that no +: signal that is unblocked by using sigmask will be delivered? + +Link: http://lkml.kernel.org/r/20190604134117.GA29963@redhat.com +Fixes: 854a6ed56839a40f6b5d02a2962f48841482eec4 ("signal: Add restore_user_sigmask()") +Signed-off-by: Oleg Nesterov +Reported-by: Eric Wong +Tested-by: Eric Wong +Acked-by: "Eric W. Biederman" +Acked-by: Arnd Bergmann +Acked-by: Deepa Dinamani +Cc: Michael Kerrisk +Cc: Jens Axboe +Cc: Davidlohr Bueso +Cc: Jason Baron +Cc: Thomas Gleixner +Cc: Al Viro +Cc: David Laight +Cc: [5.0+] +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + fs/aio.c | 28 ++++++++++++++++++++-------- + fs/eventpoll.c | 4 ++-- + fs/io_uring.c | 2 +- + fs/select.c | 18 ++++++------------ + include/linux/signal.h | 2 +- + kernel/signal.c | 5 +++-- + 6 files changed, 33 insertions(+), 26 deletions(-) + +--- a/fs/aio.c ++++ b/fs/aio.c +@@ -2095,6 +2095,7 @@ SYSCALL_DEFINE6(io_pgetevents, + struct __aio_sigset ksig = { NULL, }; + sigset_t ksigmask, sigsaved; + struct timespec64 ts; ++ bool interrupted; + int ret; + + if (timeout && unlikely(get_timespec64(&ts, timeout))) +@@ -2108,8 +2109,10 @@ SYSCALL_DEFINE6(io_pgetevents, + return ret; + + ret = do_io_getevents(ctx_id, min_nr, nr, events, timeout ? &ts : NULL); +- restore_user_sigmask(ksig.sigmask, &sigsaved); +- if (signal_pending(current) && !ret) ++ ++ interrupted = signal_pending(current); ++ restore_user_sigmask(ksig.sigmask, &sigsaved, interrupted); ++ if (interrupted && !ret) + ret = -ERESTARTNOHAND; + + return ret; +@@ -2128,6 +2131,7 @@ SYSCALL_DEFINE6(io_pgetevents_time32, + struct __aio_sigset ksig = { NULL, }; + sigset_t ksigmask, sigsaved; + struct timespec64 ts; ++ bool interrupted; + int ret; + + if (timeout && unlikely(get_old_timespec32(&ts, timeout))) +@@ -2142,8 +2146,10 @@ SYSCALL_DEFINE6(io_pgetevents_time32, + return ret; + + ret = do_io_getevents(ctx_id, min_nr, nr, events, timeout ? &ts : NULL); +- restore_user_sigmask(ksig.sigmask, &sigsaved); +- if (signal_pending(current) && !ret) ++ ++ interrupted = signal_pending(current); ++ restore_user_sigmask(ksig.sigmask, &sigsaved, interrupted); ++ if (interrupted && !ret) + ret = -ERESTARTNOHAND; + + return ret; +@@ -2193,6 +2199,7 @@ COMPAT_SYSCALL_DEFINE6(io_pgetevents, + struct __compat_aio_sigset ksig = { NULL, }; + sigset_t ksigmask, sigsaved; + struct timespec64 t; ++ bool interrupted; + int ret; + + if (timeout && get_old_timespec32(&t, timeout)) +@@ -2206,8 +2213,10 @@ COMPAT_SYSCALL_DEFINE6(io_pgetevents, + return ret; + + ret = do_io_getevents(ctx_id, min_nr, nr, events, timeout ? &t : NULL); +- restore_user_sigmask(ksig.sigmask, &sigsaved); +- if (signal_pending(current) && !ret) ++ ++ interrupted = signal_pending(current); ++ restore_user_sigmask(ksig.sigmask, &sigsaved, interrupted); ++ if (interrupted && !ret) + ret = -ERESTARTNOHAND; + + return ret; +@@ -2226,6 +2235,7 @@ COMPAT_SYSCALL_DEFINE6(io_pgetevents_tim + struct __compat_aio_sigset ksig = { NULL, }; + sigset_t ksigmask, sigsaved; + struct timespec64 t; ++ bool interrupted; + int ret; + + if (timeout && get_timespec64(&t, timeout)) +@@ -2239,8 +2249,10 @@ COMPAT_SYSCALL_DEFINE6(io_pgetevents_tim + return ret; + + ret = do_io_getevents(ctx_id, min_nr, nr, events, timeout ? &t : NULL); +- restore_user_sigmask(ksig.sigmask, &sigsaved); +- if (signal_pending(current) && !ret) ++ ++ interrupted = signal_pending(current); ++ restore_user_sigmask(ksig.sigmask, &sigsaved, interrupted); ++ if (interrupted && !ret) + ret = -ERESTARTNOHAND; + + return ret; +--- a/fs/eventpoll.c ++++ b/fs/eventpoll.c +@@ -2330,7 +2330,7 @@ SYSCALL_DEFINE6(epoll_pwait, int, epfd, + + error = do_epoll_wait(epfd, events, maxevents, timeout); + +- restore_user_sigmask(sigmask, &sigsaved); ++ restore_user_sigmask(sigmask, &sigsaved, error == -EINTR); + + return error; + } +@@ -2355,7 +2355,7 @@ COMPAT_SYSCALL_DEFINE6(epoll_pwait, int, + + err = do_epoll_wait(epfd, events, maxevents, timeout); + +- restore_user_sigmask(sigmask, &sigsaved); ++ restore_user_sigmask(sigmask, &sigsaved, err == -EINTR); + + return err; + } +--- a/fs/io_uring.c ++++ b/fs/io_uring.c +@@ -2096,7 +2096,7 @@ static int io_cqring_wait(struct io_ring + finish_wait(&ctx->wait, &wait); + + if (sig) +- restore_user_sigmask(sig, &sigsaved); ++ restore_user_sigmask(sig, &sigsaved, ret == -EINTR); + + return READ_ONCE(ring->r.head) == READ_ONCE(ring->r.tail) ? ret : 0; + } +--- a/fs/select.c ++++ b/fs/select.c +@@ -758,10 +758,9 @@ static long do_pselect(int n, fd_set __u + return ret; + + ret = core_sys_select(n, inp, outp, exp, to); ++ restore_user_sigmask(sigmask, &sigsaved, ret == -ERESTARTNOHAND); + ret = poll_select_copy_remaining(&end_time, tsp, type, ret); + +- restore_user_sigmask(sigmask, &sigsaved); +- + return ret; + } + +@@ -1106,8 +1105,7 @@ SYSCALL_DEFINE5(ppoll, struct pollfd __u + + ret = do_sys_poll(ufds, nfds, to); + +- restore_user_sigmask(sigmask, &sigsaved); +- ++ restore_user_sigmask(sigmask, &sigsaved, ret == -EINTR); + /* We can restart this syscall, usually */ + if (ret == -EINTR) + ret = -ERESTARTNOHAND; +@@ -1142,8 +1140,7 @@ SYSCALL_DEFINE5(ppoll_time32, struct pol + + ret = do_sys_poll(ufds, nfds, to); + +- restore_user_sigmask(sigmask, &sigsaved); +- ++ restore_user_sigmask(sigmask, &sigsaved, ret == -EINTR); + /* We can restart this syscall, usually */ + if (ret == -EINTR) + ret = -ERESTARTNOHAND; +@@ -1350,10 +1347,9 @@ static long do_compat_pselect(int n, com + return ret; + + ret = compat_core_sys_select(n, inp, outp, exp, to); ++ restore_user_sigmask(sigmask, &sigsaved, ret == -ERESTARTNOHAND); + ret = poll_select_copy_remaining(&end_time, tsp, type, ret); + +- restore_user_sigmask(sigmask, &sigsaved); +- + return ret; + } + +@@ -1425,8 +1421,7 @@ COMPAT_SYSCALL_DEFINE5(ppoll_time32, str + + ret = do_sys_poll(ufds, nfds, to); + +- restore_user_sigmask(sigmask, &sigsaved); +- ++ restore_user_sigmask(sigmask, &sigsaved, ret == -EINTR); + /* We can restart this syscall, usually */ + if (ret == -EINTR) + ret = -ERESTARTNOHAND; +@@ -1461,8 +1456,7 @@ COMPAT_SYSCALL_DEFINE5(ppoll_time64, str + + ret = do_sys_poll(ufds, nfds, to); + +- restore_user_sigmask(sigmask, &sigsaved); +- ++ restore_user_sigmask(sigmask, &sigsaved, ret == -EINTR); + /* We can restart this syscall, usually */ + if (ret == -EINTR) + ret = -ERESTARTNOHAND; +--- a/include/linux/signal.h ++++ b/include/linux/signal.h +@@ -276,7 +276,7 @@ extern int sigprocmask(int, sigset_t *, + extern int set_user_sigmask(const sigset_t __user *usigmask, sigset_t *set, + sigset_t *oldset, size_t sigsetsize); + extern void restore_user_sigmask(const void __user *usigmask, +- sigset_t *sigsaved); ++ sigset_t *sigsaved, bool interrupted); + extern void set_current_blocked(sigset_t *); + extern void __set_current_blocked(const sigset_t *); + extern int show_unhandled_signals; +--- a/kernel/signal.c ++++ b/kernel/signal.c +@@ -2851,7 +2851,8 @@ EXPORT_SYMBOL(set_compat_user_sigmask); + * This is useful for syscalls such as ppoll, pselect, io_pgetevents and + * epoll_pwait where a new sigmask is passed in from userland for the syscalls. + */ +-void restore_user_sigmask(const void __user *usigmask, sigset_t *sigsaved) ++void restore_user_sigmask(const void __user *usigmask, sigset_t *sigsaved, ++ bool interrupted) + { + + if (!usigmask) +@@ -2861,7 +2862,7 @@ void restore_user_sigmask(const void __u + * Restoring sigmask here can lead to delivering signals that the above + * syscalls are intended to block because of the sigmask passed in. + */ +- if (signal_pending(current)) { ++ if (interrupted) { + current->saved_sigmask = *sigsaved; + set_restore_sigmask(); + return;