diff options
| -rw-r--r-- | net/core/scm.c | 31 | ||||
| -rw-r--r-- | net/core/sock.c | 4 |
2 files changed, 25 insertions, 10 deletions
diff --git a/net/core/scm.c b/net/core/scm.c index 8f6ccfd68ef4..5472ae7a0657 100644 --- a/net/core/scm.c +++ b/net/core/scm.c | |||
| @@ -45,12 +45,17 @@ | |||
| 45 | static __inline__ int scm_check_creds(struct ucred *creds) | 45 | static __inline__ int scm_check_creds(struct ucred *creds) |
| 46 | { | 46 | { |
| 47 | const struct cred *cred = current_cred(); | 47 | const struct cred *cred = current_cred(); |
| 48 | kuid_t uid = make_kuid(cred->user_ns, creds->uid); | ||
| 49 | kgid_t gid = make_kgid(cred->user_ns, creds->gid); | ||
| 50 | |||
| 51 | if (!uid_valid(uid) || !gid_valid(gid)) | ||
| 52 | return -EINVAL; | ||
| 48 | 53 | ||
| 49 | if ((creds->pid == task_tgid_vnr(current) || capable(CAP_SYS_ADMIN)) && | 54 | if ((creds->pid == task_tgid_vnr(current) || capable(CAP_SYS_ADMIN)) && |
| 50 | ((creds->uid == cred->uid || creds->uid == cred->euid || | 55 | ((uid_eq(uid, cred->uid) || uid_eq(uid, cred->euid) || |
| 51 | creds->uid == cred->suid) || capable(CAP_SETUID)) && | 56 | uid_eq(uid, cred->suid)) || capable(CAP_SETUID)) && |
| 52 | ((creds->gid == cred->gid || creds->gid == cred->egid || | 57 | ((gid_eq(gid, cred->gid) || gid_eq(gid, cred->egid) || |
| 53 | creds->gid == cred->sgid) || capable(CAP_SETGID))) { | 58 | gid_eq(gid, cred->sgid)) || capable(CAP_SETGID))) { |
| 54 | return 0; | 59 | return 0; |
| 55 | } | 60 | } |
| 56 | return -EPERM; | 61 | return -EPERM; |
| @@ -149,6 +154,9 @@ int __scm_send(struct socket *sock, struct msghdr *msg, struct scm_cookie *p) | |||
| 149 | goto error; | 154 | goto error; |
| 150 | break; | 155 | break; |
| 151 | case SCM_CREDENTIALS: | 156 | case SCM_CREDENTIALS: |
| 157 | { | ||
| 158 | kuid_t uid; | ||
| 159 | kgid_t gid; | ||
| 152 | if (cmsg->cmsg_len != CMSG_LEN(sizeof(struct ucred))) | 160 | if (cmsg->cmsg_len != CMSG_LEN(sizeof(struct ucred))) |
| 153 | goto error; | 161 | goto error; |
| 154 | memcpy(&p->creds, CMSG_DATA(cmsg), sizeof(struct ucred)); | 162 | memcpy(&p->creds, CMSG_DATA(cmsg), sizeof(struct ucred)); |
| @@ -166,22 +174,29 @@ int __scm_send(struct socket *sock, struct msghdr *msg, struct scm_cookie *p) | |||
| 166 | p->pid = pid; | 174 | p->pid = pid; |
| 167 | } | 175 | } |
| 168 | 176 | ||
| 177 | err = -EINVAL; | ||
| 178 | uid = make_kuid(current_user_ns(), p->creds.uid); | ||
| 179 | gid = make_kgid(current_user_ns(), p->creds.gid); | ||
| 180 | if (!uid_valid(uid) || !gid_valid(gid)) | ||
| 181 | goto error; | ||
| 182 | |||
| 169 | if (!p->cred || | 183 | if (!p->cred || |
| 170 | (p->cred->euid != p->creds.uid) || | 184 | !uid_eq(p->cred->euid, uid) || |
| 171 | (p->cred->egid != p->creds.gid)) { | 185 | !gid_eq(p->cred->egid, gid)) { |
| 172 | struct cred *cred; | 186 | struct cred *cred; |
| 173 | err = -ENOMEM; | 187 | err = -ENOMEM; |
| 174 | cred = prepare_creds(); | 188 | cred = prepare_creds(); |
| 175 | if (!cred) | 189 | if (!cred) |
| 176 | goto error; | 190 | goto error; |
| 177 | 191 | ||
| 178 | cred->uid = cred->euid = p->creds.uid; | 192 | cred->uid = cred->euid = uid; |
| 179 | cred->gid = cred->egid = p->creds.gid; | 193 | cred->gid = cred->egid = gid; |
| 180 | if (p->cred) | 194 | if (p->cred) |
| 181 | put_cred(p->cred); | 195 | put_cred(p->cred); |
| 182 | p->cred = cred; | 196 | p->cred = cred; |
| 183 | } | 197 | } |
| 184 | break; | 198 | break; |
| 199 | } | ||
| 185 | default: | 200 | default: |
| 186 | goto error; | 201 | goto error; |
| 187 | } | 202 | } |
diff --git a/net/core/sock.c b/net/core/sock.c index 6b654b3ddfda..9c7fe4ff30fc 100644 --- a/net/core/sock.c +++ b/net/core/sock.c | |||
| @@ -868,8 +868,8 @@ void cred_to_ucred(struct pid *pid, const struct cred *cred, | |||
| 868 | if (cred) { | 868 | if (cred) { |
| 869 | struct user_namespace *current_ns = current_user_ns(); | 869 | struct user_namespace *current_ns = current_user_ns(); |
| 870 | 870 | ||
| 871 | ucred->uid = from_kuid(current_ns, cred->euid); | 871 | ucred->uid = from_kuid_munged(current_ns, cred->euid); |
| 872 | ucred->gid = from_kgid(current_ns, cred->egid); | 872 | ucred->gid = from_kgid_munged(current_ns, cred->egid); |
| 873 | } | 873 | } |
| 874 | } | 874 | } |
| 875 | EXPORT_SYMBOL_GPL(cred_to_ucred); | 875 | EXPORT_SYMBOL_GPL(cred_to_ucred); |
