Code: static int ndp_sock_recv(struct ndp *ndp)
{
	struct ndp_msg *msg;
	enum ndp_msg_type msg_type;
	size_t len;
	int err;

	msg = ndp_msg_alloc();
	if (!msg)
		return -ENOMEM;
 
 	len = ndp_msg_payload_maxlen(msg);
 	err = myrecvfrom6(ndp->sock, msg->buf, &len, 0,
			  &msg->addrto, &msg->ifindex);
 	if (err) {
 		err(ndp, "Failed to receive message");
 		goto free_msg;
 	}
	dbg(ndp, "rcvd from: %s, ifindex: %u",
		 str_in6_addr(&msg->addrto), msg->ifindex);
 
 	if (len < sizeof(*msg->icmp6_hdr)) {
 		warn(ndp, "rcvd icmp6 packet too short (%luB)", len);
		err = 0;
		goto free_msg;
	}
	err = ndp_msg_type_by_raw_type(&msg_type, msg->icmp6_hdr->icmp6_type);
	if (err) {
		err = 0;
		goto free_msg;
	}
	ndp_msg_init(msg, msg_type);
	ndp_msg_payload_len_set(msg, len);

	if (!ndp_msg_check_valid(msg)) {
		warn(ndp, "rcvd invalid ND message");
		err = 0;
		goto free_msg;
	}

	dbg(ndp, "rcvd %s, len: %zuB",
		 ndp_msg_type_info(msg_type)->strabbr, len);

	if (!ndp_msg_check_opts(msg)) {
		err = 0;
		goto free_msg;
	}

	err = ndp_call_handlers(ndp, msg);;

free_msg:
	ndp_msg_destroy(msg);
	return err;
}

Vulnerability Type: DoS 
CWE ID: CWE-284
Summary: libndp before 1.6, as used in NetworkManager, does not properly validate the origin of Neighbor Discovery Protocol (NDP) messages, which allows remote attackers to conduct man-in-the-middle attacks or cause a denial of service (network connectivity disruption) by advertising a node as a router from a non-local network.
Commit Message: libndp: validate the IPv6 hop limit

None of the NDP messages should ever come from a non-local network; as
stated in RFC4861's 6.1.1 (RS), 6.1.2 (RA), 7.1.1 (NS), 7.1.2 (NA),
and 8.1. (redirect):

  - The IP Hop Limit field has a value of 255, i.e., the packet
    could not possibly have been forwarded by a router.

This fixes CVE-2016-3698.

Reported by: Julien BERNARD <julien.bernard@viagenie.ca>
Signed-off-by: Lubomir Rintel <lkundrak@v3.sk>
Signed-off-by: Jiri Pirko <jiri@mellanox.com>