From: Jerome Marchand <jmarchan@redhat.com> Date: Tue, 7 Sep 2010 14:00:40 -0400 Subject: [misc] uid/gid: fix integer overflow in groups_search Message-id: <4C864588.1010301@redhat.com> Patchwork-id: 28169 O-Subject: [RHEL5.7 PATCH] fix integer overflow in groups_search Bugzilla: 629626 RH-Acked-by: Jarod Wilson <jarod@redhat.com> Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=629626 Description: gid_t is a unsigned int. If group_info contains a gid greater than MAX_INT, groups_search() function may look on the wrong side of the search tree. This solves some unfair "permission denied" problems. This patch also include some fixes for int / [gu]id_t type mismatches which are not upstream. Upstream status: The patch has been added to the -mm tree. Regards, Jerome diff --git a/kernel/sys.c b/kernel/sys.c index 98a8608..43cca93 100644 --- a/kernel/sys.c +++ b/kernel/sys.c @@ -800,10 +800,10 @@ void ctrl_alt_del(void) */ asmlinkage long sys_setregid(gid_t rgid, gid_t egid) { - int old_rgid = current->gid; - int old_egid = current->egid; - int new_rgid = old_rgid; - int new_egid = old_egid; + gid_t old_rgid = current->gid; + gid_t old_egid = current->egid; + gid_t new_rgid = old_rgid; + gid_t new_egid = old_egid; int retval; retval = security_task_setgid(rgid, egid, (gid_t)-1, LSM_SETID_RE); @@ -851,7 +851,7 @@ asmlinkage long sys_setregid(gid_t rgid, gid_t egid) */ asmlinkage long sys_setgid(gid_t gid) { - int old_egid = current->egid; + gid_t old_egid = current->egid; int retval; retval = security_task_setgid(gid, (gid_t)-1, (gid_t)-1, LSM_SETID_ID); @@ -927,7 +927,7 @@ static int set_user(uid_t new_ruid, int dumpclear) */ asmlinkage long sys_setreuid(uid_t ruid, uid_t euid) { - int old_ruid, old_euid, old_suid, new_ruid, new_euid; + uid_t old_ruid, old_euid, old_suid, new_ruid, new_euid; int retval; retval = security_task_setuid(ruid, euid, (uid_t)-1, LSM_SETID_RE); @@ -990,8 +990,8 @@ asmlinkage long sys_setreuid(uid_t ruid, uid_t euid) */ asmlinkage long sys_setuid(uid_t uid) { - int old_euid = current->euid; - int old_ruid, old_suid, new_ruid, new_suid; + uid_t old_euid = current->euid; + uid_t old_ruid, old_suid, new_ruid, new_suid; int retval; retval = security_task_setuid(uid, (uid_t)-1, (uid_t)-1, LSM_SETID_ID); @@ -1030,9 +1030,9 @@ asmlinkage long sys_setuid(uid_t uid) */ asmlinkage long sys_setresuid(uid_t ruid, uid_t euid, uid_t suid) { - int old_ruid = current->uid; - int old_euid = current->euid; - int old_suid = current->suid; + uid_t old_ruid = current->uid; + uid_t old_euid = current->euid; + uid_t old_suid = current->suid; int retval; retval = security_task_setuid(ruid, euid, suid, LSM_SETID_RES); @@ -1175,7 +1175,7 @@ asmlinkage long sys_setfsuid(uid_t uid) */ asmlinkage long sys_setfsgid(gid_t gid) { - int old_fsgid; + gid_t old_fsgid; old_fsgid = current->fsgid; if (security_task_setgid(gid, (gid_t)-1, (gid_t)-1, LSM_SETID_FS)) @@ -1548,10 +1548,9 @@ int groups_search(struct group_info *group_info, gid_t grp) right = group_info->ngroups; while (left < right) { unsigned int mid = (left+right)/2; - int cmp = grp - GROUP_AT(group_info, mid); - if (cmp > 0) + if (grp > GROUP_AT(group_info, mid)) left = mid + 1; - else if (cmp < 0) + else if (grp < GROUP_AT(group_info, mid)) right = mid; else return 1;