X-Git-Url: http://pilppa.org/gitweb/gitweb.cgi?a=blobdiff_plain;f=net%2Fcore%2Fscm.c;h=10f5c65f6a470cc914de500b43d63990e89db1b6;hb=ba8ed1210b4e5449c80beef321c4459e840fece1;hp=271cf060ef8c69fb79f37768972af65b5457d835;hpb=bdbf77d6707a52bdeff223d0a60df12d086d21d7;p=linux-2.6-omap-h63xx.git diff --git a/net/core/scm.c b/net/core/scm.c index 271cf060ef8..10f5c65f6a4 100644 --- a/net/core/scm.c +++ b/net/core/scm.c @@ -24,6 +24,8 @@ #include #include #include +#include +#include #include #include @@ -36,13 +38,13 @@ /* - * Only allow a user to send credentials, that they could set with + * Only allow a user to send credentials, that they could set with * setu(g)id. */ static __inline__ int scm_check_creds(struct ucred *creds) { - if ((creds->pid == current->tgid || capable(CAP_SYS_ADMIN)) && + if ((creds->pid == task_tgid_vnr(current) || capable(CAP_SYS_ADMIN)) && ((creds->uid == current->uid || creds->uid == current->euid || creds->uid == current->suid) || capable(CAP_SETUID)) && ((creds->gid == current->gid || creds->gid == current->egid || @@ -79,11 +81,11 @@ static int scm_fp_copy(struct cmsghdr *cmsg, struct scm_fp_list **fplp) if (fpl->count + num > SCM_MAX_FD) return -EINVAL; - + /* * Verify the descriptors and increment the usage count. */ - + for (i=0; i< num; i++) { int fd = fdp[i]; @@ -123,7 +125,7 @@ int __scm_send(struct socket *sock, struct msghdr *msg, struct scm_cookie *p) /* The first check was omitted in <= 2.2.5. The reasoning was that parser checks cmsg_len in any case, so that additional check would be work duplication. - But if cmsg_level is not SOL_SOCKET, we do not check + But if cmsg_level is not SOL_SOCKET, we do not check for too short ancillary data object at all! Oops. OK, let's add it... */ @@ -159,7 +161,7 @@ int __scm_send(struct socket *sock, struct msghdr *msg, struct scm_cookie *p) p->fp = NULL; } return 0; - + error: scm_destroy(p); return err; @@ -167,7 +169,8 @@ error: int put_cmsg(struct msghdr * msg, int level, int type, int len, void *data) { - struct cmsghdr __user *cm = (struct cmsghdr __user *)msg->msg_control; + struct cmsghdr __user *cm + = (__force struct cmsghdr __user *)msg->msg_control; struct cmsghdr cmhdr; int cmlen = CMSG_LEN(len); int err; @@ -189,10 +192,12 @@ int put_cmsg(struct msghdr * msg, int level, int type, int len, void *data) err = -EFAULT; if (copy_to_user(cm, &cmhdr, sizeof cmhdr)) - goto out; + goto out; if (copy_to_user(CMSG_DATA(cm), data, cmlen - sizeof(struct cmsghdr))) goto out; cmlen = CMSG_SPACE(len); + if (msg->msg_controllen < cmlen) + cmlen = msg->msg_controllen; msg->msg_control += cmlen; msg->msg_controllen -= cmlen; err = 0; @@ -202,7 +207,8 @@ out: void scm_detach_fds(struct msghdr *msg, struct scm_cookie *scm) { - struct cmsghdr __user *cm = (struct cmsghdr __user*)msg->msg_control; + struct cmsghdr __user *cm + = (__force struct cmsghdr __user*)msg->msg_control; int fdmax = 0; int fdnum = scm->fp->count; @@ -222,13 +228,15 @@ void scm_detach_fds(struct msghdr *msg, struct scm_cookie *scm) if (fdnum < fdmax) fdmax = fdnum; - for (i=0, cmfptr=(int __user *)CMSG_DATA(cm); imsg_flags + ? O_CLOEXEC : 0); if (err < 0) break; new_fd = err;