Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a447189e authored by David S. Miller's avatar David S. Miller
Browse files

nfnetlink_queue: Stop using NLA_PUT*().



These macros contain a hidden goto, and are thus extremely error
prone and make code hard to audit.

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 444653f6
Loading
Loading
Loading
Loading
+35 −24
Original line number Original line Diff line number Diff line
@@ -288,58 +288,67 @@ nfqnl_build_packet_message(struct nfqnl_instance *queue,
	indev = entry->indev;
	indev = entry->indev;
	if (indev) {
	if (indev) {
#ifndef CONFIG_BRIDGE_NETFILTER
#ifndef CONFIG_BRIDGE_NETFILTER
		NLA_PUT_BE32(skb, NFQA_IFINDEX_INDEV, htonl(indev->ifindex));
		if (nla_put_be32(skb, NFQA_IFINDEX_INDEV, htonl(indev->ifindex)))
			goto nla_put_failure;
#else
#else
		if (entry->pf == PF_BRIDGE) {
		if (entry->pf == PF_BRIDGE) {
			/* Case 1: indev is physical input device, we need to
			/* Case 1: indev is physical input device, we need to
			 * look for bridge group (when called from
			 * look for bridge group (when called from
			 * netfilter_bridge) */
			 * netfilter_bridge) */
			NLA_PUT_BE32(skb, NFQA_IFINDEX_PHYSINDEV,
			if (nla_put_be32(skb, NFQA_IFINDEX_PHYSINDEV,
				     htonl(indev->ifindex));
					 htonl(indev->ifindex)) ||
			/* this is the bridge group "brX" */
			/* this is the bridge group "brX" */
			/* rcu_read_lock()ed by __nf_queue */
			/* rcu_read_lock()ed by __nf_queue */
			NLA_PUT_BE32(skb, NFQA_IFINDEX_INDEV,
			    nla_put_be32(skb, NFQA_IFINDEX_INDEV,
				     htonl(br_port_get_rcu(indev)->br->dev->ifindex));
					 htonl(br_port_get_rcu(indev)->br->dev->ifindex)))
				goto nla_put_failure;
		} else {
		} else {
			/* Case 2: indev is bridge group, we need to look for
			/* Case 2: indev is bridge group, we need to look for
			 * physical device (when called from ipv4) */
			 * physical device (when called from ipv4) */
			NLA_PUT_BE32(skb, NFQA_IFINDEX_INDEV,
			if (nla_put_be32(skb, NFQA_IFINDEX_INDEV,
				     htonl(indev->ifindex));
					 htonl(indev->ifindex)))
			if (entskb->nf_bridge && entskb->nf_bridge->physindev)
				goto nla_put_failure;
				NLA_PUT_BE32(skb, NFQA_IFINDEX_PHYSINDEV,
			if (entskb->nf_bridge && entskb->nf_bridge->physindev &&
					     htonl(entskb->nf_bridge->physindev->ifindex));
			    nla_put_be32(skb, NFQA_IFINDEX_PHYSINDEV,
					 htonl(entskb->nf_bridge->physindev->ifindex)))
				goto nla_put_failure;
		}
		}
#endif
#endif
	}
	}


	if (outdev) {
	if (outdev) {
#ifndef CONFIG_BRIDGE_NETFILTER
#ifndef CONFIG_BRIDGE_NETFILTER
		NLA_PUT_BE32(skb, NFQA_IFINDEX_OUTDEV, htonl(outdev->ifindex));
		if (nla_put_be32(skb, NFQA_IFINDEX_OUTDEV, htonl(outdev->ifindex)))
			goto nla_put_failure;
#else
#else
		if (entry->pf == PF_BRIDGE) {
		if (entry->pf == PF_BRIDGE) {
			/* Case 1: outdev is physical output device, we need to
			/* Case 1: outdev is physical output device, we need to
			 * look for bridge group (when called from
			 * look for bridge group (when called from
			 * netfilter_bridge) */
			 * netfilter_bridge) */
			NLA_PUT_BE32(skb, NFQA_IFINDEX_PHYSOUTDEV,
			if (nla_put_be32(skb, NFQA_IFINDEX_PHYSOUTDEV,
				     htonl(outdev->ifindex));
					 htonl(outdev->ifindex)) ||
			/* this is the bridge group "brX" */
			/* this is the bridge group "brX" */
			/* rcu_read_lock()ed by __nf_queue */
			/* rcu_read_lock()ed by __nf_queue */
			NLA_PUT_BE32(skb, NFQA_IFINDEX_OUTDEV,
			    nla_put_be32(skb, NFQA_IFINDEX_OUTDEV,
				     htonl(br_port_get_rcu(outdev)->br->dev->ifindex));
					 htonl(br_port_get_rcu(outdev)->br->dev->ifindex)))
				goto nla_put_failure;
		} else {
		} else {
			/* Case 2: outdev is bridge group, we need to look for
			/* Case 2: outdev is bridge group, we need to look for
			 * physical output device (when called from ipv4) */
			 * physical output device (when called from ipv4) */
			NLA_PUT_BE32(skb, NFQA_IFINDEX_OUTDEV,
			if (nla_put_be32(skb, NFQA_IFINDEX_OUTDEV,
				     htonl(outdev->ifindex));
					 htonl(outdev->ifindex)))
			if (entskb->nf_bridge && entskb->nf_bridge->physoutdev)
				goto nla_put_failure;
				NLA_PUT_BE32(skb, NFQA_IFINDEX_PHYSOUTDEV,
			if (entskb->nf_bridge && entskb->nf_bridge->physoutdev &&
					     htonl(entskb->nf_bridge->physoutdev->ifindex));
			    nla_put_be32(skb, NFQA_IFINDEX_PHYSOUTDEV,
					 htonl(entskb->nf_bridge->physoutdev->ifindex)))
				goto nla_put_failure;
		}
		}
#endif
#endif
	}
	}


	if (entskb->mark)
	if (entskb->mark &&
		NLA_PUT_BE32(skb, NFQA_MARK, htonl(entskb->mark));
	    nla_put_be32(skb, NFQA_MARK, htonl(entskb->mark)))
		goto nla_put_failure;


	if (indev && entskb->dev &&
	if (indev && entskb->dev &&
	    entskb->mac_header != entskb->network_header) {
	    entskb->mac_header != entskb->network_header) {
@@ -347,7 +356,8 @@ nfqnl_build_packet_message(struct nfqnl_instance *queue,
		int len = dev_parse_header(entskb, phw.hw_addr);
		int len = dev_parse_header(entskb, phw.hw_addr);
		if (len) {
		if (len) {
			phw.hw_addrlen = htons(len);
			phw.hw_addrlen = htons(len);
			NLA_PUT(skb, NFQA_HWADDR, sizeof(phw), &phw);
			if (nla_put(skb, NFQA_HWADDR, sizeof(phw), &phw))
				goto nla_put_failure;
		}
		}
	}
	}


@@ -357,7 +367,8 @@ nfqnl_build_packet_message(struct nfqnl_instance *queue,
		ts.sec = cpu_to_be64(tv.tv_sec);
		ts.sec = cpu_to_be64(tv.tv_sec);
		ts.usec = cpu_to_be64(tv.tv_usec);
		ts.usec = cpu_to_be64(tv.tv_usec);


		NLA_PUT(skb, NFQA_TIMESTAMP, sizeof(ts), &ts);
		if (nla_put(skb, NFQA_TIMESTAMP, sizeof(ts), &ts))
			goto nla_put_failure;
	}
	}


	if (data_len) {
	if (data_len) {