Skip to content

Commit 4b0ce98

Browse files
wkenningtongregkh
authored andcommitted
net: mctp i2c: check length before marking flow active
[ Upstream commit 4ca07b9 ] Currently, mctp_i2c_get_tx_flow_state() is called before the packet length sanity check. This function marks a new flow as active in the MCTP core. If the sanity check fails, mctp_i2c_xmit() returns early without calling mctp_i2c_lock_nest(). This results in a mismatched locking state: the flow is active, but the I2C bus lock was never acquired for it. When the flow is later released, mctp_i2c_release_flow() will see the active state and queue an unlock marker. The TX thread will then decrement midev->i2c_lock_count from 0, causing it to underflow to -1. This underflow permanently breaks the driver's locking logic, allowing future transmissions to occur without holding the I2C bus lock, leading to bus collisions and potential hardware hangs. Move the mctp_i2c_get_tx_flow_state() call to after the length sanity check to ensure we only transition the flow state if we are actually going to proceed with the transmission and locking. Fixes: f5b8abf ("mctp i2c: MCTP I2C binding driver") Signed-off-by: William A. Kennington III <william@wkennington.com> Acked-by: Jeremy Kerr <jk@codeconstruct.com.au> Link: https://patch.msgid.link/20260423074741.201460-1-william@wkennington.com Signed-off-by: Paolo Abeni <pabeni@redhat.com> Signed-off-by: Sasha Levin <sashal@kernel.org>
1 parent c71bf35 commit 4b0ce98

2 files changed

Lines changed: 5 additions & 3 deletions

File tree

drivers/net/mctp/mctp-i2c.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -497,8 +497,6 @@ static void mctp_i2c_xmit(struct mctp_i2c_dev *midev, struct sk_buff *skb)
497497
u8 *pecp;
498498
int rc;
499499

500-
fs = mctp_i2c_get_tx_flow_state(midev, skb);
501-
502500
hdr = (void *)skb_mac_header(skb);
503501
/* Sanity check that packet contents matches skb length,
504502
* and can't exceed MCTP_I2C_BUFSZ
@@ -510,6 +508,8 @@ static void mctp_i2c_xmit(struct mctp_i2c_dev *midev, struct sk_buff *skb)
510508
return;
511509
}
512510

511+
fs = mctp_i2c_get_tx_flow_state(midev, skb);
512+
513513
if (skb_tailroom(skb) >= 1) {
514514
/* Linear case with space, we can just append the PEC */
515515
skb_put(skb, 1);

net/sched/cls_flower.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -560,6 +560,7 @@ static int __fl_delete(struct tcf_proto *tp, struct cls_fl_filter *f,
560560
struct netlink_ext_ack *extack)
561561
{
562562
struct cls_fl_head *head = fl_head_dereference(tp);
563+
struct fl_flow_mask *mask;
563564

564565
*last = false;
565566

@@ -576,11 +577,12 @@ static int __fl_delete(struct tcf_proto *tp, struct cls_fl_filter *f,
576577
list_del_rcu(&f->list);
577578
spin_unlock(&tp->lock);
578579

579-
*last = fl_mask_put(head, f->mask);
580+
mask = f->mask;
580581
if (!tc_skip_hw(f->flags))
581582
fl_hw_destroy_filter(tp, f, rtnl_held, extack);
582583
tcf_unbind_filter(tp, &f->res);
583584
__fl_put(f);
585+
*last = fl_mask_put(head, mask);
584586

585587
return 0;
586588
}

0 commit comments

Comments
 (0)