diff options
| author | Paul Mundt <lethal@linux-sh.org> | 2011-01-13 15:06:28 +0900 | 
|---|---|---|
| committer | Paul Mundt <lethal@linux-sh.org> | 2011-01-13 15:06:28 +0900 | 
| commit | f43dc23d5ea91fca257be02138a255f02d98e806 (patch) | |
| tree | b29722f6e965316e90ac97abf79923ced250dc21 /net/core/scm.c | |
| parent | f8e53553f452dcbf67cb89c8cba63a1cd6eb4cc0 (diff) | |
| parent | 4162cf64973df51fc885825bc9ca4d055891c49f (diff) | |
Merge branch 'master' of master.kernel.org:/pub/scm/linux/kernel/git/torvalds/linux-2.6 into common/serial-rework
Conflicts:
	arch/sh/kernel/cpu/sh2/setup-sh7619.c
	arch/sh/kernel/cpu/sh2a/setup-mxg.c
	arch/sh/kernel/cpu/sh2a/setup-sh7201.c
	arch/sh/kernel/cpu/sh2a/setup-sh7203.c
	arch/sh/kernel/cpu/sh2a/setup-sh7206.c
	arch/sh/kernel/cpu/sh3/setup-sh7705.c
	arch/sh/kernel/cpu/sh3/setup-sh770x.c
	arch/sh/kernel/cpu/sh3/setup-sh7710.c
	arch/sh/kernel/cpu/sh3/setup-sh7720.c
	arch/sh/kernel/cpu/sh4/setup-sh4-202.c
	arch/sh/kernel/cpu/sh4/setup-sh7750.c
	arch/sh/kernel/cpu/sh4/setup-sh7760.c
	arch/sh/kernel/cpu/sh4a/setup-sh7343.c
	arch/sh/kernel/cpu/sh4a/setup-sh7366.c
	arch/sh/kernel/cpu/sh4a/setup-sh7722.c
	arch/sh/kernel/cpu/sh4a/setup-sh7723.c
	arch/sh/kernel/cpu/sh4a/setup-sh7724.c
	arch/sh/kernel/cpu/sh4a/setup-sh7763.c
	arch/sh/kernel/cpu/sh4a/setup-sh7770.c
	arch/sh/kernel/cpu/sh4a/setup-sh7780.c
	arch/sh/kernel/cpu/sh4a/setup-sh7785.c
	arch/sh/kernel/cpu/sh4a/setup-sh7786.c
	arch/sh/kernel/cpu/sh4a/setup-shx3.c
	arch/sh/kernel/cpu/sh5/setup-sh5.c
	drivers/serial/sh-sci.c
	drivers/serial/sh-sci.h
	include/linux/serial_sci.h
Diffstat (limited to 'net/core/scm.c')
| -rw-r--r-- | net/core/scm.c | 46 | 
1 files changed, 37 insertions, 9 deletions
diff --git a/net/core/scm.c b/net/core/scm.c index b7ba91b074b..bbe45445080 100644 --- a/net/core/scm.c +++ b/net/core/scm.c @@ -26,6 +26,7 @@  #include <linux/security.h>  #include <linux/pid.h>  #include <linux/nsproxy.h> +#include <linux/slab.h>  #include <asm/system.h>  #include <asm/uaccess.h> @@ -78,10 +79,11 @@ static int scm_fp_copy(struct cmsghdr *cmsg, struct scm_fp_list **fplp)  			return -ENOMEM;  		*fplp = fpl;  		fpl->count = 0; +		fpl->max = SCM_MAX_FD;  	}  	fpp = &fpl->fp[fpl->count]; -	if (fpl->count + num > SCM_MAX_FD) +	if (fpl->count + num > fpl->max)  		return -EINVAL;  	/* @@ -129,6 +131,7 @@ void __scm_destroy(struct scm_cookie *scm)  		}  	}  } +EXPORT_SYMBOL(__scm_destroy);  int __scm_send(struct socket *sock, struct msghdr *msg, struct scm_cookie *p)  { @@ -156,6 +159,8 @@ int __scm_send(struct socket *sock, struct msghdr *msg, struct scm_cookie *p)  		switch (cmsg->cmsg_type)  		{  		case SCM_RIGHTS: +			if (!sock->ops || sock->ops->family != PF_UNIX) +				goto error;  			err=scm_fp_copy(cmsg, &p->fp);  			if (err<0)  				goto error; @@ -167,6 +172,30 @@ int __scm_send(struct socket *sock, struct msghdr *msg, struct scm_cookie *p)  			err = scm_check_creds(&p->creds);  			if (err)  				goto error; + +			if (pid_vnr(p->pid) != p->creds.pid) { +				struct pid *pid; +				err = -ESRCH; +				pid = find_get_pid(p->creds.pid); +				if (!pid) +					goto error; +				put_pid(p->pid); +				p->pid = pid; +			} + +			if ((p->cred->euid != p->creds.uid) || +				(p->cred->egid != p->creds.gid)) { +				struct cred *cred; +				err = -ENOMEM; +				cred = prepare_creds(); +				if (!cred) +					goto error; + +				cred->uid = cred->euid = p->creds.uid; +				cred->gid = cred->egid = p->creds.uid; +				put_cred(p->cred); +				p->cred = cred; +			}  			break;  		default:  			goto error; @@ -184,6 +213,7 @@ error:  	scm_destroy(p);  	return err;  } +EXPORT_SYMBOL(__scm_send);  int put_cmsg(struct msghdr * msg, int level, int type, int len, void *data)  { @@ -222,6 +252,7 @@ int put_cmsg(struct msghdr * msg, int level, int type, int len, void *data)  out:  	return err;  } +EXPORT_SYMBOL(put_cmsg);  void scm_detach_fds(struct msghdr *msg, struct scm_cookie *scm)  { @@ -291,6 +322,7 @@ void scm_detach_fds(struct msghdr *msg, struct scm_cookie *scm)  	 */  	__scm_destroy(scm);  } +EXPORT_SYMBOL(scm_detach_fds);  struct scm_fp_list *scm_fp_dup(struct scm_fp_list *fpl)  { @@ -300,17 +332,13 @@ struct scm_fp_list *scm_fp_dup(struct scm_fp_list *fpl)  	if (!fpl)  		return NULL; -	new_fpl = kmalloc(sizeof(*fpl), GFP_KERNEL); +	new_fpl = kmemdup(fpl, offsetof(struct scm_fp_list, fp[fpl->count]), +			  GFP_KERNEL);  	if (new_fpl) { -		for (i=fpl->count-1; i>=0; i--) +		for (i = 0; i < fpl->count; i++)  			get_file(fpl->fp[i]); -		memcpy(new_fpl, fpl, sizeof(*fpl)); +		new_fpl->max = new_fpl->count;  	}  	return new_fpl;  } - -EXPORT_SYMBOL(__scm_destroy); -EXPORT_SYMBOL(__scm_send); -EXPORT_SYMBOL(put_cmsg); -EXPORT_SYMBOL(scm_detach_fds);  EXPORT_SYMBOL(scm_fp_dup);  | 
