Skip to content

Commit d214c75

Browse files
ummakynesdavem330
authored andcommitted
filter: add SKF_AD_NLATTR_NEST to look for nested attributes
SKF_AD_NLATTR allows us to find the first matching attribute in a stream of netlink attributes from one offset to the end of the netlink message. This is not suitable to look for a specific matching inside a set of nested attributes. For example, in ctnetlink messages, if we look for the CTA_V6_SRC attribute in a message that talks about an IPv4 connection, SKF_AD_NLATTR returns the offset of CTA_STATUS which has the same value of CTA_V6_SRC but outside the nest. To differenciate CTA_STATUS and CTA_V6_SRC, we would have to make assumptions on the size of the attribute and the usual offset, resulting in horrible BSF code. This patch adds SKF_AD_NLATTR_NEST, which is a variant of SKF_AD_NLATTR, that looks for an attribute inside the limits of a nested attributes, but not further. This patch validates that we have enough room to look for the nested attributes - based on a suggestion from Patrick McHardy. Signed-off-by: Pablo Neira Ayuso <[email protected]> Acked-by: Patrick McHardy <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 68fd991 commit d214c75

File tree

2 files changed

+21
-1
lines changed

2 files changed

+21
-1
lines changed

include/linux/filter.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,8 @@ struct sock_fprog /* Required for SO_ATTACH_FILTER. */
122122
#define SKF_AD_PKTTYPE 4
123123
#define SKF_AD_IFINDEX 8
124124
#define SKF_AD_NLATTR 12
125-
#define SKF_AD_MAX 16
125+
#define SKF_AD_NLATTR_NEST 16
126+
#define SKF_AD_MAX 20
126127
#define SKF_NET_OFF (-0x100000)
127128
#define SKF_LL_OFF (-0x200000)
128129

net/core/filter.c

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -319,6 +319,25 @@ unsigned int sk_run_filter(struct sk_buff *skb, struct sock_filter *filter, int
319319
A = 0;
320320
continue;
321321
}
322+
case SKF_AD_NLATTR_NEST: {
323+
struct nlattr *nla;
324+
325+
if (skb_is_nonlinear(skb))
326+
return 0;
327+
if (A > skb->len - sizeof(struct nlattr))
328+
return 0;
329+
330+
nla = (struct nlattr *)&skb->data[A];
331+
if (nla->nla_len > A - skb->len)
332+
return 0;
333+
334+
nla = nla_find_nested(nla, X);
335+
if (nla)
336+
A = (void *)nla - (void *)skb->data;
337+
else
338+
A = 0;
339+
continue;
340+
}
322341
default:
323342
return 0;
324343
}

0 commit comments

Comments
 (0)