diff options
| author | Jonathan Corbet <[email protected]> | 2016-12-27 12:53:44 -0700 | 
|---|---|---|
| committer | Jonathan Corbet <[email protected]> | 2016-12-27 12:53:44 -0700 | 
| commit | 54ab6db0909061ab7ee07233d3cab86d29f86e6c (patch) | |
| tree | a7650ab5c0fa3a6a3841de8e8693041b3e009054 /net/socket.c | |
| parent | 217e2bfab22e740227df09f22165e834cddd8a3b (diff) | |
| parent | 7ce7d89f48834cefece7804d38fc5d85382edf77 (diff) | |
Merge tag 'v4.10-rc1' into docs-next
Linux 4.10-rc1
Diffstat (limited to 'net/socket.c')
| -rw-r--r-- | net/socket.c | 57 | 
1 files changed, 53 insertions, 4 deletions
| diff --git a/net/socket.c b/net/socket.c index 5a9bf5ee2464..8487bf136e5c 100644 --- a/net/socket.c +++ b/net/socket.c @@ -90,7 +90,7 @@  #include <linux/slab.h>  #include <linux/xattr.h> -#include <asm/uaccess.h> +#include <linux/uaccess.h>  #include <asm/unistd.h>  #include <net/compat.h> @@ -341,8 +341,23 @@ static const struct xattr_handler sockfs_xattr_handler = {  	.get = sockfs_xattr_get,  }; +static int sockfs_security_xattr_set(const struct xattr_handler *handler, +				     struct dentry *dentry, struct inode *inode, +				     const char *suffix, const void *value, +				     size_t size, int flags) +{ +	/* Handled by LSM. */ +	return -EAGAIN; +} + +static const struct xattr_handler sockfs_security_xattr_handler = { +	.prefix = XATTR_SECURITY_PREFIX, +	.set = sockfs_security_xattr_set, +}; +  static const struct xattr_handler *sockfs_xattr_handlers[] = {  	&sockfs_xattr_handler, +	&sockfs_security_xattr_handler,  	NULL  }; @@ -518,8 +533,22 @@ static ssize_t sockfs_listxattr(struct dentry *dentry, char *buffer,  	return used;  } +int sockfs_setattr(struct dentry *dentry, struct iattr *iattr) +{ +	int err = simple_setattr(dentry, iattr); + +	if (!err) { +		struct socket *sock = SOCKET_I(d_inode(dentry)); + +		sock->sk->sk_uid = iattr->ia_uid; +	} + +	return err; +} +  static const struct inode_operations sockfs_inode_ops = {  	.listxattr = sockfs_listxattr, +	.setattr = sockfs_setattr,  };  /** @@ -639,7 +668,7 @@ void __sock_recv_timestamp(struct msghdr *msg, struct sock *sk,  	/* Race occurred between timestamp enabling and packet  	   receiving.  Fill in the current time for now. */ -	if (need_software_tstamp && skb->tstamp.tv64 == 0) +	if (need_software_tstamp && skb->tstamp == 0)  		__net_timestamp(skb);  	if (need_software_tstamp) { @@ -664,9 +693,14 @@ void __sock_recv_timestamp(struct msghdr *msg, struct sock *sk,  	    (sk->sk_tsflags & SOF_TIMESTAMPING_RAW_HARDWARE) &&  	    ktime_to_timespec_cond(shhwtstamps->hwtstamp, tss.ts + 2))  		empty = 0; -	if (!empty) +	if (!empty) {  		put_cmsg(msg, SOL_SOCKET,  			 SCM_TIMESTAMPING, sizeof(tss), &tss); + +		if (skb->len && (sk->sk_tsflags & SOF_TIMESTAMPING_OPT_STATS)) +			put_cmsg(msg, SOL_SOCKET, SCM_TIMESTAMPING_OPT_STATS, +				 skb->len, skb->data); +	}  }  EXPORT_SYMBOL_GPL(__sock_recv_timestamp); @@ -877,6 +911,11 @@ static long sock_do_ioctl(struct net *net, struct socket *sock,   *	what to do with it - that's up to the protocol still.   */ +static struct ns_common *get_net_ns(struct ns_common *ns) +{ +	return &get_net(container_of(ns, struct net, ns))->ns; +} +  static long sock_ioctl(struct file *file, unsigned cmd, unsigned long arg)  {  	struct socket *sock; @@ -945,6 +984,13 @@ static long sock_ioctl(struct file *file, unsigned cmd, unsigned long arg)  				err = dlci_ioctl_hook(cmd, argp);  			mutex_unlock(&dlci_ioctl_mutex);  			break; +		case SIOCGSKNS: +			err = -EPERM; +			if (!ns_capable(net->user_ns, CAP_NET_ADMIN)) +				break; + +			err = open_related_ns(&net->ns, get_net_ns); +			break;  		default:  			err = sock_do_ioctl(net, sock, cmd, arg);  			break; @@ -1872,7 +1918,7 @@ static int ___sys_sendmsg(struct socket *sock, struct user_msghdr __user *msg,  	struct sockaddr_storage address;  	struct iovec iovstack[UIO_FASTIOV], *iov = iovstack;  	unsigned char ctl[sizeof(struct cmsghdr) + 20] -	    __attribute__ ((aligned(sizeof(__kernel_size_t)))); +				__aligned(sizeof(__kernel_size_t));  	/* 20 is size of ipv6_pktinfo */  	unsigned char *ctl_buf = ctl;  	int ctl_len; @@ -2038,6 +2084,8 @@ int __sys_sendmmsg(int fd, struct mmsghdr __user *mmsg, unsigned int vlen,  		if (err)  			break;  		++datagrams; +		if (msg_data_left(&msg_sys)) +			break;  		cond_resched();  	} @@ -3093,6 +3141,7 @@ static int compat_sock_ioctl_trans(struct file *file, struct socket *sock,  	case SIOCSIFVLAN:  	case SIOCADDDLCI:  	case SIOCDELDLCI: +	case SIOCGSKNS:  		return sock_ioctl(file, cmd, arg);  	case SIOCGIFFLAGS: |