diff mbox series

[net-next] net/sched: fix error recovery in qdisc_create()

Message ID 20230210152605.1852743-1-edumazet@google.com (mailing list archive)
State Accepted
Commit 4fab64126891d413f207dacd5762a839b3470315
Delegated to: Netdev Maintainers
Headers show
Series [net-next] net/sched: fix error recovery in qdisc_create() | expand

Checks

Context Check Description
netdev/tree_selection success Clearly marked for net-next
netdev/fixes_present success Fixes tag not required for -next series
netdev/subject_prefix success Link
netdev/cover_letter success Single patches do not need cover letters
netdev/patch_count success Link
netdev/header_inline success No static functions without inline keyword in header files
netdev/build_32bit success Errors and warnings before: 3 this patch: 3
netdev/cc_maintainers warning 1 maintainers not CCed: jiri@resnulli.us
netdev/build_clang success Errors and warnings before: 1 this patch: 1
netdev/module_param success Was 0 now: 0
netdev/verify_signedoff success Signed-off-by tag matches author and committer
netdev/check_selftest success No net selftest shell script
netdev/verify_fixes success Fixes tag looks correct
netdev/build_allmodconfig_warn success Errors and warnings before: 3 this patch: 3
netdev/checkpatch success total: 0 errors, 0 warnings, 0 checks, 48 lines checked
netdev/kdoc success Errors and warnings before: 0 this patch: 0
netdev/source_inline success Was 0 now: 0

Commit Message

Eric Dumazet Feb. 10, 2023, 3:26 p.m. UTC
If TCA_STAB attribute is malformed, qdisc_get_stab() returns
an error, and we end up calling ops->destroy() while ops->init()
has not been called yet.

While we are at it, call qdisc_put_stab() after ops->destroy().

Fixes: 1f62879e3632 ("net/sched: make stab available before ops->init() call")
Reported-by: syzbot+d44d88f1d11e6ca8576b@syzkaller.appspotmail.com
Signed-off-by: Eric Dumazet <edumazet@google.com>
Cc: Vladimir Oltean <vladimir.oltean@nxp.com>
Cc: Kurt Kanzenbach <kurt@linutronix.de>
---
 net/sched/sch_api.c | 15 ++++++++-------
 1 file changed, 8 insertions(+), 7 deletions(-)

Comments

Vladimir Oltean Feb. 10, 2023, 4:16 p.m. UTC | #1
On Fri, Feb 10, 2023 at 03:26:05PM +0000, Eric Dumazet wrote:
> If TCA_STAB attribute is malformed, qdisc_get_stab() returns
> an error, and we end up calling ops->destroy() while ops->init()
> has not been called yet.
> 
> While we are at it, call qdisc_put_stab() after ops->destroy().
> 
> Fixes: 1f62879e3632 ("net/sched: make stab available before ops->init() call")
> Reported-by: syzbot+d44d88f1d11e6ca8576b@syzkaller.appspotmail.com
> Signed-off-by: Eric Dumazet <edumazet@google.com>
> Cc: Vladimir Oltean <vladimir.oltean@nxp.com>
> Cc: Kurt Kanzenbach <kurt@linutronix.de>
> ---

Reviewed-by: Vladimir Oltean <vladimir.oltean@nxp.com>
patchwork-bot+netdevbpf@kernel.org Feb. 13, 2023, 10 a.m. UTC | #2
Hello:

This patch was applied to netdev/net-next.git (master)
by David S. Miller <davem@davemloft.net>:

On Fri, 10 Feb 2023 15:26:05 +0000 you wrote:
> If TCA_STAB attribute is malformed, qdisc_get_stab() returns
> an error, and we end up calling ops->destroy() while ops->init()
> has not been called yet.
> 
> While we are at it, call qdisc_put_stab() after ops->destroy().
> 
> Fixes: 1f62879e3632 ("net/sched: make stab available before ops->init() call")
> Reported-by: syzbot+d44d88f1d11e6ca8576b@syzkaller.appspotmail.com
> Signed-off-by: Eric Dumazet <edumazet@google.com>
> Cc: Vladimir Oltean <vladimir.oltean@nxp.com>
> Cc: Kurt Kanzenbach <kurt@linutronix.de>
> 
> [...]

Here is the summary with links:
  - [net-next] net/sched: fix error recovery in qdisc_create()
    https://git.kernel.org/netdev/net-next/c/4fab64126891

You are awesome, thank you!
diff mbox series

Patch

diff --git a/net/sched/sch_api.c b/net/sched/sch_api.c
index e9780631b5b58202068e20c42ccf1197eac2194c..aba789c30a2eb50d339b8a888495b794825e1775 100644
--- a/net/sched/sch_api.c
+++ b/net/sched/sch_api.c
@@ -1286,7 +1286,7 @@  static struct Qdisc *qdisc_create(struct net_device *dev,
 		stab = qdisc_get_stab(tca[TCA_STAB], extack);
 		if (IS_ERR(stab)) {
 			err = PTR_ERR(stab);
-			goto err_out4;
+			goto err_out3;
 		}
 		rcu_assign_pointer(sch->stab, stab);
 	}
@@ -1294,14 +1294,14 @@  static struct Qdisc *qdisc_create(struct net_device *dev,
 	if (ops->init) {
 		err = ops->init(sch, tca[TCA_OPTIONS], extack);
 		if (err != 0)
-			goto err_out5;
+			goto err_out4;
 	}
 
 	if (tca[TCA_RATE]) {
 		err = -EOPNOTSUPP;
 		if (sch->flags & TCQ_F_MQROOT) {
 			NL_SET_ERR_MSG(extack, "Cannot attach rate estimator to a multi-queue root qdisc");
-			goto err_out5;
+			goto err_out4;
 		}
 
 		err = gen_new_estimator(&sch->bstats,
@@ -1312,7 +1312,7 @@  static struct Qdisc *qdisc_create(struct net_device *dev,
 					tca[TCA_RATE]);
 		if (err) {
 			NL_SET_ERR_MSG(extack, "Failed to generate new estimator");
-			goto err_out5;
+			goto err_out4;
 		}
 	}
 
@@ -1321,12 +1321,13 @@  static struct Qdisc *qdisc_create(struct net_device *dev,
 
 	return sch;
 
-err_out5:
-	qdisc_put_stab(rtnl_dereference(sch->stab));
 err_out4:
-	/* ops->init() failed, we call ->destroy() like qdisc_create_dflt() */
+	/* Even if ops->init() failed, we call ops->destroy()
+	 * like qdisc_create_dflt().
+	 */
 	if (ops->destroy)
 		ops->destroy(sch);
+	qdisc_put_stab(rtnl_dereference(sch->stab));
 err_out3:
 	netdev_put(dev, &sch->dev_tracker);
 	qdisc_free(sch);