linux-next: umh: fix processed error when UMH_WAIT_PROC is used seems to break linux bridge on s390x (bisected)
Luis Chamberlain
mcgrof at kernel.org
Wed Jul 1 13:46:35 UTC 2020
On Wed, Jul 01, 2020 at 12:08:11PM +0200, Christian Borntraeger wrote:
> dmesg attached
> [ 14.438482] virbr0: port 1(virbr0-nic) entered blocking state
> [ 14.438485] virbr0: port 1(virbr0-nic) entered disabled state
> [ 14.438635] device virbr0-nic entered promiscuous mode
> [ 14.439654] umh: sub_info->path: /sbin/bridge-stp
> [ 14.439656] /sbin/bridge-stp
> [ 14.439656] virbr0
> [ 14.439656] start
OK so what we seem to want to debug is the umh call for:
/sbin/bridge-stp virbr0 start
> [ 14.439734] == ret: 00
> [ 14.439735] == KWIFEXITED(ret): 01
> [ 14.439736] KWEXITSTATUS(ret): 0
Its not clear if this is the respective return value, but now
that we have a clue that this is the the only non-modprobe
call, we should have a clearer certainty that this is the
issue.
Indeed my patch "umh: fix processed error when UMH_WAIT_PROC is used"
did modify bridge-stp in the following way:
diff --git a/net/bridge/br_stp_if.c b/net/bridge/br_stp_if.c
index ba55851fe132..bdd94b45396b 100644
--- a/net/bridge/br_stp_if.c
+++ b/net/bridge/br_stp_if.c
@@ -133,14 +133,8 @@ static int br_stp_call_user(struct net_bridge *br, char *arg)
/* call userspace STP and report program errors */
rc = call_usermodehelper(BR_STP_PROG, argv, envp, UMH_WAIT_PROC);
- if (rc > 0) {
- if (rc & 0xff)
- br_debug(br, BR_STP_PROG " received signal %d\n",
- rc & 0x7f);
- else
- br_debug(br, BR_STP_PROG " exited with code %d\n",
- (rc >> 8) & 0xff);
- }
+ if (rc != 0)
+ br_debug(br, BR_STP_PROG " failed with exit code %d\n", rc);
return rc;
}
If you look at this carefully though you'll notice that the change just
modifies *when* we issue the debug print. The more important relevant
part of the patch however was that we now do return a correct error
value when the call fails.
More importantly, depending on if an error or not we run the kernel STP
or userspace STP later:
static void br_stp_start(struct net_bridge *br)
{
int err = -ENOENT;
if (net_eq(dev_net(br->dev), &init_net))
err = br_stp_call_user(br, "start");
if (err && err != -ENOENT)
br_err(br, "failed to start userspace STP (%d)\n", err);
spin_lock_bh(&br->lock);
if (br->bridge_forward_delay < BR_MIN_FORWARD_DELAY)
__br_set_forward_delay(br, BR_MIN_FORWARD_DELAY);
else if (br->bridge_forward_delay > BR_MAX_FORWARD_DELAY)
__br_set_forward_delay(br, BR_MAX_FORWARD_DELAY);
---------------------> can you enable debug print for this to see what
---------------------> you end up using?
if (!err) {
br->stp_enabled = BR_USER_STP;
br_debug(br, "userspace STP started\n");
} else {
br->stp_enabled = BR_KERNEL_STP;
br_debug(br, "using kernel STP\n");
/* To start timers on any ports left in blocking */
if (br->dev->flags & IFF_UP)
mod_timer(&br->hello_timer, jiffies + br->hello_time);
br_port_state_selection(br);
}
----------------->
spin_unlock_bh(&br->lock);
}
More information about the Linux-security-module-archive
mailing list