xfrm: Add dir validation to "in" data path lookup
Introduces validation for the x->dir attribute within the XFRM input data lookup path. If the configured direction does not match the expected direction, input, increment the XfrmInStateDirError counter and drop the packet to ensure data integrity and correct flow handling. grep -vw 0 /proc/net/xfrm_stat XfrmInStateDirError 1 Signed-off-by: Antony Antony <antony.antony@secunet.com> Reviewed-by: Sabrina Dubroca <sd@queasysnail.net> Reviewed-by: Nicolas Dichtel <nicolas.dichtel@6wind.com> Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
This commit is contained in:
parent
601a0867f8
commit
304b44f0d5
@ -73,6 +73,9 @@ XfrmAcquireError:
|
||||
XfrmFwdHdrError:
|
||||
Forward routing of a packet is not allowed
|
||||
|
||||
XfrmInStateDirError:
|
||||
State direction mismatch (lookup found an output state on the input path, expected input or no direction)
|
||||
|
||||
Outbound errors
|
||||
~~~~~~~~~~~~~~~
|
||||
XfrmOutError:
|
||||
|
@ -338,6 +338,7 @@ enum
|
||||
LINUX_MIB_XFRMOUTSTATEINVALID, /* XfrmOutStateInvalid */
|
||||
LINUX_MIB_XFRMACQUIREERROR, /* XfrmAcquireError */
|
||||
LINUX_MIB_XFRMOUTSTATEDIRERROR, /* XfrmOutStateDirError */
|
||||
LINUX_MIB_XFRMINSTATEDIRERROR, /* XfrmInStateDirError */
|
||||
__LINUX_MIB_XFRMMAX
|
||||
};
|
||||
|
||||
|
@ -266,6 +266,13 @@ int xfrm6_input_addr(struct sk_buff *skb, xfrm_address_t *daddr,
|
||||
if (!x)
|
||||
continue;
|
||||
|
||||
if (unlikely(x->dir && x->dir != XFRM_SA_DIR_IN)) {
|
||||
XFRM_INC_STATS(net, LINUX_MIB_XFRMINSTATEDIRERROR);
|
||||
xfrm_state_put(x);
|
||||
x = NULL;
|
||||
continue;
|
||||
}
|
||||
|
||||
spin_lock(&x->lock);
|
||||
|
||||
if ((!i || (x->props.flags & XFRM_STATE_WILDRECV)) &&
|
||||
|
@ -466,6 +466,11 @@ int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type)
|
||||
if (encap_type < 0 || (xo && xo->flags & XFRM_GRO)) {
|
||||
x = xfrm_input_state(skb);
|
||||
|
||||
if (unlikely(x->dir && x->dir != XFRM_SA_DIR_IN)) {
|
||||
XFRM_INC_STATS(net, LINUX_MIB_XFRMINSTATEDIRERROR);
|
||||
goto drop;
|
||||
}
|
||||
|
||||
if (unlikely(x->km.state != XFRM_STATE_VALID)) {
|
||||
if (x->km.state == XFRM_STATE_ACQ)
|
||||
XFRM_INC_STATS(net, LINUX_MIB_XFRMACQUIREERROR);
|
||||
@ -571,6 +576,12 @@ int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type)
|
||||
goto drop;
|
||||
}
|
||||
|
||||
if (unlikely(x->dir && x->dir != XFRM_SA_DIR_IN)) {
|
||||
XFRM_INC_STATS(net, LINUX_MIB_XFRMINSTATEDIRERROR);
|
||||
xfrm_state_put(x);
|
||||
goto drop;
|
||||
}
|
||||
|
||||
skb->mark = xfrm_smark_get(skb->mark, x);
|
||||
|
||||
sp->xvec[sp->len++] = x;
|
||||
|
@ -42,6 +42,7 @@ static const struct snmp_mib xfrm_mib_list[] = {
|
||||
SNMP_MIB_ITEM("XfrmOutStateInvalid", LINUX_MIB_XFRMOUTSTATEINVALID),
|
||||
SNMP_MIB_ITEM("XfrmAcquireError", LINUX_MIB_XFRMACQUIREERROR),
|
||||
SNMP_MIB_ITEM("XfrmOutStateDirError", LINUX_MIB_XFRMOUTSTATEDIRERROR),
|
||||
SNMP_MIB_ITEM("XfrmInStateDirError", LINUX_MIB_XFRMINSTATEDIRERROR),
|
||||
SNMP_MIB_SENTINEL
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user