浏览代码

userns: Convert setting and getting uid and gid system calls to use kuid and kgid

Convert setregid, setgid, setreuid, setuid,
setresuid, getresuid, setresgid, getresgid, setfsuid, setfsgid,
getuid, geteuid, getgid, getegid,
waitpid, waitid, wait4.

Convert userspace uids and gids into kuids and kgids before
being placed on struct cred.  Convert struct cred kuids and
kgids into userspace uids and gids when returning them.

Signed-off-by: Eric W. Biederman <ebiederm@xmission.com>
Eric W. Biederman 13 年之前
父节点
当前提交
a29c33f4e5
共有 4 个文件被更改,包括 178 次插入86 次删除
  1. 3 3
      kernel/exit.c
  2. 149 67
      kernel/sys.c
  3. 4 4
      kernel/timer.c
  4. 22 12
      kernel/uid16.c

+ 3 - 3
kernel/exit.c

@@ -1214,7 +1214,7 @@ static int wait_task_zombie(struct wait_opts *wo, struct task_struct *p)
 	unsigned long state;
 	unsigned long state;
 	int retval, status, traced;
 	int retval, status, traced;
 	pid_t pid = task_pid_vnr(p);
 	pid_t pid = task_pid_vnr(p);
-	uid_t uid = __task_cred(p)->uid;
+	uid_t uid = from_kuid_munged(current_user_ns(), __task_cred(p)->uid);
 	struct siginfo __user *infop;
 	struct siginfo __user *infop;
 
 
 	if (!likely(wo->wo_flags & WEXITED))
 	if (!likely(wo->wo_flags & WEXITED))
@@ -1427,7 +1427,7 @@ static int wait_task_stopped(struct wait_opts *wo,
 	if (!unlikely(wo->wo_flags & WNOWAIT))
 	if (!unlikely(wo->wo_flags & WNOWAIT))
 		*p_code = 0;
 		*p_code = 0;
 
 
-	uid = task_uid(p);
+	uid = from_kuid_munged(current_user_ns(), __task_cred(p)->uid);
 unlock_sig:
 unlock_sig:
 	spin_unlock_irq(&p->sighand->siglock);
 	spin_unlock_irq(&p->sighand->siglock);
 	if (!exit_code)
 	if (!exit_code)
@@ -1500,7 +1500,7 @@ static int wait_task_continued(struct wait_opts *wo, struct task_struct *p)
 	}
 	}
 	if (!unlikely(wo->wo_flags & WNOWAIT))
 	if (!unlikely(wo->wo_flags & WNOWAIT))
 		p->signal->flags &= ~SIGNAL_STOP_CONTINUED;
 		p->signal->flags &= ~SIGNAL_STOP_CONTINUED;
-	uid = task_uid(p);
+	uid = from_kuid_munged(current_user_ns(), __task_cred(p)->uid);
 	spin_unlock_irq(&p->sighand->siglock);
 	spin_unlock_irq(&p->sighand->siglock);
 
 
 	pid = task_pid_vnr(p);
 	pid = task_pid_vnr(p);

+ 149 - 67
kernel/sys.c

@@ -555,9 +555,19 @@ void ctrl_alt_del(void)
  */
  */
 SYSCALL_DEFINE2(setregid, gid_t, rgid, gid_t, egid)
 SYSCALL_DEFINE2(setregid, gid_t, rgid, gid_t, egid)
 {
 {
+	struct user_namespace *ns = current_user_ns();
 	const struct cred *old;
 	const struct cred *old;
 	struct cred *new;
 	struct cred *new;
 	int retval;
 	int retval;
+	kgid_t krgid, kegid;
+
+	krgid = make_kgid(ns, rgid);
+	kegid = make_kgid(ns, egid);
+
+	if ((rgid != (gid_t) -1) && !gid_valid(krgid))
+		return -EINVAL;
+	if ((egid != (gid_t) -1) && !gid_valid(kegid))
+		return -EINVAL;
 
 
 	new = prepare_creds();
 	new = prepare_creds();
 	if (!new)
 	if (!new)
@@ -566,25 +576,25 @@ SYSCALL_DEFINE2(setregid, gid_t, rgid, gid_t, egid)
 
 
 	retval = -EPERM;
 	retval = -EPERM;
 	if (rgid != (gid_t) -1) {
 	if (rgid != (gid_t) -1) {
-		if (old->gid == rgid ||
-		    old->egid == rgid ||
+		if (gid_eq(old->gid, krgid) ||
+		    gid_eq(old->egid, krgid) ||
 		    nsown_capable(CAP_SETGID))
 		    nsown_capable(CAP_SETGID))
-			new->gid = rgid;
+			new->gid = krgid;
 		else
 		else
 			goto error;
 			goto error;
 	}
 	}
 	if (egid != (gid_t) -1) {
 	if (egid != (gid_t) -1) {
-		if (old->gid == egid ||
-		    old->egid == egid ||
-		    old->sgid == egid ||
+		if (gid_eq(old->gid, kegid) ||
+		    gid_eq(old->egid, kegid) ||
+		    gid_eq(old->sgid, kegid) ||
 		    nsown_capable(CAP_SETGID))
 		    nsown_capable(CAP_SETGID))
-			new->egid = egid;
+			new->egid = kegid;
 		else
 		else
 			goto error;
 			goto error;
 	}
 	}
 
 
 	if (rgid != (gid_t) -1 ||
 	if (rgid != (gid_t) -1 ||
-	    (egid != (gid_t) -1 && egid != old->gid))
+	    (egid != (gid_t) -1 && !gid_eq(kegid, old->gid)))
 		new->sgid = new->egid;
 		new->sgid = new->egid;
 	new->fsgid = new->egid;
 	new->fsgid = new->egid;
 
 
@@ -602,9 +612,15 @@ error:
  */
  */
 SYSCALL_DEFINE1(setgid, gid_t, gid)
 SYSCALL_DEFINE1(setgid, gid_t, gid)
 {
 {
+	struct user_namespace *ns = current_user_ns();
 	const struct cred *old;
 	const struct cred *old;
 	struct cred *new;
 	struct cred *new;
 	int retval;
 	int retval;
+	kgid_t kgid;
+
+	kgid = make_kgid(ns, gid);
+	if (!gid_valid(kgid))
+		return -EINVAL;
 
 
 	new = prepare_creds();
 	new = prepare_creds();
 	if (!new)
 	if (!new)
@@ -613,9 +629,9 @@ SYSCALL_DEFINE1(setgid, gid_t, gid)
 
 
 	retval = -EPERM;
 	retval = -EPERM;
 	if (nsown_capable(CAP_SETGID))
 	if (nsown_capable(CAP_SETGID))
-		new->gid = new->egid = new->sgid = new->fsgid = gid;
-	else if (gid == old->gid || gid == old->sgid)
-		new->egid = new->fsgid = gid;
+		new->gid = new->egid = new->sgid = new->fsgid = kgid;
+	else if (gid_eq(kgid, old->gid) || gid_eq(kgid, old->sgid))
+		new->egid = new->fsgid = kgid;
 	else
 	else
 		goto error;
 		goto error;
 
 
@@ -672,9 +688,19 @@ static int set_user(struct cred *new)
  */
  */
 SYSCALL_DEFINE2(setreuid, uid_t, ruid, uid_t, euid)
 SYSCALL_DEFINE2(setreuid, uid_t, ruid, uid_t, euid)
 {
 {
+	struct user_namespace *ns = current_user_ns();
 	const struct cred *old;
 	const struct cred *old;
 	struct cred *new;
 	struct cred *new;
 	int retval;
 	int retval;
+	kuid_t kruid, keuid;
+
+	kruid = make_kuid(ns, ruid);
+	keuid = make_kuid(ns, euid);
+
+	if ((ruid != (uid_t) -1) && !uid_valid(kruid))
+		return -EINVAL;
+	if ((euid != (uid_t) -1) && !uid_valid(keuid))
+		return -EINVAL;
 
 
 	new = prepare_creds();
 	new = prepare_creds();
 	if (!new)
 	if (!new)
@@ -683,29 +709,29 @@ SYSCALL_DEFINE2(setreuid, uid_t, ruid, uid_t, euid)
 
 
 	retval = -EPERM;
 	retval = -EPERM;
 	if (ruid != (uid_t) -1) {
 	if (ruid != (uid_t) -1) {
-		new->uid = ruid;
-		if (old->uid != ruid &&
-		    old->euid != ruid &&
+		new->uid = kruid;
+		if (!uid_eq(old->uid, kruid) &&
+		    !uid_eq(old->euid, kruid) &&
 		    !nsown_capable(CAP_SETUID))
 		    !nsown_capable(CAP_SETUID))
 			goto error;
 			goto error;
 	}
 	}
 
 
 	if (euid != (uid_t) -1) {
 	if (euid != (uid_t) -1) {
-		new->euid = euid;
-		if (old->uid != euid &&
-		    old->euid != euid &&
-		    old->suid != euid &&
+		new->euid = keuid;
+		if (!uid_eq(old->uid, keuid) &&
+		    !uid_eq(old->euid, keuid) &&
+		    !uid_eq(old->suid, keuid) &&
 		    !nsown_capable(CAP_SETUID))
 		    !nsown_capable(CAP_SETUID))
 			goto error;
 			goto error;
 	}
 	}
 
 
-	if (new->uid != old->uid) {
+	if (!uid_eq(new->uid, old->uid)) {
 		retval = set_user(new);
 		retval = set_user(new);
 		if (retval < 0)
 		if (retval < 0)
 			goto error;
 			goto error;
 	}
 	}
 	if (ruid != (uid_t) -1 ||
 	if (ruid != (uid_t) -1 ||
-	    (euid != (uid_t) -1 && euid != old->uid))
+	    (euid != (uid_t) -1 && !uid_eq(keuid, old->uid)))
 		new->suid = new->euid;
 		new->suid = new->euid;
 	new->fsuid = new->euid;
 	new->fsuid = new->euid;
 
 
@@ -733,9 +759,15 @@ error:
  */
  */
 SYSCALL_DEFINE1(setuid, uid_t, uid)
 SYSCALL_DEFINE1(setuid, uid_t, uid)
 {
 {
+	struct user_namespace *ns = current_user_ns();
 	const struct cred *old;
 	const struct cred *old;
 	struct cred *new;
 	struct cred *new;
 	int retval;
 	int retval;
+	kuid_t kuid;
+
+	kuid = make_kuid(ns, uid);
+	if (!uid_valid(kuid))
+		return -EINVAL;
 
 
 	new = prepare_creds();
 	new = prepare_creds();
 	if (!new)
 	if (!new)
@@ -744,17 +776,17 @@ SYSCALL_DEFINE1(setuid, uid_t, uid)
 
 
 	retval = -EPERM;
 	retval = -EPERM;
 	if (nsown_capable(CAP_SETUID)) {
 	if (nsown_capable(CAP_SETUID)) {
-		new->suid = new->uid = uid;
-		if (uid != old->uid) {
+		new->suid = new->uid = kuid;
+		if (!uid_eq(kuid, old->uid)) {
 			retval = set_user(new);
 			retval = set_user(new);
 			if (retval < 0)
 			if (retval < 0)
 				goto error;
 				goto error;
 		}
 		}
-	} else if (uid != old->uid && uid != new->suid) {
+	} else if (!uid_eq(kuid, old->uid) && !uid_eq(kuid, new->suid)) {
 		goto error;
 		goto error;
 	}
 	}
 
 
-	new->fsuid = new->euid = uid;
+	new->fsuid = new->euid = kuid;
 
 
 	retval = security_task_fix_setuid(new, old, LSM_SETID_ID);
 	retval = security_task_fix_setuid(new, old, LSM_SETID_ID);
 	if (retval < 0)
 	if (retval < 0)
@@ -774,9 +806,24 @@ error:
  */
  */
 SYSCALL_DEFINE3(setresuid, uid_t, ruid, uid_t, euid, uid_t, suid)
 SYSCALL_DEFINE3(setresuid, uid_t, ruid, uid_t, euid, uid_t, suid)
 {
 {
+	struct user_namespace *ns = current_user_ns();
 	const struct cred *old;
 	const struct cred *old;
 	struct cred *new;
 	struct cred *new;
 	int retval;
 	int retval;
+	kuid_t kruid, keuid, ksuid;
+
+	kruid = make_kuid(ns, ruid);
+	keuid = make_kuid(ns, euid);
+	ksuid = make_kuid(ns, suid);
+
+	if ((ruid != (uid_t) -1) && !uid_valid(kruid))
+		return -EINVAL;
+
+	if ((euid != (uid_t) -1) && !uid_valid(keuid))
+		return -EINVAL;
+
+	if ((suid != (uid_t) -1) && !uid_valid(ksuid))
+		return -EINVAL;
 
 
 	new = prepare_creds();
 	new = prepare_creds();
 	if (!new)
 	if (!new)
@@ -786,29 +833,29 @@ SYSCALL_DEFINE3(setresuid, uid_t, ruid, uid_t, euid, uid_t, suid)
 
 
 	retval = -EPERM;
 	retval = -EPERM;
 	if (!nsown_capable(CAP_SETUID)) {
 	if (!nsown_capable(CAP_SETUID)) {
-		if (ruid != (uid_t) -1 && ruid != old->uid &&
-		    ruid != old->euid  && ruid != old->suid)
+		if (ruid != (uid_t) -1        && !uid_eq(kruid, old->uid) &&
+		    !uid_eq(kruid, old->euid) && !uid_eq(kruid, old->suid))
 			goto error;
 			goto error;
-		if (euid != (uid_t) -1 && euid != old->uid &&
-		    euid != old->euid  && euid != old->suid)
+		if (euid != (uid_t) -1        && !uid_eq(keuid, old->uid) &&
+		    !uid_eq(keuid, old->euid) && !uid_eq(keuid, old->suid))
 			goto error;
 			goto error;
-		if (suid != (uid_t) -1 && suid != old->uid &&
-		    suid != old->euid  && suid != old->suid)
+		if (suid != (uid_t) -1        && !uid_eq(ksuid, old->uid) &&
+		    !uid_eq(ksuid, old->euid) && !uid_eq(ksuid, old->suid))
 			goto error;
 			goto error;
 	}
 	}
 
 
 	if (ruid != (uid_t) -1) {
 	if (ruid != (uid_t) -1) {
-		new->uid = ruid;
-		if (ruid != old->uid) {
+		new->uid = kruid;
+		if (!uid_eq(kruid, old->uid)) {
 			retval = set_user(new);
 			retval = set_user(new);
 			if (retval < 0)
 			if (retval < 0)
 				goto error;
 				goto error;
 		}
 		}
 	}
 	}
 	if (euid != (uid_t) -1)
 	if (euid != (uid_t) -1)
-		new->euid = euid;
+		new->euid = keuid;
 	if (suid != (uid_t) -1)
 	if (suid != (uid_t) -1)
-		new->suid = suid;
+		new->suid = ksuid;
 	new->fsuid = new->euid;
 	new->fsuid = new->euid;
 
 
 	retval = security_task_fix_setuid(new, old, LSM_SETID_RES);
 	retval = security_task_fix_setuid(new, old, LSM_SETID_RES);
@@ -822,14 +869,19 @@ error:
 	return retval;
 	return retval;
 }
 }
 
 
-SYSCALL_DEFINE3(getresuid, uid_t __user *, ruid, uid_t __user *, euid, uid_t __user *, suid)
+SYSCALL_DEFINE3(getresuid, uid_t __user *, ruidp, uid_t __user *, euidp, uid_t __user *, suidp)
 {
 {
 	const struct cred *cred = current_cred();
 	const struct cred *cred = current_cred();
 	int retval;
 	int retval;
+	uid_t ruid, euid, suid;
+
+	ruid = from_kuid_munged(cred->user_ns, cred->uid);
+	euid = from_kuid_munged(cred->user_ns, cred->euid);
+	suid = from_kuid_munged(cred->user_ns, cred->suid);
 
 
-	if (!(retval   = put_user(cred->uid,  ruid)) &&
-	    !(retval   = put_user(cred->euid, euid)))
-		retval = put_user(cred->suid, suid);
+	if (!(retval   = put_user(ruid, ruidp)) &&
+	    !(retval   = put_user(euid, euidp)))
+		retval = put_user(suid, suidp);
 
 
 	return retval;
 	return retval;
 }
 }
@@ -839,9 +891,22 @@ SYSCALL_DEFINE3(getresuid, uid_t __user *, ruid, uid_t __user *, euid, uid_t __u
  */
  */
 SYSCALL_DEFINE3(setresgid, gid_t, rgid, gid_t, egid, gid_t, sgid)
 SYSCALL_DEFINE3(setresgid, gid_t, rgid, gid_t, egid, gid_t, sgid)
 {
 {
+	struct user_namespace *ns = current_user_ns();
 	const struct cred *old;
 	const struct cred *old;
 	struct cred *new;
 	struct cred *new;
 	int retval;
 	int retval;
+	kgid_t krgid, kegid, ksgid;
+
+	krgid = make_kgid(ns, rgid);
+	kegid = make_kgid(ns, egid);
+	ksgid = make_kgid(ns, sgid);
+
+	if ((rgid != (gid_t) -1) && !gid_valid(krgid))
+		return -EINVAL;
+	if ((egid != (gid_t) -1) && !gid_valid(kegid))
+		return -EINVAL;
+	if ((sgid != (gid_t) -1) && !gid_valid(ksgid))
+		return -EINVAL;
 
 
 	new = prepare_creds();
 	new = prepare_creds();
 	if (!new)
 	if (!new)
@@ -850,23 +915,23 @@ SYSCALL_DEFINE3(setresgid, gid_t, rgid, gid_t, egid, gid_t, sgid)
 
 
 	retval = -EPERM;
 	retval = -EPERM;
 	if (!nsown_capable(CAP_SETGID)) {
 	if (!nsown_capable(CAP_SETGID)) {
-		if (rgid != (gid_t) -1 && rgid != old->gid &&
-		    rgid != old->egid  && rgid != old->sgid)
+		if (rgid != (gid_t) -1        && !gid_eq(krgid, old->gid) &&
+		    !gid_eq(krgid, old->egid) && !gid_eq(krgid, old->sgid))
 			goto error;
 			goto error;
-		if (egid != (gid_t) -1 && egid != old->gid &&
-		    egid != old->egid  && egid != old->sgid)
+		if (egid != (gid_t) -1        && !gid_eq(kegid, old->gid) &&
+		    !gid_eq(kegid, old->egid) && !gid_eq(kegid, old->sgid))
 			goto error;
 			goto error;
-		if (sgid != (gid_t) -1 && sgid != old->gid &&
-		    sgid != old->egid  && sgid != old->sgid)
+		if (sgid != (gid_t) -1        && !gid_eq(ksgid, old->gid) &&
+		    !gid_eq(ksgid, old->egid) && !gid_eq(ksgid, old->sgid))
 			goto error;
 			goto error;
 	}
 	}
 
 
 	if (rgid != (gid_t) -1)
 	if (rgid != (gid_t) -1)
-		new->gid = rgid;
+		new->gid = krgid;
 	if (egid != (gid_t) -1)
 	if (egid != (gid_t) -1)
-		new->egid = egid;
+		new->egid = kegid;
 	if (sgid != (gid_t) -1)
 	if (sgid != (gid_t) -1)
-		new->sgid = sgid;
+		new->sgid = ksgid;
 	new->fsgid = new->egid;
 	new->fsgid = new->egid;
 
 
 	return commit_creds(new);
 	return commit_creds(new);
@@ -876,14 +941,19 @@ error:
 	return retval;
 	return retval;
 }
 }
 
 
-SYSCALL_DEFINE3(getresgid, gid_t __user *, rgid, gid_t __user *, egid, gid_t __user *, sgid)
+SYSCALL_DEFINE3(getresgid, gid_t __user *, rgidp, gid_t __user *, egidp, gid_t __user *, sgidp)
 {
 {
 	const struct cred *cred = current_cred();
 	const struct cred *cred = current_cred();
 	int retval;
 	int retval;
+	gid_t rgid, egid, sgid;
+
+	rgid = from_kgid_munged(cred->user_ns, cred->gid);
+	egid = from_kgid_munged(cred->user_ns, cred->egid);
+	sgid = from_kgid_munged(cred->user_ns, cred->sgid);
 
 
-	if (!(retval   = put_user(cred->gid,  rgid)) &&
-	    !(retval   = put_user(cred->egid, egid)))
-		retval = put_user(cred->sgid, sgid);
+	if (!(retval   = put_user(rgid, rgidp)) &&
+	    !(retval   = put_user(egid, egidp)))
+		retval = put_user(sgid, sgidp);
 
 
 	return retval;
 	return retval;
 }
 }
@@ -900,18 +970,24 @@ SYSCALL_DEFINE1(setfsuid, uid_t, uid)
 	const struct cred *old;
 	const struct cred *old;
 	struct cred *new;
 	struct cred *new;
 	uid_t old_fsuid;
 	uid_t old_fsuid;
+	kuid_t kuid;
+
+	old = current_cred();
+	old_fsuid = from_kuid_munged(old->user_ns, old->fsuid);
+
+	kuid = make_kuid(old->user_ns, uid);
+	if (!uid_valid(kuid))
+		return old_fsuid;
 
 
 	new = prepare_creds();
 	new = prepare_creds();
 	if (!new)
 	if (!new)
-		return current_fsuid();
-	old = current_cred();
-	old_fsuid = old->fsuid;
+		return old_fsuid;
 
 
-	if (uid == old->uid  || uid == old->euid  ||
-	    uid == old->suid || uid == old->fsuid ||
+	if (uid_eq(kuid, old->uid)  || uid_eq(kuid, old->euid)  ||
+	    uid_eq(kuid, old->suid) || uid_eq(kuid, old->fsuid) ||
 	    nsown_capable(CAP_SETUID)) {
 	    nsown_capable(CAP_SETUID)) {
-		if (uid != old_fsuid) {
-			new->fsuid = uid;
+		if (!uid_eq(kuid, old->fsuid)) {
+			new->fsuid = kuid;
 			if (security_task_fix_setuid(new, old, LSM_SETID_FS) == 0)
 			if (security_task_fix_setuid(new, old, LSM_SETID_FS) == 0)
 				goto change_okay;
 				goto change_okay;
 		}
 		}
@@ -933,18 +1009,24 @@ SYSCALL_DEFINE1(setfsgid, gid_t, gid)
 	const struct cred *old;
 	const struct cred *old;
 	struct cred *new;
 	struct cred *new;
 	gid_t old_fsgid;
 	gid_t old_fsgid;
+	kgid_t kgid;
+
+	old = current_cred();
+	old_fsgid = from_kgid_munged(old->user_ns, old->fsgid);
+
+	kgid = make_kgid(old->user_ns, gid);
+	if (!gid_valid(kgid))
+		return old_fsgid;
 
 
 	new = prepare_creds();
 	new = prepare_creds();
 	if (!new)
 	if (!new)
-		return current_fsgid();
-	old = current_cred();
-	old_fsgid = old->fsgid;
+		return old_fsgid;
 
 
-	if (gid == old->gid  || gid == old->egid  ||
-	    gid == old->sgid || gid == old->fsgid ||
+	if (gid_eq(kgid, old->gid)  || gid_eq(kgid, old->egid)  ||
+	    gid_eq(kgid, old->sgid) || gid_eq(kgid, old->fsgid) ||
 	    nsown_capable(CAP_SETGID)) {
 	    nsown_capable(CAP_SETGID)) {
-		if (gid != old_fsgid) {
-			new->fsgid = gid;
+		if (!gid_eq(kgid, old->fsgid)) {
+			new->fsgid = kgid;
 			goto change_okay;
 			goto change_okay;
 		}
 		}
 	}
 	}
@@ -1503,10 +1585,10 @@ static int check_prlimit_permission(struct task_struct *task)
 	if (cred->user_ns == tcred->user_ns &&
 	if (cred->user_ns == tcred->user_ns &&
 	    (cred->uid == tcred->euid &&
 	    (cred->uid == tcred->euid &&
 	     cred->uid == tcred->suid &&
 	     cred->uid == tcred->suid &&
-	     cred->uid == tcred->uid  &&
+	     cred->uid == tcred->uid &&
 	     cred->gid == tcred->egid &&
 	     cred->gid == tcred->egid &&
 	     cred->gid == tcred->sgid &&
 	     cred->gid == tcred->sgid &&
-	     cred->gid == tcred->gid))
+		    cred->gid == tcred->gid))
 		return 0;
 		return 0;
 	if (ns_capable(tcred->user_ns, CAP_SYS_RESOURCE))
 	if (ns_capable(tcred->user_ns, CAP_SYS_RESOURCE))
 		return 0;
 		return 0;

+ 4 - 4
kernel/timer.c

@@ -1427,25 +1427,25 @@ SYSCALL_DEFINE0(getppid)
 SYSCALL_DEFINE0(getuid)
 SYSCALL_DEFINE0(getuid)
 {
 {
 	/* Only we change this so SMP safe */
 	/* Only we change this so SMP safe */
-	return current_uid();
+	return from_kuid_munged(current_user_ns(), current_uid());
 }
 }
 
 
 SYSCALL_DEFINE0(geteuid)
 SYSCALL_DEFINE0(geteuid)
 {
 {
 	/* Only we change this so SMP safe */
 	/* Only we change this so SMP safe */
-	return current_euid();
+	return from_kuid_munged(current_user_ns(), current_euid());
 }
 }
 
 
 SYSCALL_DEFINE0(getgid)
 SYSCALL_DEFINE0(getgid)
 {
 {
 	/* Only we change this so SMP safe */
 	/* Only we change this so SMP safe */
-	return current_gid();
+	return from_kgid_munged(current_user_ns(), current_gid());
 }
 }
 
 
 SYSCALL_DEFINE0(getegid)
 SYSCALL_DEFINE0(getegid)
 {
 {
 	/* Only we change this so SMP safe */
 	/* Only we change this so SMP safe */
-	return  current_egid();
+	return from_kgid_munged(current_user_ns(), current_egid());
 }
 }
 
 
 #endif
 #endif

+ 22 - 12
kernel/uid16.c

@@ -81,14 +81,19 @@ SYSCALL_DEFINE3(setresuid16, old_uid_t, ruid, old_uid_t, euid, old_uid_t, suid)
 	return ret;
 	return ret;
 }
 }
 
 
-SYSCALL_DEFINE3(getresuid16, old_uid_t __user *, ruid, old_uid_t __user *, euid, old_uid_t __user *, suid)
+SYSCALL_DEFINE3(getresuid16, old_uid_t __user *, ruidp, old_uid_t __user *, euidp, old_uid_t __user *, suidp)
 {
 {
 	const struct cred *cred = current_cred();
 	const struct cred *cred = current_cred();
 	int retval;
 	int retval;
+	old_uid_t ruid, euid, suid;
 
 
-	if (!(retval   = put_user(high2lowuid(cred->uid),  ruid)) &&
-	    !(retval   = put_user(high2lowuid(cred->euid), euid)))
-		retval = put_user(high2lowuid(cred->suid), suid);
+	ruid = high2lowuid(from_kuid_munged(cred->user_ns, cred->uid));
+	euid = high2lowuid(from_kuid_munged(cred->user_ns, cred->euid));
+	suid = high2lowuid(from_kuid_munged(cred->user_ns, cred->suid));
+
+	if (!(retval   = put_user(ruid, ruidp)) &&
+	    !(retval   = put_user(euid, euidp)))
+		retval = put_user(suid, suidp);
 
 
 	return retval;
 	return retval;
 }
 }
@@ -103,14 +108,19 @@ SYSCALL_DEFINE3(setresgid16, old_gid_t, rgid, old_gid_t, egid, old_gid_t, sgid)
 }
 }
 
 
 
 
-SYSCALL_DEFINE3(getresgid16, old_gid_t __user *, rgid, old_gid_t __user *, egid, old_gid_t __user *, sgid)
+SYSCALL_DEFINE3(getresgid16, old_gid_t __user *, rgidp, old_gid_t __user *, egidp, old_gid_t __user *, sgidp)
 {
 {
 	const struct cred *cred = current_cred();
 	const struct cred *cred = current_cred();
 	int retval;
 	int retval;
+	old_gid_t rgid, egid, sgid;
+
+	rgid = high2lowgid(from_kgid_munged(cred->user_ns, cred->gid));
+	egid = high2lowgid(from_kgid_munged(cred->user_ns, cred->egid));
+	sgid = high2lowgid(from_kgid_munged(cred->user_ns, cred->sgid));
 
 
-	if (!(retval   = put_user(high2lowgid(cred->gid),  rgid)) &&
-	    !(retval   = put_user(high2lowgid(cred->egid), egid)))
-		retval = put_user(high2lowgid(cred->sgid), sgid);
+	if (!(retval   = put_user(rgid, rgidp)) &&
+	    !(retval   = put_user(egid, egidp)))
+		retval = put_user(sgid, sgidp);
 
 
 	return retval;
 	return retval;
 }
 }
@@ -221,20 +231,20 @@ SYSCALL_DEFINE2(setgroups16, int, gidsetsize, old_gid_t __user *, grouplist)
 
 
 SYSCALL_DEFINE0(getuid16)
 SYSCALL_DEFINE0(getuid16)
 {
 {
-	return high2lowuid(current_uid());
+	return high2lowuid(from_kuid_munged(current_user_ns(), current_uid()));
 }
 }
 
 
 SYSCALL_DEFINE0(geteuid16)
 SYSCALL_DEFINE0(geteuid16)
 {
 {
-	return high2lowuid(current_euid());
+	return high2lowuid(from_kuid_munged(current_user_ns(), current_euid()));
 }
 }
 
 
 SYSCALL_DEFINE0(getgid16)
 SYSCALL_DEFINE0(getgid16)
 {
 {
-	return high2lowgid(current_gid());
+	return high2lowgid(from_kgid_munged(current_user_ns(), current_gid()));
 }
 }
 
 
 SYSCALL_DEFINE0(getegid16)
 SYSCALL_DEFINE0(getegid16)
 {
 {
-	return high2lowgid(current_egid());
+	return high2lowgid(from_kgid_munged(current_user_ns(), current_egid()));
 }
 }