net: check the length of the socket address passed to connect(2)
authorChangli Gao <xiaosuo@gmail.com>
Wed, 31 Mar 2010 22:58:26 +0000 (22:58 +0000)
committerDavid S. Miller <davem@davemloft.net>
Fri, 2 Apr 2010 00:26:01 +0000 (17:26 -0700)
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>
net/bluetooth/l2cap.c
net/bluetooth/rfcomm/sock.c
net/bluetooth/sco.c
net/can/bcm.c
net/ieee802154/af_ieee802154.c
net/ipv4/af_inet.c
net/netlink/af_netlink.c

index 7794a2e2adcea93128fc5fcf4ccf8a8e306af434..99d68c34e4f11d4de5e2b7822f07b0384798eb78 100644 (file)
@@ -1002,7 +1002,8 @@ static int l2cap_sock_connect(struct socket *sock, struct sockaddr *addr, int al
 
        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;
 
        memset(&la, 0, sizeof(la));
index 7f439765403dced3bbbad74cb1a38dcec1a52327..8ed3c37684fa345326366239d719a1b1a100458b 100644 (file)
@@ -397,7 +397,8 @@ static int rfcomm_sock_connect(struct socket *sock, struct sockaddr *addr, int a
 
        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;
 
        lock_sock(sk);
index e5b16b76b22e5619825a09c5b0870be74297bd73..ca6b2ad1c3fc02a6bcbf16a034aa253e05b1a456 100644 (file)
@@ -499,7 +499,8 @@ static int sco_sock_connect(struct socket *sock, struct sockaddr *addr, int alen
 
        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;
 
        if (sk->sk_state != BT_OPEN && sk->sk_state != BT_BOUND)
index e32af52238a2a437787b4adaa7a7616e195b0e57..629ad1debe81db814f2105804ecd9a45b90bbbcd 100644 (file)
@@ -1478,6 +1478,9 @@ static int bcm_connect(struct socket *sock, struct sockaddr *uaddr, int len,
        struct sock *sk = sock->sk;
        struct bcm_sock *bo = bcm_sk(sk);
 
+       if (len < sizeof(*addr))
+               return -EINVAL;
+
        if (bo->bound)
                return -EISCONN;
 
index bad1c49fd9607ab5e70ee95a3134a28aa6a7bdbd..01beb6c112057692bfc981a781c948cc5accb594 100644 (file)
@@ -126,6 +126,9 @@ static int ieee802154_sock_connect(struct socket *sock, struct sockaddr *uaddr,
 {
        struct sock *sk = sock->sk;
 
+       if (addr_len < sizeof(uaddr->sa_family))
+               return -EINVAL;
+
        if (uaddr->sa_family == AF_UNSPEC)
                return sk->sk_prot->disconnect(sk, flags);
 
index 33b7dffa773240a1d017a03a2f606988f4ef4e30..a366861bf4cd5d421cb80e369f8a12e0efc7d97a 100644 (file)
@@ -530,6 +530,8 @@ int inet_dgram_connect(struct socket *sock, struct sockaddr * uaddr,
 {
        struct sock *sk = sock->sk;
 
+       if (addr_len < sizeof(uaddr->sa_family))
+               return -EINVAL;
        if (uaddr->sa_family == AF_UNSPEC)
                return sk->sk_prot->disconnect(sk, flags);
 
@@ -573,6 +575,9 @@ int inet_stream_connect(struct socket *sock, struct sockaddr *uaddr,
        int err;
        long timeo;
 
+       if (addr_len < sizeof(uaddr->sa_family))
+               return -EINVAL;
+
        lock_sock(sk);
 
        if (uaddr->sa_family == AF_UNSPEC) {
index acbbae1e89b580cddd91f8d425052ca200540b43..795424396aff62fba6971aaff0eb6631965ce481 100644 (file)
@@ -683,6 +683,9 @@ static int netlink_connect(struct socket *sock, struct sockaddr *addr,
        struct netlink_sock *nlk = nlk_sk(sk);
        struct sockaddr_nl *nladdr = (struct sockaddr_nl *)addr;
 
+       if (alen < sizeof(addr->sa_family))
+               return -EINVAL;
+
        if (addr->sa_family == AF_UNSPEC) {
                sk->sk_state    = NETLINK_UNCONNECTED;
                nlk->dst_pid    = 0;