--- /dev/null
+From fc0494ead6398609c49afa37bc949b61c5c16b91 Mon Sep 17 00:00:00 2001
+From: Takeshi Misawa <jeliantsurux@gmail.com>
+Date: Mon, 22 Feb 2021 08:44:27 +0900
+Subject: net: qrtr: Fix memory leak in qrtr_tun_open
+
+From: Takeshi Misawa <jeliantsurux@gmail.com>
+
+commit fc0494ead6398609c49afa37bc949b61c5c16b91 upstream.
+
+If qrtr_endpoint_register() failed, tun is leaked.
+Fix this, by freeing tun in error path.
+
+syzbot report:
+BUG: memory leak
+unreferenced object 0xffff88811848d680 (size 64):
+ comm "syz-executor684", pid 10171, jiffies 4294951561 (age 26.070s)
+ hex dump (first 32 bytes):
+ 80 dd 0a 84 ff ff ff ff 00 00 00 00 00 00 00 00 ................
+ 90 d6 48 18 81 88 ff ff 90 d6 48 18 81 88 ff ff ..H.......H.....
+ backtrace:
+ [<0000000018992a50>] kmalloc include/linux/slab.h:552 [inline]
+ [<0000000018992a50>] kzalloc include/linux/slab.h:682 [inline]
+ [<0000000018992a50>] qrtr_tun_open+0x22/0x90 net/qrtr/tun.c:35
+ [<0000000003a453ef>] misc_open+0x19c/0x1e0 drivers/char/misc.c:141
+ [<00000000dec38ac8>] chrdev_open+0x10d/0x340 fs/char_dev.c:414
+ [<0000000079094996>] do_dentry_open+0x1e6/0x620 fs/open.c:817
+ [<000000004096d290>] do_open fs/namei.c:3252 [inline]
+ [<000000004096d290>] path_openat+0x74a/0x1b00 fs/namei.c:3369
+ [<00000000b8e64241>] do_filp_open+0xa0/0x190 fs/namei.c:3396
+ [<00000000a3299422>] do_sys_openat2+0xed/0x230 fs/open.c:1172
+ [<000000002c1bdcef>] do_sys_open fs/open.c:1188 [inline]
+ [<000000002c1bdcef>] __do_sys_openat fs/open.c:1204 [inline]
+ [<000000002c1bdcef>] __se_sys_openat fs/open.c:1199 [inline]
+ [<000000002c1bdcef>] __x64_sys_openat+0x7f/0xe0 fs/open.c:1199
+ [<00000000f3a5728f>] do_syscall_64+0x2d/0x70 arch/x86/entry/common.c:46
+ [<000000004b38b7ec>] entry_SYSCALL_64_after_hwframe+0x44/0xa9
+
+Fixes: 28fb4e59a47d ("net: qrtr: Expose tunneling endpoint to user space")
+Reported-by: syzbot+5d6e4af21385f5cfc56a@syzkaller.appspotmail.com
+Signed-off-by: Takeshi Misawa <jeliantsurux@gmail.com>
+Link: https://lore.kernel.org/r/20210221234427.GA2140@DESKTOP
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/qrtr/tun.c | 12 +++++++++++-
+ 1 file changed, 11 insertions(+), 1 deletion(-)
+
+--- a/net/qrtr/tun.c
++++ b/net/qrtr/tun.c
+@@ -31,6 +31,7 @@ static int qrtr_tun_send(struct qrtr_end
+ static int qrtr_tun_open(struct inode *inode, struct file *filp)
+ {
+ struct qrtr_tun *tun;
++ int ret;
+
+ tun = kzalloc(sizeof(*tun), GFP_KERNEL);
+ if (!tun)
+@@ -43,7 +44,16 @@ static int qrtr_tun_open(struct inode *i
+
+ filp->private_data = tun;
+
+- return qrtr_endpoint_register(&tun->ep, QRTR_EP_NID_AUTO);
++ ret = qrtr_endpoint_register(&tun->ep, QRTR_EP_NID_AUTO);
++ if (ret)
++ goto out;
++
++ return 0;
++
++out:
++ filp->private_data = NULL;
++ kfree(tun);
++ return ret;
+ }
+
+ static ssize_t qrtr_tun_read_iter(struct kiocb *iocb, struct iov_iter *to)
--- /dev/null
+From d349f997686887906b1183b5be96933c5452362a Mon Sep 17 00:00:00 2001
+From: Cong Wang <cong.wang@bytedance.com>
+Date: Sat, 16 Jan 2021 16:56:57 -0800
+Subject: net_sched: fix RTNL deadlock again caused by request_module()
+
+From: Cong Wang <cong.wang@bytedance.com>
+
+commit d349f997686887906b1183b5be96933c5452362a upstream.
+
+tcf_action_init_1() loads tc action modules automatically with
+request_module() after parsing the tc action names, and it drops RTNL
+lock and re-holds it before and after request_module(). This causes a
+lot of troubles, as discovered by syzbot, because we can be in the
+middle of batch initializations when we create an array of tc actions.
+
+One of the problem is deadlock:
+
+CPU 0 CPU 1
+rtnl_lock();
+for (...) {
+ tcf_action_init_1();
+ -> rtnl_unlock();
+ -> request_module();
+ rtnl_lock();
+ for (...) {
+ tcf_action_init_1();
+ -> tcf_idr_check_alloc();
+ // Insert one action into idr,
+ // but it is not committed until
+ // tcf_idr_insert_many(), then drop
+ // the RTNL lock in the _next_
+ // iteration
+ -> rtnl_unlock();
+ -> rtnl_lock();
+ -> a_o->init();
+ -> tcf_idr_check_alloc();
+ // Now waiting for the same index
+ // to be committed
+ -> request_module();
+ -> rtnl_lock()
+ // Now waiting for RTNL lock
+ }
+ rtnl_unlock();
+}
+rtnl_unlock();
+
+This is not easy to solve, we can move the request_module() before
+this loop and pre-load all the modules we need for this netlink
+message and then do the rest initializations. So the loop breaks down
+to two now:
+
+ for (i = 1; i <= TCA_ACT_MAX_PRIO && tb[i]; i++) {
+ struct tc_action_ops *a_o;
+
+ a_o = tc_action_load_ops(name, tb[i]...);
+ ops[i - 1] = a_o;
+ }
+
+ for (i = 1; i <= TCA_ACT_MAX_PRIO && tb[i]; i++) {
+ act = tcf_action_init_1(ops[i - 1]...);
+ }
+
+Although this looks serious, it only has been reported by syzbot, so it
+seems hard to trigger this by humans. And given the size of this patch,
+I'd suggest to make it to net-next and not to backport to stable.
+
+This patch has been tested by syzbot and tested with tdc.py by me.
+
+Fixes: 0fedc63fadf0 ("net_sched: commit action insertions together")
+Reported-and-tested-by: syzbot+82752bc5331601cf4899@syzkaller.appspotmail.com
+Reported-and-tested-by: syzbot+b3b63b6bff456bd95294@syzkaller.appspotmail.com
+Reported-by: syzbot+ba67b12b1ca729912834@syzkaller.appspotmail.com
+Cc: Jiri Pirko <jiri@resnulli.us>
+Signed-off-by: Cong Wang <cong.wang@bytedance.com>
+Tested-by: Jamal Hadi Salim <jhs@mojatatu.com>
+Acked-by: Jamal Hadi Salim <jhs@mojatatu.com>
+Link: https://lore.kernel.org/r/20210117005657.14810-1-xiyou.wangcong@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ include/net/act_api.h | 5 +-
+ net/sched/act_api.c | 104 +++++++++++++++++++++++++++++++-------------------
+ net/sched/cls_api.c | 11 ++++-
+ 3 files changed, 79 insertions(+), 41 deletions(-)
+
+--- a/include/net/act_api.h
++++ b/include/net/act_api.h
+@@ -187,10 +187,13 @@ int tcf_action_init(struct net *net, str
+ struct nlattr *est, char *name, int ovr, int bind,
+ struct tc_action *actions[], size_t *attr_size,
+ bool rtnl_held, struct netlink_ext_ack *extack);
++struct tc_action_ops *tc_action_load_ops(char *name, struct nlattr *nla,
++ bool rtnl_held,
++ struct netlink_ext_ack *extack);
+ 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,
+- bool rtnl_held,
++ struct tc_action_ops *ops, bool rtnl_held,
+ struct netlink_ext_ack *extack);
+ int tcf_action_dump(struct sk_buff *skb, struct tc_action *actions[], int bind,
+ int ref, bool terse);
+--- a/net/sched/act_api.c
++++ b/net/sched/act_api.c
+@@ -908,19 +908,13 @@ void tcf_idr_insert_many(struct tc_actio
+ }
+ }
+
+-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,
+- bool rtnl_held,
+- struct netlink_ext_ack *extack)
++struct tc_action_ops *tc_action_load_ops(char *name, struct nlattr *nla,
++ bool rtnl_held,
++ struct netlink_ext_ack *extack)
+ {
+- struct nla_bitfield32 flags = { 0, 0 };
+- u8 hw_stats = TCA_ACT_HW_STATS_ANY;
+- struct tc_action *a;
++ struct nlattr *tb[TCA_ACT_MAX + 1];
+ struct tc_action_ops *a_o;
+- struct tc_cookie *cookie = NULL;
+ char act_name[IFNAMSIZ];
+- struct nlattr *tb[TCA_ACT_MAX + 1];
+ struct nlattr *kind;
+ int err;
+
+@@ -928,33 +922,21 @@ struct tc_action *tcf_action_init_1(stru
+ err = nla_parse_nested_deprecated(tb, TCA_ACT_MAX, nla,
+ tcf_action_policy, extack);
+ if (err < 0)
+- goto err_out;
++ return ERR_PTR(err);
+ err = -EINVAL;
+ kind = tb[TCA_ACT_KIND];
+ if (!kind) {
+ NL_SET_ERR_MSG(extack, "TC action kind must be specified");
+- goto err_out;
++ return ERR_PTR(err);
+ }
+ if (nla_strlcpy(act_name, kind, IFNAMSIZ) >= IFNAMSIZ) {
+ NL_SET_ERR_MSG(extack, "TC action name too long");
+- goto err_out;
++ return ERR_PTR(err);
+ }
+- if (tb[TCA_ACT_COOKIE]) {
+- cookie = nla_memdup_cookie(tb);
+- if (!cookie) {
+- NL_SET_ERR_MSG(extack, "No memory to generate TC cookie");
+- err = -ENOMEM;
+- goto err_out;
+- }
+- }
+- hw_stats = tcf_action_hw_stats_get(tb[TCA_ACT_HW_STATS]);
+- if (tb[TCA_ACT_FLAGS])
+- flags = nla_get_bitfield32(tb[TCA_ACT_FLAGS]);
+ } else {
+ if (strlcpy(act_name, name, IFNAMSIZ) >= IFNAMSIZ) {
+ NL_SET_ERR_MSG(extack, "TC action name too long");
+- err = -EINVAL;
+- goto err_out;
++ return ERR_PTR(-EINVAL);
+ }
+ }
+
+@@ -976,24 +958,56 @@ struct tc_action *tcf_action_init_1(stru
+ * indicate this using -EAGAIN.
+ */
+ if (a_o != NULL) {
+- err = -EAGAIN;
+- goto err_mod;
++ module_put(a_o->owner);
++ return ERR_PTR(-EAGAIN);
+ }
+ #endif
+ NL_SET_ERR_MSG(extack, "Failed to load TC action module");
+- err = -ENOENT;
+- goto err_free;
++ return ERR_PTR(-ENOENT);
+ }
+
++ return a_o;
++}
++
++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,
++ struct tc_action_ops *a_o, bool rtnl_held,
++ struct netlink_ext_ack *extack)
++{
++ struct nla_bitfield32 flags = { 0, 0 };
++ u8 hw_stats = TCA_ACT_HW_STATS_ANY;
++ struct nlattr *tb[TCA_ACT_MAX + 1];
++ struct tc_cookie *cookie = NULL;
++ struct tc_action *a;
++ int err;
++
+ /* backward compatibility for policer */
+- if (name == NULL)
++ if (name == NULL) {
++ err = nla_parse_nested_deprecated(tb, TCA_ACT_MAX, nla,
++ tcf_action_policy, extack);
++ if (err < 0)
++ return ERR_PTR(err);
++ if (tb[TCA_ACT_COOKIE]) {
++ cookie = nla_memdup_cookie(tb);
++ if (!cookie) {
++ NL_SET_ERR_MSG(extack, "No memory to generate TC cookie");
++ err = -ENOMEM;
++ goto err_out;
++ }
++ }
++ hw_stats = tcf_action_hw_stats_get(tb[TCA_ACT_HW_STATS]);
++ if (tb[TCA_ACT_FLAGS])
++ flags = nla_get_bitfield32(tb[TCA_ACT_FLAGS]);
++
+ err = a_o->init(net, tb[TCA_ACT_OPTIONS], est, &a, ovr, bind,
+ rtnl_held, tp, flags.value, extack);
+- else
++ } else {
+ err = a_o->init(net, nla, est, &a, ovr, bind, rtnl_held,
+ tp, flags.value, extack);
++ }
+ if (err < 0)
+- goto err_mod;
++ goto err_out;
+
+ if (!name && tb[TCA_ACT_COOKIE])
+ tcf_set_action_cookie(&a->act_cookie, cookie);
+@@ -1010,14 +1024,11 @@ struct tc_action *tcf_action_init_1(stru
+
+ return a;
+
+-err_mod:
+- module_put(a_o->owner);
+-err_free:
++err_out:
+ if (cookie) {
+ kfree(cookie->data);
+ kfree(cookie);
+ }
+-err_out:
+ return ERR_PTR(err);
+ }
+
+@@ -1028,6 +1039,7 @@ int tcf_action_init(struct net *net, str
+ struct tc_action *actions[], size_t *attr_size,
+ bool rtnl_held, struct netlink_ext_ack *extack)
+ {
++ struct tc_action_ops *ops[TCA_ACT_MAX_PRIO] = {};
+ struct nlattr *tb[TCA_ACT_MAX_PRIO + 1];
+ struct tc_action *act;
+ size_t sz = 0;
+@@ -1040,8 +1052,19 @@ int tcf_action_init(struct net *net, str
+ return err;
+
+ for (i = 1; i <= TCA_ACT_MAX_PRIO && tb[i]; i++) {
++ struct tc_action_ops *a_o;
++
++ a_o = tc_action_load_ops(name, tb[i], rtnl_held, extack);
++ if (IS_ERR(a_o)) {
++ err = PTR_ERR(a_o);
++ goto err_mod;
++ }
++ ops[i - 1] = a_o;
++ }
++
++ for (i = 1; i <= TCA_ACT_MAX_PRIO && tb[i]; i++) {
+ act = tcf_action_init_1(net, tp, tb[i], est, name, ovr, bind,
+- rtnl_held, extack);
++ ops[i - 1], rtnl_held, extack);
+ if (IS_ERR(act)) {
+ err = PTR_ERR(act);
+ goto err;
+@@ -1061,6 +1084,11 @@ int tcf_action_init(struct net *net, str
+
+ err:
+ tcf_action_destroy(actions, bind);
++err_mod:
++ for (i = 0; i < TCA_ACT_MAX_PRIO; i++) {
++ if (ops[i])
++ module_put(ops[i]->owner);
++ }
+ return err;
+ }
+
+--- a/net/sched/cls_api.c
++++ b/net/sched/cls_api.c
+@@ -3055,12 +3055,19 @@ int tcf_exts_validate(struct net *net, s
+ size_t attr_size = 0;
+
+ if (exts->police && tb[exts->police]) {
++ struct tc_action_ops *a_o;
++
++ a_o = tc_action_load_ops("police", tb[exts->police], rtnl_held, extack);
++ if (IS_ERR(a_o))
++ return PTR_ERR(a_o);
+ act = tcf_action_init_1(net, tp, tb[exts->police],
+ rate_tlv, "police", ovr,
+- TCA_ACT_BIND, rtnl_held,
++ TCA_ACT_BIND, a_o, rtnl_held,
+ extack);
+- if (IS_ERR(act))
++ if (IS_ERR(act)) {
++ module_put(a_o->owner);
+ return PTR_ERR(act);
++ }
+
+ act->type = exts->type = TCA_OLD_COMPAT;
+ exts->actions[0] = act;