diff options
Diffstat (limited to 'net/bluetooth/rfcomm/sock.c')
| -rw-r--r-- | net/bluetooth/rfcomm/sock.c | 28 | 
1 files changed, 16 insertions, 12 deletions
diff --git a/net/bluetooth/rfcomm/sock.c b/net/bluetooth/rfcomm/sock.c index 825e8fb5114b..7511df72347f 100644 --- a/net/bluetooth/rfcomm/sock.c +++ b/net/bluetooth/rfcomm/sock.c @@ -269,12 +269,12 @@ static struct proto rfcomm_proto = {  	.obj_size	= sizeof(struct rfcomm_pinfo)  }; -static struct sock *rfcomm_sock_alloc(struct net *net, struct socket *sock, int proto, gfp_t prio) +static struct sock *rfcomm_sock_alloc(struct net *net, struct socket *sock, int proto, gfp_t prio, int kern)  {  	struct rfcomm_dlc *d;  	struct sock *sk; -	sk = sk_alloc(net, PF_BLUETOOTH, prio, &rfcomm_proto); +	sk = sk_alloc(net, PF_BLUETOOTH, prio, &rfcomm_proto, kern);  	if (!sk)  		return NULL; @@ -324,7 +324,7 @@ static int rfcomm_sock_create(struct net *net, struct socket *sock,  	sock->ops = &rfcomm_sock_ops; -	sk = rfcomm_sock_alloc(net, sock, protocol, GFP_ATOMIC); +	sk = rfcomm_sock_alloc(net, sock, protocol, GFP_ATOMIC, kern);  	if (!sk)  		return -ENOMEM; @@ -334,16 +334,19 @@ static int rfcomm_sock_create(struct net *net, struct socket *sock,  static int rfcomm_sock_bind(struct socket *sock, struct sockaddr *addr, int addr_len)  { -	struct sockaddr_rc *sa = (struct sockaddr_rc *) addr; +	struct sockaddr_rc sa;  	struct sock *sk = sock->sk; -	int chan = sa->rc_channel; -	int err = 0; - -	BT_DBG("sk %p %pMR", sk, &sa->rc_bdaddr); +	int len, err = 0;  	if (!addr || addr->sa_family != AF_BLUETOOTH)  		return -EINVAL; +	memset(&sa, 0, sizeof(sa)); +	len = min_t(unsigned int, sizeof(sa), addr_len); +	memcpy(&sa, addr, len); + +	BT_DBG("sk %p %pMR", sk, &sa.rc_bdaddr); +  	lock_sock(sk);  	if (sk->sk_state != BT_OPEN) { @@ -358,12 +361,13 @@ static int rfcomm_sock_bind(struct socket *sock, struct sockaddr *addr, int addr  	write_lock(&rfcomm_sk_list.lock); -	if (chan && __rfcomm_get_listen_sock_by_addr(chan, &sa->rc_bdaddr)) { +	if (sa.rc_channel && +	    __rfcomm_get_listen_sock_by_addr(sa.rc_channel, &sa.rc_bdaddr)) {  		err = -EADDRINUSE;  	} else {  		/* Save source address */ -		bacpy(&rfcomm_pi(sk)->src, &sa->rc_bdaddr); -		rfcomm_pi(sk)->channel = chan; +		bacpy(&rfcomm_pi(sk)->src, &sa.rc_bdaddr); +		rfcomm_pi(sk)->channel = sa.rc_channel;  		sk->sk_state = BT_BOUND;  	} @@ -969,7 +973,7 @@ int rfcomm_connect_ind(struct rfcomm_session *s, u8 channel, struct rfcomm_dlc *  		goto done;  	} -	sk = rfcomm_sock_alloc(sock_net(parent), NULL, BTPROTO_RFCOMM, GFP_ATOMIC); +	sk = rfcomm_sock_alloc(sock_net(parent), NULL, BTPROTO_RFCOMM, GFP_ATOMIC, 0);  	if (!sk)  		goto done;  |