diff options
Diffstat (limited to 'net/netfilter/nfnetlink_log.c')
| -rw-r--r-- | net/netfilter/nfnetlink_log.c | 100 | 
1 files changed, 58 insertions, 42 deletions
diff --git a/net/netfilter/nfnetlink_log.c b/net/netfilter/nfnetlink_log.c index 66b2c54c544..3c3cfc0cc9b 100644 --- a/net/netfilter/nfnetlink_log.c +++ b/net/netfilter/nfnetlink_log.c @@ -391,67 +391,78 @@ __build_packet_message(struct nfulnl_instance *inst,  	pmsg.hw_protocol	= skb->protocol;  	pmsg.hook		= hooknum; -	NLA_PUT(inst->skb, NFULA_PACKET_HDR, sizeof(pmsg), &pmsg); +	if (nla_put(inst->skb, NFULA_PACKET_HDR, sizeof(pmsg), &pmsg)) +		goto nla_put_failure; -	if (prefix) -		NLA_PUT(inst->skb, NFULA_PREFIX, plen, prefix); +	if (prefix && +	    nla_put(inst->skb, NFULA_PREFIX, plen, prefix)) +		goto nla_put_failure;  	if (indev) {  #ifndef CONFIG_BRIDGE_NETFILTER -		NLA_PUT_BE32(inst->skb, NFULA_IFINDEX_INDEV, -			     htonl(indev->ifindex)); +		if (nla_put_be32(inst->skb, NFULA_IFINDEX_INDEV, +				 htonl(indev->ifindex))) +			goto nla_put_failure;  #else  		if (pf == PF_BRIDGE) {  			/* Case 1: outdev is physical input device, we need to  			 * look for bridge group (when called from  			 * netfilter_bridge) */ -			NLA_PUT_BE32(inst->skb, NFULA_IFINDEX_PHYSINDEV, -				     htonl(indev->ifindex)); +			if (nla_put_be32(inst->skb, NFULA_IFINDEX_PHYSINDEV, +					 htonl(indev->ifindex)) ||  			/* this is the bridge group "brX" */  			/* rcu_read_lock()ed by nf_hook_slow or nf_log_packet */ -			NLA_PUT_BE32(inst->skb, NFULA_IFINDEX_INDEV, -				     htonl(br_port_get_rcu(indev)->br->dev->ifindex)); +			    nla_put_be32(inst->skb, NFULA_IFINDEX_INDEV, +					 htonl(br_port_get_rcu(indev)->br->dev->ifindex))) +				goto nla_put_failure;  		} else {  			/* Case 2: indev is bridge group, we need to look for  			 * physical device (when called from ipv4) */ -			NLA_PUT_BE32(inst->skb, NFULA_IFINDEX_INDEV, -				     htonl(indev->ifindex)); -			if (skb->nf_bridge && skb->nf_bridge->physindev) -				NLA_PUT_BE32(inst->skb, NFULA_IFINDEX_PHYSINDEV, -					     htonl(skb->nf_bridge->physindev->ifindex)); +			if (nla_put_be32(inst->skb, NFULA_IFINDEX_INDEV, +					 htonl(indev->ifindex))) +				goto nla_put_failure; +			if (skb->nf_bridge && skb->nf_bridge->physindev && +			    nla_put_be32(inst->skb, NFULA_IFINDEX_PHYSINDEV, +					 htonl(skb->nf_bridge->physindev->ifindex))) +				goto nla_put_failure;  		}  #endif  	}  	if (outdev) {  #ifndef CONFIG_BRIDGE_NETFILTER -		NLA_PUT_BE32(inst->skb, NFULA_IFINDEX_OUTDEV, -			     htonl(outdev->ifindex)); +		if (nla_put_be32(inst->skb, NFULA_IFINDEX_OUTDEV, +				 htonl(outdev->ifindex))) +			goto nla_put_failure;  #else  		if (pf == PF_BRIDGE) {  			/* Case 1: outdev is physical output device, we need to  			 * look for bridge group (when called from  			 * netfilter_bridge) */ -			NLA_PUT_BE32(inst->skb, NFULA_IFINDEX_PHYSOUTDEV, -				     htonl(outdev->ifindex)); +			if (nla_put_be32(inst->skb, NFULA_IFINDEX_PHYSOUTDEV, +					 htonl(outdev->ifindex)) ||  			/* this is the bridge group "brX" */  			/* rcu_read_lock()ed by nf_hook_slow or nf_log_packet */ -			NLA_PUT_BE32(inst->skb, NFULA_IFINDEX_OUTDEV, -				     htonl(br_port_get_rcu(outdev)->br->dev->ifindex)); +			    nla_put_be32(inst->skb, NFULA_IFINDEX_OUTDEV, +					 htonl(br_port_get_rcu(outdev)->br->dev->ifindex))) +				goto nla_put_failure;  		} else {  			/* Case 2: indev is a bridge group, we need to look  			 * for physical device (when called from ipv4) */ -			NLA_PUT_BE32(inst->skb, NFULA_IFINDEX_OUTDEV, -				     htonl(outdev->ifindex)); -			if (skb->nf_bridge && skb->nf_bridge->physoutdev) -				NLA_PUT_BE32(inst->skb, NFULA_IFINDEX_PHYSOUTDEV, -					     htonl(skb->nf_bridge->physoutdev->ifindex)); +			if (nla_put_be32(inst->skb, NFULA_IFINDEX_OUTDEV, +					 htonl(outdev->ifindex))) +				goto nla_put_failure; +			if (skb->nf_bridge && skb->nf_bridge->physoutdev && +			    nla_put_be32(inst->skb, NFULA_IFINDEX_PHYSOUTDEV, +					 htonl(skb->nf_bridge->physoutdev->ifindex))) +				goto nla_put_failure;  		}  #endif  	} -	if (skb->mark) -		NLA_PUT_BE32(inst->skb, NFULA_MARK, htonl(skb->mark)); +	if (skb->mark && +	    nla_put_be32(inst->skb, NFULA_MARK, htonl(skb->mark))) +		goto nla_put_failure;  	if (indev && skb->dev &&  	    skb->mac_header != skb->network_header) { @@ -459,16 +470,18 @@ __build_packet_message(struct nfulnl_instance *inst,  		int len = dev_parse_header(skb, phw.hw_addr);  		if (len > 0) {  			phw.hw_addrlen = htons(len); -			NLA_PUT(inst->skb, NFULA_HWADDR, sizeof(phw), &phw); +			if (nla_put(inst->skb, NFULA_HWADDR, sizeof(phw), &phw)) +				goto nla_put_failure;  		}  	}  	if (indev && skb_mac_header_was_set(skb)) { -		NLA_PUT_BE16(inst->skb, NFULA_HWTYPE, htons(skb->dev->type)); -		NLA_PUT_BE16(inst->skb, NFULA_HWLEN, -			     htons(skb->dev->hard_header_len)); -		NLA_PUT(inst->skb, NFULA_HWHEADER, skb->dev->hard_header_len, -			skb_mac_header(skb)); +		if (nla_put_be32(inst->skb, NFULA_HWTYPE, htons(skb->dev->type)) || +		    nla_put_be16(inst->skb, NFULA_HWLEN, +				 htons(skb->dev->hard_header_len)) || +		    nla_put(inst->skb, NFULA_HWHEADER, skb->dev->hard_header_len, +			    skb_mac_header(skb))) +			goto nla_put_failure;  	}  	if (skb->tstamp.tv64) { @@ -477,7 +490,8 @@ __build_packet_message(struct nfulnl_instance *inst,  		ts.sec = cpu_to_be64(tv.tv_sec);  		ts.usec = cpu_to_be64(tv.tv_usec); -		NLA_PUT(inst->skb, NFULA_TIMESTAMP, sizeof(ts), &ts); +		if (nla_put(inst->skb, NFULA_TIMESTAMP, sizeof(ts), &ts)) +			goto nla_put_failure;  	}  	/* UID */ @@ -487,22 +501,24 @@ __build_packet_message(struct nfulnl_instance *inst,  			struct file *file = skb->sk->sk_socket->file;  			__be32 uid = htonl(file->f_cred->fsuid);  			__be32 gid = htonl(file->f_cred->fsgid); -			/* need to unlock here since NLA_PUT may goto */  			read_unlock_bh(&skb->sk->sk_callback_lock); -			NLA_PUT_BE32(inst->skb, NFULA_UID, uid); -			NLA_PUT_BE32(inst->skb, NFULA_GID, gid); +			if (nla_put_be32(inst->skb, NFULA_UID, uid) || +			    nla_put_be32(inst->skb, NFULA_GID, gid)) +				goto nla_put_failure;  		} else  			read_unlock_bh(&skb->sk->sk_callback_lock);  	}  	/* local sequence number */ -	if (inst->flags & NFULNL_CFG_F_SEQ) -		NLA_PUT_BE32(inst->skb, NFULA_SEQ, htonl(inst->seq++)); +	if ((inst->flags & NFULNL_CFG_F_SEQ) && +	    nla_put_be32(inst->skb, NFULA_SEQ, htonl(inst->seq++))) +		goto nla_put_failure;  	/* global sequence number */ -	if (inst->flags & NFULNL_CFG_F_SEQ_GLOBAL) -		NLA_PUT_BE32(inst->skb, NFULA_SEQ_GLOBAL, -			     htonl(atomic_inc_return(&global_seq))); +	if ((inst->flags & NFULNL_CFG_F_SEQ_GLOBAL) && +	    nla_put_be32(inst->skb, NFULA_SEQ_GLOBAL, +			 htonl(atomic_inc_return(&global_seq)))) +		goto nla_put_failure;  	if (data_len) {  		struct nlattr *nla;  | 
