浏览代码

net: check the length of the socket address passed to connect(2)

check the length of the socket address passed to connect(2).

Check the length of the socket address passed to connect(2). If the
length is invalid, -EINVAL will be returned.

Signed-off-by: Changli Gao <xiaosuo@gmail.com>
----
net/bluetooth/l2cap.c | 3 ++-
net/bluetooth/rfcomm/sock.c | 3 ++-
net/bluetooth/sco.c | 3 ++-
net/can/bcm.c | 3 +++
net/ieee802154/af_ieee802154.c | 3 +++
net/ipv4/af_inet.c | 5 +++++
net/netlink/af_netlink.c | 3 +++
7 files changed, 20 insertions(+), 3 deletions(-)
Signed-off-by: David S. Miller <davem@davemloft.net>
Changli Gao 15 年之前
父节点
当前提交
6503d96168
共有 7 个文件被更改,包括 20 次插入3 次删除
  1. 2 1
      net/bluetooth/l2cap.c
  2. 2 1
      net/bluetooth/rfcomm/sock.c
  3. 2 1
      net/bluetooth/sco.c
  4. 3 0
      net/can/bcm.c
  5. 3 0
      net/ieee802154/af_ieee802154.c
  6. 5 0
      net/ipv4/af_inet.c
  7. 3 0
      net/netlink/af_netlink.c

+ 2 - 1
net/bluetooth/l2cap.c

@@ -1002,7 +1002,8 @@ static int l2cap_sock_connect(struct socket *sock, struct sockaddr *addr, int al
 
 
 	BT_DBG("sk %p", sk);
 	BT_DBG("sk %p", sk);
 
 
-	if (!addr || addr->sa_family != AF_BLUETOOTH)
+	if (!addr || alen < sizeof(addr->sa_family) ||
+	    addr->sa_family != AF_BLUETOOTH)
 		return -EINVAL;
 		return -EINVAL;
 
 
 	memset(&la, 0, sizeof(la));
 	memset(&la, 0, sizeof(la));

+ 2 - 1
net/bluetooth/rfcomm/sock.c

@@ -397,7 +397,8 @@ static int rfcomm_sock_connect(struct socket *sock, struct sockaddr *addr, int a
 
 
 	BT_DBG("sk %p", sk);
 	BT_DBG("sk %p", sk);
 
 
-	if (addr->sa_family != AF_BLUETOOTH || alen < sizeof(struct sockaddr_rc))
+	if (alen < sizeof(struct sockaddr_rc) ||
+	    addr->sa_family != AF_BLUETOOTH)
 		return -EINVAL;
 		return -EINVAL;
 
 
 	lock_sock(sk);
 	lock_sock(sk);

+ 2 - 1
net/bluetooth/sco.c

@@ -499,7 +499,8 @@ static int sco_sock_connect(struct socket *sock, struct sockaddr *addr, int alen
 
 
 	BT_DBG("sk %p", sk);
 	BT_DBG("sk %p", sk);
 
 
-	if (addr->sa_family != AF_BLUETOOTH || alen < sizeof(struct sockaddr_sco))
+	if (alen < sizeof(struct sockaddr_sco) ||
+	    addr->sa_family != AF_BLUETOOTH)
 		return -EINVAL;
 		return -EINVAL;
 
 
 	if (sk->sk_state != BT_OPEN && sk->sk_state != BT_BOUND)
 	if (sk->sk_state != BT_OPEN && sk->sk_state != BT_BOUND)

+ 3 - 0
net/can/bcm.c

@@ -1478,6 +1478,9 @@ static int bcm_connect(struct socket *sock, struct sockaddr *uaddr, int len,
 	struct sock *sk = sock->sk;
 	struct sock *sk = sock->sk;
 	struct bcm_sock *bo = bcm_sk(sk);
 	struct bcm_sock *bo = bcm_sk(sk);
 
 
+	if (len < sizeof(*addr))
+		return -EINVAL;
+
 	if (bo->bound)
 	if (bo->bound)
 		return -EISCONN;
 		return -EISCONN;
 
 

+ 3 - 0
net/ieee802154/af_ieee802154.c

@@ -126,6 +126,9 @@ static int ieee802154_sock_connect(struct socket *sock, struct sockaddr *uaddr,
 {
 {
 	struct sock *sk = sock->sk;
 	struct sock *sk = sock->sk;
 
 
+	if (addr_len < sizeof(uaddr->sa_family))
+		return -EINVAL;
+
 	if (uaddr->sa_family == AF_UNSPEC)
 	if (uaddr->sa_family == AF_UNSPEC)
 		return sk->sk_prot->disconnect(sk, flags);
 		return sk->sk_prot->disconnect(sk, flags);
 
 

+ 5 - 0
net/ipv4/af_inet.c

@@ -530,6 +530,8 @@ int inet_dgram_connect(struct socket *sock, struct sockaddr * uaddr,
 {
 {
 	struct sock *sk = sock->sk;
 	struct sock *sk = sock->sk;
 
 
+	if (addr_len < sizeof(uaddr->sa_family))
+		return -EINVAL;
 	if (uaddr->sa_family == AF_UNSPEC)
 	if (uaddr->sa_family == AF_UNSPEC)
 		return sk->sk_prot->disconnect(sk, flags);
 		return sk->sk_prot->disconnect(sk, flags);
 
 
@@ -573,6 +575,9 @@ int inet_stream_connect(struct socket *sock, struct sockaddr *uaddr,
 	int err;
 	int err;
 	long timeo;
 	long timeo;
 
 
+	if (addr_len < sizeof(uaddr->sa_family))
+		return -EINVAL;
+
 	lock_sock(sk);
 	lock_sock(sk);
 
 
 	if (uaddr->sa_family == AF_UNSPEC) {
 	if (uaddr->sa_family == AF_UNSPEC) {

+ 3 - 0
net/netlink/af_netlink.c

@@ -683,6 +683,9 @@ static int netlink_connect(struct socket *sock, struct sockaddr *addr,
 	struct netlink_sock *nlk = nlk_sk(sk);
 	struct netlink_sock *nlk = nlk_sk(sk);
 	struct sockaddr_nl *nladdr = (struct sockaddr_nl *)addr;
 	struct sockaddr_nl *nladdr = (struct sockaddr_nl *)addr;
 
 
+	if (alen < sizeof(addr->sa_family))
+		return -EINVAL;
+
 	if (addr->sa_family == AF_UNSPEC) {
 	if (addr->sa_family == AF_UNSPEC) {
 		sk->sk_state	= NETLINK_UNCONNECTED;
 		sk->sk_state	= NETLINK_UNCONNECTED;
 		nlk->dst_pid	= 0;
 		nlk->dst_pid	= 0;