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

Commit 342dfc30 authored by Steffen Hurrle's avatar Steffen Hurrle Committed by David S. Miller
Browse files

net: add build-time checks for msg->msg_name size



This is a follow-up patch to f3d33426 ("net: rework recvmsg
handler msg_name and msg_namelen logic").

DECLARE_SOCKADDR validates that the structure we use for writing the
name information to is not larger than the buffer which is reserved
for msg->msg_name (which is 128 bytes). Also use DECLARE_SOCKADDR
consistently in sendmsg code paths.

Signed-off-by: default avatarSteffen Hurrle <steffen@hurrle.net>
Suggested-by: default avatarHannes Frederic Sowa <hannes@stressinduktion.org>
Acked-by: default avatarHannes Frederic Sowa <hannes@stressinduktion.org>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent ea02f941
Loading
Loading
Loading
Loading
+2 −3
Original line number Diff line number Diff line
@@ -135,7 +135,7 @@ mISDN_sock_recvmsg(struct kiocb *iocb, struct socket *sock,
		return err;

	if (msg->msg_name) {
		struct sockaddr_mISDN *maddr = msg->msg_name;
		DECLARE_SOCKADDR(struct sockaddr_mISDN *, maddr, msg->msg_name);

		maddr->family = AF_ISDN;
		maddr->dev = _pms(sk)->dev->id;
@@ -179,7 +179,6 @@ mISDN_sock_sendmsg(struct kiocb *iocb, struct socket *sock,
	struct sock		*sk = sock->sk;
	struct sk_buff		*skb;
	int			err = -ENOMEM;
	struct sockaddr_mISDN	*maddr;

	if (*debug & DEBUG_SOCKET)
		printk(KERN_DEBUG "%s: len %d flags %x ch %d proto %x\n",
@@ -214,7 +213,7 @@ mISDN_sock_sendmsg(struct kiocb *iocb, struct socket *sock,

	if (msg->msg_namelen >= sizeof(struct sockaddr_mISDN)) {
		/* if we have a address, we use it */
		maddr = (struct sockaddr_mISDN *)msg->msg_name;
		DECLARE_SOCKADDR(struct sockaddr_mISDN *, maddr, msg->msg_name);
		mISDN_HEAD_ID(skb) = maddr->channel;
	} else { /* use default for L2 messages */
		if ((sk->sk_protocol == ISDN_P_LAPD_TE) ||
+2 −2
Original line number Diff line number Diff line
@@ -1566,7 +1566,7 @@ static int atalk_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr
{
	struct sock *sk = sock->sk;
	struct atalk_sock *at = at_sk(sk);
	struct sockaddr_at *usat = (struct sockaddr_at *)msg->msg_name;
	DECLARE_SOCKADDR(struct sockaddr_at *, usat, msg->msg_name);
	int flags = msg->msg_flags;
	int loopback = 0;
	struct sockaddr_at local_satalk, gsat;
@@ -1764,7 +1764,7 @@ static int atalk_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr
	err = skb_copy_datagram_iovec(skb, offset, msg->msg_iov, copied);

	if (!err && msg->msg_name) {
		struct sockaddr_at *sat = msg->msg_name;
		DECLARE_SOCKADDR(struct sockaddr_at *, sat, msg->msg_name);
		sat->sat_family      = AF_APPLETALK;
		sat->sat_port        = ddp->deh_sport;
		sat->sat_addr.s_node = ddp->deh_snode;
+2 −2
Original line number Diff line number Diff line
@@ -1435,7 +1435,7 @@ static int ax25_getname(struct socket *sock, struct sockaddr *uaddr,
static int ax25_sendmsg(struct kiocb *iocb, struct socket *sock,
			struct msghdr *msg, size_t len)
{
	struct sockaddr_ax25 *usax = (struct sockaddr_ax25 *)msg->msg_name;
	DECLARE_SOCKADDR(struct sockaddr_ax25 *, usax, msg->msg_name);
	struct sock *sk = sock->sk;
	struct sockaddr_ax25 sax;
	struct sk_buff *skb;
@@ -1640,7 +1640,7 @@ static int ax25_recvmsg(struct kiocb *iocb, struct socket *sock,
		ax25_digi digi;
		ax25_address src;
		const unsigned char *mac = skb_mac_header(skb);
		struct sockaddr_ax25 *sax = msg->msg_name;
		DECLARE_SOCKADDR(struct sockaddr_ax25 *, sax, msg->msg_name);

		memset(sax, 0, sizeof(struct full_sockaddr_ax25));
		ax25_addr_parse(mac + 1, skb->data - mac - 1, &src, NULL,
+1 −1
Original line number Diff line number Diff line
@@ -1413,7 +1413,7 @@ static void l2cap_sock_destruct(struct sock *sk)
static void l2cap_skb_msg_name(struct sk_buff *skb, void *msg_name,
			       int *msg_namelen)
{
	struct sockaddr_l2 *la = (struct sockaddr_l2 *) msg_name;
	DECLARE_SOCKADDR(struct sockaddr_l2 *, la, msg_name);

	memset(la, 0, sizeof(struct sockaddr_l2));
	la->l2_family = AF_BLUETOOTH;
+2 −2
Original line number Diff line number Diff line
@@ -1256,8 +1256,7 @@ static int bcm_sendmsg(struct kiocb *iocb, struct socket *sock,

	if (!ifindex && msg->msg_name) {
		/* no bound device as default => check msg_name */
		struct sockaddr_can *addr =
			(struct sockaddr_can *)msg->msg_name;
		DECLARE_SOCKADDR(struct sockaddr_can *, addr, msg->msg_name);

		if (msg->msg_namelen < sizeof(*addr))
			return -EINVAL;
@@ -1568,6 +1567,7 @@ static int bcm_recvmsg(struct kiocb *iocb, struct socket *sock,
	sock_recv_ts_and_drops(msg, sk, skb);

	if (msg->msg_name) {
		__sockaddr_check_size(sizeof(struct sockaddr_can));
		msg->msg_namelen = sizeof(struct sockaddr_can);
		memcpy(msg->msg_name, skb->cb, msg->msg_namelen);
	}
Loading