diff options
Diffstat (limited to 'net/netlink')
| -rw-r--r-- | net/netlink/af_netlink.c | 4 | ||||
| -rw-r--r-- | net/netlink/genetlink.c | 21 | 
2 files changed, 25 insertions, 0 deletions
| diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c index b077b90c1254..34a656d90175 100644 --- a/net/netlink/af_netlink.c +++ b/net/netlink/af_netlink.c @@ -1773,6 +1773,9 @@ struct sk_buff *netlink_alloc_skb(struct sock *ssk, unsigned int size,  	if (ring->pg_vec == NULL)  		goto out_put; +	if (ring->frame_size - NL_MMAP_HDRLEN < size) +		goto out_put; +  	skb = alloc_skb_head(gfp_mask);  	if (skb == NULL)  		goto err1; @@ -1782,6 +1785,7 @@ struct sk_buff *netlink_alloc_skb(struct sock *ssk, unsigned int size,  	if (ring->pg_vec == NULL)  		goto out_free; +	/* check again under lock */  	maxlen = ring->frame_size - NL_MMAP_HDRLEN;  	if (maxlen < size)  		goto out_free; diff --git a/net/netlink/genetlink.c b/net/netlink/genetlink.c index 713671ae45af..b1dcdb932a86 100644 --- a/net/netlink/genetlink.c +++ b/net/netlink/genetlink.c @@ -461,6 +461,26 @@ int genl_unregister_family(struct genl_family *family)  EXPORT_SYMBOL(genl_unregister_family);  /** + * genlmsg_new_unicast - Allocate generic netlink message for unicast + * @payload: size of the message payload + * @info: information on destination + * @flags: the type of memory to allocate + * + * Allocates a new sk_buff large enough to cover the specified payload + * plus required Netlink headers. Will check receiving socket for + * memory mapped i/o capability and use it if enabled. Will fall back + * to non-mapped skb if message size exceeds the frame size of the ring. + */ +struct sk_buff *genlmsg_new_unicast(size_t payload, struct genl_info *info, +				    gfp_t flags) +{ +	size_t len = nlmsg_total_size(genlmsg_total_size(payload)); + +	return netlink_alloc_skb(info->dst_sk, len, info->snd_portid, flags); +} +EXPORT_SYMBOL_GPL(genlmsg_new_unicast); + +/**   * genlmsg_put - Add generic netlink header to netlink message   * @skb: socket buffer holding the message   * @portid: netlink portid the message is addressed to @@ -600,6 +620,7 @@ static int genl_family_rcv_msg(struct genl_family *family,  	info.genlhdr = nlmsg_data(nlh);  	info.userhdr = nlmsg_data(nlh) + GENL_HDRLEN;  	info.attrs = attrbuf; +	info.dst_sk = skb->sk;  	genl_info_net_set(&info, net);  	memset(&info.user_ptr, 0, sizeof(info.user_ptr)); | 
