diff options
Diffstat (limited to 'net/core/scm.c')
| -rw-r--r-- | net/core/scm.c | 33 | 
1 files changed, 28 insertions, 5 deletions
diff --git a/net/core/scm.c b/net/core/scm.c index b88f6f9d0b9..413cab89017 100644 --- a/net/core/scm.c +++ b/net/core/scm.c @@ -130,6 +130,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)  { @@ -170,6 +171,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; @@ -187,6 +212,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)  { @@ -225,6 +251,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)  { @@ -294,6 +321,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)  { @@ -311,9 +339,4 @@ struct scm_fp_list *scm_fp_dup(struct scm_fp_list *fpl)  	}  	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);  | 
