Commit 8783a1ce authored by Tomas Olsson's avatar Tomas Olsson Committed by Linus Torvalds

[PATCH] getgroups16() fix

sys_getgroups16 (or rather groups16_to_user()) returns large gids
truncated.  Needs to be fixed, one way or another.  Don't know why the
other similar casts are still there.
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent 406e1707
......@@ -364,6 +364,12 @@ struct group_info {
gid_t *blocks[0];
};
/*
* get_group_info() must be called with the owning task locked (via task_lock())
* when task != current. The reason being that the vast majority of callers are
* looking at current->group_info, which can not be changed except by the
* current task. Changing current->group_info requires the task lock, too.
*/
#define get_group_info(group_info) do { \
atomic_inc(&(group_info)->usage); \
} while (0)
......@@ -930,7 +936,9 @@ static inline int thread_group_empty(task_t *p)
extern void unhash_process(struct task_struct *p);
/*
* Protects ->fs, ->files, ->mm, ->ptrace and synchronises with wait4().
* Protects ->fs, ->files, ->mm, ->ptrace, ->group_info and synchronises with
* wait4().
*
* Nests both inside and outside of read_lock(&tasklist_lock).
* It must not be nested with write_lock_irq(&tasklist_lock),
* neither inside nor outside.
......
......@@ -39,7 +39,7 @@ asmlinkage long sys_setregid16(old_gid_t rgid, old_gid_t egid)
asmlinkage long sys_setgid16(old_gid_t gid)
{
return sys_setgid((gid_t)gid);
return sys_setgid(low2highgid(gid));
}
asmlinkage long sys_setreuid16(old_uid_t ruid, old_uid_t euid)
......@@ -49,7 +49,7 @@ asmlinkage long sys_setreuid16(old_uid_t ruid, old_uid_t euid)
asmlinkage long sys_setuid16(old_uid_t uid)
{
return sys_setuid((uid_t)uid);
return sys_setuid(low2highuid(uid));
}
asmlinkage long sys_setresuid16(old_uid_t ruid, old_uid_t euid, old_uid_t suid)
......@@ -88,12 +88,12 @@ asmlinkage long sys_getresgid16(old_gid_t __user *rgid, old_gid_t __user *egid,
asmlinkage long sys_setfsuid16(old_uid_t uid)
{
return sys_setfsuid((uid_t)uid);
return sys_setfsuid(low2highuid(uid));
}
asmlinkage long sys_setfsgid16(old_gid_t gid)
{
return sys_setfsgid((gid_t)gid);
return sys_setfsgid(low2highgid(gid));
}
static int groups16_to_user(old_gid_t __user *grouplist,
......@@ -103,7 +103,7 @@ static int groups16_to_user(old_gid_t __user *grouplist,
old_gid_t group;
for (i = 0; i < group_info->ngroups; i++) {
group = (old_gid_t)GROUP_AT(group_info, i);
group = high2lowgid(GROUP_AT(group_info, i));
if (put_user(group, grouplist+i))
return -EFAULT;
}
......@@ -120,7 +120,7 @@ static int groups16_from_user(struct group_info *group_info,
for (i = 0; i < group_info->ngroups; i++) {
if (get_user(group, grouplist+i))
return -EFAULT;
GROUP_AT(group_info, i) = (gid_t)group;
GROUP_AT(group_info, i) = low2highgid(group);
}
return 0;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment