From 03b79d4ba7fac4f971b88a7697a9f40e75442c5e Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 30 Mar 2020 15:46:45 +0200 Subject: [PATCH] 5.5-stable patches added patches: afs-fix-client-call-rx-phase-signal-handling.patch afs-fix-handling-of-an-abort-from-a-service-handler.patch afs-fix-some-tracing-details.patch afs-fix-unpinned-address-list-during-probing.patch bpf-fix-cgroup-ref-leak-in-cgroup_bpf_inherit-on-out-of-memory.patch genirq-fix-reference-leaks-on-irq-affinity-notifiers.patch gpiolib-acpi-add-quirk-to-ignore-ec-wakeups-on-hp-x2-10-byt-axp288-model.patch gpiolib-acpi-correct-comment-for-hp-x2-10-honor_wakeup-quirk.patch gpiolib-acpi-rework-honor_wakeup-option-into-an-ignore_wake-option.patch ieee80211-fix-he-spr-size-calculation.patch mac80211-set-ieee80211_tx_ctrl_port_ctrl_proto-for-nl80211-tx.patch netfilter-flowtable-fix-flushing-of-offloaded-flows-on-free.patch netfilter-flowtable-populate-addr_type-mask.patch netfilter-flowtable-reload-ip-v6-h-in-nf_flow_tuple_ip-v6.patch netfilter-nft_fwd_netdev-allow-to-redirect-to-ifb-via-ingress.patch netfilter-nft_fwd_netdev-validate-family-and-chain-type.patch rdma-core-ensure-security-pkey-modify-is-not-lost.patch rdma-mlx5-block-delay-drop-to-unprivileged-users.patch rdma-mlx5-fix-access-to-wrong-pointer-while-performing-flush-due-to-error.patch rdma-mlx5-fix-the-number-of-hwcounters-of-a-dynamic-counter.patch vti-fix-packet-tx-through-bpf_redirect-in-xiny-cases.patch xfrm-add-the-missing-verify_sec_ctx_len-check-in-xfrm_add_acquire.patch xfrm-fix-uctx-len-check-in-verify_sec_ctx_len.patch xfrm-handle-netdev_unregister-for-xfrm-device.patch xfrm-policy-fix-doulbe-free-in-xfrm_policy_timer.patch --- ...client-call-rx-phase-signal-handling.patch | 183 +++++++++++++++ ...g-of-an-abort-from-a-service-handler.patch | 203 +++++++++++++++++ queue-5.5/afs-fix-some-tracing-details.patch | 56 +++++ ...unpinned-address-list-during-probing.patch | 48 ++++ ...-cgroup_bpf_inherit-on-out-of-memory.patch | 36 +++ ...ence-leaks-on-irq-affinity-notifiers.patch | 60 +++++ ...wakeups-on-hp-x2-10-byt-axp288-model.patch | 64 ++++++ ...ment-for-hp-x2-10-honor_wakeup-quirk.patch | 72 ++++++ ...up-option-into-an-ignore_wake-option.patch | 215 ++++++++++++++++++ ...eee80211-fix-he-spr-size-calculation.patch | 43 ++++ ..._ctrl_port_ctrl_proto-for-nl80211-tx.patch | 62 +++++ ...-flushing-of-offloaded-flows-on-free.patch | 37 +++ ...er-flowtable-populate-addr_type-mask.patch | 31 +++ ...eload-ip-v6-h-in-nf_flow_tuple_ip-v6.patch | 40 ++++ ...allow-to-redirect-to-ifb-via-ingress.patch | 38 ++++ ...etdev-validate-family-and-chain-type.patch | 51 +++++ ...ure-security-pkey-modify-is-not-lost.patch | 75 ++++++ ...ock-delay-drop-to-unprivileged-users.patch | 36 +++ ...-while-performing-flush-due-to-error.patch | 130 +++++++++++ ...r-of-hwcounters-of-a-dynamic-counter.patch | 90 ++++++++ queue-5.5/series | 25 ++ ...x-through-bpf_redirect-in-xiny-cases.patch | 124 ++++++++++ ...ec_ctx_len-check-in-xfrm_add_acquire.patch | 60 +++++ ...uctx-len-check-in-verify_sec_ctx_len.patch | 37 +++ ...le-netdev_unregister-for-xfrm-device.patch | 34 +++ ...fix-doulbe-free-in-xfrm_policy_timer.patch | 73 ++++++ 26 files changed, 1923 insertions(+) create mode 100644 queue-5.5/afs-fix-client-call-rx-phase-signal-handling.patch create mode 100644 queue-5.5/afs-fix-handling-of-an-abort-from-a-service-handler.patch create mode 100644 queue-5.5/afs-fix-some-tracing-details.patch create mode 100644 queue-5.5/afs-fix-unpinned-address-list-during-probing.patch create mode 100644 queue-5.5/bpf-fix-cgroup-ref-leak-in-cgroup_bpf_inherit-on-out-of-memory.patch create mode 100644 queue-5.5/genirq-fix-reference-leaks-on-irq-affinity-notifiers.patch create mode 100644 queue-5.5/gpiolib-acpi-add-quirk-to-ignore-ec-wakeups-on-hp-x2-10-byt-axp288-model.patch create mode 100644 queue-5.5/gpiolib-acpi-correct-comment-for-hp-x2-10-honor_wakeup-quirk.patch create mode 100644 queue-5.5/gpiolib-acpi-rework-honor_wakeup-option-into-an-ignore_wake-option.patch create mode 100644 queue-5.5/ieee80211-fix-he-spr-size-calculation.patch create mode 100644 queue-5.5/mac80211-set-ieee80211_tx_ctrl_port_ctrl_proto-for-nl80211-tx.patch create mode 100644 queue-5.5/netfilter-flowtable-fix-flushing-of-offloaded-flows-on-free.patch create mode 100644 queue-5.5/netfilter-flowtable-populate-addr_type-mask.patch create mode 100644 queue-5.5/netfilter-flowtable-reload-ip-v6-h-in-nf_flow_tuple_ip-v6.patch create mode 100644 queue-5.5/netfilter-nft_fwd_netdev-allow-to-redirect-to-ifb-via-ingress.patch create mode 100644 queue-5.5/netfilter-nft_fwd_netdev-validate-family-and-chain-type.patch create mode 100644 queue-5.5/rdma-core-ensure-security-pkey-modify-is-not-lost.patch create mode 100644 queue-5.5/rdma-mlx5-block-delay-drop-to-unprivileged-users.patch create mode 100644 queue-5.5/rdma-mlx5-fix-access-to-wrong-pointer-while-performing-flush-due-to-error.patch create mode 100644 queue-5.5/rdma-mlx5-fix-the-number-of-hwcounters-of-a-dynamic-counter.patch create mode 100644 queue-5.5/vti-fix-packet-tx-through-bpf_redirect-in-xiny-cases.patch create mode 100644 queue-5.5/xfrm-add-the-missing-verify_sec_ctx_len-check-in-xfrm_add_acquire.patch create mode 100644 queue-5.5/xfrm-fix-uctx-len-check-in-verify_sec_ctx_len.patch create mode 100644 queue-5.5/xfrm-handle-netdev_unregister-for-xfrm-device.patch create mode 100644 queue-5.5/xfrm-policy-fix-doulbe-free-in-xfrm_policy_timer.patch diff --git a/queue-5.5/afs-fix-client-call-rx-phase-signal-handling.patch b/queue-5.5/afs-fix-client-call-rx-phase-signal-handling.patch new file mode 100644 index 00000000000..387f6ec9659 --- /dev/null +++ b/queue-5.5/afs-fix-client-call-rx-phase-signal-handling.patch @@ -0,0 +1,183 @@ +From 7d7587db0d7fd1138f2afcffdc46a8e15630b944 Mon Sep 17 00:00:00 2001 +From: David Howells +Date: Thu, 12 Mar 2020 21:40:06 +0000 +Subject: afs: Fix client call Rx-phase signal handling + +From: David Howells + +commit 7d7587db0d7fd1138f2afcffdc46a8e15630b944 upstream. + +Fix the handling of signals in client rxrpc calls made by the afs +filesystem. Ignore signals completely, leaving call abandonment or +connection loss to be detected by timeouts inside AF_RXRPC. + +Allowing a filesystem call to be interrupted after the entire request has +been transmitted and an abort sent means that the server may or may not +have done the action - and we don't know. It may even be worse than that +for older servers. + +Fixes: bc5e3a546d55 ("rxrpc: Use MSG_WAITALL to tell sendmsg() to temporarily ignore signals") +Signed-off-by: David Howells +Signed-off-by: Greg Kroah-Hartman + +--- + fs/afs/rxrpc.c | 34 ++-------------------------------- + include/net/af_rxrpc.h | 4 +--- + net/rxrpc/af_rxrpc.c | 33 +++------------------------------ + net/rxrpc/ar-internal.h | 1 - + net/rxrpc/input.c | 1 - + 5 files changed, 6 insertions(+), 67 deletions(-) + +--- a/fs/afs/rxrpc.c ++++ b/fs/afs/rxrpc.c +@@ -603,11 +603,7 @@ call_complete: + long afs_wait_for_call_to_complete(struct afs_call *call, + struct afs_addr_cursor *ac) + { +- signed long rtt2, timeout; + long ret; +- bool stalled = false; +- u64 rtt; +- u32 life, last_life; + bool rxrpc_complete = false; + + DECLARE_WAITQUEUE(myself, current); +@@ -618,14 +614,6 @@ long afs_wait_for_call_to_complete(struc + if (ret < 0) + goto out; + +- rtt = rxrpc_kernel_get_rtt(call->net->socket, call->rxcall); +- rtt2 = nsecs_to_jiffies64(rtt) * 2; +- if (rtt2 < 2) +- rtt2 = 2; +- +- timeout = rtt2; +- rxrpc_kernel_check_life(call->net->socket, call->rxcall, &last_life); +- + add_wait_queue(&call->waitq, &myself); + for (;;) { + set_current_state(TASK_UNINTERRUPTIBLE); +@@ -636,37 +624,19 @@ long afs_wait_for_call_to_complete(struc + call->need_attention = false; + __set_current_state(TASK_RUNNING); + afs_deliver_to_call(call); +- timeout = rtt2; + continue; + } + + if (afs_check_call_state(call, AFS_CALL_COMPLETE)) + break; + +- if (!rxrpc_kernel_check_life(call->net->socket, call->rxcall, &life)) { ++ if (!rxrpc_kernel_check_life(call->net->socket, call->rxcall)) { + /* rxrpc terminated the call. */ + rxrpc_complete = true; + break; + } + +- if (call->intr && timeout == 0 && +- life == last_life && signal_pending(current)) { +- if (stalled) +- break; +- __set_current_state(TASK_RUNNING); +- rxrpc_kernel_probe_life(call->net->socket, call->rxcall); +- timeout = rtt2; +- stalled = true; +- continue; +- } +- +- if (life != last_life) { +- timeout = rtt2; +- last_life = life; +- stalled = false; +- } +- +- timeout = schedule_timeout(timeout); ++ schedule(); + } + + remove_wait_queue(&call->waitq, &myself); +--- a/include/net/af_rxrpc.h ++++ b/include/net/af_rxrpc.h +@@ -58,9 +58,7 @@ int rxrpc_kernel_charge_accept(struct so + rxrpc_user_attach_call_t, unsigned long, gfp_t, + unsigned int); + void rxrpc_kernel_set_tx_length(struct socket *, struct rxrpc_call *, s64); +-bool rxrpc_kernel_check_life(const struct socket *, const struct rxrpc_call *, +- u32 *); +-void rxrpc_kernel_probe_life(struct socket *, struct rxrpc_call *); ++bool rxrpc_kernel_check_life(const struct socket *, const struct rxrpc_call *); + u32 rxrpc_kernel_get_epoch(struct socket *, struct rxrpc_call *); + bool rxrpc_kernel_get_reply_time(struct socket *, struct rxrpc_call *, + ktime_t *); +--- a/net/rxrpc/af_rxrpc.c ++++ b/net/rxrpc/af_rxrpc.c +@@ -371,45 +371,18 @@ EXPORT_SYMBOL(rxrpc_kernel_end_call); + * rxrpc_kernel_check_life - Check to see whether a call is still alive + * @sock: The socket the call is on + * @call: The call to check +- * @_life: Where to store the life value + * +- * Allow a kernel service to find out whether a call is still alive - ie. we're +- * getting ACKs from the server. Passes back in *_life a number representing +- * the life state which can be compared to that returned by a previous call and +- * return true if the call is still alive. +- * +- * If the life state stalls, rxrpc_kernel_probe_life() should be called and +- * then 2RTT waited. ++ * Allow a kernel service to find out whether a call is still alive - ++ * ie. whether it has completed. + */ + bool rxrpc_kernel_check_life(const struct socket *sock, +- const struct rxrpc_call *call, +- u32 *_life) ++ const struct rxrpc_call *call) + { +- *_life = call->acks_latest; + return call->state != RXRPC_CALL_COMPLETE; + } + EXPORT_SYMBOL(rxrpc_kernel_check_life); + + /** +- * rxrpc_kernel_probe_life - Poke the peer to see if it's still alive +- * @sock: The socket the call is on +- * @call: The call to check +- * +- * In conjunction with rxrpc_kernel_check_life(), allow a kernel service to +- * find out whether a call is still alive by pinging it. This should cause the +- * life state to be bumped in about 2*RTT. +- * +- * The must be called in TASK_RUNNING state on pain of might_sleep() objecting. +- */ +-void rxrpc_kernel_probe_life(struct socket *sock, struct rxrpc_call *call) +-{ +- rxrpc_propose_ACK(call, RXRPC_ACK_PING, 0, true, false, +- rxrpc_propose_ack_ping_for_check_life); +- rxrpc_send_ack_packet(call, true, NULL); +-} +-EXPORT_SYMBOL(rxrpc_kernel_probe_life); +- +-/** + * rxrpc_kernel_get_epoch - Retrieve the epoch value from a call. + * @sock: The socket the call is on + * @call: The call to query +--- a/net/rxrpc/ar-internal.h ++++ b/net/rxrpc/ar-internal.h +@@ -675,7 +675,6 @@ struct rxrpc_call { + + /* transmission-phase ACK management */ + ktime_t acks_latest_ts; /* Timestamp of latest ACK received */ +- rxrpc_serial_t acks_latest; /* serial number of latest ACK received */ + rxrpc_seq_t acks_lowest_nak; /* Lowest NACK in the buffer (or ==tx_hard_ack) */ + rxrpc_seq_t acks_lost_top; /* tx_top at the time lost-ack ping sent */ + rxrpc_serial_t acks_lost_ping; /* Serial number of probe ACK */ +--- a/net/rxrpc/input.c ++++ b/net/rxrpc/input.c +@@ -882,7 +882,6 @@ static void rxrpc_input_ack(struct rxrpc + before(prev_pkt, call->ackr_prev_seq)) + goto out; + call->acks_latest_ts = skb->tstamp; +- call->acks_latest = sp->hdr.serial; + + call->ackr_first_seq = first_soft_ack; + call->ackr_prev_seq = prev_pkt; diff --git a/queue-5.5/afs-fix-handling-of-an-abort-from-a-service-handler.patch b/queue-5.5/afs-fix-handling-of-an-abort-from-a-service-handler.patch new file mode 100644 index 00000000000..ab004e7fec5 --- /dev/null +++ b/queue-5.5/afs-fix-handling-of-an-abort-from-a-service-handler.patch @@ -0,0 +1,203 @@ +From dde9f095583b3f375ba23979045ee10dfcebec2f Mon Sep 17 00:00:00 2001 +From: David Howells +Date: Fri, 13 Mar 2020 13:46:08 +0000 +Subject: afs: Fix handling of an abort from a service handler + +From: David Howells + +commit dde9f095583b3f375ba23979045ee10dfcebec2f upstream. + +When an AFS service handler function aborts a call, AF_RXRPC marks the call +as complete - which means that it's not going to get any more packets from +the receiver. This is a problem because reception of the final ACK is what +triggers afs_deliver_to_call() to drop the final ref on the afs_call +object. + +Instead, aborted AFS service calls may then just sit around waiting for +ever or until they're displaced by a new call on the same connection +channel or a connection-level abort. + +Fix this by calling afs_set_call_complete() to finalise the afs_call struct +representing the call. + +However, we then need to drop the ref that stops the call from being +deallocated. We can do this in afs_set_call_complete(), as the work queue +is holding a separate ref of its own, but then we shouldn't do it in +afs_process_async_call() and afs_delete_async_call(). + +call->drop_ref is set to indicate that a ref needs dropping for a call and +this is dealt with when we transition a call to AFS_CALL_COMPLETE. + +But then we also need to get rid of the ref that pins an asynchronous +client call. We can do this by the same mechanism, setting call->drop_ref +for an async client call too. + +We can also get rid of call->incoming since nothing ever sets it and only +one thing ever checks it (futilely). + + +A trace of the rxrpc_call and afs_call struct ref counting looks like: + + -0 [001] ..s5 164.764892: rxrpc_call: c=00000002 SEE u=3 sp=rxrpc_new_incoming_call+0x473/0xb34 a=00000000442095b5 + -0 [001] .Ns5 164.766001: rxrpc_call: c=00000002 QUE u=4 sp=rxrpc_propose_ACK+0xbe/0x551 a=00000000442095b5 + -0 [001] .Ns4 164.766005: rxrpc_call: c=00000002 PUT u=3 sp=rxrpc_new_incoming_call+0xa3f/0xb34 a=00000000442095b5 + -0 [001] .Ns7 164.766433: afs_call: c=00000002 WAKE u=2 o=11 sp=rxrpc_notify_socket+0x196/0x33c + kworker/1:2-1810 [001] ...1 164.768409: rxrpc_call: c=00000002 SEE u=3 sp=rxrpc_process_call+0x25/0x7ae a=00000000442095b5 + kworker/1:2-1810 [001] ...1 164.769439: rxrpc_tx_packet: c=00000002 e9f1a7a8:95786a88:00000008:09c5 00000001 00000000 02 22 ACK CallAck + kworker/1:2-1810 [001] ...1 164.769459: rxrpc_call: c=00000002 PUT u=2 sp=rxrpc_process_call+0x74f/0x7ae a=00000000442095b5 + kworker/1:2-1810 [001] ...1 164.770794: afs_call: c=00000002 QUEUE u=3 o=12 sp=afs_deliver_to_call+0x449/0x72c + kworker/1:2-1810 [001] ...1 164.770829: afs_call: c=00000002 PUT u=2 o=12 sp=afs_process_async_call+0xdb/0x11e + kworker/1:2-1810 [001] ...2 164.771084: rxrpc_abort: c=00000002 95786a88:00000008 s=0 a=1 e=1 K-1 + kworker/1:2-1810 [001] ...1 164.771461: rxrpc_tx_packet: c=00000002 e9f1a7a8:95786a88:00000008:09c5 00000002 00000000 04 00 ABORT CallAbort + kworker/1:2-1810 [001] ...1 164.771466: afs_call: c=00000002 PUT u=1 o=12 sp=SRXAFSCB_ProbeUuid+0xc1/0x106 + +The abort generated in SRXAFSCB_ProbeUuid(), labelled "K-1", indicates that +the local filesystem/cache manager didn't recognise the UUID as its own. + +Fixes: 2067b2b3f484 ("afs: Fix the CB.ProbeUuid service handler to reply correctly") +Signed-off-by: David Howells +Signed-off-by: Greg Kroah-Hartman + +--- + fs/afs/cmservice.c | 14 ++++++++++++-- + fs/afs/internal.h | 12 ++++++++++-- + fs/afs/rxrpc.c | 33 ++++----------------------------- + 3 files changed, 26 insertions(+), 33 deletions(-) + +--- a/fs/afs/cmservice.c ++++ b/fs/afs/cmservice.c +@@ -244,6 +244,17 @@ static void afs_cm_destructor(struct afs + } + + /* ++ * Abort a service call from within an action function. ++ */ ++static void afs_abort_service_call(struct afs_call *call, u32 abort_code, int error, ++ const char *why) ++{ ++ rxrpc_kernel_abort_call(call->net->socket, call->rxcall, ++ abort_code, error, why); ++ afs_set_call_complete(call, error, 0); ++} ++ ++/* + * The server supplied a list of callbacks that it wanted to break. + */ + static void SRXAFSCB_CallBack(struct work_struct *work) +@@ -510,8 +521,7 @@ static void SRXAFSCB_ProbeUuid(struct wo + if (memcmp(r, &call->net->uuid, sizeof(call->net->uuid)) == 0) + afs_send_empty_reply(call); + else +- rxrpc_kernel_abort_call(call->net->socket, call->rxcall, +- 1, 1, "K-1"); ++ afs_abort_service_call(call, 1, 1, "K-1"); + + afs_put_call(call); + _leave(""); +--- a/fs/afs/internal.h ++++ b/fs/afs/internal.h +@@ -154,7 +154,7 @@ struct afs_call { + }; + unsigned char unmarshall; /* unmarshalling phase */ + unsigned char addr_ix; /* Address in ->alist */ +- bool incoming; /* T if incoming call */ ++ bool drop_ref; /* T if need to drop ref for incoming call */ + bool send_pages; /* T if data from mapping should be sent */ + bool need_attention; /* T if RxRPC poked us */ + bool async; /* T if asynchronous */ +@@ -1209,8 +1209,16 @@ static inline void afs_set_call_complete + ok = true; + } + spin_unlock_bh(&call->state_lock); +- if (ok) ++ if (ok) { + trace_afs_call_done(call); ++ ++ /* Asynchronous calls have two refs to release - one from the alloc and ++ * one queued with the work item - and we can't just deallocate the ++ * call because the work item may be queued again. ++ */ ++ if (call->drop_ref) ++ afs_put_call(call); ++ } + } + + /* +--- a/fs/afs/rxrpc.c ++++ b/fs/afs/rxrpc.c +@@ -18,7 +18,6 @@ struct workqueue_struct *afs_async_calls + + static void afs_wake_up_call_waiter(struct sock *, struct rxrpc_call *, unsigned long); + static void afs_wake_up_async_call(struct sock *, struct rxrpc_call *, unsigned long); +-static void afs_delete_async_call(struct work_struct *); + static void afs_process_async_call(struct work_struct *); + static void afs_rx_new_call(struct sock *, struct rxrpc_call *, unsigned long); + static void afs_rx_discard_new_call(struct rxrpc_call *, unsigned long); +@@ -402,8 +401,10 @@ void afs_make_call(struct afs_addr_curso + /* If the call is going to be asynchronous, we need an extra ref for + * the call to hold itself so the caller need not hang on to its ref. + */ +- if (call->async) ++ if (call->async) { + afs_get_call(call, afs_call_trace_get); ++ call->drop_ref = true; ++ } + + /* create a call */ + rxcall = rxrpc_kernel_begin_call(call->net->socket, srx, call->key, +@@ -584,8 +585,6 @@ static void afs_deliver_to_call(struct a + done: + if (call->type->done) + call->type->done(call); +- if (state == AFS_CALL_COMPLETE && call->incoming) +- afs_put_call(call); + out: + _leave(""); + return; +@@ -745,21 +744,6 @@ static void afs_wake_up_async_call(struc + } + + /* +- * Delete an asynchronous call. The work item carries a ref to the call struct +- * that we need to release. +- */ +-static void afs_delete_async_call(struct work_struct *work) +-{ +- struct afs_call *call = container_of(work, struct afs_call, async_work); +- +- _enter(""); +- +- afs_put_call(call); +- +- _leave(""); +-} +- +-/* + * Perform I/O processing on an asynchronous call. The work item carries a ref + * to the call struct that we either need to release or to pass on. + */ +@@ -774,16 +758,6 @@ static void afs_process_async_call(struc + afs_deliver_to_call(call); + } + +- if (call->state == AFS_CALL_COMPLETE) { +- /* We have two refs to release - one from the alloc and one +- * queued with the work item - and we can't just deallocate the +- * call because the work item may be queued again. +- */ +- call->async_work.func = afs_delete_async_call; +- if (!queue_work(afs_async_calls, &call->async_work)) +- afs_put_call(call); +- } +- + afs_put_call(call); + _leave(""); + } +@@ -810,6 +784,7 @@ void afs_charge_preallocation(struct wor + if (!call) + break; + ++ call->drop_ref = true; + call->async = true; + call->state = AFS_CALL_SV_AWAIT_OP_ID; + init_waitqueue_head(&call->waitq); diff --git a/queue-5.5/afs-fix-some-tracing-details.patch b/queue-5.5/afs-fix-some-tracing-details.patch new file mode 100644 index 00000000000..85221c90831 --- /dev/null +++ b/queue-5.5/afs-fix-some-tracing-details.patch @@ -0,0 +1,56 @@ +From 4636cf184d6d9a92a56c2554681ea520dd4fe49a Mon Sep 17 00:00:00 2001 +From: David Howells +Date: Fri, 13 Mar 2020 13:36:01 +0000 +Subject: afs: Fix some tracing details + +From: David Howells + +commit 4636cf184d6d9a92a56c2554681ea520dd4fe49a upstream. + +Fix a couple of tracelines to indicate the usage count after the atomic op, +not the usage count before it to be consistent with other afs and rxrpc +trace lines. + +Change the wording of the afs_call_trace_work trace ID label from "WORK" to +"QUEUE" to reflect the fact that it's queueing work, not doing work. + +Fixes: 341f741f04be ("afs: Refcount the afs_call struct") +Signed-off-by: David Howells +Signed-off-by: Greg Kroah-Hartman + +--- + fs/afs/rxrpc.c | 4 ++-- + include/trace/events/afs.h | 2 +- + 2 files changed, 3 insertions(+), 3 deletions(-) + +--- a/fs/afs/rxrpc.c ++++ b/fs/afs/rxrpc.c +@@ -168,7 +168,7 @@ void afs_put_call(struct afs_call *call) + int n = atomic_dec_return(&call->usage); + int o = atomic_read(&net->nr_outstanding_calls); + +- trace_afs_call(call, afs_call_trace_put, n + 1, o, ++ trace_afs_call(call, afs_call_trace_put, n, o, + __builtin_return_address(0)); + + ASSERTCMP(n, >=, 0); +@@ -704,7 +704,7 @@ static void afs_wake_up_async_call(struc + + u = atomic_fetch_add_unless(&call->usage, 1, 0); + if (u != 0) { +- trace_afs_call(call, afs_call_trace_wake, u, ++ trace_afs_call(call, afs_call_trace_wake, u + 1, + atomic_read(&call->net->nr_outstanding_calls), + __builtin_return_address(0)); + +--- a/include/trace/events/afs.h ++++ b/include/trace/events/afs.h +@@ -233,7 +233,7 @@ enum afs_cb_break_reason { + EM(afs_call_trace_get, "GET ") \ + EM(afs_call_trace_put, "PUT ") \ + EM(afs_call_trace_wake, "WAKE ") \ +- E_(afs_call_trace_work, "WORK ") ++ E_(afs_call_trace_work, "QUEUE") + + #define afs_server_traces \ + EM(afs_server_trace_alloc, "ALLOC ") \ diff --git a/queue-5.5/afs-fix-unpinned-address-list-during-probing.patch b/queue-5.5/afs-fix-unpinned-address-list-during-probing.patch new file mode 100644 index 00000000000..d57e7496150 --- /dev/null +++ b/queue-5.5/afs-fix-unpinned-address-list-during-probing.patch @@ -0,0 +1,48 @@ +From 9efcc4a129363187c9bf15338692f107c5c9b6f0 Mon Sep 17 00:00:00 2001 +From: David Howells +Date: Thu, 26 Mar 2020 15:24:07 +0000 +Subject: afs: Fix unpinned address list during probing + +From: David Howells + +commit 9efcc4a129363187c9bf15338692f107c5c9b6f0 upstream. + +When it's probing all of a fileserver's interfaces to find which one is +best to use, afs_do_probe_fileserver() takes a lock on the server record +and notes the pointer to the address list. + +It doesn't, however, pin the address list, so as soon as it drops the +lock, there's nothing to stop the address list from being freed under +us. + +Fix this by taking a ref on the address list inside the locked section +and dropping it at the end of the function. + +Fixes: 3bf0fb6f33dd ("afs: Probe multiple fileservers simultaneously") +Signed-off-by: David Howells +Reviewed-by: Marc Dionne +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + fs/afs/fs_probe.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/fs/afs/fs_probe.c ++++ b/fs/afs/fs_probe.c +@@ -145,6 +145,7 @@ static int afs_do_probe_fileserver(struc + read_lock(&server->fs_lock); + ac.alist = rcu_dereference_protected(server->addresses, + lockdep_is_held(&server->fs_lock)); ++ afs_get_addrlist(ac.alist); + read_unlock(&server->fs_lock); + + atomic_set(&server->probe_outstanding, ac.alist->nr_addrs); +@@ -163,6 +164,7 @@ static int afs_do_probe_fileserver(struc + + if (!in_progress) + afs_fs_probe_done(server); ++ afs_put_addrlist(ac.alist); + return in_progress; + } + diff --git a/queue-5.5/bpf-fix-cgroup-ref-leak-in-cgroup_bpf_inherit-on-out-of-memory.patch b/queue-5.5/bpf-fix-cgroup-ref-leak-in-cgroup_bpf_inherit-on-out-of-memory.patch new file mode 100644 index 00000000000..0adf0969019 --- /dev/null +++ b/queue-5.5/bpf-fix-cgroup-ref-leak-in-cgroup_bpf_inherit-on-out-of-memory.patch @@ -0,0 +1,36 @@ +From 1d8006abaab4cb90f81add86e8d1bf9411add05a Mon Sep 17 00:00:00 2001 +From: Andrii Nakryiko +Date: Mon, 9 Mar 2020 15:40:17 -0700 +Subject: bpf: Fix cgroup ref leak in cgroup_bpf_inherit on out-of-memory + +From: Andrii Nakryiko + +commit 1d8006abaab4cb90f81add86e8d1bf9411add05a upstream. + +There is no compensating cgroup_bpf_put() for each ancestor cgroup in +cgroup_bpf_inherit(). If compute_effective_progs returns error, those cgroups +won't be freed ever. Fix it by putting them in cleanup code path. + +Fixes: e10360f815ca ("bpf: cgroup: prevent out-of-order release of cgroup bpf") +Signed-off-by: Andrii Nakryiko +Signed-off-by: Alexei Starovoitov +Acked-by: Roman Gushchin +Link: https://lore.kernel.org/bpf/20200309224017.1063297-1-andriin@fb.com +Signed-off-by: Greg Kroah-Hartman + +--- + kernel/bpf/cgroup.c | 3 +++ + 1 file changed, 3 insertions(+) + +--- a/kernel/bpf/cgroup.c ++++ b/kernel/bpf/cgroup.c +@@ -228,6 +228,9 @@ cleanup: + for (i = 0; i < NR; i++) + bpf_prog_array_free(arrays[i]); + ++ for (p = cgroup_parent(cgrp); p; p = cgroup_parent(p)) ++ cgroup_bpf_put(p); ++ + percpu_ref_exit(&cgrp->bpf.refcnt); + + return -ENOMEM; diff --git a/queue-5.5/genirq-fix-reference-leaks-on-irq-affinity-notifiers.patch b/queue-5.5/genirq-fix-reference-leaks-on-irq-affinity-notifiers.patch new file mode 100644 index 00000000000..dd44e4da20c --- /dev/null +++ b/queue-5.5/genirq-fix-reference-leaks-on-irq-affinity-notifiers.patch @@ -0,0 +1,60 @@ +From df81dfcfd6991d547653d46c051bac195cd182c1 Mon Sep 17 00:00:00 2001 +From: Edward Cree +Date: Fri, 13 Mar 2020 20:33:07 +0000 +Subject: genirq: Fix reference leaks on irq affinity notifiers + +From: Edward Cree + +commit df81dfcfd6991d547653d46c051bac195cd182c1 upstream. + +The handling of notify->work did not properly maintain notify->kref in two + cases: +1) where the work was already scheduled, another irq_set_affinity_locked() + would get the ref and (no-op-ly) schedule the work. Thus when + irq_affinity_notify() ran, it would drop the original ref but not the + additional one. +2) when cancelling the (old) work in irq_set_affinity_notifier(), if there + was outstanding work a ref had been got for it but was never put. +Fix both by checking the return values of the work handling functions + (schedule_work() for (1) and cancel_work_sync() for (2)) and put the + extra ref if the return value indicates preexisting work. + +Fixes: cd7eab44e994 ("genirq: Add IRQ affinity notifiers") +Fixes: 59c39840f5ab ("genirq: Prevent use-after-free and work list corruption") +Signed-off-by: Edward Cree +Signed-off-by: Thomas Gleixner +Acked-by: Ben Hutchings +Link: https://lkml.kernel.org/r/24f5983f-2ab5-e83a-44ee-a45b5f9300f5@solarflare.com +Signed-off-by: Greg Kroah-Hartman + +--- + kernel/irq/manage.c | 11 +++++++++-- + 1 file changed, 9 insertions(+), 2 deletions(-) + +--- a/kernel/irq/manage.c ++++ b/kernel/irq/manage.c +@@ -284,7 +284,11 @@ int irq_set_affinity_locked(struct irq_d + + if (desc->affinity_notify) { + kref_get(&desc->affinity_notify->kref); +- schedule_work(&desc->affinity_notify->work); ++ if (!schedule_work(&desc->affinity_notify->work)) { ++ /* Work was already scheduled, drop our extra ref */ ++ kref_put(&desc->affinity_notify->kref, ++ desc->affinity_notify->release); ++ } + } + irqd_set(data, IRQD_AFFINITY_SET); + +@@ -384,7 +388,10 @@ irq_set_affinity_notifier(unsigned int i + raw_spin_unlock_irqrestore(&desc->lock, flags); + + if (old_notify) { +- cancel_work_sync(&old_notify->work); ++ if (cancel_work_sync(&old_notify->work)) { ++ /* Pending work had a ref, put that one too */ ++ kref_put(&old_notify->kref, old_notify->release); ++ } + kref_put(&old_notify->kref, old_notify->release); + } + diff --git a/queue-5.5/gpiolib-acpi-add-quirk-to-ignore-ec-wakeups-on-hp-x2-10-byt-axp288-model.patch b/queue-5.5/gpiolib-acpi-add-quirk-to-ignore-ec-wakeups-on-hp-x2-10-byt-axp288-model.patch new file mode 100644 index 00000000000..f3cc76076aa --- /dev/null +++ b/queue-5.5/gpiolib-acpi-add-quirk-to-ignore-ec-wakeups-on-hp-x2-10-byt-axp288-model.patch @@ -0,0 +1,64 @@ +From 0e91506ba00730f088961a8d39f8693b0f8e3fea Mon Sep 17 00:00:00 2001 +From: Hans de Goede +Date: Mon, 2 Mar 2020 12:12:24 +0100 +Subject: gpiolib: acpi: Add quirk to ignore EC wakeups on HP x2 10 BYT + AXP288 model + +From: Hans de Goede + +commit 0e91506ba00730f088961a8d39f8693b0f8e3fea upstream. + +Commit aa23ca3d98f7 ("gpiolib: acpi: Add honor_wakeup module-option + +quirk mechanism") was added to deal with spurious wakeups on one specific +model of the HP x2 10 series. In the mean time I have learned that there +are at least 3 different HP x2 10 models: + +Bay Trail SoC + AXP288 PMIC +Cherry Trail SoC + AXP288 PMIC +Cherry Trail SoC + TI PMIC + +And the original quirk is only correct for (and only matches the) +Cherry Trail SoC + TI PMIC model. + +The Bay Trail SoC + AXP288 PMIC model has different DMI strings, has +the external EC interrupt on a different GPIO pin and only needs to ignore +wakeups on the EC interrupt, the INT0002 device works fine on this model. + +This commit adds an extra DMI based quirk for the HP x2 10 BYT + AXP288 +model, ignoring wakeups for ACPI GPIO events on the EC interrupt pin +on this model. This fixes spurious wakeups from suspend on this model. + +Fixes: aa23ca3d98f7 ("gpiolib: acpi: Add honor_wakeup module-option + quirk mechanism") +Signed-off-by: Hans de Goede +Link: https://lore.kernel.org/r/20200302111225.6641-3-hdegoede@redhat.com +Acked-by: Mika Westerberg +Signed-off-by: Linus Walleij +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/gpio/gpiolib-acpi.c | 15 +++++++++++++++ + 1 file changed, 15 insertions(+) + +--- a/drivers/gpio/gpiolib-acpi.c ++++ b/drivers/gpio/gpiolib-acpi.c +@@ -1422,6 +1422,21 @@ static const struct dmi_system_id gpioli + .ignore_wake = "INT33FF:01@0,INT0002:00@2", + }, + }, ++ { ++ /* ++ * HP X2 10 models with Bay Trail SoC + AXP288 PMIC use an ++ * external embedded-controller connected via I2C + an ACPI GPIO ++ * event handler on INT33FC:02 pin 28, causing spurious wakeups. ++ */ ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), ++ DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion x2 Detachable"), ++ DMI_MATCH(DMI_BOARD_NAME, "815D"), ++ }, ++ .driver_data = &(struct acpi_gpiolib_dmi_quirk) { ++ .ignore_wake = "INT33FC:02@28", ++ }, ++ }, + {} /* Terminating entry */ + }; + diff --git a/queue-5.5/gpiolib-acpi-correct-comment-for-hp-x2-10-honor_wakeup-quirk.patch b/queue-5.5/gpiolib-acpi-correct-comment-for-hp-x2-10-honor_wakeup-quirk.patch new file mode 100644 index 00000000000..4c57a33b17d --- /dev/null +++ b/queue-5.5/gpiolib-acpi-correct-comment-for-hp-x2-10-honor_wakeup-quirk.patch @@ -0,0 +1,72 @@ +From efaa87fa0947d525cf7c075316adde4e3ac7720b Mon Sep 17 00:00:00 2001 +From: Hans de Goede +Date: Mon, 2 Mar 2020 12:12:22 +0100 +Subject: gpiolib: acpi: Correct comment for HP x2 10 honor_wakeup quirk + +From: Hans de Goede + +commit efaa87fa0947d525cf7c075316adde4e3ac7720b upstream. + +Commit aa23ca3d98f7 ("gpiolib: acpi: Add honor_wakeup module-option + +quirk mechanism") added a quirk for some models of the HP x2 10 series. + +There are 2 issues with the comment describing the quirk: +1) The comment claims the DMI quirk applies to all Cherry Trail based HP x2 + 10 models. In the mean time I have learned that there are at least 3 + models of the HP x2 10 models: + + Bay Trail SoC + AXP288 PMIC + Cherry Trail SoC + AXP288 PMIC + Cherry Trail SoC + TI PMIC + + And this quirk's DMI matches only match the Cherry Trail SoC + TI PMIC + SoC, which is good because we want a slightly different quirk for the + others. This commit updates the comment to make it clear that the quirk + is only for the Cherry Trail SoC + TI PMIC models. + +2) The comment says that it is ok to disable wakeup on all ACPI GPIO event + handlers, because there is only the one for the embedded-controller + events. This is not true, there also is a handler for the special + INT0002 device which is related to USB wakeups. We need to also disable + wakeups on that one because the device turns of the USB-keyboard built + into the dock when closing the lid. The XHCI controller takes a while + to notice this, so it only notices it when already suspended, causing + a spurious wakeup because of this. So disabling wakeup on all handlers + is the right thing to do, but not because there only is the one handler + for the EC events. This commit updates the comment to correctly reflect + this. + +Fixes: aa23ca3d98f7 ("gpiolib: acpi: Add honor_wakeup module-option + quirk mechanism") +Signed-off-by: Hans de Goede +Link: https://lore.kernel.org/r/20200302111225.6641-1-hdegoede@redhat.com +Acked-by: Mika Westerberg +Signed-off-by: Linus Walleij +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/gpio/gpiolib-acpi.c | 14 ++++++++------ + 1 file changed, 8 insertions(+), 6 deletions(-) + +--- a/drivers/gpio/gpiolib-acpi.c ++++ b/drivers/gpio/gpiolib-acpi.c +@@ -1345,12 +1345,14 @@ static const struct dmi_system_id gpioli + }, + { + /* +- * Various HP X2 10 Cherry Trail models use an external +- * embedded-controller connected via I2C + an ACPI GPIO +- * event handler. The embedded controller generates various +- * spurious wakeup events when suspended. So disable wakeup +- * for its handler (it uses the only ACPI GPIO event handler). +- * This breaks wakeup when opening the lid, the user needs ++ * HP X2 10 models with Cherry Trail SoC + TI PMIC use an ++ * external embedded-controller connected via I2C + an ACPI GPIO ++ * event handler on INT33FF:01 pin 0, causing spurious wakeups. ++ * When suspending by closing the LID, the power to the USB ++ * keyboard is turned off, causing INT0002 ACPI events to ++ * trigger once the XHCI controller notices the keyboard is ++ * gone. So INT0002 events cause spurious wakeups too. Ignoring ++ * EC wakes breaks wakeup when opening the lid, the user needs + * to press the power-button to wakeup the system. The + * alternative is suspend simply not working, which is worse. + */ diff --git a/queue-5.5/gpiolib-acpi-rework-honor_wakeup-option-into-an-ignore_wake-option.patch b/queue-5.5/gpiolib-acpi-rework-honor_wakeup-option-into-an-ignore_wake-option.patch new file mode 100644 index 00000000000..2802700fd97 --- /dev/null +++ b/queue-5.5/gpiolib-acpi-rework-honor_wakeup-option-into-an-ignore_wake-option.patch @@ -0,0 +1,215 @@ +From 2ccb21f5516afef5e251184eeefbf36db90206d7 Mon Sep 17 00:00:00 2001 +From: Hans de Goede +Date: Mon, 2 Mar 2020 12:12:23 +0100 +Subject: gpiolib: acpi: Rework honor_wakeup option into an ignore_wake option + +From: Hans de Goede + +commit 2ccb21f5516afef5e251184eeefbf36db90206d7 upstream. + +Commit aa23ca3d98f7 ("gpiolib: acpi: Add honor_wakeup module-option + +quirk mechanism") was added to deal with spurious wakeups on one specific +model of the HP x2 10 series. + +The approach taken there was to add a bool controlling wakeup support for +all ACPI GPIO events. This was sufficient for the specific HP x2 10 model +the commit was trying to fix, but in the mean time other models have +turned up which need a similar workaround to avoid spurious wakeups from +suspend, but only for one of the pins on which the ACPI tables request +ACPI GPIO events. + +Since the honor_wakeup option was added to be able to ignore wake events, +the name was perhaps not the best, this commit renames it to ignore_wake +and changes it to a string with the following format: +gpiolib_acpi.ignore_wake=controller@pin[,controller@pin[,...]] + +This allows working around spurious wakeup issues on a per pin basis. + +This commit also reworks the existing quirk for the HP x2 10 so that +it functions as before. + +Note: +-This removes the honor_wakeup parameter. This has only been upstream for + a short time and to the best of my knowledge there are no users using + this module parameter. + +-The controller@pin[,controller@pin[,...]] syntax is based on an existing + kernel module parameter using the same controller@pin format. That version + uses ';' as separator, but in practice that is problematic because grub2 + cannot handle this without taking special care to escape the ';', so here + we are using a ',' as separator instead which does not have this issue. + +Fixes: aa23ca3d98f7 ("gpiolib: acpi: Add honor_wakeup module-option + quirk mechanism") +Signed-off-by: Hans de Goede +Link: https://lore.kernel.org/r/20200302111225.6641-2-hdegoede@redhat.com +Acked-by: Mika Westerberg +Reviewed-by: Andy Shevchenko +Signed-off-by: Linus Walleij +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/gpio/gpiolib-acpi.c | 96 ++++++++++++++++++++++++++++++++++---------- + 1 file changed, 76 insertions(+), 20 deletions(-) + +--- a/drivers/gpio/gpiolib-acpi.c ++++ b/drivers/gpio/gpiolib-acpi.c +@@ -21,18 +21,21 @@ + #include "gpiolib.h" + #include "gpiolib-acpi.h" + +-#define QUIRK_NO_EDGE_EVENTS_ON_BOOT 0x01l +-#define QUIRK_NO_WAKEUP 0x02l +- + static int run_edge_events_on_boot = -1; + module_param(run_edge_events_on_boot, int, 0444); + MODULE_PARM_DESC(run_edge_events_on_boot, + "Run edge _AEI event-handlers at boot: 0=no, 1=yes, -1=auto"); + +-static int honor_wakeup = -1; +-module_param(honor_wakeup, int, 0444); +-MODULE_PARM_DESC(honor_wakeup, +- "Honor the ACPI wake-capable flag: 0=no, 1=yes, -1=auto"); ++static char *ignore_wake; ++module_param(ignore_wake, charp, 0444); ++MODULE_PARM_DESC(ignore_wake, ++ "controller@pin combos on which to ignore the ACPI wake flag " ++ "ignore_wake=controller@pin[,controller@pin[,...]]"); ++ ++struct acpi_gpiolib_dmi_quirk { ++ bool no_edge_events_on_boot; ++ char *ignore_wake; ++}; + + /** + * struct acpi_gpio_event - ACPI GPIO event handler data +@@ -202,6 +205,57 @@ static void acpi_gpiochip_request_irqs(s + acpi_gpiochip_request_irq(acpi_gpio, event); + } + ++static bool acpi_gpio_in_ignore_list(const char *controller_in, int pin_in) ++{ ++ const char *controller, *pin_str; ++ int len, pin; ++ char *endp; ++ ++ controller = ignore_wake; ++ while (controller) { ++ pin_str = strchr(controller, '@'); ++ if (!pin_str) ++ goto err; ++ ++ len = pin_str - controller; ++ if (len == strlen(controller_in) && ++ strncmp(controller, controller_in, len) == 0) { ++ pin = simple_strtoul(pin_str + 1, &endp, 10); ++ if (*endp != 0 && *endp != ',') ++ goto err; ++ ++ if (pin == pin_in) ++ return true; ++ } ++ ++ controller = strchr(controller, ','); ++ if (controller) ++ controller++; ++ } ++ ++ return false; ++err: ++ pr_err_once("Error invalid value for gpiolib_acpi.ignore_wake: %s\n", ++ ignore_wake); ++ return false; ++} ++ ++static bool acpi_gpio_irq_is_wake(struct device *parent, ++ struct acpi_resource_gpio *agpio) ++{ ++ int pin = agpio->pin_table[0]; ++ ++ if (agpio->wake_capable != ACPI_WAKE_CAPABLE) ++ return false; ++ ++ if (acpi_gpio_in_ignore_list(dev_name(parent), pin)) { ++ dev_info(parent, "Ignoring wakeup on pin %d\n", pin); ++ return false; ++ } ++ ++ return true; ++} ++ + /* Always returns AE_OK so that we keep looping over the resources */ + static acpi_status acpi_gpiochip_alloc_event(struct acpi_resource *ares, + void *context) +@@ -289,7 +343,7 @@ static acpi_status acpi_gpiochip_alloc_e + event->handle = evt_handle; + event->handler = handler; + event->irq = irq; +- event->irq_is_wake = honor_wakeup && agpio->wake_capable == ACPI_WAKE_CAPABLE; ++ event->irq_is_wake = acpi_gpio_irq_is_wake(chip->parent, agpio); + event->pin = pin; + event->desc = desc; + +@@ -1328,7 +1382,9 @@ static const struct dmi_system_id gpioli + DMI_MATCH(DMI_SYS_VENDOR, "MINIX"), + DMI_MATCH(DMI_PRODUCT_NAME, "Z83-4"), + }, +- .driver_data = (void *)QUIRK_NO_EDGE_EVENTS_ON_BOOT, ++ .driver_data = &(struct acpi_gpiolib_dmi_quirk) { ++ .no_edge_events_on_boot = true, ++ }, + }, + { + /* +@@ -1341,7 +1397,9 @@ static const struct dmi_system_id gpioli + DMI_MATCH(DMI_SYS_VENDOR, "Wortmann_AG"), + DMI_MATCH(DMI_PRODUCT_NAME, "TERRA_PAD_1061"), + }, +- .driver_data = (void *)QUIRK_NO_EDGE_EVENTS_ON_BOOT, ++ .driver_data = &(struct acpi_gpiolib_dmi_quirk) { ++ .no_edge_events_on_boot = true, ++ }, + }, + { + /* +@@ -1360,33 +1418,31 @@ static const struct dmi_system_id gpioli + DMI_MATCH(DMI_SYS_VENDOR, "HP"), + DMI_MATCH(DMI_PRODUCT_NAME, "HP x2 Detachable 10-p0XX"), + }, +- .driver_data = (void *)QUIRK_NO_WAKEUP, ++ .driver_data = &(struct acpi_gpiolib_dmi_quirk) { ++ .ignore_wake = "INT33FF:01@0,INT0002:00@2", ++ }, + }, + {} /* Terminating entry */ + }; + + static int acpi_gpio_setup_params(void) + { ++ const struct acpi_gpiolib_dmi_quirk *quirk = NULL; + const struct dmi_system_id *id; +- long quirks = 0; + + id = dmi_first_match(gpiolib_acpi_quirks); + if (id) +- quirks = (long)id->driver_data; ++ quirk = id->driver_data; + + if (run_edge_events_on_boot < 0) { +- if (quirks & QUIRK_NO_EDGE_EVENTS_ON_BOOT) ++ if (quirk && quirk->no_edge_events_on_boot) + run_edge_events_on_boot = 0; + else + run_edge_events_on_boot = 1; + } + +- if (honor_wakeup < 0) { +- if (quirks & QUIRK_NO_WAKEUP) +- honor_wakeup = 0; +- else +- honor_wakeup = 1; +- } ++ if (ignore_wake == NULL && quirk && quirk->ignore_wake) ++ ignore_wake = quirk->ignore_wake; + + return 0; + } diff --git a/queue-5.5/ieee80211-fix-he-spr-size-calculation.patch b/queue-5.5/ieee80211-fix-he-spr-size-calculation.patch new file mode 100644 index 00000000000..8e2dfa4bad8 --- /dev/null +++ b/queue-5.5/ieee80211-fix-he-spr-size-calculation.patch @@ -0,0 +1,43 @@ +From 575a97acc3b7446094b0dcaf6285c7c6934c2477 Mon Sep 17 00:00:00 2001 +From: Johannes Berg +Date: Wed, 25 Mar 2020 09:09:19 +0100 +Subject: ieee80211: fix HE SPR size calculation + +From: Johannes Berg + +commit 575a97acc3b7446094b0dcaf6285c7c6934c2477 upstream. + +The he_sr_control field is just a u8, so le32_to_cpu() +shouldn't be applied to it; this was evidently copied +from ieee80211_he_oper_size(). Fix it, and also adjust +the type of the local variable. + +Fixes: ef11a931bd1c ("mac80211: HE: add Spatial Reuse element parsing support") +Signed-off-by: Johannes Berg +Link: https://lore.kernel.org/r/20200325090918.dfe483b49e06.Ia53622f23b2610a2ae6ea39a199866196fe946c1@changeid +Signed-off-by: Johannes Berg +Signed-off-by: Greg Kroah-Hartman + +--- + include/linux/ieee80211.h | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/include/linux/ieee80211.h ++++ b/include/linux/ieee80211.h +@@ -2102,14 +2102,14 @@ ieee80211_he_spr_size(const u8 *he_spr_i + { + struct ieee80211_he_spr *he_spr = (void *)he_spr_ie; + u8 spr_len = sizeof(struct ieee80211_he_spr); +- u32 he_spr_params; ++ u8 he_spr_params; + + /* Make sure the input is not NULL */ + if (!he_spr_ie) + return 0; + + /* Calc required length */ +- he_spr_params = le32_to_cpu(he_spr->he_sr_control); ++ he_spr_params = he_spr->he_sr_control; + if (he_spr_params & IEEE80211_HE_SPR_NON_SRG_OFFSET_PRESENT) + spr_len++; + if (he_spr_params & IEEE80211_HE_SPR_SRG_INFORMATION_PRESENT) diff --git a/queue-5.5/mac80211-set-ieee80211_tx_ctrl_port_ctrl_proto-for-nl80211-tx.patch b/queue-5.5/mac80211-set-ieee80211_tx_ctrl_port_ctrl_proto-for-nl80211-tx.patch new file mode 100644 index 00000000000..b4c81d470a9 --- /dev/null +++ b/queue-5.5/mac80211-set-ieee80211_tx_ctrl_port_ctrl_proto-for-nl80211-tx.patch @@ -0,0 +1,62 @@ +From b95d2ccd2ccb834394d50347d0e40dc38a954e4a Mon Sep 17 00:00:00 2001 +From: Johannes Berg +Date: Thu, 26 Mar 2020 15:53:34 +0100 +Subject: mac80211: set IEEE80211_TX_CTRL_PORT_CTRL_PROTO for nl80211 TX + +From: Johannes Berg + +commit b95d2ccd2ccb834394d50347d0e40dc38a954e4a upstream. + +When a frame is transmitted via the nl80211 TX rather than as a +normal frame, IEEE80211_TX_CTRL_PORT_CTRL_PROTO wasn't set and +this will lead to wrong decisions (rate control etc.) being made +about the frame; fix this. + +Fixes: 911806491425 ("mac80211: Add support for tx_control_port") +Signed-off-by: Johannes Berg +Link: https://lore.kernel.org/r/20200326155333.f183f52b02f0.I4054e2a8c11c2ddcb795a0103c87be3538690243@changeid +Signed-off-by: Johannes Berg +Signed-off-by: Greg Kroah-Hartman + +--- + net/mac80211/tx.c | 8 ++++++-- + 1 file changed, 6 insertions(+), 2 deletions(-) + +--- a/net/mac80211/tx.c ++++ b/net/mac80211/tx.c +@@ -5,7 +5,7 @@ + * Copyright 2006-2007 Jiri Benc + * Copyright 2007 Johannes Berg + * Copyright 2013-2014 Intel Mobile Communications GmbH +- * Copyright (C) 2018 Intel Corporation ++ * Copyright (C) 2018, 2020 Intel Corporation + * + * Transmit and frame generation functions. + */ +@@ -5135,6 +5135,7 @@ int ieee80211_tx_control_port(struct wip + struct ieee80211_local *local = sdata->local; + struct sk_buff *skb; + struct ethhdr *ehdr; ++ u32 ctrl_flags = 0; + u32 flags; + + /* Only accept CONTROL_PORT_PROTOCOL configured in CONNECT/ASSOCIATE +@@ -5144,6 +5145,9 @@ int ieee80211_tx_control_port(struct wip + proto != cpu_to_be16(ETH_P_PREAUTH)) + return -EINVAL; + ++ if (proto == sdata->control_port_protocol) ++ ctrl_flags |= IEEE80211_TX_CTRL_PORT_CTRL_PROTO; ++ + if (unencrypted) + flags = IEEE80211_TX_INTFL_DONT_ENCRYPT; + else +@@ -5169,7 +5173,7 @@ int ieee80211_tx_control_port(struct wip + skb_reset_mac_header(skb); + + local_bh_disable(); +- __ieee80211_subif_start_xmit(skb, skb->dev, flags, 0); ++ __ieee80211_subif_start_xmit(skb, skb->dev, flags, ctrl_flags); + local_bh_enable(); + + return 0; diff --git a/queue-5.5/netfilter-flowtable-fix-flushing-of-offloaded-flows-on-free.patch b/queue-5.5/netfilter-flowtable-fix-flushing-of-offloaded-flows-on-free.patch new file mode 100644 index 00000000000..e353c2ac847 --- /dev/null +++ b/queue-5.5/netfilter-flowtable-fix-flushing-of-offloaded-flows-on-free.patch @@ -0,0 +1,37 @@ +From c921ffe853332584eae4f5905cb2a14a7b3c9932 Mon Sep 17 00:00:00 2001 +From: Paul Blakey +Date: Thu, 19 Mar 2020 11:52:25 +0200 +Subject: netfilter: flowtable: Fix flushing of offloaded flows on free + +From: Paul Blakey + +commit c921ffe853332584eae4f5905cb2a14a7b3c9932 upstream. + +Freeing a flowtable with offloaded flows, the flow are deleted from +hardware but are not deleted from the flow table, leaking them, +and leaving their offload bit on. + +Add a second pass of the disabled gc to delete the these flows from +the flow table before freeing it. + +Fixes: c29f74e0df7a ("netfilter: nf_flow_table: hardware offload support") +Signed-off-by: Paul Blakey +Signed-off-by: Pablo Neira Ayuso +Signed-off-by: Greg Kroah-Hartman + +--- + net/netfilter/nf_flow_table_core.c | 3 +++ + 1 file changed, 3 insertions(+) + +--- a/net/netfilter/nf_flow_table_core.c ++++ b/net/netfilter/nf_flow_table_core.c +@@ -554,6 +554,9 @@ void nf_flow_table_free(struct nf_flowta + nf_flow_table_iterate(flow_table, nf_flow_table_do_cleanup, NULL); + nf_flow_table_iterate(flow_table, nf_flow_offload_gc_step, flow_table); + nf_flow_table_offload_flush(flow_table); ++ if (nf_flowtable_hw_offload(flow_table)) ++ nf_flow_table_iterate(flow_table, nf_flow_offload_gc_step, ++ flow_table); + rhashtable_destroy(&flow_table->rhashtable); + } + EXPORT_SYMBOL_GPL(nf_flow_table_free); diff --git a/queue-5.5/netfilter-flowtable-populate-addr_type-mask.patch b/queue-5.5/netfilter-flowtable-populate-addr_type-mask.patch new file mode 100644 index 00000000000..fe332394cd3 --- /dev/null +++ b/queue-5.5/netfilter-flowtable-populate-addr_type-mask.patch @@ -0,0 +1,31 @@ +From 15ff197237e76c4dab06b7b518afaa4ebb1c43e0 Mon Sep 17 00:00:00 2001 +From: Edward Cree +Date: Thu, 19 Mar 2020 19:37:21 +0000 +Subject: netfilter: flowtable: populate addr_type mask + +From: Edward Cree + +commit 15ff197237e76c4dab06b7b518afaa4ebb1c43e0 upstream. + +nf_flow_rule_match() sets control.addr_type in key, so needs to also set + the corresponding mask. An exact match is wanted, so mask is all ones. + +Fixes: c29f74e0df7a ("netfilter: nf_flow_table: hardware offload support") +Signed-off-by: Edward Cree +Signed-off-by: Pablo Neira Ayuso +Signed-off-by: Greg Kroah-Hartman + +--- + net/netfilter/nf_flow_table_offload.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/net/netfilter/nf_flow_table_offload.c ++++ b/net/netfilter/nf_flow_table_offload.c +@@ -87,6 +87,7 @@ static int nf_flow_rule_match(struct nf_ + default: + return -EOPNOTSUPP; + } ++ mask->control.addr_type = 0xffff; + match->dissector.used_keys |= BIT(key->control.addr_type); + mask->basic.n_proto = 0xffff; + diff --git a/queue-5.5/netfilter-flowtable-reload-ip-v6-h-in-nf_flow_tuple_ip-v6.patch b/queue-5.5/netfilter-flowtable-reload-ip-v6-h-in-nf_flow_tuple_ip-v6.patch new file mode 100644 index 00000000000..5c1120d9bb1 --- /dev/null +++ b/queue-5.5/netfilter-flowtable-reload-ip-v6-h-in-nf_flow_tuple_ip-v6.patch @@ -0,0 +1,40 @@ +From 41e9ec5a54f95eee1a57c8d26ab70e0492548c1b Mon Sep 17 00:00:00 2001 +From: Haishuang Yan +Date: Tue, 17 Mar 2020 10:02:53 +0800 +Subject: netfilter: flowtable: reload ip{v6}h in nf_flow_tuple_ip{v6} + +From: Haishuang Yan + +commit 41e9ec5a54f95eee1a57c8d26ab70e0492548c1b upstream. + +Since pskb_may_pull may change skb->data, so we need to reload ip{v6}h at +the right place. + +Fixes: a908fdec3dda ("netfilter: nf_flow_table: move ipv6 offload hook code to nf_flow_table") +Fixes: 7d2086871762 ("netfilter: nf_flow_table: move ipv4 offload hook code to nf_flow_table") +Signed-off-by: Haishuang Yan +Signed-off-by: Pablo Neira Ayuso +Signed-off-by: Greg Kroah-Hartman + +--- + net/netfilter/nf_flow_table_ip.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/net/netfilter/nf_flow_table_ip.c ++++ b/net/netfilter/nf_flow_table_ip.c +@@ -189,6 +189,7 @@ static int nf_flow_tuple_ip(struct sk_bu + if (!pskb_may_pull(skb, thoff + sizeof(*ports))) + return -1; + ++ iph = ip_hdr(skb); + ports = (struct flow_ports *)(skb_network_header(skb) + thoff); + + tuple->src_v4.s_addr = iph->saddr; +@@ -449,6 +450,7 @@ static int nf_flow_tuple_ipv6(struct sk_ + if (!pskb_may_pull(skb, thoff + sizeof(*ports))) + return -1; + ++ ip6h = ipv6_hdr(skb); + ports = (struct flow_ports *)(skb_network_header(skb) + thoff); + + tuple->src_v6 = ip6h->saddr; diff --git a/queue-5.5/netfilter-nft_fwd_netdev-allow-to-redirect-to-ifb-via-ingress.patch b/queue-5.5/netfilter-nft_fwd_netdev-allow-to-redirect-to-ifb-via-ingress.patch new file mode 100644 index 00000000000..529630df410 --- /dev/null +++ b/queue-5.5/netfilter-nft_fwd_netdev-allow-to-redirect-to-ifb-via-ingress.patch @@ -0,0 +1,38 @@ +From bcfabee1afd99484b6ba067361b8678e28bbc065 Mon Sep 17 00:00:00 2001 +From: Pablo Neira Ayuso +Date: Mon, 23 Mar 2020 19:53:10 +0100 +Subject: netfilter: nft_fwd_netdev: allow to redirect to ifb via ingress + +From: Pablo Neira Ayuso + +commit bcfabee1afd99484b6ba067361b8678e28bbc065 upstream. + +Set skb->tc_redirected to 1, otherwise the ifb driver drops the packet. +Set skb->tc_from_ingress to 1 to reinject the packet back to the ingress +path after leaving the ifb egress path. + +This patch inconditionally sets on these two skb fields that are +meaningful to the ifb driver. The existing forward action is guaranteed +to run from ingress path. + +Fixes: 39e6dea28adc ("netfilter: nf_tables: add forward expression to the netdev family") +Signed-off-by: Pablo Neira Ayuso +Signed-off-by: Greg Kroah-Hartman + +--- + net/netfilter/nft_fwd_netdev.c | 4 ++++ + 1 file changed, 4 insertions(+) + +--- a/net/netfilter/nft_fwd_netdev.c ++++ b/net/netfilter/nft_fwd_netdev.c +@@ -28,6 +28,10 @@ static void nft_fwd_netdev_eval(const st + struct nft_fwd_netdev *priv = nft_expr_priv(expr); + int oif = regs->data[priv->sreg_dev]; + ++ /* These are used by ifb only. */ ++ pkt->skb->tc_redirected = 1; ++ pkt->skb->tc_from_ingress = 1; ++ + nf_fwd_netdev_egress(pkt, oif); + regs->verdict.code = NF_STOLEN; + } diff --git a/queue-5.5/netfilter-nft_fwd_netdev-validate-family-and-chain-type.patch b/queue-5.5/netfilter-nft_fwd_netdev-validate-family-and-chain-type.patch new file mode 100644 index 00000000000..17b76ca0242 --- /dev/null +++ b/queue-5.5/netfilter-nft_fwd_netdev-validate-family-and-chain-type.patch @@ -0,0 +1,51 @@ +From 76a109fac206e158eb3c967af98c178cff738e6a Mon Sep 17 00:00:00 2001 +From: Pablo Neira Ayuso +Date: Mon, 23 Mar 2020 14:27:16 +0100 +Subject: netfilter: nft_fwd_netdev: validate family and chain type + +From: Pablo Neira Ayuso + +commit 76a109fac206e158eb3c967af98c178cff738e6a upstream. + +Make sure the forward action is only used from ingress. + +Fixes: 39e6dea28adc ("netfilter: nf_tables: add forward expression to the netdev family") +Signed-off-by: Pablo Neira Ayuso +Signed-off-by: Greg Kroah-Hartman + +--- + net/netfilter/nft_fwd_netdev.c | 9 +++++++++ + 1 file changed, 9 insertions(+) + +--- a/net/netfilter/nft_fwd_netdev.c ++++ b/net/netfilter/nft_fwd_netdev.c +@@ -190,6 +190,13 @@ nla_put_failure: + return -1; + } + ++static int nft_fwd_validate(const struct nft_ctx *ctx, ++ const struct nft_expr *expr, ++ const struct nft_data **data) ++{ ++ return nft_chain_validate_hooks(ctx->chain, (1 << NF_NETDEV_INGRESS)); ++} ++ + static struct nft_expr_type nft_fwd_netdev_type; + static const struct nft_expr_ops nft_fwd_neigh_netdev_ops = { + .type = &nft_fwd_netdev_type, +@@ -197,6 +204,7 @@ static const struct nft_expr_ops nft_fwd + .eval = nft_fwd_neigh_eval, + .init = nft_fwd_neigh_init, + .dump = nft_fwd_neigh_dump, ++ .validate = nft_fwd_validate, + }; + + static const struct nft_expr_ops nft_fwd_netdev_ops = { +@@ -205,6 +213,7 @@ static const struct nft_expr_ops nft_fwd + .eval = nft_fwd_netdev_eval, + .init = nft_fwd_netdev_init, + .dump = nft_fwd_netdev_dump, ++ .validate = nft_fwd_validate, + .offload = nft_fwd_netdev_offload, + }; + diff --git a/queue-5.5/rdma-core-ensure-security-pkey-modify-is-not-lost.patch b/queue-5.5/rdma-core-ensure-security-pkey-modify-is-not-lost.patch new file mode 100644 index 00000000000..173e3f0bbb1 --- /dev/null +++ b/queue-5.5/rdma-core-ensure-security-pkey-modify-is-not-lost.patch @@ -0,0 +1,75 @@ +From 2d47fbacf2725a67869f4d3634c2415e7dfab2f4 Mon Sep 17 00:00:00 2001 +From: Mike Marciniszyn +Date: Fri, 13 Mar 2020 08:47:05 -0400 +Subject: RDMA/core: Ensure security pkey modify is not lost + +From: Mike Marciniszyn + +commit 2d47fbacf2725a67869f4d3634c2415e7dfab2f4 upstream. + +The following modify sequence (loosely based on ipoib) will lose a pkey +modifcation: + +- Modify (pkey index, port) +- Modify (new pkey index, NO port) + +After the first modify, the qp_pps list will have saved the pkey and the +unit on the main list. + +During the second modify, get_new_pps() will fetch the port from qp_pps +and read the new pkey index from qp_attr->pkey_index. The state will +still be zero, or IB_PORT_PKEY_NOT_VALID. Because of the invalid state, +the new values will never replace the one in the qp pps list, losing the +new pkey. + +This happens because the following if statements will never correct the +state because the first term will be false. If the code had been executed, +it would incorrectly overwrite valid values. + + if ((qp_attr_mask & IB_QP_PKEY_INDEX) && (qp_attr_mask & IB_QP_PORT)) + new_pps->main.state = IB_PORT_PKEY_VALID; + + if (!(qp_attr_mask & (IB_QP_PKEY_INDEX | IB_QP_PORT)) && qp_pps) { + new_pps->main.port_num = qp_pps->main.port_num; + new_pps->main.pkey_index = qp_pps->main.pkey_index; + if (qp_pps->main.state != IB_PORT_PKEY_NOT_VALID) + new_pps->main.state = IB_PORT_PKEY_VALID; + } + +Fix by joining the two if statements with an or test to see if qp_pps is +non-NULL and in the correct state. + +Fixes: 1dd017882e01 ("RDMA/core: Fix protection fault in get_pkey_idx_qp_list") +Link: https://lore.kernel.org/r/20200313124704.14982.55907.stgit@awfm-01.aw.intel.com +Reviewed-by: Kaike Wan +Signed-off-by: Mike Marciniszyn +Reviewed-by: Leon Romanovsky +Signed-off-by: Jason Gunthorpe +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/infiniband/core/security.c | 11 +++-------- + 1 file changed, 3 insertions(+), 8 deletions(-) + +--- a/drivers/infiniband/core/security.c ++++ b/drivers/infiniband/core/security.c +@@ -349,16 +349,11 @@ static struct ib_ports_pkeys *get_new_pp + else if (qp_pps) + new_pps->main.pkey_index = qp_pps->main.pkey_index; + +- if ((qp_attr_mask & IB_QP_PKEY_INDEX) && (qp_attr_mask & IB_QP_PORT)) ++ if (((qp_attr_mask & IB_QP_PKEY_INDEX) && ++ (qp_attr_mask & IB_QP_PORT)) || ++ (qp_pps && qp_pps->main.state != IB_PORT_PKEY_NOT_VALID)) + new_pps->main.state = IB_PORT_PKEY_VALID; + +- if (!(qp_attr_mask & (IB_QP_PKEY_INDEX | IB_QP_PORT)) && qp_pps) { +- new_pps->main.port_num = qp_pps->main.port_num; +- new_pps->main.pkey_index = qp_pps->main.pkey_index; +- if (qp_pps->main.state != IB_PORT_PKEY_NOT_VALID) +- new_pps->main.state = IB_PORT_PKEY_VALID; +- } +- + if (qp_attr_mask & IB_QP_ALT_PATH) { + new_pps->alt.port_num = qp_attr->alt_port_num; + new_pps->alt.pkey_index = qp_attr->alt_pkey_index; diff --git a/queue-5.5/rdma-mlx5-block-delay-drop-to-unprivileged-users.patch b/queue-5.5/rdma-mlx5-block-delay-drop-to-unprivileged-users.patch new file mode 100644 index 00000000000..326c496e679 --- /dev/null +++ b/queue-5.5/rdma-mlx5-block-delay-drop-to-unprivileged-users.patch @@ -0,0 +1,36 @@ +From ba80013fba656b9830ef45cd40a6a1e44707f47a Mon Sep 17 00:00:00 2001 +From: Maor Gottlieb +Date: Sun, 22 Mar 2020 14:49:06 +0200 +Subject: RDMA/mlx5: Block delay drop to unprivileged users + +From: Maor Gottlieb + +commit ba80013fba656b9830ef45cd40a6a1e44707f47a upstream. + +It has been discovered that this feature can globally block the RX port, +so it should be allowed for highly privileged users only. + +Fixes: 03404e8ae652("IB/mlx5: Add support to dropless RQ") +Link: https://lore.kernel.org/r/20200322124906.1173790-1-leon@kernel.org +Signed-off-by: Maor Gottlieb +Signed-off-by: Leon Romanovsky +Signed-off-by: Jason Gunthorpe +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/infiniband/hw/mlx5/qp.c | 4 ++++ + 1 file changed, 4 insertions(+) + +--- a/drivers/infiniband/hw/mlx5/qp.c ++++ b/drivers/infiniband/hw/mlx5/qp.c +@@ -6158,6 +6158,10 @@ struct ib_wq *mlx5_ib_create_wq(struct i + if (udata->outlen && udata->outlen < min_resp_len) + return ERR_PTR(-EINVAL); + ++ if (!capable(CAP_SYS_RAWIO) && ++ init_attr->create_flags & IB_WQ_FLAGS_DELAY_DROP) ++ return ERR_PTR(-EPERM); ++ + dev = to_mdev(pd->device); + switch (init_attr->wq_type) { + case IB_WQT_RQ: diff --git a/queue-5.5/rdma-mlx5-fix-access-to-wrong-pointer-while-performing-flush-due-to-error.patch b/queue-5.5/rdma-mlx5-fix-access-to-wrong-pointer-while-performing-flush-due-to-error.patch new file mode 100644 index 00000000000..3e32fa3d2ea --- /dev/null +++ b/queue-5.5/rdma-mlx5-fix-access-to-wrong-pointer-while-performing-flush-due-to-error.patch @@ -0,0 +1,130 @@ +From 950bf4f17725556bbc773a5b71e88a6c14c9ff25 Mon Sep 17 00:00:00 2001 +From: Leon Romanovsky +Date: Wed, 18 Mar 2020 11:16:40 +0200 +Subject: RDMA/mlx5: Fix access to wrong pointer while performing flush due to error + +From: Leon Romanovsky + +commit 950bf4f17725556bbc773a5b71e88a6c14c9ff25 upstream. + +The main difference between send and receive SW completions is related to +separate treatment of WQ queue. For receive completions, the initial index +to be flushed is stored in "tail", while for send completions, it is in +deleted "last_poll". + + CPU: 54 PID: 53405 Comm: kworker/u161:0 Kdump: loaded Tainted: G OE --------- -t - 4.18.0-147.el8.ppc64le #1 + Workqueue: ib-comp-unb-wq ib_cq_poll_work [ib_core] + NIP: c000003c7c00a000 LR: c00800000e586af4 CTR: c000003c7c00a000 + REGS: c0000036cc9db940 TRAP: 0400 Tainted: G OE --------- -t - (4.18.0-147.el8.ppc64le) + MSR: 9000000010009033 CR: 24004488 XER: 20040000 + CFAR: c00800000e586af0 IRQMASK: 0 + GPR00: c00800000e586ab4 c0000036cc9dbbc0 c00800000e5f1a00 c0000037d8433800 + GPR04: c000003895a26800 c0000037293f2000 0000000000000201 0000000000000011 + GPR08: c000003895a26c80 c000003c7c00a000 0000000000000000 c00800000ed30438 + GPR12: c000003c7c00a000 c000003fff684b80 c00000000017c388 c00000396ec4be40 + GPR16: 0000000000000000 0000000000000000 0000000000000000 0000000000000000 + GPR20: c00000000151e498 0000000000000010 c000003895a26848 0000000000000010 + GPR24: 0000000000000010 0000000000010000 c000003895a26800 0000000000000000 + GPR28: 0000000000000010 c0000037d8433800 c000003895a26c80 c000003895a26800 + NIP [c000003c7c00a000] 0xc000003c7c00a000 + LR [c00800000e586af4] __ib_process_cq+0xec/0x1b0 [ib_core] + Call Trace: + [c0000036cc9dbbc0] [c00800000e586ab4] __ib_process_cq+0xac/0x1b0 [ib_core] (unreliable) + [c0000036cc9dbc40] [c00800000e586c88] ib_cq_poll_work+0x40/0xb0 [ib_core] + [c0000036cc9dbc70] [c000000000171f44] process_one_work+0x2f4/0x5c0 + [c0000036cc9dbd10] [c000000000172a0c] worker_thread+0xcc/0x760 + [c0000036cc9dbdc0] [c00000000017c52c] kthread+0x1ac/0x1c0 + [c0000036cc9dbe30] [c00000000000b75c] ret_from_kernel_thread+0x5c/0x80 + +Fixes: 8e3b68830186 ("RDMA/mlx5: Delete unreachable handle_atomic code by simplifying SW completion") +Link: https://lore.kernel.org/r/20200318091640.44069-1-leon@kernel.org +Signed-off-by: Leon Romanovsky +Signed-off-by: Jason Gunthorpe +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/infiniband/hw/mlx5/cq.c | 27 +++++++++++++++++++++++++-- + drivers/infiniband/hw/mlx5/mlx5_ib.h | 1 + + drivers/infiniband/hw/mlx5/qp.c | 1 + + 3 files changed, 27 insertions(+), 2 deletions(-) + +--- a/drivers/infiniband/hw/mlx5/cq.c ++++ b/drivers/infiniband/hw/mlx5/cq.c +@@ -330,6 +330,22 @@ static void mlx5_handle_error_cqe(struct + dump_cqe(dev, cqe); + } + ++static void handle_atomics(struct mlx5_ib_qp *qp, struct mlx5_cqe64 *cqe64, ++ u16 tail, u16 head) ++{ ++ u16 idx; ++ ++ do { ++ idx = tail & (qp->sq.wqe_cnt - 1); ++ if (idx == head) ++ break; ++ ++ tail = qp->sq.w_list[idx].next; ++ } while (1); ++ tail = qp->sq.w_list[idx].next; ++ qp->sq.last_poll = tail; ++} ++ + static void free_cq_buf(struct mlx5_ib_dev *dev, struct mlx5_ib_cq_buf *buf) + { + mlx5_frag_buf_free(dev->mdev, &buf->frag_buf); +@@ -368,7 +384,7 @@ static void get_sig_err_item(struct mlx5 + } + + static void sw_comp(struct mlx5_ib_qp *qp, int num_entries, struct ib_wc *wc, +- int *npolled, int is_send) ++ int *npolled, bool is_send) + { + struct mlx5_ib_wq *wq; + unsigned int cur; +@@ -383,10 +399,16 @@ static void sw_comp(struct mlx5_ib_qp *q + return; + + for (i = 0; i < cur && np < num_entries; i++) { +- wc->wr_id = wq->wrid[wq->tail & (wq->wqe_cnt - 1)]; ++ unsigned int idx; ++ ++ idx = (is_send) ? wq->last_poll : wq->tail; ++ idx &= (wq->wqe_cnt - 1); ++ wc->wr_id = wq->wrid[idx]; + wc->status = IB_WC_WR_FLUSH_ERR; + wc->vendor_err = MLX5_CQE_SYNDROME_WR_FLUSH_ERR; + wq->tail++; ++ if (is_send) ++ wq->last_poll = wq->w_list[idx].next; + np++; + wc->qp = &qp->ibqp; + wc++; +@@ -473,6 +495,7 @@ repoll: + wqe_ctr = be16_to_cpu(cqe64->wqe_counter); + idx = wqe_ctr & (wq->wqe_cnt - 1); + handle_good_req(wc, cqe64, wq, idx); ++ handle_atomics(*cur_qp, cqe64, wq->last_poll, idx); + wc->wr_id = wq->wrid[idx]; + wq->tail = wq->wqe_head[idx] + 1; + wc->status = IB_WC_SUCCESS; +--- a/drivers/infiniband/hw/mlx5/mlx5_ib.h ++++ b/drivers/infiniband/hw/mlx5/mlx5_ib.h +@@ -282,6 +282,7 @@ struct mlx5_ib_wq { + unsigned head; + unsigned tail; + u16 cur_post; ++ u16 last_poll; + void *cur_edge; + }; + +--- a/drivers/infiniband/hw/mlx5/qp.c ++++ b/drivers/infiniband/hw/mlx5/qp.c +@@ -3728,6 +3728,7 @@ static int __mlx5_ib_modify_qp(struct ib + qp->sq.cur_post = 0; + if (qp->sq.wqe_cnt) + qp->sq.cur_edge = get_sq_edge(&qp->sq, 0); ++ qp->sq.last_poll = 0; + qp->db.db[MLX5_RCV_DBR] = 0; + qp->db.db[MLX5_SND_DBR] = 0; + } diff --git a/queue-5.5/rdma-mlx5-fix-the-number-of-hwcounters-of-a-dynamic-counter.patch b/queue-5.5/rdma-mlx5-fix-the-number-of-hwcounters-of-a-dynamic-counter.patch new file mode 100644 index 00000000000..3cc129649f2 --- /dev/null +++ b/queue-5.5/rdma-mlx5-fix-the-number-of-hwcounters-of-a-dynamic-counter.patch @@ -0,0 +1,90 @@ +From ec16b6bbdab1ce2b03f46271460efc7f450658cd Mon Sep 17 00:00:00 2001 +From: Mark Zhang +Date: Thu, 5 Mar 2020 14:40:52 +0200 +Subject: RDMA/mlx5: Fix the number of hwcounters of a dynamic counter + +From: Mark Zhang + +commit ec16b6bbdab1ce2b03f46271460efc7f450658cd upstream. + +When we read the global counter and there's any dynamic counter allocated, +the value of a hwcounter is the sum of the default counter and all dynamic +counters. So the number of hwcounters of a dynamically allocated counter +must be same as of the default counter, otherwise there will be read +violations. + +This fixes the KASAN slab-out-of-bounds bug: + + BUG: KASAN: slab-out-of-bounds in rdma_counter_get_hwstat_value+0x36d/0x390 [ib_core] + Read of size 8 at addr ffff8884192a5778 by task rdma/10138 + + CPU: 7 PID: 10138 Comm: rdma Not tainted 5.5.0-for-upstream-dbg-2020-02-06_18-30-19-27 #1 + Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS rel-1.12.1-0-ga5cab58e9a3f-prebuilt.qemu.org 04/01/2014 + Call Trace: + dump_stack+0xb7/0x10b + print_address_description.constprop.4+0x1e2/0x400 + ? rdma_counter_get_hwstat_value+0x36d/0x390 [ib_core] + __kasan_report+0x15c/0x1e0 + ? mlx5_ib_query_q_counters+0x13f/0x270 [mlx5_ib] + ? rdma_counter_get_hwstat_value+0x36d/0x390 [ib_core] + kasan_report+0xe/0x20 + rdma_counter_get_hwstat_value+0x36d/0x390 [ib_core] + ? rdma_counter_query_stats+0xd0/0xd0 [ib_core] + ? memcpy+0x34/0x50 + ? nla_put+0xe2/0x170 + nldev_stat_get_doit+0x9c7/0x14f0 [ib_core] + ... + do_syscall_64+0x95/0x490 + entry_SYSCALL_64_after_hwframe+0x49/0xbe + RIP: 0033:0x7fcc457fe65a + Code: bb 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 44 00 00 8b 05 fa f1 2b 00 45 89 c9 4c 63 d1 48 63 ff 85 c0 75 15 b8 2c 00 00 00 0f 05 <48> 3d 00 f0 ff ff 77 76 f3 c3 0f 1f 40 00 41 55 41 54 4d 89 c5 55 + RSP: 002b:00007ffc0586f868 EFLAGS: 00000246 ORIG_RAX: 000000000000002c + RAX: ffffffffffffffda RBX: 0000000000000000 RCX: 00007fcc457fe65a + RDX: 0000000000000020 RSI: 00000000013db920 RDI: 0000000000000003 + RBP: 00007ffc0586fa90 R08: 00007fcc45ac10e0 R09: 000000000000000c + R10: 0000000000000000 R11: 0000000000000246 R12: 00000000004089c0 + R13: 0000000000000000 R14: 00007ffc0586fab0 R15: 00000000013dc9a0 + + Allocated by task 9700: + save_stack+0x19/0x80 + __kasan_kmalloc.constprop.7+0xa0/0xd0 + mlx5_ib_counter_alloc_stats+0xd1/0x1d0 [mlx5_ib] + rdma_counter_alloc+0x16d/0x3f0 [ib_core] + rdma_counter_bind_qpn_alloc+0x216/0x4e0 [ib_core] + nldev_stat_set_doit+0x8c2/0xb10 [ib_core] + rdma_nl_rcv_msg+0x3d2/0x730 [ib_core] + rdma_nl_rcv+0x2a8/0x400 [ib_core] + netlink_unicast+0x448/0x620 + netlink_sendmsg+0x731/0xd10 + sock_sendmsg+0xb1/0xf0 + __sys_sendto+0x25d/0x2c0 + __x64_sys_sendto+0xdd/0x1b0 + do_syscall_64+0x95/0x490 + entry_SYSCALL_64_after_hwframe+0x49/0xbe + +Fixes: 18d422ce8ccf ("IB/mlx5: Add counter_alloc_stats() and counter_update_stats() support") +Link: https://lore.kernel.org/r/20200305124052.196688-1-leon@kernel.org +Signed-off-by: Mark Zhang +Signed-off-by: Leon Romanovsky +Signed-off-by: Jason Gunthorpe +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/infiniband/hw/mlx5/main.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +--- a/drivers/infiniband/hw/mlx5/main.c ++++ b/drivers/infiniband/hw/mlx5/main.c +@@ -5666,9 +5666,10 @@ mlx5_ib_counter_alloc_stats(struct rdma_ + const struct mlx5_ib_counters *cnts = + get_counters(dev, counter->port - 1); + +- /* Q counters are in the beginning of all counters */ + return rdma_alloc_hw_stats_struct(cnts->names, +- cnts->num_q_counters, ++ cnts->num_q_counters + ++ cnts->num_cong_counters + ++ cnts->num_ext_ppcnt_counters, + RDMA_HW_STATS_DEFAULT_LIFESPAN); + } + diff --git a/queue-5.5/series b/queue-5.5/series index 9f067439184..87728c986bd 100644 --- a/queue-5.5/series +++ b/queue-5.5/series @@ -112,3 +112,28 @@ mm-swapfile.c-move-inode_lock-out-of-claim_swapfile.patch drivers-base-memory.c-indicate-all-memory-blocks-as-removable.patch mm-sparse-fix-kernel-crash-with-pfn_section_valid-check.patch mm-fork-fix-kernel_stack-memcg-stats-for-various-stack-implementations.patch +gpiolib-acpi-correct-comment-for-hp-x2-10-honor_wakeup-quirk.patch +gpiolib-acpi-rework-honor_wakeup-option-into-an-ignore_wake-option.patch +gpiolib-acpi-add-quirk-to-ignore-ec-wakeups-on-hp-x2-10-byt-axp288-model.patch +bpf-fix-cgroup-ref-leak-in-cgroup_bpf_inherit-on-out-of-memory.patch +rdma-core-ensure-security-pkey-modify-is-not-lost.patch +afs-fix-handling-of-an-abort-from-a-service-handler.patch +genirq-fix-reference-leaks-on-irq-affinity-notifiers.patch +xfrm-handle-netdev_unregister-for-xfrm-device.patch +vti-fix-packet-tx-through-bpf_redirect-in-xiny-cases.patch +rdma-mlx5-fix-the-number-of-hwcounters-of-a-dynamic-counter.patch +rdma-mlx5-fix-access-to-wrong-pointer-while-performing-flush-due-to-error.patch +rdma-mlx5-block-delay-drop-to-unprivileged-users.patch +xfrm-fix-uctx-len-check-in-verify_sec_ctx_len.patch +xfrm-add-the-missing-verify_sec_ctx_len-check-in-xfrm_add_acquire.patch +xfrm-policy-fix-doulbe-free-in-xfrm_policy_timer.patch +afs-fix-client-call-rx-phase-signal-handling.patch +afs-fix-some-tracing-details.patch +afs-fix-unpinned-address-list-during-probing.patch +ieee80211-fix-he-spr-size-calculation.patch +mac80211-set-ieee80211_tx_ctrl_port_ctrl_proto-for-nl80211-tx.patch +netfilter-flowtable-reload-ip-v6-h-in-nf_flow_tuple_ip-v6.patch +netfilter-flowtable-fix-flushing-of-offloaded-flows-on-free.patch +netfilter-flowtable-populate-addr_type-mask.patch +netfilter-nft_fwd_netdev-validate-family-and-chain-type.patch +netfilter-nft_fwd_netdev-allow-to-redirect-to-ifb-via-ingress.patch diff --git a/queue-5.5/vti-fix-packet-tx-through-bpf_redirect-in-xiny-cases.patch b/queue-5.5/vti-fix-packet-tx-through-bpf_redirect-in-xiny-cases.patch new file mode 100644 index 00000000000..2736eb7eeeb --- /dev/null +++ b/queue-5.5/vti-fix-packet-tx-through-bpf_redirect-in-xiny-cases.patch @@ -0,0 +1,124 @@ +From f1ed10264ed6b66b9cd5e8461cffce69be482356 Mon Sep 17 00:00:00 2001 +From: Nicolas Dichtel +Date: Tue, 4 Feb 2020 17:00:27 +0100 +Subject: vti[6]: fix packet tx through bpf_redirect() in XinY cases + +From: Nicolas Dichtel + +commit f1ed10264ed6b66b9cd5e8461cffce69be482356 upstream. + +I forgot the 4in6/6in4 cases in my previous patch. Let's fix them. + +Fixes: 95224166a903 ("vti[6]: fix packet tx through bpf_redirect()") +Signed-off-by: Nicolas Dichtel +Signed-off-by: Steffen Klassert +Signed-off-by: Greg Kroah-Hartman + +--- + net/ipv4/Kconfig | 1 + + net/ipv4/ip_vti.c | 36 +++++++++++++++++++++++++++++------- + net/ipv6/ip6_vti.c | 32 +++++++++++++++++++++++++------- + 3 files changed, 55 insertions(+), 14 deletions(-) + +--- a/net/ipv4/Kconfig ++++ b/net/ipv4/Kconfig +@@ -303,6 +303,7 @@ config SYN_COOKIES + + config NET_IPVTI + tristate "Virtual (secure) IP: tunneling" ++ depends on IPV6 || IPV6=n + select INET_TUNNEL + select NET_IP_TUNNEL + select XFRM +--- a/net/ipv4/ip_vti.c ++++ b/net/ipv4/ip_vti.c +@@ -187,17 +187,39 @@ static netdev_tx_t vti_xmit(struct sk_bu + int mtu; + + if (!dst) { +- struct rtable *rt; ++ switch (skb->protocol) { ++ case htons(ETH_P_IP): { ++ struct rtable *rt; + +- fl->u.ip4.flowi4_oif = dev->ifindex; +- fl->u.ip4.flowi4_flags |= FLOWI_FLAG_ANYSRC; +- rt = __ip_route_output_key(dev_net(dev), &fl->u.ip4); +- if (IS_ERR(rt)) { ++ fl->u.ip4.flowi4_oif = dev->ifindex; ++ fl->u.ip4.flowi4_flags |= FLOWI_FLAG_ANYSRC; ++ rt = __ip_route_output_key(dev_net(dev), &fl->u.ip4); ++ if (IS_ERR(rt)) { ++ dev->stats.tx_carrier_errors++; ++ goto tx_error_icmp; ++ } ++ dst = &rt->dst; ++ skb_dst_set(skb, dst); ++ break; ++ } ++#if IS_ENABLED(CONFIG_IPV6) ++ case htons(ETH_P_IPV6): ++ fl->u.ip6.flowi6_oif = dev->ifindex; ++ fl->u.ip6.flowi6_flags |= FLOWI_FLAG_ANYSRC; ++ dst = ip6_route_output(dev_net(dev), NULL, &fl->u.ip6); ++ if (dst->error) { ++ dst_release(dst); ++ dst = NULL; ++ dev->stats.tx_carrier_errors++; ++ goto tx_error_icmp; ++ } ++ skb_dst_set(skb, dst); ++ break; ++#endif ++ default: + dev->stats.tx_carrier_errors++; + goto tx_error_icmp; + } +- dst = &rt->dst; +- skb_dst_set(skb, dst); + } + + dst_hold(dst); +--- a/net/ipv6/ip6_vti.c ++++ b/net/ipv6/ip6_vti.c +@@ -450,15 +450,33 @@ vti6_xmit(struct sk_buff *skb, struct ne + int mtu; + + if (!dst) { +- fl->u.ip6.flowi6_oif = dev->ifindex; +- fl->u.ip6.flowi6_flags |= FLOWI_FLAG_ANYSRC; +- dst = ip6_route_output(dev_net(dev), NULL, &fl->u.ip6); +- if (dst->error) { +- dst_release(dst); +- dst = NULL; ++ switch (skb->protocol) { ++ case htons(ETH_P_IP): { ++ struct rtable *rt; ++ ++ fl->u.ip4.flowi4_oif = dev->ifindex; ++ fl->u.ip4.flowi4_flags |= FLOWI_FLAG_ANYSRC; ++ rt = __ip_route_output_key(dev_net(dev), &fl->u.ip4); ++ if (IS_ERR(rt)) ++ goto tx_err_link_failure; ++ dst = &rt->dst; ++ skb_dst_set(skb, dst); ++ break; ++ } ++ case htons(ETH_P_IPV6): ++ fl->u.ip6.flowi6_oif = dev->ifindex; ++ fl->u.ip6.flowi6_flags |= FLOWI_FLAG_ANYSRC; ++ dst = ip6_route_output(dev_net(dev), NULL, &fl->u.ip6); ++ if (dst->error) { ++ dst_release(dst); ++ dst = NULL; ++ goto tx_err_link_failure; ++ } ++ skb_dst_set(skb, dst); ++ break; ++ default: + goto tx_err_link_failure; + } +- skb_dst_set(skb, dst); + } + + dst_hold(dst); diff --git a/queue-5.5/xfrm-add-the-missing-verify_sec_ctx_len-check-in-xfrm_add_acquire.patch b/queue-5.5/xfrm-add-the-missing-verify_sec_ctx_len-check-in-xfrm_add_acquire.patch new file mode 100644 index 00000000000..9c19fdb8622 --- /dev/null +++ b/queue-5.5/xfrm-add-the-missing-verify_sec_ctx_len-check-in-xfrm_add_acquire.patch @@ -0,0 +1,60 @@ +From a1a7e3a36e01ca6e67014f8cf673cb8e47be5550 Mon Sep 17 00:00:00 2001 +From: Xin Long +Date: Sun, 9 Feb 2020 21:16:38 +0800 +Subject: xfrm: add the missing verify_sec_ctx_len check in xfrm_add_acquire + +From: Xin Long + +commit a1a7e3a36e01ca6e67014f8cf673cb8e47be5550 upstream. + +Without doing verify_sec_ctx_len() check in xfrm_add_acquire(), it may be +out-of-bounds to access uctx->ctx_str with uctx->ctx_len, as noticed by +syz: + + BUG: KASAN: slab-out-of-bounds in selinux_xfrm_alloc_user+0x237/0x430 + Read of size 768 at addr ffff8880123be9b4 by task syz-executor.1/11650 + + Call Trace: + dump_stack+0xe8/0x16e + print_address_description.cold.3+0x9/0x23b + kasan_report.cold.4+0x64/0x95 + memcpy+0x1f/0x50 + selinux_xfrm_alloc_user+0x237/0x430 + security_xfrm_policy_alloc+0x5c/0xb0 + xfrm_policy_construct+0x2b1/0x650 + xfrm_add_acquire+0x21d/0xa10 + xfrm_user_rcv_msg+0x431/0x6f0 + netlink_rcv_skb+0x15a/0x410 + xfrm_netlink_rcv+0x6d/0x90 + netlink_unicast+0x50e/0x6a0 + netlink_sendmsg+0x8ae/0xd40 + sock_sendmsg+0x133/0x170 + ___sys_sendmsg+0x834/0x9a0 + __sys_sendmsg+0x100/0x1e0 + do_syscall_64+0xe5/0x660 + entry_SYSCALL_64_after_hwframe+0x6a/0xdf + +So fix it by adding the missing verify_sec_ctx_len check there. + +Fixes: 980ebd25794f ("[IPSEC]: Sync series - acquire insert") +Reported-by: Hangbin Liu +Signed-off-by: Xin Long +Signed-off-by: Steffen Klassert +Signed-off-by: Greg Kroah-Hartman + +--- + net/xfrm/xfrm_user.c | 3 +++ + 1 file changed, 3 insertions(+) + +--- a/net/xfrm/xfrm_user.c ++++ b/net/xfrm/xfrm_user.c +@@ -2276,6 +2276,9 @@ static int xfrm_add_acquire(struct sk_bu + err = verify_newpolicy_info(&ua->policy); + if (err) + goto free_state; ++ err = verify_sec_ctx_len(attrs); ++ if (err) ++ goto free_state; + + /* build an XP */ + xp = xfrm_policy_construct(net, &ua->policy, attrs, &err); diff --git a/queue-5.5/xfrm-fix-uctx-len-check-in-verify_sec_ctx_len.patch b/queue-5.5/xfrm-fix-uctx-len-check-in-verify_sec_ctx_len.patch new file mode 100644 index 00000000000..c503d00cf2f --- /dev/null +++ b/queue-5.5/xfrm-fix-uctx-len-check-in-verify_sec_ctx_len.patch @@ -0,0 +1,37 @@ +From 171d449a028573b2f0acdc7f31ecbb045391b320 Mon Sep 17 00:00:00 2001 +From: Xin Long +Date: Sun, 9 Feb 2020 21:15:29 +0800 +Subject: xfrm: fix uctx len check in verify_sec_ctx_len + +From: Xin Long + +commit 171d449a028573b2f0acdc7f31ecbb045391b320 upstream. + +It's not sufficient to do 'uctx->len != (sizeof(struct xfrm_user_sec_ctx) + +uctx->ctx_len)' check only, as uctx->len may be greater than nla_len(rt), +in which case it will cause slab-out-of-bounds when accessing uctx->ctx_str +later. + +This patch is to fix it by return -EINVAL when uctx->len > nla_len(rt). + +Fixes: df71837d5024 ("[LSM-IPSec]: Security association restriction.") +Signed-off-by: Xin Long +Signed-off-by: Steffen Klassert +Signed-off-by: Greg Kroah-Hartman + +--- + net/xfrm/xfrm_user.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/net/xfrm/xfrm_user.c ++++ b/net/xfrm/xfrm_user.c +@@ -110,7 +110,8 @@ static inline int verify_sec_ctx_len(str + return 0; + + uctx = nla_data(rt); +- if (uctx->len != (sizeof(struct xfrm_user_sec_ctx) + uctx->ctx_len)) ++ if (uctx->len > nla_len(rt) || ++ uctx->len != (sizeof(struct xfrm_user_sec_ctx) + uctx->ctx_len)) + return -EINVAL; + + return 0; diff --git a/queue-5.5/xfrm-handle-netdev_unregister-for-xfrm-device.patch b/queue-5.5/xfrm-handle-netdev_unregister-for-xfrm-device.patch new file mode 100644 index 00000000000..9f1c0faf6fc --- /dev/null +++ b/queue-5.5/xfrm-handle-netdev_unregister-for-xfrm-device.patch @@ -0,0 +1,34 @@ +From 03891f820c2117b19e80b370281eb924a09cf79f Mon Sep 17 00:00:00 2001 +From: Raed Salem +Date: Sun, 2 Feb 2020 13:19:34 +0200 +Subject: xfrm: handle NETDEV_UNREGISTER for xfrm device + +From: Raed Salem + +commit 03891f820c2117b19e80b370281eb924a09cf79f upstream. + +This patch to handle the asynchronous unregister +device event so the device IPsec offload resources +could be cleanly released. + +Fixes: e4db5b61c572 ("xfrm: policy: remove pcpu policy cache") +Signed-off-by: Raed Salem +Reviewed-by: Boris Pismenny +Reviewed-by: Saeed Mahameed +Signed-off-by: Steffen Klassert +Signed-off-by: Greg Kroah-Hartman + +--- + net/xfrm/xfrm_device.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/net/xfrm/xfrm_device.c ++++ b/net/xfrm/xfrm_device.c +@@ -390,6 +390,7 @@ static int xfrm_dev_event(struct notifie + return xfrm_dev_feat_change(dev); + + case NETDEV_DOWN: ++ case NETDEV_UNREGISTER: + return xfrm_dev_down(dev); + } + return NOTIFY_DONE; diff --git a/queue-5.5/xfrm-policy-fix-doulbe-free-in-xfrm_policy_timer.patch b/queue-5.5/xfrm-policy-fix-doulbe-free-in-xfrm_policy_timer.patch new file mode 100644 index 00000000000..f16ff1d5194 --- /dev/null +++ b/queue-5.5/xfrm-policy-fix-doulbe-free-in-xfrm_policy_timer.patch @@ -0,0 +1,73 @@ +From 4c59406ed00379c8663f8663d82b2537467ce9d7 Mon Sep 17 00:00:00 2001 +From: YueHaibing +Date: Mon, 23 Mar 2020 15:32:39 +0800 +Subject: xfrm: policy: Fix doulbe free in xfrm_policy_timer +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: YueHaibing + +commit 4c59406ed00379c8663f8663d82b2537467ce9d7 upstream. + +After xfrm_add_policy add a policy, its ref is 2, then + + xfrm_policy_timer + read_lock + xp->walk.dead is 0 + .... + mod_timer() +xfrm_policy_kill + policy->walk.dead = 1 + .... + del_timer(&policy->timer) + xfrm_pol_put //ref is 1 + xfrm_pol_put //ref is 0 + xfrm_policy_destroy + call_rcu + xfrm_pol_hold //ref is 1 + read_unlock + xfrm_pol_put //ref is 0 + xfrm_policy_destroy + call_rcu + +xfrm_policy_destroy is called twice, which may leads to +double free. + +Call Trace: +RIP: 0010:refcount_warn_saturate+0x161/0x210 +... + xfrm_policy_timer+0x522/0x600 + call_timer_fn+0x1b3/0x5e0 + ? __xfrm_decode_session+0x2990/0x2990 + ? msleep+0xb0/0xb0 + ? _raw_spin_unlock_irq+0x24/0x40 + ? __xfrm_decode_session+0x2990/0x2990 + ? __xfrm_decode_session+0x2990/0x2990 + run_timer_softirq+0x5c5/0x10e0 + +Fix this by use write_lock_bh in xfrm_policy_kill. + +Fixes: ea2dea9dacc2 ("xfrm: remove policy lock when accessing policy->walk.dead") +Signed-off-by: YueHaibing +Acked-by: Timo Teräs +Acked-by: Herbert Xu +Signed-off-by: Steffen Klassert +Signed-off-by: Greg Kroah-Hartman + +--- + net/xfrm/xfrm_policy.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/net/xfrm/xfrm_policy.c ++++ b/net/xfrm/xfrm_policy.c +@@ -431,7 +431,9 @@ EXPORT_SYMBOL(xfrm_policy_destroy); + + static void xfrm_policy_kill(struct xfrm_policy *policy) + { ++ write_lock_bh(&policy->lock); + policy->walk.dead = 1; ++ write_unlock_bh(&policy->lock); + + atomic_inc(&policy->genid); + -- 2.47.3