From: Greg Kroah-Hartman Date: Mon, 12 Oct 2020 13:14:49 +0000 (+0200) Subject: 5.4-stable patches X-Git-Tag: v4.4.239~5 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=a4b5bb875a5fedaff6d12bf436d2f4776cb14211;p=thirdparty%2Fkernel%2Fstable-queue.git 5.4-stable patches added patches: input-ati_remote2-add-missing-newlines-when-printing-module-parameters.patch net-usb-rtl8150-set-random-mac-address-when-set_ethernet_addr-fails.patch net_sched-commit-action-insertions-together.patch net_sched-defer-tcf_idr_insert-in-tcf_action_init_1.patch --- diff --git a/queue-5.4/input-ati_remote2-add-missing-newlines-when-printing-module-parameters.patch b/queue-5.4/input-ati_remote2-add-missing-newlines-when-printing-module-parameters.patch new file mode 100644 index 00000000000..ee6be9fc193 --- /dev/null +++ b/queue-5.4/input-ati_remote2-add-missing-newlines-when-printing-module-parameters.patch @@ -0,0 +1,43 @@ +From 37bd9e803daea816f2dc2c8f6dc264097eb3ebd2 Mon Sep 17 00:00:00 2001 +From: Xiongfeng Wang +Date: Tue, 21 Jul 2020 22:24:24 -0700 +Subject: Input: ati_remote2 - add missing newlines when printing module parameters + +From: Xiongfeng Wang + +commit 37bd9e803daea816f2dc2c8f6dc264097eb3ebd2 upstream. + +When I cat some module parameters by sysfs, it displays as follows. It's +better to add a newline for easy reading. + +root@syzkaller:~# cat /sys/module/ati_remote2/parameters/mode_mask +0x1froot@syzkaller:~# cat /sys/module/ati_remote2/parameters/channel_mask +0xffffroot@syzkaller:~# + +Signed-off-by: Xiongfeng Wang +Link: https://lore.kernel.org/r/20200720092148.9320-1-wangxiongfeng2@huawei.com +Signed-off-by: Dmitry Torokhov +Signed-off-by: Greg Kroah-Hartman + +diff --git a/drivers/input/misc/ati_remote2.c b/drivers/input/misc/ati_remote2.c +index 305f0160506a..8a36d78fed63 100644 +--- a/drivers/input/misc/ati_remote2.c ++++ b/drivers/input/misc/ati_remote2.c +@@ -68,7 +68,7 @@ static int ati_remote2_get_channel_mask(char *buffer, + { + pr_debug("%s()\n", __func__); + +- return sprintf(buffer, "0x%04x", *(unsigned int *)kp->arg); ++ return sprintf(buffer, "0x%04x\n", *(unsigned int *)kp->arg); + } + + static int ati_remote2_set_mode_mask(const char *val, +@@ -84,7 +84,7 @@ static int ati_remote2_get_mode_mask(char *buffer, + { + pr_debug("%s()\n", __func__); + +- return sprintf(buffer, "0x%02x", *(unsigned int *)kp->arg); ++ return sprintf(buffer, "0x%02x\n", *(unsigned int *)kp->arg); + } + + static unsigned int channel_mask = ATI_REMOTE2_MAX_CHANNEL_MASK; diff --git a/queue-5.4/net-usb-rtl8150-set-random-mac-address-when-set_ethernet_addr-fails.patch b/queue-5.4/net-usb-rtl8150-set-random-mac-address-when-set_ethernet_addr-fails.patch new file mode 100644 index 00000000000..6ae52f4f673 --- /dev/null +++ b/queue-5.4/net-usb-rtl8150-set-random-mac-address-when-set_ethernet_addr-fails.patch @@ -0,0 +1,58 @@ +From f45a4248ea4cc13ed50618ff066849f9587226b2 Mon Sep 17 00:00:00 2001 +From: Anant Thazhemadam +Date: Mon, 5 Oct 2020 18:59:58 +0530 +Subject: net: usb: rtl8150: set random MAC address when set_ethernet_addr() fails + +From: Anant Thazhemadam + +commit f45a4248ea4cc13ed50618ff066849f9587226b2 upstream. + +When get_registers() fails in set_ethernet_addr(),the uninitialized +value of node_id gets copied over as the address. +So, check the return value of get_registers(). + +If get_registers() executed successfully (i.e., it returns +sizeof(node_id)), copy over the MAC address using ether_addr_copy() +(instead of using memcpy()). + +Else, if get_registers() failed instead, a randomly generated MAC +address is set as the MAC address instead. + +Reported-by: syzbot+abbc768b560c84d92fd3@syzkaller.appspotmail.com +Tested-by: syzbot+abbc768b560c84d92fd3@syzkaller.appspotmail.com +Acked-by: Petko Manolov +Signed-off-by: Anant Thazhemadam +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/net/usb/rtl8150.c | 16 ++++++++++++---- + 1 file changed, 12 insertions(+), 4 deletions(-) + +--- a/drivers/net/usb/rtl8150.c ++++ b/drivers/net/usb/rtl8150.c +@@ -274,12 +274,20 @@ static int write_mii_word(rtl8150_t * de + return 1; + } + +-static inline void set_ethernet_addr(rtl8150_t * dev) ++static void set_ethernet_addr(rtl8150_t *dev) + { +- u8 node_id[6]; ++ u8 node_id[ETH_ALEN]; ++ int ret; + +- get_registers(dev, IDR, sizeof(node_id), node_id); +- memcpy(dev->netdev->dev_addr, node_id, sizeof(node_id)); ++ ret = get_registers(dev, IDR, sizeof(node_id), node_id); ++ ++ if (ret == sizeof(node_id)) { ++ ether_addr_copy(dev->netdev->dev_addr, node_id); ++ } else { ++ eth_hw_addr_random(dev->netdev); ++ netdev_notice(dev->netdev, "Assigned a random MAC address: %pM\n", ++ dev->netdev->dev_addr); ++ } + } + + static int rtl8150_set_mac_address(struct net_device *netdev, void *p) diff --git a/queue-5.4/net_sched-commit-action-insertions-together.patch b/queue-5.4/net_sched-commit-action-insertions-together.patch new file mode 100644 index 00000000000..21780f064fc --- /dev/null +++ b/queue-5.4/net_sched-commit-action-insertions-together.patch @@ -0,0 +1,101 @@ +From 0fedc63fadf0404a729e73a35349481c8009c02f Mon Sep 17 00:00:00 2001 +From: Cong Wang +Date: Tue, 22 Sep 2020 20:56:24 -0700 +Subject: net_sched: commit action insertions together + +From: Cong Wang + +commit 0fedc63fadf0404a729e73a35349481c8009c02f upstream. + +syzbot is able to trigger a failure case inside the loop in +tcf_action_init(), and when this happens we clean up with +tcf_action_destroy(). But, as these actions are already inserted +into the global IDR, other parallel process could free them +before tcf_action_destroy(), then we will trigger a use-after-free. + +Fix this by deferring the insertions even later, after the loop, +and committing all the insertions in a separate loop, so we will +never fail in the middle of the insertions any more. + +One side effect is that the window between alloction and final +insertion becomes larger, now it is more likely that the loop in +tcf_del_walker() sees the placeholder -EBUSY pointer. So we have +to check for error pointer in tcf_del_walker(). + +Reported-and-tested-by: syzbot+2287853d392e4b42374a@syzkaller.appspotmail.com +Fixes: 0190c1d452a9 ("net: sched: atomically check-allocate action") +Cc: Vlad Buslov +Cc: Jamal Hadi Salim +Cc: Jiri Pirko +Signed-off-by: Cong Wang +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman + +--- + net/sched/act_api.c | 32 +++++++++++++++++++++++--------- + 1 file changed, 23 insertions(+), 9 deletions(-) + +--- a/net/sched/act_api.c ++++ b/net/sched/act_api.c +@@ -303,6 +303,8 @@ static int tcf_del_walker(struct tcf_idr + + mutex_lock(&idrinfo->lock); + idr_for_each_entry_ul(idr, p, tmp, id) { ++ if (IS_ERR(p)) ++ continue; + ret = tcf_idr_release_unsafe(p); + if (ret == ACT_P_DELETED) { + module_put(ops->owner); +@@ -828,14 +830,24 @@ static const struct nla_policy tcf_actio + [TCA_ACT_OPTIONS] = { .type = NLA_NESTED }, + }; + +-static void tcf_idr_insert(struct tc_action *a) ++static void tcf_idr_insert_many(struct tc_action *actions[]) + { +- struct tcf_idrinfo *idrinfo = a->idrinfo; ++ int i; + +- mutex_lock(&idrinfo->lock); +- /* Replace ERR_PTR(-EBUSY) allocated by tcf_idr_check_alloc */ +- WARN_ON(!IS_ERR(idr_replace(&idrinfo->action_idr, a, a->tcfa_index))); +- mutex_unlock(&idrinfo->lock); ++ for (i = 0; i < TCA_ACT_MAX_PRIO; i++) { ++ struct tc_action *a = actions[i]; ++ struct tcf_idrinfo *idrinfo; ++ ++ if (!a) ++ continue; ++ idrinfo = a->idrinfo; ++ mutex_lock(&idrinfo->lock); ++ /* Replace ERR_PTR(-EBUSY) allocated by tcf_idr_check_alloc if ++ * it is just created, otherwise this is just a nop. ++ */ ++ idr_replace(&idrinfo->action_idr, a, a->tcfa_index); ++ mutex_unlock(&idrinfo->lock); ++ } + } + + struct tc_action *tcf_action_init_1(struct net *net, struct tcf_proto *tp, +@@ -927,9 +939,6 @@ struct tc_action *tcf_action_init_1(stru + return ERR_PTR(-EINVAL); + } + +- if (err == ACT_P_CREATED) +- tcf_idr_insert(a); +- + if (!name && tb[TCA_ACT_COOKIE]) + tcf_set_action_cookie(&a->act_cookie, cookie); + +@@ -983,6 +992,11 @@ int tcf_action_init(struct net *net, str + actions[i - 1] = act; + } + ++ /* We have to commit them all together, because if any error happened in ++ * between, we could not handle the failure gracefully. ++ */ ++ tcf_idr_insert_many(actions); ++ + *attr_size = tcf_action_full_attrs_size(sz); + return i - 1; + diff --git a/queue-5.4/net_sched-defer-tcf_idr_insert-in-tcf_action_init_1.patch b/queue-5.4/net_sched-defer-tcf_idr_insert-in-tcf_action_init_1.patch new file mode 100644 index 00000000000..6a59433e58b --- /dev/null +++ b/queue-5.4/net_sched-defer-tcf_idr_insert-in-tcf_action_init_1.patch @@ -0,0 +1,346 @@ +From e49d8c22f1261c43a986a7fdbf677ac309682a07 Mon Sep 17 00:00:00 2001 +From: Cong Wang +Date: Tue, 22 Sep 2020 20:56:23 -0700 +Subject: net_sched: defer tcf_idr_insert() in tcf_action_init_1() + +From: Cong Wang + +commit e49d8c22f1261c43a986a7fdbf677ac309682a07 upstream. + +All TC actions call tcf_idr_insert() for new action at the end +of their ->init(), so we can actually move it to a central place +in tcf_action_init_1(). + +And once the action is inserted into the global IDR, other parallel +process could free it immediately as its refcnt is still 1, so we can +not fail after this, we need to move it after the goto action +validation to avoid handling the failure case after insertion. + +This is found during code review, is not directly triggered by syzbot. +And this prepares for the next patch. + +Cc: Vlad Buslov +Cc: Jamal Hadi Salim +Cc: Jiri Pirko +Signed-off-by: Cong Wang +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman + +--- + include/net/act_api.h | 2 -- + net/sched/act_api.c | 38 ++++++++++++++++++++------------------ + net/sched/act_bpf.c | 4 +--- + net/sched/act_connmark.c | 1 - + net/sched/act_csum.c | 3 --- + net/sched/act_ct.c | 2 -- + net/sched/act_ctinfo.c | 3 --- + net/sched/act_gact.c | 2 -- + net/sched/act_ife.c | 3 --- + net/sched/act_ipt.c | 2 -- + net/sched/act_mirred.c | 2 -- + net/sched/act_mpls.c | 2 -- + net/sched/act_nat.c | 3 --- + net/sched/act_pedit.c | 2 -- + net/sched/act_police.c | 2 -- + net/sched/act_sample.c | 2 -- + net/sched/act_simple.c | 2 -- + net/sched/act_skbedit.c | 2 -- + net/sched/act_skbmod.c | 2 -- + net/sched/act_tunnel_key.c | 3 --- + net/sched/act_vlan.c | 2 -- + 21 files changed, 21 insertions(+), 63 deletions(-) + +--- a/include/net/act_api.h ++++ b/include/net/act_api.h +@@ -156,8 +156,6 @@ int tcf_idr_search(struct tc_action_net + int tcf_idr_create(struct tc_action_net *tn, u32 index, struct nlattr *est, + struct tc_action **a, const struct tc_action_ops *ops, + int bind, bool cpustats); +-void tcf_idr_insert(struct tc_action_net *tn, struct tc_action *a); +- + void tcf_idr_cleanup(struct tc_action_net *tn, u32 index); + int tcf_idr_check_alloc(struct tc_action_net *tn, u32 *index, + struct tc_action **a, int bind); +--- a/net/sched/act_api.c ++++ b/net/sched/act_api.c +@@ -451,17 +451,6 @@ err1: + } + EXPORT_SYMBOL(tcf_idr_create); + +-void tcf_idr_insert(struct tc_action_net *tn, struct tc_action *a) +-{ +- struct tcf_idrinfo *idrinfo = tn->idrinfo; +- +- mutex_lock(&idrinfo->lock); +- /* Replace ERR_PTR(-EBUSY) allocated by tcf_idr_check_alloc */ +- WARN_ON(!IS_ERR(idr_replace(&idrinfo->action_idr, a, a->tcfa_index))); +- mutex_unlock(&idrinfo->lock); +-} +-EXPORT_SYMBOL(tcf_idr_insert); +- + /* Cleanup idr index that was allocated but not initialized. */ + + void tcf_idr_cleanup(struct tc_action_net *tn, u32 index) +@@ -839,6 +828,16 @@ static const struct nla_policy tcf_actio + [TCA_ACT_OPTIONS] = { .type = NLA_NESTED }, + }; + ++static void tcf_idr_insert(struct tc_action *a) ++{ ++ struct tcf_idrinfo *idrinfo = a->idrinfo; ++ ++ mutex_lock(&idrinfo->lock); ++ /* Replace ERR_PTR(-EBUSY) allocated by tcf_idr_check_alloc */ ++ WARN_ON(!IS_ERR(idr_replace(&idrinfo->action_idr, a, a->tcfa_index))); ++ mutex_unlock(&idrinfo->lock); ++} ++ + struct tc_action *tcf_action_init_1(struct net *net, struct tcf_proto *tp, + struct nlattr *nla, struct nlattr *est, + char *name, int ovr, int bind, +@@ -921,6 +920,16 @@ struct tc_action *tcf_action_init_1(stru + if (err < 0) + goto err_mod; + ++ if (TC_ACT_EXT_CMP(a->tcfa_action, TC_ACT_GOTO_CHAIN) && ++ !rcu_access_pointer(a->goto_chain)) { ++ tcf_action_destroy_1(a, bind); ++ NL_SET_ERR_MSG(extack, "can't use goto chain with NULL chain"); ++ return ERR_PTR(-EINVAL); ++ } ++ ++ if (err == ACT_P_CREATED) ++ tcf_idr_insert(a); ++ + if (!name && tb[TCA_ACT_COOKIE]) + tcf_set_action_cookie(&a->act_cookie, cookie); + +@@ -931,13 +940,6 @@ struct tc_action *tcf_action_init_1(stru + if (err != ACT_P_CREATED) + module_put(a_o->owner); + +- if (TC_ACT_EXT_CMP(a->tcfa_action, TC_ACT_GOTO_CHAIN) && +- !rcu_access_pointer(a->goto_chain)) { +- tcf_action_destroy_1(a, bind); +- NL_SET_ERR_MSG(extack, "can't use goto chain with NULL chain"); +- return ERR_PTR(-EINVAL); +- } +- + return a; + + err_mod: +--- a/net/sched/act_bpf.c ++++ b/net/sched/act_bpf.c +@@ -361,9 +361,7 @@ static int tcf_bpf_init(struct net *net, + if (goto_ch) + tcf_chain_put_by_act(goto_ch); + +- if (res == ACT_P_CREATED) { +- tcf_idr_insert(tn, *act); +- } else { ++ if (res != ACT_P_CREATED) { + /* make sure the program being replaced is no longer executing */ + synchronize_rcu(); + tcf_bpf_cfg_cleanup(&old); +--- a/net/sched/act_connmark.c ++++ b/net/sched/act_connmark.c +@@ -139,7 +139,6 @@ static int tcf_connmark_init(struct net + ci->net = net; + ci->zone = parm->zone; + +- tcf_idr_insert(tn, *a); + ret = ACT_P_CREATED; + } else if (ret > 0) { + ci = to_connmark(*a); +--- a/net/sched/act_csum.c ++++ b/net/sched/act_csum.c +@@ -110,9 +110,6 @@ static int tcf_csum_init(struct net *net + if (params_new) + kfree_rcu(params_new, rcu); + +- if (ret == ACT_P_CREATED) +- tcf_idr_insert(tn, *a); +- + return ret; + put_chain: + if (goto_ch) +--- a/net/sched/act_ct.c ++++ b/net/sched/act_ct.c +@@ -740,8 +740,6 @@ static int tcf_ct_init(struct net *net, + tcf_chain_put_by_act(goto_ch); + if (params) + call_rcu(¶ms->rcu, tcf_ct_params_free); +- if (res == ACT_P_CREATED) +- tcf_idr_insert(tn, *a); + + return res; + +--- a/net/sched/act_ctinfo.c ++++ b/net/sched/act_ctinfo.c +@@ -269,9 +269,6 @@ static int tcf_ctinfo_init(struct net *n + if (cp_new) + kfree_rcu(cp_new, rcu); + +- if (ret == ACT_P_CREATED) +- tcf_idr_insert(tn, *a); +- + return ret; + + put_chain: +--- a/net/sched/act_gact.c ++++ b/net/sched/act_gact.c +@@ -139,8 +139,6 @@ static int tcf_gact_init(struct net *net + if (goto_ch) + tcf_chain_put_by_act(goto_ch); + +- if (ret == ACT_P_CREATED) +- tcf_idr_insert(tn, *a); + return ret; + release_idr: + tcf_idr_release(*a, bind); +--- a/net/sched/act_ife.c ++++ b/net/sched/act_ife.c +@@ -626,9 +626,6 @@ static int tcf_ife_init(struct net *net, + if (p) + kfree_rcu(p, rcu); + +- if (ret == ACT_P_CREATED) +- tcf_idr_insert(tn, *a); +- + return ret; + metadata_parse_err: + if (goto_ch) +--- a/net/sched/act_ipt.c ++++ b/net/sched/act_ipt.c +@@ -189,8 +189,6 @@ static int __tcf_ipt_init(struct net *ne + ipt->tcfi_t = t; + ipt->tcfi_hook = hook; + spin_unlock_bh(&ipt->tcf_lock); +- if (ret == ACT_P_CREATED) +- tcf_idr_insert(tn, *a); + return ret; + + err3: +--- a/net/sched/act_mirred.c ++++ b/net/sched/act_mirred.c +@@ -194,8 +194,6 @@ static int tcf_mirred_init(struct net *n + spin_lock(&mirred_list_lock); + list_add(&m->tcfm_list, &mirred_list); + spin_unlock(&mirred_list_lock); +- +- tcf_idr_insert(tn, *a); + } + + return ret; +--- a/net/sched/act_mpls.c ++++ b/net/sched/act_mpls.c +@@ -273,8 +273,6 @@ static int tcf_mpls_init(struct net *net + if (p) + kfree_rcu(p, rcu); + +- if (ret == ACT_P_CREATED) +- tcf_idr_insert(tn, *a); + return ret; + put_chain: + if (goto_ch) +--- a/net/sched/act_nat.c ++++ b/net/sched/act_nat.c +@@ -93,9 +93,6 @@ static int tcf_nat_init(struct net *net, + if (goto_ch) + tcf_chain_put_by_act(goto_ch); + +- if (ret == ACT_P_CREATED) +- tcf_idr_insert(tn, *a); +- + return ret; + release_idr: + tcf_idr_release(*a, bind); +--- a/net/sched/act_pedit.c ++++ b/net/sched/act_pedit.c +@@ -237,8 +237,6 @@ static int tcf_pedit_init(struct net *ne + spin_unlock_bh(&p->tcf_lock); + if (goto_ch) + tcf_chain_put_by_act(goto_ch); +- if (ret == ACT_P_CREATED) +- tcf_idr_insert(tn, *a); + return ret; + + put_chain: +--- a/net/sched/act_police.c ++++ b/net/sched/act_police.c +@@ -201,8 +201,6 @@ static int tcf_police_init(struct net *n + if (new) + kfree_rcu(new, rcu); + +- if (ret == ACT_P_CREATED) +- tcf_idr_insert(tn, *a); + return ret; + + failure: +--- a/net/sched/act_sample.c ++++ b/net/sched/act_sample.c +@@ -116,8 +116,6 @@ static int tcf_sample_init(struct net *n + if (goto_ch) + tcf_chain_put_by_act(goto_ch); + +- if (ret == ACT_P_CREATED) +- tcf_idr_insert(tn, *a); + return ret; + put_chain: + if (goto_ch) +--- a/net/sched/act_simple.c ++++ b/net/sched/act_simple.c +@@ -156,8 +156,6 @@ static int tcf_simp_init(struct net *net + goto release_idr; + } + +- if (ret == ACT_P_CREATED) +- tcf_idr_insert(tn, *a); + return ret; + put_chain: + if (goto_ch) +--- a/net/sched/act_skbedit.c ++++ b/net/sched/act_skbedit.c +@@ -214,8 +214,6 @@ static int tcf_skbedit_init(struct net * + if (goto_ch) + tcf_chain_put_by_act(goto_ch); + +- if (ret == ACT_P_CREATED) +- tcf_idr_insert(tn, *a); + return ret; + put_chain: + if (goto_ch) +--- a/net/sched/act_skbmod.c ++++ b/net/sched/act_skbmod.c +@@ -190,8 +190,6 @@ static int tcf_skbmod_init(struct net *n + if (goto_ch) + tcf_chain_put_by_act(goto_ch); + +- if (ret == ACT_P_CREATED) +- tcf_idr_insert(tn, *a); + return ret; + put_chain: + if (goto_ch) +--- a/net/sched/act_tunnel_key.c ++++ b/net/sched/act_tunnel_key.c +@@ -392,9 +392,6 @@ static int tunnel_key_init(struct net *n + if (goto_ch) + tcf_chain_put_by_act(goto_ch); + +- if (ret == ACT_P_CREATED) +- tcf_idr_insert(tn, *a); +- + return ret; + + put_chain: +--- a/net/sched/act_vlan.c ++++ b/net/sched/act_vlan.c +@@ -228,8 +228,6 @@ static int tcf_vlan_init(struct net *net + if (p) + kfree_rcu(p, rcu); + +- if (ret == ACT_P_CREATED) +- tcf_idr_insert(tn, *a); + return ret; + put_chain: + if (goto_ch) diff --git a/queue-5.4/series b/queue-5.4/series index 37c072c50bc..67bd8950a8b 100644 --- a/queue-5.4/series +++ b/queue-5.4/series @@ -79,3 +79,7 @@ tcp-fix-receive-window-update-in-tcp_add_backlog.patch net-core-check-length-before-updating-ethertype-in-skb_mpls_-push-pop.patch net-tls-race-causes-kernel-panic.patch net-mlx5e-fix-driver-s-declaration-to-support-gre-offload.patch +input-ati_remote2-add-missing-newlines-when-printing-module-parameters.patch +net-usb-rtl8150-set-random-mac-address-when-set_ethernet_addr-fails.patch +net_sched-defer-tcf_idr_insert-in-tcf_action_init_1.patch +net_sched-commit-action-insertions-together.patch