diff options
Diffstat (limited to 'net/core')
| -rw-r--r-- | net/core/net_namespace.c | 8 | ||||
| -rw-r--r-- | net/core/scm.c | 32 | 
2 files changed, 36 insertions, 4 deletions
| diff --git a/net/core/net_namespace.c b/net/core/net_namespace.c index ae54f26709ca..03cf87d3b380 100644 --- a/net/core/net_namespace.c +++ b/net/core/net_namespace.c @@ -796,11 +796,19 @@ static __net_init int net_ns_net_init(struct net *net)  #ifdef CONFIG_NET_NS  	net->ns.ops = &netns_operations;  #endif +	if (net == &init_net) { +		net->ns.inum = PROC_NET_INIT_INO; +		return 0; +	}  	return ns_alloc_inum(&net->ns);  }  static __net_exit void net_ns_net_exit(struct net *net)  { +	/* +	 * Initial network namespace doesn't exit so we don't need any +	 * special checks here. +	 */  	ns_free_inum(&net->ns);  } diff --git a/net/core/scm.c b/net/core/scm.c index 0225bd94170f..072d5742440a 100644 --- a/net/core/scm.c +++ b/net/core/scm.c @@ -23,6 +23,8 @@  #include <linux/security.h>  #include <linux/pid_namespace.h>  #include <linux/pid.h> +#include <uapi/linux/pidfd.h> +#include <linux/pidfs.h>  #include <linux/nsproxy.h>  #include <linux/slab.h>  #include <linux/errqueue.h> @@ -145,6 +147,22 @@ void __scm_destroy(struct scm_cookie *scm)  }  EXPORT_SYMBOL(__scm_destroy); +static inline int scm_replace_pid(struct scm_cookie *scm, struct pid *pid) +{ +	int err; + +	/* drop all previous references */ +	scm_destroy_cred(scm); + +	err = pidfs_register_pid(pid); +	if (unlikely(err)) +		return err; + +	scm->pid = pid; +	scm->creds.pid = pid_vnr(pid); +	return 0; +} +  int __scm_send(struct socket *sock, struct msghdr *msg, struct scm_cookie *p)  {  	const struct proto_ops *ops = READ_ONCE(sock->ops); @@ -189,15 +207,21 @@ int __scm_send(struct socket *sock, struct msghdr *msg, struct scm_cookie *p)  			if (err)  				goto error; -			p->creds.pid = creds.pid;  			if (!p->pid || pid_vnr(p->pid) != creds.pid) {  				struct pid *pid;  				err = -ESRCH;  				pid = find_get_pid(creds.pid);  				if (!pid)  					goto error; -				put_pid(p->pid); -				p->pid = pid; + +				/* pass a struct pid reference from +				 * find_get_pid() to scm_replace_pid(). +				 */ +				err = scm_replace_pid(p, pid); +				if (err) { +					put_pid(pid); +					goto error; +				}  			}  			err = -EINVAL; @@ -459,7 +483,7 @@ static void scm_pidfd_recv(struct msghdr *msg, struct scm_cookie *scm)  	if (!scm->pid)  		return; -	pidfd = pidfd_prepare(scm->pid, 0, &pidfd_file); +	pidfd = pidfd_prepare(scm->pid, PIDFD_STALE, &pidfd_file);  	if (put_cmsg(msg, SOL_SOCKET, SCM_PIDFD, sizeof(int), &pidfd)) {  		if (pidfd_file) { | 
