Hello, em_meta_change() copies the user-supplied header without validating hdr.shift, and meta_int_apply_extras() then executes dst->value >>= v->hdr.shift on an unsigned long. A shift count of BITS_PER_LONG or more (the field is a u8, so up to 255) is undefined behaviour - on x86 the count is hardware-masked, so the practical effect is a wrong match verdict or a UBSAN splat, not corruption. act_pedit clamps its shift for exactly this class. The patch clamps both values at change time, like act_pedit does. Affected version/commit: mainline fa4ad798f6f681031775266044ba1b0cf3c670bd (v7.4-rc1, 2026-11-07), net/sched/em_meta.c:762-770 (meta_int_apply_extras), 906-941 (em_meta_change). Longstanding code; the sibling fix pattern exists in act_pedit. This was found during an assisted (AI-supported) static source review of mainline fa4ad798f6f681031775266044ba1b0cf3c670bd (v7.4-rc1, 2026-11-07); every code path cited below was re-verified by the reporter against that tree. The patch below has NOT been compiled and has NOT been runtime tested, and no reproducer was produced - the triggering conditions are described above instead. Please treat this as a report for verification rather than a battle-tested fix. Reported-by: Noah Weinberger --- diff --git a/net/sched/em_meta.c b/net/sched/em_meta.c index 48bdd77..6681c67 100644 --- a/net/sched/em_meta.c +++ b/net/sched/em_meta.c @@ -936,6 +936,14 @@ static int em_meta_change(struct net *net, void *data, int len, memcpy(&meta->lvalue.hdr, &hdr->left, sizeof(hdr->left)); memcpy(&meta->rvalue.hdr, &hdr->right, sizeof(hdr->right)); + /* Keep the shift within the value width to avoid undefined + * behaviour in meta_int_apply_extras(), like act_pedit does. + */ + if (meta->lvalue.hdr.shift > BITS_PER_LONG - 1) + meta->lvalue.hdr.shift = BITS_PER_LONG - 1; + if (meta->rvalue.hdr.shift > BITS_PER_LONG - 1) + meta->rvalue.hdr.shift = BITS_PER_LONG - 1; + if (!meta_is_supported(&meta->lvalue) || !meta_is_supported(&meta->rvalue)) { err = -EOPNOTSUPP;