diff options
Diffstat (limited to 'net/can/raw.c')
| -rw-r--r-- | net/can/raw.c | 44 | 
1 files changed, 25 insertions, 19 deletions
diff --git a/net/can/raw.c b/net/can/raw.c index afcbff063a67..59c039d73c6d 100644 --- a/net/can/raw.c +++ b/net/can/raw.c @@ -1,5 +1,5 @@ -/* - * raw.c - Raw sockets for protocol family CAN +// SPDX-License-Identifier: ((GPL-2.0 WITH Linux-syscall-note) OR BSD-3-Clause) +/* raw.c - Raw sockets for protocol family CAN   *   * Copyright (c) 2002-2007 Volkswagen Group Electronic Research   * All rights reserved. @@ -64,8 +64,7 @@ MODULE_ALIAS("can-proto-1");  #define MASK_ALL 0 -/* - * A raw socket has a list of can_filters attached to it, each receiving +/* A raw socket has a list of can_filters attached to it, each receiving   * the CAN frames matching that filter.  If the filter list is empty,   * no CAN frames will be received by the socket.  The default after   * opening the socket, is to have one filter which receives all frames. @@ -96,8 +95,7 @@ struct raw_sock {  	struct uniqframe __percpu *uniq;  }; -/* - * Return pointer to store the extra msg flags for raw_recvmsg(). +/* Return pointer to store the extra msg flags for raw_recvmsg().   * We use the space of one unsigned int beyond the 'struct sockaddr_can'   * in skb->cb.   */ @@ -156,8 +154,7 @@ static void raw_rcv(struct sk_buff *oskb, void *data)  	if (!skb)  		return; -	/* -	 *  Put the datagram to the queue so that raw_recvmsg() can +	/*  Put the datagram to the queue so that raw_recvmsg() can  	 *  get it from there.  We need to pass the interface index to  	 *  raw_recvmsg().  We pass a whole struct sockaddr_can in skb->cb  	 *  containing the interface index. @@ -283,7 +280,6 @@ static int raw_notifier(struct notifier_block *nb,  		return NOTIFY_DONE;  	switch (msg) { -  	case NETDEV_UNREGISTER:  		lock_sock(sk);  		/* remove current filters & unregister */ @@ -369,8 +365,9 @@ static int raw_release(struct socket *sock)  				raw_disable_allfilters(dev_net(dev), dev, sk);  				dev_put(dev);  			} -		} else +		} else {  			raw_disable_allfilters(sock_net(sk), NULL, sk); +		}  	}  	if (ro->count > 1) @@ -399,7 +396,7 @@ static int raw_bind(struct socket *sock, struct sockaddr *uaddr, int len)  	int err = 0;  	int notify_enetdown = 0; -	if (len < sizeof(*addr)) +	if (len < CAN_REQUIRED_SIZE(*addr, can_ifindex))  		return -EINVAL;  	if (addr->can_family != AF_CAN)  		return -EINVAL; @@ -450,8 +447,9 @@ static int raw_bind(struct socket *sock, struct sockaddr *uaddr, int len)  							       dev, sk);  					dev_put(dev);  				} -			} else +			} else {  				raw_disable_allfilters(sock_net(sk), NULL, sk); +			}  		}  		ro->ifindex = ifindex;  		ro->bound = 1; @@ -502,7 +500,6 @@ static int raw_setsockopt(struct socket *sock, int level, int optname,  		return -EINVAL;  	switch (optname) { -  	case CAN_RAW_FILTER:  		if (optlen % sizeof(struct can_filter) != 0)  			return -EINVAL; @@ -665,17 +662,18 @@ static int raw_getsockopt(struct socket *sock, int level, int optname,  		return -EINVAL;  	switch (optname) { -  	case CAN_RAW_FILTER:  		lock_sock(sk);  		if (ro->count > 0) {  			int fsize = ro->count * sizeof(struct can_filter); +  			if (len > fsize)  				len = fsize;  			if (copy_to_user(optval, ro->filter, len))  				err = -EFAULT; -		} else +		} else {  			len = 0; +		}  		release_sock(sk);  		if (!err) @@ -735,15 +733,16 @@ static int raw_sendmsg(struct socket *sock, struct msghdr *msg, size_t size)  	if (msg->msg_name) {  		DECLARE_SOCKADDR(struct sockaddr_can *, addr, msg->msg_name); -		if (msg->msg_namelen < sizeof(*addr)) +		if (msg->msg_namelen < CAN_REQUIRED_SIZE(*addr, can_ifindex))  			return -EINVAL;  		if (addr->can_family != AF_CAN)  			return -EINVAL;  		ifindex = addr->can_ifindex; -	} else +	} else {  		ifindex = ro->ifindex; +	}  	dev = dev_get_by_index(sock_net(sk), ifindex);  	if (!dev) @@ -836,6 +835,13 @@ static int raw_recvmsg(struct socket *sock, struct msghdr *msg, size_t size,  	return size;  } +static int raw_sock_no_ioctlcmd(struct socket *sock, unsigned int cmd, +				unsigned long arg) +{ +	/* no ioctls for socket layer -> hand it down to NIC layer */ +	return -ENOIOCTLCMD; +} +  static const struct proto_ops raw_ops = {  	.family        = PF_CAN,  	.release       = raw_release, @@ -845,7 +851,7 @@ static const struct proto_ops raw_ops = {  	.accept        = sock_no_accept,  	.getname       = raw_getname,  	.poll          = datagram_poll, -	.ioctl         = can_ioctl,	/* use can_ioctl() from af_can.c */ +	.ioctl         = raw_sock_no_ioctlcmd,  	.gettstamp     = sock_gettstamp,  	.listen        = sock_no_listen,  	.shutdown      = sock_no_shutdown, @@ -879,7 +885,7 @@ static __init int raw_module_init(void)  	err = can_proto_register(&raw_can_proto);  	if (err < 0) -		printk(KERN_ERR "can: registration of raw protocol failed\n"); +		pr_err("can: registration of raw protocol failed\n");  	return err;  }  |