Skip to content

Commit 2793a23

Browse files
wdebruijdavem330
authored andcommitted
net: validate variable length ll headers
Netdevice parameter hard_header_len is variously interpreted both as an upper and lower bound on link layer header length. The field is used as upper bound when reserving room at allocation, as lower bound when validating user input in PF_PACKET. Clarify the definition to be maximum header length. For validation of untrusted headers, add an optional validate member to header_ops. Allow bypassing of validation by passing CAP_SYS_RAWIO, for instance for deliberate testing of corrupt input. In this case, pad trailing bytes, as some device drivers expect completely initialized headers. See also http://comments.gmane.org/gmane.linux.network/401064 Signed-off-by: Willem de Bruijn <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 9531ab6 commit 2793a23

File tree

1 file changed

+20
-2
lines changed

1 file changed

+20
-2
lines changed

include/linux/netdevice.h

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -268,6 +268,7 @@ struct header_ops {
268268
void (*cache_update)(struct hh_cache *hh,
269269
const struct net_device *dev,
270270
const unsigned char *haddr);
271+
bool (*validate)(const char *ll_header, unsigned int len);
271272
};
272273

273274
/* These flag bits are private to the generic network queueing
@@ -1459,8 +1460,7 @@ enum netdev_priv_flags {
14591460
* @dma: DMA channel
14601461
* @mtu: Interface MTU value
14611462
* @type: Interface hardware type
1462-
* @hard_header_len: Hardware header length, which means that this is the
1463-
* minimum size of a packet.
1463+
* @hard_header_len: Maximum hardware header length.
14641464
*
14651465
* @needed_headroom: Extra headroom the hardware may need, but not in all
14661466
* cases can this be guaranteed
@@ -2687,6 +2687,24 @@ static inline int dev_parse_header(const struct sk_buff *skb,
26872687
return dev->header_ops->parse(skb, haddr);
26882688
}
26892689

2690+
/* ll_header must have at least hard_header_len allocated */
2691+
static inline bool dev_validate_header(const struct net_device *dev,
2692+
char *ll_header, int len)
2693+
{
2694+
if (likely(len >= dev->hard_header_len))
2695+
return true;
2696+
2697+
if (capable(CAP_SYS_RAWIO)) {
2698+
memset(ll_header + len, 0, dev->hard_header_len - len);
2699+
return true;
2700+
}
2701+
2702+
if (dev->header_ops && dev->header_ops->validate)
2703+
return dev->header_ops->validate(ll_header, len);
2704+
2705+
return false;
2706+
}
2707+
26902708
typedef int gifconf_func_t(struct net_device * dev, char __user * bufptr, int len);
26912709
int register_gifconf(unsigned int family, gifconf_func_t *gifconf);
26922710
static inline int unregister_gifconf(unsigned int family)

0 commit comments

Comments
 (0)