diff options
Diffstat (limited to 'net/ax25/af_ax25.c')
| -rw-r--r-- | net/ax25/af_ax25.c | 98 | 
1 files changed, 43 insertions, 55 deletions
diff --git a/net/ax25/af_ax25.c b/net/ax25/af_ax25.c index bb86d293239..c35c3f48fc0 100644 --- a/net/ax25/af_ax25.c +++ b/net/ax25/af_ax25.c @@ -33,7 +33,6 @@  #include <linux/skbuff.h>  #include <net/sock.h>  #include <asm/uaccess.h> -#include <asm/system.h>  #include <linux/fcntl.h>  #include <linux/termios.h>	/* For TIOCINQ/OUTQ */  #include <linux/mm.h> @@ -82,14 +81,13 @@ static void ax25_kill_by_device(struct net_device *dev)  {  	ax25_dev *ax25_dev;  	ax25_cb *s; -	struct hlist_node *node;  	if ((ax25_dev = ax25_dev_ax25dev(dev)) == NULL)  		return;  	spin_lock_bh(&ax25_list_lock);  again: -	ax25_for_each(s, node, &ax25_list) { +	ax25_for_each(s, &ax25_list) {  		if (s->ax25_dev == ax25_dev) {  			s->ax25_dev = NULL;  			spin_unlock_bh(&ax25_list_lock); @@ -113,9 +111,9 @@ again:   *	Handle device status changes.   */  static int ax25_device_event(struct notifier_block *this, unsigned long event, -	void *ptr) +			     void *ptr)  { -	struct net_device *dev = (struct net_device *)ptr; +	struct net_device *dev = netdev_notifier_info_to_dev(ptr);  	if (!net_eq(dev_net(dev), &init_net))  		return NOTIFY_DONE; @@ -159,10 +157,9 @@ struct sock *ax25_find_listener(ax25_address *addr, int digi,  	struct net_device *dev, int type)  {  	ax25_cb *s; -	struct hlist_node *node;  	spin_lock(&ax25_list_lock); -	ax25_for_each(s, node, &ax25_list) { +	ax25_for_each(s, &ax25_list) {  		if ((s->iamdigi && !digi) || (!s->iamdigi && digi))  			continue;  		if (s->sk && !ax25cmp(&s->source_addr, addr) && @@ -188,10 +185,9 @@ struct sock *ax25_get_socket(ax25_address *my_addr, ax25_address *dest_addr,  {  	struct sock *sk = NULL;  	ax25_cb *s; -	struct hlist_node *node;  	spin_lock(&ax25_list_lock); -	ax25_for_each(s, node, &ax25_list) { +	ax25_for_each(s, &ax25_list) {  		if (s->sk && !ax25cmp(&s->source_addr, my_addr) &&  		    !ax25cmp(&s->dest_addr, dest_addr) &&  		    s->sk->sk_type == type) { @@ -214,10 +210,9 @@ ax25_cb *ax25_find_cb(ax25_address *src_addr, ax25_address *dest_addr,  	ax25_digi *digi, struct net_device *dev)  {  	ax25_cb *s; -	struct hlist_node *node;  	spin_lock_bh(&ax25_list_lock); -	ax25_for_each(s, node, &ax25_list) { +	ax25_for_each(s, &ax25_list) {  		if (s->sk && s->sk->sk_type != SOCK_SEQPACKET)  			continue;  		if (s->ax25_dev == NULL) @@ -249,10 +244,9 @@ void ax25_send_to_raw(ax25_address *addr, struct sk_buff *skb, int proto)  {  	ax25_cb *s;  	struct sk_buff *copy; -	struct hlist_node *node;  	spin_lock(&ax25_list_lock); -	ax25_for_each(s, node, &ax25_list) { +	ax25_for_each(s, &ax25_list) {  		if (s->sk != NULL && ax25cmp(&s->source_addr, addr) == 0 &&  		    s->sk->sk_type == SOCK_RAW &&  		    s->sk->sk_protocol == proto && @@ -402,14 +396,14 @@ static int ax25_ctl_ioctl(const unsigned int cmd, void __user *arg)  		break;  	case AX25_T1: -		if (ax25_ctl.arg < 1) +		if (ax25_ctl.arg < 1 || ax25_ctl.arg > ULONG_MAX / HZ)  			goto einval_put;  		ax25->rtt = (ax25_ctl.arg * HZ) / 2;  		ax25->t1  = ax25_ctl.arg * HZ;  		break;  	case AX25_T2: -		if (ax25_ctl.arg < 1) +		if (ax25_ctl.arg < 1 || ax25_ctl.arg > ULONG_MAX / HZ)  			goto einval_put;  		ax25->t2 = ax25_ctl.arg * HZ;  		break; @@ -422,10 +416,15 @@ static int ax25_ctl_ioctl(const unsigned int cmd, void __user *arg)  		break;  	case AX25_T3: +		if (ax25_ctl.arg > ULONG_MAX / HZ) +			goto einval_put;  		ax25->t3 = ax25_ctl.arg * HZ;  		break;  	case AX25_IDLE: +		if (ax25_ctl.arg > ULONG_MAX / (60 * HZ)) +			goto einval_put; +  		ax25->idle = ax25_ctl.arg * 60 * HZ;  		break; @@ -540,15 +539,16 @@ static int ax25_setsockopt(struct socket *sock, int level, int optname,  	ax25_cb *ax25;  	struct net_device *dev;  	char devname[IFNAMSIZ]; -	int opt, res = 0; +	unsigned long opt; +	int res = 0;  	if (level != SOL_AX25)  		return -ENOPROTOOPT; -	if (optlen < sizeof(int)) +	if (optlen < sizeof(unsigned int))  		return -EINVAL; -	if (get_user(opt, (int __user *)optval)) +	if (get_user(opt, (unsigned int __user *)optval))  		return -EFAULT;  	lock_sock(sk); @@ -571,7 +571,7 @@ static int ax25_setsockopt(struct socket *sock, int level, int optname,  		break;  	case AX25_T1: -		if (opt < 1) { +		if (opt < 1 || opt > ULONG_MAX / HZ) {  			res = -EINVAL;  			break;  		} @@ -580,7 +580,7 @@ static int ax25_setsockopt(struct socket *sock, int level, int optname,  		break;  	case AX25_T2: -		if (opt < 1) { +		if (opt < 1 || opt > ULONG_MAX / HZ) {  			res = -EINVAL;  			break;  		} @@ -596,7 +596,7 @@ static int ax25_setsockopt(struct socket *sock, int level, int optname,  		break;  	case AX25_T3: -		if (opt < 1) { +		if (opt < 1 || opt > ULONG_MAX / HZ) {  			res = -EINVAL;  			break;  		} @@ -604,7 +604,7 @@ static int ax25_setsockopt(struct socket *sock, int level, int optname,  		break;  	case AX25_IDLE: -		if (opt < 0) { +		if (opt > ULONG_MAX / (60 * HZ)) {  			res = -EINVAL;  			break;  		} @@ -612,7 +612,7 @@ static int ax25_setsockopt(struct socket *sock, int level, int optname,  		break;  	case AX25_BACKOFF: -		if (opt < 0 || opt > 2) { +		if (opt > 2) {  			res = -EINVAL;  			break;  		} @@ -837,6 +837,7 @@ static int ax25_create(struct net *net, struct socket *sock, int protocol,  		case AX25_P_NETROM:  			if (ax25_protocol_is_registered(AX25_P_NETROM))  				return -ESOCKTNOSUPPORT; +			break;  #endif  #ifdef CONFIG_ROSE_MODULE  		case AX25_P_ROSE: @@ -1392,7 +1393,7 @@ static int ax25_getname(struct socket *sock, struct sockaddr *uaddr,  	ax25_cb *ax25;  	int err = 0; -	memset(fsa, 0, sizeof(fsa)); +	memset(fsa, 0, sizeof(*fsa));  	lock_sock(sk);  	ax25 = ax25_sk(sk); @@ -1434,7 +1435,7 @@ out:  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; @@ -1538,8 +1539,6 @@ static int ax25_sendmsg(struct kiocb *iocb, struct socket *sock,  	}  	/* Build a packet */ -	SOCK_DEBUG(sk, "AX.25: sendto: Addresses built. Building packet.\n"); -  	/* Assume the worst case */  	size = len + ax25->ax25_dev->dev->hard_header_len; @@ -1549,8 +1548,6 @@ static int ax25_sendmsg(struct kiocb *iocb, struct socket *sock,  	skb_reserve(skb, size - len); -	SOCK_DEBUG(sk, "AX.25: Appending user data\n"); -  	/* User data follows immediately after the AX.25 data */  	if (memcpy_fromiovec(skb_put(skb, len), msg->msg_iov, len)) {  		err = -EFAULT; @@ -1564,8 +1561,6 @@ static int ax25_sendmsg(struct kiocb *iocb, struct socket *sock,  	if (!ax25->pidincl)  		*skb_push(skb, 1) = sk->sk_protocol; -	SOCK_DEBUG(sk, "AX.25: Transmitting buffer\n"); -  	if (sk->sk_type == SOCK_SEQPACKET) {  		/* Connected mode sockets go via the LAPB machine */  		if (sk->sk_state != TCP_ESTABLISHED) { @@ -1583,22 +1578,14 @@ static int ax25_sendmsg(struct kiocb *iocb, struct socket *sock,  	skb_push(skb, 1 + ax25_addr_size(dp)); -	SOCK_DEBUG(sk, "Building AX.25 Header (dp=%p).\n", dp); - -	if (dp != NULL) -		SOCK_DEBUG(sk, "Num digipeaters=%d\n", dp->ndigi); +	/* Building AX.25 Header */  	/* Build an AX.25 header */  	lv = ax25_addr_build(skb->data, &ax25->source_addr, &sax.sax25_call,  			     dp, AX25_COMMAND, AX25_MODULUS); -	SOCK_DEBUG(sk, "Built header (%d bytes)\n",lv); -  	skb_set_transport_header(skb, lv); -	SOCK_DEBUG(sk, "base=%p pos=%p\n", -		   skb->data, skb_transport_header(skb)); -  	*skb_transport_header(skb) = AX25_UI;  	/* Datagram frames go straight out of the door as UI */ @@ -1649,12 +1636,13 @@ static int ax25_recvmsg(struct kiocb *iocb, struct socket *sock,  	skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied); -	if (msg->msg_namelen != 0) { -		struct sockaddr_ax25 *sax = (struct sockaddr_ax25 *)msg->msg_name; +	if (msg->msg_name) {  		ax25_digi digi;  		ax25_address src;  		const unsigned char *mac = skb_mac_header(skb); +		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,  				&digi, NULL, NULL);  		sax->sax25_family = AF_AX25; @@ -1747,7 +1735,7 @@ static int ax25_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)  			res = -EFAULT;  			break;  		} -		if (amount > AX25_NOUID_BLOCK) { +		if (amount < 0 || amount > AX25_NOUID_BLOCK) {  			res = -EINVAL;  			break;  		} @@ -1986,7 +1974,7 @@ static struct packet_type ax25_packet_type __read_mostly = {  };  static struct notifier_block ax25_dev_notifier = { -	.notifier_call =ax25_device_event, +	.notifier_call = ax25_device_event,  };  static int __init ax25_init(void) @@ -1999,11 +1987,11 @@ static int __init ax25_init(void)  	sock_register(&ax25_family_ops);  	dev_add_pack(&ax25_packet_type);  	register_netdevice_notifier(&ax25_dev_notifier); -	ax25_register_sysctl(); -	proc_net_fops_create(&init_net, "ax25_route", S_IRUGO, &ax25_route_fops); -	proc_net_fops_create(&init_net, "ax25", S_IRUGO, &ax25_info_fops); -	proc_net_fops_create(&init_net, "ax25_calls", S_IRUGO, &ax25_uid_fops); +	proc_create("ax25_route", S_IRUGO, init_net.proc_net, +		    &ax25_route_fops); +	proc_create("ax25", S_IRUGO, init_net.proc_net, &ax25_info_fops); +	proc_create("ax25_calls", S_IRUGO, init_net.proc_net, &ax25_uid_fops);  out:  	return rc;  } @@ -2017,19 +2005,19 @@ MODULE_ALIAS_NETPROTO(PF_AX25);  static void __exit ax25_exit(void)  { -	proc_net_remove(&init_net, "ax25_route"); -	proc_net_remove(&init_net, "ax25"); -	proc_net_remove(&init_net, "ax25_calls"); -	ax25_rt_free(); -	ax25_uid_free(); -	ax25_dev_free(); +	remove_proc_entry("ax25_route", init_net.proc_net); +	remove_proc_entry("ax25", init_net.proc_net); +	remove_proc_entry("ax25_calls", init_net.proc_net); -	ax25_unregister_sysctl();  	unregister_netdevice_notifier(&ax25_dev_notifier);  	dev_remove_pack(&ax25_packet_type);  	sock_unregister(PF_AX25);  	proto_unregister(&ax25_proto); + +	ax25_rt_free(); +	ax25_uid_free(); +	ax25_dev_free();  }  module_exit(ax25_exit);  | 
