diff -u --recursive --new-file linux-2.5.33/arch/s390x/kernel/linux32.c linux-2.5.33-vfscred/arch/s390x/kernel/linux32.c --- linux-2.5.33/arch/s390x/kernel/linux32.c Tue Jul 30 00:08:09 2002 +++ linux-2.5.33-vfscred/arch/s390x/kernel/linux32.c Sun Sep 8 20:05:43 2002 @@ -194,12 +194,10 @@ if (gidsetsize < 0) return -EINVAL; - i = current->ngroups; + i = getgroups16(NGROUPS, groups); if (gidsetsize) { if (i > gidsetsize) return -EINVAL; - for(j=0;jgroups[j]; if (copy_to_user(grouplist, groups, sizeof(u16)*i)) return -EFAULT; } @@ -217,10 +215,7 @@ return -EINVAL; if (copy_from_user(groups, grouplist, gidsetsize * sizeof(u16))) return -EFAULT; - for (i = 0 ; i < gidsetsize ; i++) - current->groups[i] = (gid_t)groups[i]; - current->ngroups = gidsetsize; - return 0; + return setgroups16(gidsetsize, grouplist); } asmlinkage long sys32_getuid16(void) diff -u --recursive --new-file linux-2.5.33/arch/sparc64/kernel/sys_sparc32.c linux-2.5.33-vfscred/arch/sparc64/kernel/sys_sparc32.c --- linux-2.5.33/arch/sparc64/kernel/sys_sparc32.c Sat Aug 24 12:59:14 2002 +++ linux-2.5.33-vfscred/arch/sparc64/kernel/sys_sparc32.c Sun Sep 8 20:05:43 2002 @@ -211,12 +211,10 @@ if (gidsetsize < 0) return -EINVAL; - i = current->ngroups; + i = getgroups16(NGROUPS, groups); if (gidsetsize) { if (i > gidsetsize) return -EINVAL; - for(j=0;jgroups[j]; if (copy_to_user(grouplist, groups, sizeof(u16)*i)) return -EFAULT; } @@ -234,10 +232,7 @@ return -EINVAL; if (copy_from_user(groups, grouplist, gidsetsize * sizeof(u16))) return -EFAULT; - for (i = 0 ; i < gidsetsize ; i++) - current->groups[i] = (gid_t)groups[i]; - current->ngroups = gidsetsize; - return 0; + return setgroups16(gidsetsize, groups); } asmlinkage long sys32_getuid16(void) diff -u --recursive --new-file linux-2.5.33/drivers/hotplug/pci_hotplug_core.c linux-2.5.33-vfscred/drivers/hotplug/pci_hotplug_core.c --- linux-2.5.33/drivers/hotplug/pci_hotplug_core.c Tue Jul 23 02:24:20 2002 +++ linux-2.5.33-vfscred/drivers/hotplug/pci_hotplug_core.c Sun Sep 8 20:05:43 2002 @@ -93,8 +93,8 @@ if (inode) { inode->i_mode = mode; - inode->i_uid = current->fsuid; - inode->i_gid = current->fsgid; + inode->i_uid = current->vfscred->uid; + inode->i_gid = current->vfscred->gid; inode->i_blksize = PAGE_CACHE_SIZE; inode->i_blocks = 0; inode->i_rdev = NODEV; diff -u --recursive --new-file linux-2.5.33/drivers/isdn/capi/capifs.c linux-2.5.33-vfscred/drivers/isdn/capi/capifs.c --- linux-2.5.33/drivers/isdn/capi/capifs.c Fri Aug 16 00:01:13 2002 +++ linux-2.5.33-vfscred/drivers/isdn/capi/capifs.c Sun Sep 8 20:05:44 2002 @@ -401,8 +401,8 @@ if ((np->inode = capifs_new_inode(sb)) != NULL) { struct inode *inode = np->inode; - inode->i_uid = sbi->setuid ? sbi->uid : current->fsuid; - inode->i_gid = sbi->setgid ? sbi->gid : current->fsgid; + inode->i_uid = sbi->setuid ? sbi->uid : current->vfscred->uid; + inode->i_gid = sbi->setgid ? sbi->gid : current->vfscred->gid; inode->i_nlink = 1; inode->i_ino = ino + 2; init_special_inode(inode, sbi->mode|S_IFCHR, kdev_t_to_nr(np->kdev)); diff -u --recursive --new-file linux-2.5.33/drivers/usb/core/inode.c linux-2.5.33-vfscred/drivers/usb/core/inode.c --- linux-2.5.33/drivers/usb/core/inode.c Fri Aug 2 19:55:22 2002 +++ linux-2.5.33-vfscred/drivers/usb/core/inode.c Sun Sep 8 20:05:44 2002 @@ -148,8 +148,8 @@ if (inode) { inode->i_mode = mode; - inode->i_uid = current->fsuid; - inode->i_gid = current->fsgid; + inode->i_uid = current->vfscred->uid; + inode->i_gid = current->vfscred->gid; inode->i_blksize = PAGE_CACHE_SIZE; inode->i_blocks = 0; inode->i_rdev = NODEV; diff -u --recursive --new-file linux-2.5.33/fs/affs/inode.c linux-2.5.33-vfscred/fs/affs/inode.c --- linux-2.5.33/fs/affs/inode.c Thu May 23 15:18:41 2002 +++ linux-2.5.33-vfscred/fs/affs/inode.c Sun Sep 8 20:05:44 2002 @@ -325,8 +325,8 @@ mark_buffer_dirty_inode(bh, inode); affs_brelse(bh); - inode->i_uid = current->fsuid; - inode->i_gid = current->fsgid; + inode->i_uid = current->vfscred->uid; + inode->i_gid = current->vfscred->gid; inode->i_ino = block; inode->i_nlink = 1; inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME; diff -u --recursive --new-file linux-2.5.33/fs/attr.c linux-2.5.33-vfscred/fs/attr.c --- linux-2.5.33/fs/attr.c Mon Jul 22 12:12:48 2002 +++ linux-2.5.33-vfscred/fs/attr.c Sun Sep 8 20:05:44 2002 @@ -30,7 +30,7 @@ /* Make sure a caller can chown. */ if ((ia_valid & ATTR_UID) && - (current->fsuid != inode->i_uid || + (current->vfscred->uid != inode->i_uid || attr->ia_uid != inode->i_uid) && !capable(CAP_CHOWN)) goto error; @@ -42,7 +42,7 @@ /* Make sure a caller can chmod. */ if (ia_valid & ATTR_MODE) { - if ((current->fsuid != inode->i_uid) && !capable(CAP_FOWNER)) + if ((current->vfscred->uid != inode->i_uid) && !capable(CAP_FOWNER)) goto error; /* Also check the setgid bit! */ if (!in_group_p((ia_valid & ATTR_GID) ? attr->ia_gid : @@ -52,7 +52,7 @@ /* Check for setting the inode time. */ if (ia_valid & (ATTR_MTIME_SET | ATTR_ATIME_SET)) { - if (current->fsuid != inode->i_uid && !capable(CAP_FOWNER)) + if (current->vfscred->uid != inode->i_uid && !capable(CAP_FOWNER)) goto error; } fine: diff -u --recursive --new-file linux-2.5.33/fs/bfs/dir.c linux-2.5.33-vfscred/fs/bfs/dir.c --- linux-2.5.33/fs/bfs/dir.c Thu May 23 15:24:30 2002 +++ linux-2.5.33-vfscred/fs/bfs/dir.c Sun Sep 8 20:05:44 2002 @@ -98,8 +98,8 @@ } set_bit(ino, info->si_imap); info->si_freei--; - inode->i_uid = current->fsuid; - inode->i_gid = (dir->i_mode & S_ISGID) ? dir->i_gid : current->fsgid; + inode->i_uid = current->vfscred->uid; + inode->i_gid = (dir->i_mode & S_ISGID) ? dir->i_gid : current->vfscred->gid; inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME; inode->i_blocks = inode->i_blksize = 0; inode->i_op = &bfs_file_inops; diff -u --recursive --new-file linux-2.5.33/fs/coda/coda_linux.c linux-2.5.33-vfscred/fs/coda/coda_linux.c --- linux-2.5.33/fs/coda/coda_linux.c Mon May 20 15:34:54 2002 +++ linux-2.5.33-vfscred/fs/coda/coda_linux.c Sun Sep 8 20:05:44 2002 @@ -66,17 +66,17 @@ cred->cr_uid = (vuid_t) current->uid; cred->cr_euid = (vuid_t) current->euid; cred->cr_suid = (vuid_t) current->suid; - cred->cr_fsuid = (vuid_t) current->fsuid; + cred->cr_fsuid = (vuid_t) current->vfscred->uid; cred->cr_groupid = (vgid_t) current->gid; cred->cr_egid = (vgid_t) current->egid; cred->cr_sgid = (vgid_t) current->sgid; - cred->cr_fsgid = (vgid_t) current->fsgid; + cred->cr_fsgid = (vgid_t) current->vfscred->gid; } int coda_cred_ok(struct coda_cred *cred) { - return(current->fsuid == cred->cr_fsuid); + return(current->vfscred->uid == cred->cr_fsuid); } int coda_cred_eq(struct coda_cred *cred1, struct coda_cred *cred2) diff -u --recursive --new-file linux-2.5.33/fs/devpts/inode.c linux-2.5.33-vfscred/fs/devpts/inode.c --- linux-2.5.33/fs/devpts/inode.c Fri Jul 5 02:02:21 2002 +++ linux-2.5.33-vfscred/fs/devpts/inode.c Sun Sep 8 20:05:44 2002 @@ -137,8 +137,8 @@ return; inode->i_ino = number+2; inode->i_blksize = 1024; - inode->i_uid = config.setuid ? config.uid : current->fsuid; - inode->i_gid = config.setgid ? config.gid : current->fsgid; + inode->i_uid = config.setuid ? config.uid : current->vfscred->uid; + inode->i_gid = config.setgid ? config.gid : current->vfscred->gid; inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME; init_special_inode(inode, S_IFCHR|config.mode, device); diff -u --recursive --new-file linux-2.5.33/fs/dquot.c linux-2.5.33-vfscred/fs/dquot.c --- linux-2.5.33/fs/dquot.c Mon Jul 22 12:12:48 2002 +++ linux-2.5.33-vfscred/fs/dquot.c Sun Sep 8 20:05:44 2002 @@ -785,7 +785,7 @@ { switch (dquot->dq_type) { case USRQUOTA: - return current->fsuid == dquot->dq_id && !(dquot->dq_flags & flag); + return current->vfscred->uid == dquot->dq_id && !(dquot->dq_flags & flag); case GRPQUOTA: return in_group_p(dquot->dq_id) && !(dquot->dq_flags & flag); } diff -u --recursive --new-file linux-2.5.33/fs/driverfs/inode.c linux-2.5.33-vfscred/fs/driverfs/inode.c --- linux-2.5.33/fs/driverfs/inode.c Mon Aug 5 20:13:07 2002 +++ linux-2.5.33-vfscred/fs/driverfs/inode.c Sun Sep 8 20:05:44 2002 @@ -98,8 +98,8 @@ if (inode) { inode->i_mode = mode; - inode->i_uid = current->fsuid; - inode->i_gid = current->fsgid; + inode->i_uid = current->vfscred->uid; + inode->i_gid = current->vfscred->gid; inode->i_blksize = PAGE_CACHE_SIZE; inode->i_blocks = 0; inode->i_rdev = NODEV; diff -u --recursive --new-file linux-2.5.33/fs/exec.c linux-2.5.33-vfscred/fs/exec.c --- linux-2.5.33/fs/exec.c Wed Aug 14 15:46:59 2002 +++ linux-2.5.33-vfscred/fs/exec.c Sun Sep 8 20:05:44 2002 @@ -770,8 +770,10 @@ do_unlock = 1; } - current->suid = current->euid = current->fsuid = bprm->e_uid; - current->sgid = current->egid = current->fsgid = bprm->e_gid; + current->suid = current->euid = bprm->e_uid; + setfsuid(bprm->e_uid); + current->sgid = current->egid = bprm->e_gid; + setfsgid(bprm->e_gid); if(do_unlock) unlock_kernel(); diff -u --recursive --new-file linux-2.5.33/fs/ext2/balloc.c linux-2.5.33-vfscred/fs/ext2/balloc.c --- linux-2.5.33/fs/ext2/balloc.c Thu Jul 4 18:17:10 2002 +++ linux-2.5.33-vfscred/fs/ext2/balloc.c Sun Sep 8 20:05:44 2002 @@ -105,7 +105,7 @@ count = free_blocks; if (free_blocks < root_blocks + count && !capable(CAP_SYS_RESOURCE) && - sbi->s_resuid != current->fsuid && + sbi->s_resuid != current->vfscred->uid && (sbi->s_resgid == 0 || !in_group_p (sbi->s_resgid))) { /* * We are too close to reserve and we are not privileged. diff -u --recursive --new-file linux-2.5.33/fs/ext2/ialloc.c linux-2.5.33-vfscred/fs/ext2/ialloc.c --- linux-2.5.33/fs/ext2/ialloc.c Thu Jul 4 18:17:10 2002 +++ linux-2.5.33-vfscred/fs/ext2/ialloc.c Sun Sep 8 20:05:44 2002 @@ -344,7 +344,7 @@ cpu_to_le32(le32_to_cpu(es->s_free_inodes_count) - 1); mark_buffer_dirty(EXT2_SB(sb)->s_sbh); sb->s_dirt = 1; - inode->i_uid = current->fsuid; + inode->i_uid = current->vfscred->uid; if (test_opt (sb, GRPID)) inode->i_gid = dir->i_gid; else if (dir->i_mode & S_ISGID) { @@ -352,7 +352,7 @@ if (S_ISDIR(mode)) mode |= S_ISGID; } else - inode->i_gid = current->fsgid; + inode->i_gid = current->vfscred->gid; inode->i_mode = mode; inode->i_ino = ino; diff -u --recursive --new-file linux-2.5.33/fs/ext2/ioctl.c linux-2.5.33-vfscred/fs/ext2/ioctl.c --- linux-2.5.33/fs/ext2/ioctl.c Fri Jun 21 07:33:18 2002 +++ linux-2.5.33-vfscred/fs/ext2/ioctl.c Sun Sep 8 20:05:44 2002 @@ -30,7 +30,7 @@ if (IS_RDONLY(inode)) return -EROFS; - if ((current->fsuid != inode->i_uid) && !capable(CAP_FOWNER)) + if ((current->vfscred->uid != inode->i_uid) && !capable(CAP_FOWNER)) return -EACCES; if (get_user(flags, (int *) arg)) @@ -79,7 +79,7 @@ case EXT2_IOC_GETVERSION: return put_user(inode->i_generation, (int *) arg); case EXT2_IOC_SETVERSION: - if ((current->fsuid != inode->i_uid) && !capable(CAP_FOWNER)) + if ((current->vfscred->uid != inode->i_uid) && !capable(CAP_FOWNER)) return -EPERM; if (IS_RDONLY(inode)) return -EROFS; diff -u --recursive --new-file linux-2.5.33/fs/ext3/balloc.c linux-2.5.33-vfscred/fs/ext3/balloc.c --- linux-2.5.33/fs/ext3/balloc.c Thu Jul 4 18:17:11 2002 +++ linux-2.5.33-vfscred/fs/ext3/balloc.c Sun Sep 8 20:05:44 2002 @@ -411,7 +411,7 @@ es = sb->u.ext3_sb.s_es; if (le32_to_cpu(es->s_free_blocks_count) <= le32_to_cpu(es->s_r_blocks_count) && - ((sb->u.ext3_sb.s_resuid != current->fsuid) && + ((sb->u.ext3_sb.s_resuid != current->vfscred->uid) && (sb->u.ext3_sb.s_resgid == 0 || !in_group_p(sb->u.ext3_sb.s_resgid)) && !capable(CAP_SYS_RESOURCE))) diff -u --recursive --new-file linux-2.5.33/fs/ext3/ialloc.c linux-2.5.33-vfscred/fs/ext3/ialloc.c --- linux-2.5.33/fs/ext3/ialloc.c Thu Jul 4 18:17:11 2002 +++ linux-2.5.33-vfscred/fs/ext3/ialloc.c Sun Sep 8 20:05:44 2002 @@ -367,7 +367,7 @@ sb->s_dirt = 1; if (err) goto fail; - inode->i_uid = current->fsuid; + inode->i_uid = current->vfscred->uid; if (test_opt (sb, GRPID)) inode->i_gid = dir->i_gid; else if (dir->i_mode & S_ISGID) { @@ -375,7 +375,7 @@ if (S_ISDIR(mode)) mode |= S_ISGID; } else - inode->i_gid = current->fsgid; + inode->i_gid = current->vfscred->gid; inode->i_mode = mode; inode->i_ino = j; diff -u --recursive --new-file linux-2.5.33/fs/ext3/ioctl.c linux-2.5.33-vfscred/fs/ext3/ioctl.c --- linux-2.5.33/fs/ext3/ioctl.c Fri Jun 21 07:33:18 2002 +++ linux-2.5.33-vfscred/fs/ext3/ioctl.c Sun Sep 8 20:05:44 2002 @@ -37,7 +37,7 @@ if (IS_RDONLY(inode)) return -EROFS; - if ((current->fsuid != inode->i_uid) && !capable(CAP_FOWNER)) + if ((current->vfscred->uid != inode->i_uid) && !capable(CAP_FOWNER)) return -EACCES; if (get_user(flags, (int *) arg)) @@ -123,7 +123,7 @@ __u32 generation; int err; - if ((current->fsuid != inode->i_uid) && !capable(CAP_FOWNER)) + if ((current->vfscred->uid != inode->i_uid) && !capable(CAP_FOWNER)) return -EPERM; if (IS_RDONLY(inode)) return -EROFS; diff -u --recursive --new-file linux-2.5.33/fs/file_table.c linux-2.5.33-vfscred/fs/file_table.c --- linux-2.5.33/fs/file_table.c Wed Aug 28 15:42:25 2002 +++ linux-2.5.33-vfscred/fs/file_table.c Sun Sep 8 20:07:58 2002 @@ -52,8 +52,8 @@ } atomic_set(&f->f_count,1); f->f_version = ++event; - f->f_uid = current->fsuid; - f->f_gid = current->fsgid; + f->f_uid = current->vfscred->fsuid; + f->f_gid = current->vfscred->fsgid; f->f_owner.lock = RW_LOCK_UNLOCKED; list_add(&f->f_list, &anon_list); file_list_unlock(); @@ -97,8 +97,8 @@ filp->f_mode = mode; atomic_set(&filp->f_count, 1); filp->f_dentry = dentry; - filp->f_uid = current->fsuid; - filp->f_gid = current->fsgid; + filp->f_uid = current->vfscred->uid; + filp->f_gid = current->vfscred->gid; filp->f_op = dentry->d_inode->i_fop; if (filp->f_op->open) return filp->f_op->open(dentry->d_inode, filp); diff -u --recursive --new-file linux-2.5.33/fs/hpfs/namei.c linux-2.5.33-vfscred/fs/hpfs/namei.c --- linux-2.5.33/fs/hpfs/namei.c Thu May 23 15:18:50 2002 +++ linux-2.5.33-vfscred/fs/hpfs/namei.c Sun Sep 8 20:05:44 2002 @@ -77,11 +77,11 @@ result->i_ctime = result->i_mtime = result->i_atime = local_to_gmt(dir->i_sb, dee.creation_date); hpfs_i(result)->i_ea_size = 0; if (dee.read_only) result->i_mode &= ~0222; - if (result->i_uid != current->fsuid || - result->i_gid != current->fsgid || + if (result->i_uid != current->vfscred->uid || + result->i_gid != current->vfscred->gid || result->i_mode != (mode | S_IFDIR)) { - result->i_uid = current->fsuid; - result->i_gid = current->fsgid; + result->i_uid = current->vfscred->uid; + result->i_gid = current->vfscred->gid; result->i_mode = mode | S_IFDIR; hpfs_write_inode_nolock(result); } @@ -152,11 +152,11 @@ result->i_data.a_ops = &hpfs_aops; hpfs_i(result)->mmu_private = 0; } - if (result->i_uid != current->fsuid || - result->i_gid != current->fsgid || + if (result->i_uid != current->vfscred->uid || + result->i_gid != current->vfscred->gid || result->i_mode != (mode | S_IFREG)) { - result->i_uid = current->fsuid; - result->i_gid = current->fsgid; + result->i_uid = current->vfscred->uid; + result->i_gid = current->vfscred->gid; result->i_mode = mode | S_IFREG; hpfs_write_inode_nolock(result); } @@ -217,8 +217,8 @@ hpfs_i(result)->i_ea_size = 0; /*if (result->i_blocks == -1) result->i_blocks = 1; if (result->i_size == -1) result->i_size = 0;*/ - result->i_uid = current->fsuid; - result->i_gid = current->fsgid; + result->i_uid = current->vfscred->uid; + result->i_gid = current->vfscred->gid; result->i_nlink = 1; result->i_size = 0; result->i_blocks = 1; @@ -288,8 +288,8 @@ /*if (result->i_blocks == -1) result->i_blocks = 1; if (result->i_size == -1) result->i_size = 0;*/ result->i_mode = S_IFLNK | 0777; - result->i_uid = current->fsuid; - result->i_gid = current->fsgid; + result->i_uid = current->vfscred->uid; + result->i_gid = current->vfscred->gid; result->i_blocks = 1; result->i_size = strlen(symlink); result->i_op = &page_symlink_inode_operations; diff -u --recursive --new-file linux-2.5.33/fs/intermezzo/file.c linux-2.5.33-vfscred/fs/intermezzo/file.c --- linux-2.5.33/fs/intermezzo/file.c Mon May 20 15:36:08 2002 +++ linux-2.5.33-vfscred/fs/intermezzo/file.c Sun Sep 8 20:05:44 2002 @@ -139,6 +139,7 @@ presto_set(file->f_dentry, PRESTO_ATTR | PRESTO_DATA); if (writable) { + struct vfs_cred *cred; PRESTO_ALLOC(fdata, struct presto_file_data *, sizeof(*fdata)); if (!fdata) { EXIT; @@ -146,15 +147,17 @@ } /* we believe that on open the kernel lock assures that only one process will do this allocation */ + cred = get_current_vfscred(); fdata->fd_do_lml = 0; - fdata->fd_fsuid = current->fsuid; - fdata->fd_fsgid = current->fsgid; + fdata->fd_fsuid = cred->uid; + fdata->fd_fsgid = cred->gid; fdata->fd_mode = file->f_dentry->d_inode->i_mode; - fdata->fd_ngroups = current->ngroups; - for (i=0 ; ingroups ; i++) - fdata->fd_groups[i] = current->groups[i]; + fdata->fd_ngroups = cred->ngroups; + for (i=0 ; ingroups ; i++) + fdata->fd_groups[i] = cred->groups[i]; fdata->fd_bytes_written = 0; /*when open,written data is zero*/ file->private_data = fdata; + put_vfscred(cred); } else { file->private_data = NULL; } diff -u --recursive --new-file linux-2.5.33/fs/intermezzo/journal.c linux-2.5.33-vfscred/fs/intermezzo/journal.c --- linux-2.5.33/fs/intermezzo/journal.c Mon May 20 15:36:12 2002 +++ linux-2.5.33-vfscred/fs/intermezzo/journal.c Sun Sep 8 20:05:44 2002 @@ -254,18 +254,22 @@ static inline char * journal_log_prefix(char *buf, int opcode, struct rec_info *rec) { + struct vfs_cred *cred; __u32 groups[NGROUPS_MAX]; int i; + cred = get_current_vfscred(); /* convert 16 bit gid's to 32 bit gid's */ - for (i=0; ingroups; i++) - groups[i] = (__u32) current->groups[i]; + for (i=0; ingroups; i++) + groups[i] = (__u32) cred->groups[i]; - return journal_log_prefix_with_groups_and_ids(buf, opcode, rec, - (__u32)current->ngroups, + i = journal_log_prefix_with_groups_and_ids(buf, opcode, rec, + (__u32)cred->ngroups, groups, - (__u32)current->fsuid, - (__u32)current->fsgid); + (__u32)cred->uid, + (__u32)cred->gid); + put_vfscred(cred); + return i; } static inline char * @@ -274,8 +278,8 @@ { return journal_log_prefix_with_groups_and_ids(buf, opcode, rec, ngroups, groups, - (__u32)current->fsuid, - (__u32)current->fsgid); + (__u32)current->vfscred->uid, + (__u32)current->vfscred->gid); } static inline char *log_version(char *buf, struct dentry *dentry) @@ -897,7 +901,7 @@ pathlen = cpu_to_le32(MYPATHLEN(buffer, path)); ino = cpu_to_le64(dentry->d_inode->i_ino); generation = cpu_to_le32(dentry->d_inode->i_generation); - size = sizeof(__u32) * current->ngroups + + size = sizeof(__u32) * current->vfscred->ngroups + sizeof(struct journal_prefix) + sizeof(*new_file_ver) + sizeof(ino) + sizeof(generation) + sizeof(pathlen) + sizeof(remote_ino) + sizeof(remote_generation) + @@ -1139,7 +1143,7 @@ BUFF_ALLOC(buffer, NULL); path = presto_path(dentry, root, buffer, PAGE_SIZE); pathlen = cpu_to_le32(MYPATHLEN(buffer, path)); - size = sizeof(__u32) * current->ngroups + + size = sizeof(__u32) * current->vfscred->ngroups + sizeof(struct journal_prefix) + sizeof(*old_ver) + sizeof(valid) + sizeof(mode) + sizeof(uid) + sizeof(gid) + sizeof(fsize) + sizeof(mtime) + sizeof(ctime) + sizeof(flags) + @@ -1220,7 +1224,7 @@ BUFF_ALLOC(buffer, NULL); path = presto_path(dentry, root, buffer, PAGE_SIZE); pathlen = cpu_to_le32(MYPATHLEN(buffer, path)); - size = sizeof(__u32) * current->ngroups + + size = sizeof(__u32) * current->vfscred->ngroups + sizeof(struct journal_prefix) + 3 * sizeof(*tgt_dir_ver) + sizeof(lmode) + sizeof(uid) + sizeof(gid) + sizeof(pathlen) + sizeof(struct journal_suffix); @@ -1282,7 +1286,7 @@ BUFF_ALLOC(buffer, NULL); path = presto_path(dentry, root, buffer, PAGE_SIZE); pathlen = cpu_to_le32(MYPATHLEN(buffer, path)); - size = sizeof(__u32) * current->ngroups + + size = sizeof(__u32) * current->vfscred->ngroups + sizeof(struct journal_prefix) + 3 * sizeof(*tgt_dir_ver) + sizeof(uid) + sizeof(gid) + sizeof(pathlen) + sizeof(targetlen) + sizeof(struct journal_suffix); @@ -1345,7 +1349,7 @@ BUFF_ALLOC(buffer, NULL); path = presto_path(dentry, root, buffer, PAGE_SIZE); pathlen = cpu_to_le32(MYPATHLEN(buffer, path)); - size = sizeof(__u32) * current->ngroups + + size = sizeof(__u32) * current->vfscred->ngroups + sizeof(struct journal_prefix) + 3 * sizeof(*tgt_dir_ver) + sizeof(lmode) + sizeof(uid) + sizeof(gid) + sizeof(pathlen) + sizeof(struct journal_suffix); @@ -1405,7 +1409,7 @@ BUFF_ALLOC(buffer, NULL); path = presto_path(dir, root, buffer, PAGE_SIZE); pathlen = cpu_to_le32(MYPATHLEN(buffer, path)); - size = sizeof(__u32) * current->ngroups + + size = sizeof(__u32) * current->vfscred->ngroups + sizeof(struct journal_prefix) + 3 * sizeof(*tgt_dir_ver) + sizeof(pathlen) + sizeof(llen) + sizeof(struct journal_suffix); @@ -1472,7 +1476,7 @@ BUFF_ALLOC(buffer, NULL); path = presto_path(dentry, root, buffer, PAGE_SIZE); pathlen = cpu_to_le32(MYPATHLEN(buffer, path)); - size = sizeof(__u32) * current->ngroups + + size = sizeof(__u32) * current->vfscred->ngroups + sizeof(struct journal_prefix) + 3 * sizeof(*tgt_dir_ver) + sizeof(lmode) + sizeof(uid) + sizeof(gid) + sizeof(lmajor) + sizeof(lminor) + sizeof(pathlen) + @@ -1537,7 +1541,7 @@ BUFF_ALLOC(buffer, srcbuffer); path = presto_path(tgt, root, buffer, PAGE_SIZE); pathlen = cpu_to_le32(MYPATHLEN(buffer, path)); - size = sizeof(__u32) * current->ngroups + + size = sizeof(__u32) * current->vfscred->ngroups + sizeof(struct journal_prefix) + 3 * sizeof(*tgt_dir_ver) + sizeof(srcpathlen) + sizeof(pathlen) + sizeof(struct journal_suffix); @@ -1600,7 +1604,7 @@ BUFF_ALLOC(buffer, srcbuffer); path = presto_path(tgt, root, buffer, PAGE_SIZE); pathlen = cpu_to_le32(MYPATHLEN(buffer, path)); - size = sizeof(__u32) * current->ngroups + + size = sizeof(__u32) * current->vfscred->ngroups + sizeof(struct journal_prefix) + 4 * sizeof(*src_dir_ver) + sizeof(srcpathlen) + sizeof(pathlen) + sizeof(struct journal_suffix); @@ -1661,7 +1665,7 @@ BUFF_ALLOC(buffer, NULL); path = presto_path(dir, root, buffer, PAGE_SIZE); pathlen = cpu_to_le32(MYPATHLEN(buffer, path)); - size = sizeof(__u32) * current->ngroups + + size = sizeof(__u32) * current->vfscred->ngroups + sizeof(struct journal_prefix) + 3 * sizeof(*tgt_dir_ver) + sizeof(pathlen) + sizeof(llen) + sizeof(struct journal_suffix); @@ -1741,14 +1745,16 @@ open_fsuid = fd->fd_fsuid; open_fsgid = fd->fd_fsgid; } else { - open_ngroups = current->ngroups; - for (i=0; ingroups; i++) - open_groups[i] = (__u32) current->groups[i]; + struct vfs_cred *cred = get_current_vfscred(); + open_ngroups = cred->ngroups; + for (i=0; ingroups; i++) + open_groups[i] = (__u32) cred->groups[i]; open_mode = dentry->d_inode->i_mode; open_uid = dentry->d_inode->i_uid; open_gid = dentry->d_inode->i_gid; - open_fsuid = current->fsuid; - open_fsgid = current->fsgid; + open_fsuid = cred->uid; + open_fsgid = cred->gid; + put_vfscred(cred); } BUFF_ALLOC(buffer, NULL); path = presto_path(dentry, root, buffer, PAGE_SIZE); @@ -2011,7 +2017,7 @@ */ mode=cpu_to_le32(dentry->d_inode->i_mode); - size = sizeof(__u32) * current->ngroups + + size = sizeof(__u32) * current->vfscred->ngroups + sizeof(struct journal_prefix) + 2 * sizeof(struct presto_version) + sizeof(flags) + sizeof(mode) + sizeof(namelen) + diff -u --recursive --new-file linux-2.5.33/fs/intermezzo/kml_reint.c linux-2.5.33-vfscred/fs/intermezzo/kml_reint.c --- linux-2.5.33/fs/intermezzo/kml_reint.c Sat Mar 2 05:19:20 2002 +++ linux-2.5.33-vfscred/fs/intermezzo/kml_reint.c Sun Sep 8 20:05:44 2002 @@ -27,18 +27,18 @@ static void kmlreint_pre_secure (struct kml_rec *rec) { - if (current->fsuid != current->uid) + if (current->vfscred->uid != current->uid) CDEBUG (D_KML, "reint_kmlreint_pre_secure: cannot setfsuid\n"); - if (current->fsgid != current->gid) + if (current->vfscred->gid != current->gid) CDEBUG (D_KML, "reint_kmlreint_pre_secure: cannot setfsgid\n"); - current->fsuid = rec->rec_head.uid; - current->fsgid = rec->rec_head.fsgid; + setfsuid(rec->rec_head.uid); + setfsgid(rec->rec_head.fsgid); } static void kmlreint_post_secure (struct kml_rec *rec) { - current->fsuid = current->uid; - current->fsgid = current->gid; + setfsuid(current->uid); + setfsgid(current->gid); /* current->egid = current->gid; */ /* ????????????? */ } diff -u --recursive --new-file linux-2.5.33/fs/intermezzo/upcall.c linux-2.5.33-vfscred/fs/intermezzo/upcall.c --- linux-2.5.33/fs/intermezzo/upcall.c Mon May 20 15:36:58 2002 +++ linux-2.5.33-vfscred/fs/intermezzo/upcall.c Sun Sep 8 20:05:44 2002 @@ -63,7 +63,7 @@ outp = (union down_args *) (inp);\ inp->uh.opcode = (op);\ inp->uh.pid = current->pid;\ - inp->uh.uid = current->fsuid;\ + inp->uh.uid = current->vfscred->uid;\ outsize = insize;\ } while (0) diff -u --recursive --new-file linux-2.5.33/fs/intermezzo/vfs.c linux-2.5.33-vfscred/fs/intermezzo/vfs.c --- linux-2.5.33/fs/intermezzo/vfs.c Tue Jun 18 16:02:41 2002 +++ linux-2.5.33-vfscred/fs/intermezzo/vfs.c Sun Sep 8 20:05:44 2002 @@ -70,9 +70,9 @@ { if (!(dir->i_mode & S_ISVTX)) return 0; - if (inode->i_uid == current->fsuid) + if (inode->i_uid == current->vfscred->uid) return 0; - if (dir->i_uid == current->fsuid) + if (dir->i_uid == current->vfscred->uid) return 0; return !capable(CAP_FOWNER); } diff -u --recursive --new-file linux-2.5.33/fs/jffs/inode-v23.c linux-2.5.33-vfscred/fs/jffs/inode-v23.c --- linux-2.5.33/fs/jffs/inode-v23.c Sat Jul 27 17:21:19 2002 +++ linux-2.5.33-vfscred/fs/jffs/inode-v23.c Sun Sep 8 20:05:44 2002 @@ -479,8 +479,8 @@ raw_inode.pino = new_dir_f->ino; /* raw_inode.version = f->highest_version + 1; */ raw_inode.mode = f->mode; - raw_inode.uid = current->fsuid; - raw_inode.gid = current->fsgid; + raw_inode.uid = current->vfscred->uid; + raw_inode.gid = current->vfscred->gid; #if 0 raw_inode.uid = f->uid; raw_inode.gid = f->gid; @@ -862,9 +862,9 @@ raw_inode.pino = dir_f->ino; raw_inode.version = 1; raw_inode.mode = dir_mode; - raw_inode.uid = current->fsuid; - raw_inode.gid = (dir->i_mode & S_ISGID) ? dir->i_gid : current->fsgid; - /* raw_inode.gid = current->fsgid; */ + raw_inode.uid = current->vfscred->uid; + raw_inode.gid = (dir->i_mode & S_ISGID) ? dir->i_gid : current->vfscred->gid; + /* raw_inode.gid = current->vfscred->gid; */ raw_inode.atime = CURRENT_TIME; raw_inode.mtime = raw_inode.atime; raw_inode.ctime = raw_inode.atime; @@ -1026,8 +1026,8 @@ raw_inode.pino = del_f->pino; /* raw_inode.version = del_f->highest_version + 1; */ raw_inode.mode = del_f->mode; - raw_inode.uid = current->fsuid; - raw_inode.gid = current->fsgid; + raw_inode.uid = current->vfscred->uid; + raw_inode.gid = current->vfscred->gid; raw_inode.atime = CURRENT_TIME; raw_inode.mtime = del_f->mtime; raw_inode.ctime = raw_inode.atime; @@ -1101,9 +1101,9 @@ raw_inode.pino = dir_f->ino; raw_inode.version = 1; raw_inode.mode = mode; - raw_inode.uid = current->fsuid; - raw_inode.gid = (dir->i_mode & S_ISGID) ? dir->i_gid : current->fsgid; - /* raw_inode.gid = current->fsgid; */ + raw_inode.uid = current->vfscred->uid; + raw_inode.gid = (dir->i_mode & S_ISGID) ? dir->i_gid : current->vfscred->gid; + /* raw_inode.gid = current->vfscred->gid; */ raw_inode.atime = CURRENT_TIME; raw_inode.mtime = raw_inode.atime; raw_inode.ctime = raw_inode.atime; @@ -1212,8 +1212,8 @@ raw_inode.pino = dir_f->ino; raw_inode.version = 1; raw_inode.mode = S_IFLNK | S_IRWXUGO; - raw_inode.uid = current->fsuid; - raw_inode.gid = (dir->i_mode & S_ISGID) ? dir->i_gid : current->fsgid; + raw_inode.uid = current->vfscred->uid; + raw_inode.gid = (dir->i_mode & S_ISGID) ? dir->i_gid : current->vfscred->gid; raw_inode.atime = CURRENT_TIME; raw_inode.mtime = raw_inode.atime; raw_inode.ctime = raw_inode.atime; @@ -1314,8 +1314,8 @@ raw_inode.pino = dir_f->ino; raw_inode.version = 1; raw_inode.mode = mode; - raw_inode.uid = current->fsuid; - raw_inode.gid = (dir->i_mode & S_ISGID) ? dir->i_gid : current->fsgid; + raw_inode.uid = current->vfscred->uid; + raw_inode.gid = (dir->i_mode & S_ISGID) ? dir->i_gid : current->vfscred->gid; raw_inode.atime = CURRENT_TIME; raw_inode.mtime = raw_inode.atime; raw_inode.ctime = raw_inode.atime; diff -u --recursive --new-file linux-2.5.33/fs/jffs2/fs.c linux-2.5.33-vfscred/fs/jffs2/fs.c --- linux-2.5.33/fs/jffs2/fs.c Tue Jul 23 15:08:22 2002 +++ linux-2.5.33-vfscred/fs/jffs2/fs.c Sun Sep 8 20:05:44 2002 @@ -229,14 +229,14 @@ memset(ri, 0, sizeof(*ri)); /* Set OS-specific defaults for new inodes */ - ri->uid = current->fsuid; + ri->uid = current->vfscred->uid; if (dir_i->i_mode & S_ISGID) { ri->gid = dir_i->i_gid; if (S_ISDIR(mode)) ri->mode |= S_ISGID; } else { - ri->gid = current->fsgid; + ri->gid = current->vfscred->gid; } ri->mode = mode; ret = jffs2_do_new_inode (c, f, mode, ri); diff -u --recursive --new-file linux-2.5.33/fs/jfs/jfs_inode.c linux-2.5.33-vfscred/fs/jfs/jfs_inode.c --- linux-2.5.33/fs/jfs/jfs_inode.c Sun Aug 4 03:47:06 2002 +++ linux-2.5.33-vfscred/fs/jfs/jfs_inode.c Sun Sep 8 20:05:44 2002 @@ -52,13 +52,13 @@ return NULL; } - inode->i_uid = current->fsuid; + inode->i_uid = current->vfscred->uid; if (parent->i_mode & S_ISGID) { inode->i_gid = parent->i_gid; if (S_ISDIR(mode)) mode |= S_ISGID; } else - inode->i_gid = current->fsgid; + inode->i_gid = current->vfscred->gid; inode->i_mode = mode; if (S_ISDIR(mode)) diff -u --recursive --new-file linux-2.5.33/fs/lockd/host.c linux-2.5.33-vfscred/fs/lockd/host.c --- linux-2.5.33/fs/lockd/host.c Tue Feb 5 08:49:27 2002 +++ linux-2.5.33-vfscred/fs/lockd/host.c Sun Sep 8 20:05:44 2002 @@ -187,14 +187,15 @@ host->h_nextrebind - jiffies); } } else { - uid_t saved_fsuid = current->fsuid; + struct vfs_cred *saved_cred = get_current_vfscred(); kernel_cap_t saved_cap = current->cap_effective; /* Create RPC socket as root user so we get a priv port */ - current->fsuid = 0; + setfsuid(0); cap_raise (current->cap_effective, CAP_NET_BIND_SERVICE); xprt = xprt_create_proto(host->h_proto, &host->h_addr, NULL); - current->fsuid = saved_fsuid; + set_current_vfscred(saved_cred); + put_vfscred(saved_cred); current->cap_effective = saved_cap; if (xprt == NULL) goto forgetit; diff -u --recursive --new-file linux-2.5.33/fs/locks.c linux-2.5.33-vfscred/fs/locks.c --- linux-2.5.33/fs/locks.c Tue Sep 3 21:41:00 2002 +++ linux-2.5.33-vfscred/fs/locks.c Sun Sep 8 20:05:44 2002 @@ -1200,7 +1200,7 @@ dentry = filp->f_dentry; inode = dentry->d_inode; - if ((current->fsuid != inode->i_uid) && !capable(CAP_LEASE)) + if ((current->vfscred->uid != inode->i_uid) && !capable(CAP_LEASE)) return -EACCES; if (!S_ISREG(inode->i_mode)) return -EINVAL; diff -u --recursive --new-file linux-2.5.33/fs/minix/bitmap.c linux-2.5.33-vfscred/fs/minix/bitmap.c --- linux-2.5.33/fs/minix/bitmap.c Thu May 23 15:18:51 2002 +++ linux-2.5.33-vfscred/fs/minix/bitmap.c Sun Sep 8 20:05:44 2002 @@ -247,8 +247,8 @@ iput(inode); return NULL; } - inode->i_uid = current->fsuid; - inode->i_gid = (dir->i_mode & S_ISGID) ? dir->i_gid : current->fsgid; + inode->i_uid = current->vfscred->uid; + inode->i_gid = (dir->i_mode & S_ISGID) ? dir->i_gid : current->vfscred->gid; inode->i_ino = j; inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME; inode->i_blocks = inode->i_blksize = 0; diff -u --recursive --new-file linux-2.5.33/fs/namei.c linux-2.5.33-vfscred/fs/namei.c --- linux-2.5.33/fs/namei.c Mon Jul 22 23:20:31 2002 +++ linux-2.5.33-vfscred/fs/namei.c Sun Sep 8 20:05:44 2002 @@ -174,7 +174,7 @@ return -EACCES; } - if (current->fsuid == inode->i_uid) + if (current->vfscred->uid == inode->i_uid) mode >>= 6; else if (in_group_p(inode->i_gid)) mode >>= 3; @@ -324,7 +324,7 @@ if ((inode->i_op && inode->i_op->permission)) return -EAGAIN; - if (current->fsuid == inode->i_uid) + if (current->vfscred->uid == inode->i_uid) mode >>= 6; else if (in_group_p(inode->i_gid)) mode >>= 3; @@ -983,9 +983,9 @@ { if (!(dir->i_mode & S_ISVTX)) return 0; - if (inode->i_uid == current->fsuid) + if (inode->i_uid == current->vfscred->uid) return 0; - if (dir->i_uid == current->fsuid) + if (dir->i_uid == current->vfscred->uid) return 0; return !capable(CAP_FOWNER); } diff -u --recursive --new-file linux-2.5.33/fs/nfsd/auth.c linux-2.5.33-vfscred/fs/nfsd/auth.c --- linux-2.5.33/fs/nfsd/auth.c Tue Feb 5 18:39:38 2002 +++ linux-2.5.33-vfscred/fs/nfsd/auth.c Sun Sep 8 20:05:44 2002 @@ -35,20 +35,19 @@ } if (cred->cr_uid != (uid_t) -1) - current->fsuid = cred->cr_uid; + setfsuid(cred->cr_uid); else - current->fsuid = exp->ex_anon_uid; + setfsuid(exp->ex_anon_uid); if (cred->cr_gid != (gid_t) -1) - current->fsgid = cred->cr_gid; + setfsgid(cred->cr_gid); else - current->fsgid = exp->ex_anon_gid; + setfsgid(exp->ex_anon_gid); for (i = 0; i < NGROUPS; i++) { gid_t group = cred->cr_groups[i]; if (group == (gid_t) NOGROUP) break; - current->groups[i] = group; } - current->ngroups = i; + setgroups(i, cred->cr_groups); if ((cred->cr_uid)) { cap_t(current->cap_effective) &= ~CAP_NFSD_MASK; diff -u --recursive --new-file linux-2.5.33/fs/nfsd/vfs.c linux-2.5.33-vfscred/fs/nfsd/vfs.c --- linux-2.5.33/fs/nfsd/vfs.c Thu Aug 29 22:27:25 2002 +++ linux-2.5.33-vfscred/fs/nfsd/vfs.c Sun Sep 8 20:05:44 2002 @@ -1497,7 +1497,7 @@ IS_APPEND(inode)? " append" : "", IS_RDONLY(inode)? " ro" : ""); dprintk(" owner %d/%d user %d/%d\n", - inode->i_uid, inode->i_gid, current->fsuid, current->fsgid); + inode->i_uid, inode->i_gid, current->vfscred->uid, current->vfscred->gid); #endif /* only care about readonly exports for files and @@ -1539,7 +1539,7 @@ * with NFSv3. */ if ((acc & MAY_OWNER_OVERRIDE) && - inode->i_uid == current->fsuid) + inode->i_uid == current->vfscred->uid) return 0; acc &= ~ MAY_OWNER_OVERRIDE; /* This bit is no longer needed, diff -u --recursive --new-file linux-2.5.33/fs/open.c linux-2.5.33-vfscred/fs/open.c --- linux-2.5.33/fs/open.c Mon Jul 22 12:12:48 2002 +++ linux-2.5.33-vfscred/fs/open.c Sun Sep 8 20:05:45 2002 @@ -259,7 +259,7 @@ newattrs.ia_valid |= ATTR_ATIME_SET | ATTR_MTIME_SET; } else { - if (current->fsuid != inode->i_uid && + if (current->vfscred->uid != inode->i_uid && (error = permission(inode,MAY_WRITE)) != 0) goto dput_and_out; } @@ -306,7 +306,7 @@ newattrs.ia_mtime = times[1].tv_sec; newattrs.ia_valid |= ATTR_ATIME_SET | ATTR_MTIME_SET; } else { - if (current->fsuid != inode->i_uid && + if (current->vfscred->uid != inode->i_uid && (error = permission(inode,MAY_WRITE)) != 0) goto dput_and_out; } @@ -327,19 +327,18 @@ asmlinkage long sys_access(const char * filename, int mode) { struct nameidata nd; - int old_fsuid, old_fsgid; + struct vfs_cred *old_cred; kernel_cap_t old_cap; int res; if (mode & ~S_IRWXO) /* where's F_OK, X_OK, W_OK, R_OK? */ return -EINVAL; - old_fsuid = current->fsuid; - old_fsgid = current->fsgid; + old_cred = get_current_vfscred(); old_cap = current->cap_effective; - current->fsuid = current->uid; - current->fsgid = current->gid; + setfsuid(current->uid); + setfsgid(current->gid); /* * Clear the capabilities if we switch to a non-root user @@ -364,8 +363,8 @@ path_release(&nd); } - current->fsuid = old_fsuid; - current->fsgid = old_fsgid; + set_current_vfscred(old_cred); + put_vfscred(old_cred); current->cap_effective = old_cap; return res; diff -u --recursive --new-file linux-2.5.33/fs/pipe.c linux-2.5.33-vfscred/fs/pipe.c --- linux-2.5.33/fs/pipe.c Mon Jul 15 19:03:05 2002 +++ linux-2.5.33-vfscred/fs/pipe.c Sun Sep 8 20:05:45 2002 @@ -564,8 +564,8 @@ */ inode->i_state = I_DIRTY; inode->i_mode = S_IFIFO | S_IRUSR | S_IWUSR; - inode->i_uid = current->fsuid; - inode->i_gid = current->fsgid; + inode->i_uid = current->vfscred->uid; + inode->i_gid = current->vfscred->gid; inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME; inode->i_blksize = PAGE_SIZE; return inode; diff -u --recursive --new-file linux-2.5.33/fs/proc/array.c linux-2.5.33-vfscred/fs/proc/array.c --- linux-2.5.33/fs/proc/array.c Thu Jul 25 03:36:09 2002 +++ linux-2.5.33-vfscred/fs/proc/array.c Sun Sep 8 20:05:45 2002 @@ -148,9 +148,11 @@ static inline char * task_state(struct task_struct *p, char *buffer) { + struct vfs_cred *cred; int g; read_lock(&tasklist_lock); + cred = get_task_vfscred(p); buffer += sprintf(buffer, "State:\t%s\n" "Tgid:\t%d\n" @@ -161,8 +163,8 @@ "Gid:\t%d\t%d\t%d\t%d\n", get_task_state(p), p->tgid, p->pid, p->pid ? p->real_parent->pid : 0, 0, - p->uid, p->euid, p->suid, p->fsuid, - p->gid, p->egid, p->sgid, p->fsgid); + p->uid, p->euid, p->suid, cred->uid, + p->gid, p->egid, p->sgid, cred->gid); read_unlock(&tasklist_lock); task_lock(p); buffer += sprintf(buffer, @@ -171,10 +173,11 @@ p->files ? p->files->max_fds : 0); task_unlock(p); - for (g = 0; g < p->ngroups; g++) - buffer += sprintf(buffer, "%d ", p->groups[g]); + for (g = 0; g < cred->ngroups; g++) + buffer += sprintf(buffer, "%d ", cred->groups[g]); buffer += sprintf(buffer, "\n"); + put_vfscred(cred); return buffer; } diff -u --recursive --new-file linux-2.5.33/fs/proc/base.c linux-2.5.33-vfscred/fs/proc/base.c --- linux-2.5.33/fs/proc/base.c Tue Aug 13 01:20:00 2002 +++ linux-2.5.33-vfscred/fs/proc/base.c Sun Sep 8 20:05:45 2002 @@ -526,7 +526,7 @@ /* We don't need a base pointer in the /proc filesystem */ path_release(nd); - if (current->fsuid != inode->i_uid && !capable(CAP_DAC_OVERRIDE)) + if (current->vfscred->uid != inode->i_uid && !capable(CAP_DAC_OVERRIDE)) goto out; error = proc_check_root(inode); if (error) @@ -568,7 +568,7 @@ lock_kernel(); - if (current->fsuid != inode->i_uid && !capable(CAP_DAC_OVERRIDE)) + if (current->vfscred->uid != inode->i_uid && !capable(CAP_DAC_OVERRIDE)) goto out; error = proc_check_root(inode); if (error) diff -u --recursive --new-file linux-2.5.33/fs/ramfs/inode.c linux-2.5.33-vfscred/fs/ramfs/inode.c --- linux-2.5.33/fs/ramfs/inode.c Sat Jul 27 17:21:19 2002 +++ linux-2.5.33-vfscred/fs/ramfs/inode.c Sun Sep 8 20:05:45 2002 @@ -85,8 +85,8 @@ if (inode) { inode->i_mode = mode; - inode->i_uid = current->fsuid; - inode->i_gid = current->fsgid; + inode->i_uid = current->vfscred->uid; + inode->i_gid = current->vfscred->gid; inode->i_blksize = PAGE_CACHE_SIZE; inode->i_blocks = 0; inode->i_rdev = NODEV; diff -u --recursive --new-file linux-2.5.33/fs/reiserfs/namei.c linux-2.5.33-vfscred/fs/reiserfs/namei.c --- linux-2.5.33/fs/reiserfs/namei.c Tue Aug 6 08:57:09 2002 +++ linux-2.5.33-vfscred/fs/reiserfs/namei.c Sun Sep 8 20:05:45 2002 @@ -545,7 +545,7 @@ /* the quota init calls have to know who to charge the quota to, so ** we have to set uid and gid here */ - inode->i_uid = current->fsuid; + inode->i_uid = current->vfscred->uid; inode->i_mode = mode; if (dir->i_mode & S_ISGID) { @@ -553,7 +553,7 @@ if (S_ISDIR(mode)) inode->i_mode |= S_ISGID; } else { - inode->i_gid = current->fsgid; + inode->i_gid = current->vfscred->gid; } return 0 ; } diff -u --recursive --new-file linux-2.5.33/fs/sysv/ialloc.c linux-2.5.33-vfscred/fs/sysv/ialloc.c --- linux-2.5.33/fs/sysv/ialloc.c Thu May 23 15:18:57 2002 +++ linux-2.5.33-vfscred/fs/sysv/ialloc.c Sun Sep 8 20:05:45 2002 @@ -165,9 +165,9 @@ if (S_ISDIR(mode)) mode |= S_ISGID; } else - inode->i_gid = current->fsgid; + inode->i_gid = current->vfscred->gid; - inode->i_uid = current->fsuid; + inode->i_uid = current->vfscred->uid; inode->i_ino = fs16_to_cpu(sbi, ino); inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME; inode->i_blocks = inode->i_blksize = 0; diff -u --recursive --new-file linux-2.5.33/fs/udf/ialloc.c linux-2.5.33-vfscred/fs/udf/ialloc.c --- linux-2.5.33/fs/udf/ialloc.c Thu May 23 15:18:59 2002 +++ linux-2.5.33-vfscred/fs/udf/ialloc.c Sun Sep 8 20:05:45 2002 @@ -118,7 +118,7 @@ mark_buffer_dirty(UDF_SB_LVIDBH(sb)); } inode->i_mode = mode; - inode->i_uid = current->fsuid; + inode->i_uid = current->vfscred->uid; if (dir->i_mode & S_ISGID) { inode->i_gid = dir->i_gid; @@ -126,7 +126,7 @@ mode |= S_ISGID; } else - inode->i_gid = current->fsgid; + inode->i_gid = current->vfscred->gid; UDF_I_LOCATION(inode).logicalBlockNum = block; UDF_I_LOCATION(inode).partitionReferenceNum = UDF_I_LOCATION(dir).partitionReferenceNum; diff -u --recursive --new-file linux-2.5.33/fs/udf/namei.c linux-2.5.33-vfscred/fs/udf/namei.c --- linux-2.5.33/fs/udf/namei.c Thu May 23 15:19:00 2002 +++ linux-2.5.33-vfscred/fs/udf/namei.c Sun Sep 8 20:05:45 2002 @@ -687,7 +687,7 @@ if (!inode) goto out; - inode->i_uid = current->fsuid; + inode->i_uid = current->vfscred->uid; init_special_inode(inode, mode, rdev); if (!(fi = udf_add_entry(dir, dentry, &fibh, &cfi, &err))) { diff -u --recursive --new-file linux-2.5.33/fs/ufs/ialloc.c linux-2.5.33-vfscred/fs/ufs/ialloc.c --- linux-2.5.33/fs/ufs/ialloc.c Tue Aug 20 14:25:37 2002 +++ linux-2.5.33-vfscred/fs/ufs/ialloc.c Sun Sep 8 20:05:45 2002 @@ -254,13 +254,13 @@ sb->s_dirt = 1; inode->i_mode = mode; - inode->i_uid = current->fsuid; + inode->i_uid = current->vfscred->uid; if (dir->i_mode & S_ISGID) { inode->i_gid = dir->i_gid; if (S_ISDIR(mode)) inode->i_mode |= S_ISGID; } else - inode->i_gid = current->fsgid; + inode->i_gid = current->vfscred->gid; inode->i_ino = cg * uspi->s_ipg + bit; inode->i_blksize = PAGE_SIZE; /* This is the optimal IO size (for stat), not the fs block size */ diff -u --recursive --new-file linux-2.5.33/fs/umsdos/namei.c linux-2.5.33-vfscred/fs/umsdos/namei.c --- linux-2.5.33/fs/umsdos/namei.c Sat Jun 1 03:18:10 2002 +++ linux-2.5.33-vfscred/fs/umsdos/namei.c Sun Sep 8 20:05:45 2002 @@ -255,8 +255,8 @@ info.entry.mode = mode; info.entry.rdev = rdev; info.entry.flags = flags; - info.entry.uid = current->fsuid; - info.entry.gid = (dir->i_mode & S_ISGID) ? dir->i_gid : current->fsgid; + info.entry.uid = current->vfscred->uid; + info.entry.gid = (dir->i_mode & S_ISGID) ? dir->i_gid : current->vfscred->gid; info.entry.ctime = info.entry.atime = info.entry.mtime = CURRENT_TIME; info.entry.nlink = 1; ret = umsdos_newentry (dentry->d_parent, &info); @@ -779,8 +779,8 @@ info.entry.mode = mode | S_IFDIR; info.entry.rdev = 0; - info.entry.uid = current->fsuid; - info.entry.gid = (dir->i_mode & S_ISGID) ? dir->i_gid : current->fsgid; + info.entry.uid = current->vfscred->uid; + info.entry.gid = (dir->i_mode & S_ISGID) ? dir->i_gid : current->vfscred->gid; info.entry.ctime = info.entry.atime = info.entry.mtime = CURRENT_TIME; info.entry.flags = 0; info.entry.nlink = 1; diff -u --recursive --new-file linux-2.5.33/include/linux/cred.h linux-2.5.33-vfscred/include/linux/cred.h --- linux-2.5.33/include/linux/cred.h Thu Jan 1 01:00:00 1970 +++ linux-2.5.33-vfscred/include/linux/cred.h Sun Sep 8 20:05:45 2002 @@ -0,0 +1,88 @@ +#ifndef _LINUX_CRED_H +#define _LINUX_CRED_H + +#ifdef __KERNEL__ + +#include +#include +#include + +/* + * VFS credentials + * + * This is for use by filesystems, sockets, RPC for user authentication + * purposes. It is a direct replacement for the 2.4.x task entries + * fsuid/fsgid + groups[]. + * + * The VFS credential may be shared among different threads, interrupts,... + * without any fancy locking mechanisms provided one sticks to using + * copy on write semantics. The latter is a guarantee that if more than + * one object is referencing the vfscred, then the data in the struct will + * not change. + * + * This again means that the recipe for changing one or more of fsuid, + * fsgid, ... for the current thread will usually be as follows: + * 1) copy the existing vfscred into a new one using clone_current_vfscred() + * 2) make all the necessary changes to the clone + * 3) use set_current_vfscred() in order to register the change to the + * task_struct + * + */ +struct vfs_cred { + atomic_t count; + + uid_t uid; + gid_t gid; + + int ngroups; + gid_t *groups; + /* Default storage for groups */ + gid_t __group_storage[NGROUPS]; +}; + +#define NOGID ((gid_t)-1) +#define NOUID ((uid_t)-1) + +extern struct vfs_cred init_vfscred; +extern void credentials_init(void); + +extern void put_vfscred(struct vfs_cred *); +extern struct vfs_cred *vfscred_create(uid_t, gid_t); +extern struct vfs_cred *vfscred_clone(struct vfs_cred *); +extern int vfscred_getgroups(struct vfs_cred *, int, gid_t *); +extern int vfscred_setgroups(struct vfs_cred *, int, gid_t *); +extern int vfscred_match_group(struct vfs_cred *, gid_t); + +static inline struct vfs_cred *get_vfscred(struct vfs_cred *cred) +{ + atomic_inc(&cred->count); + return cred; +} + +static inline int vfscred_count(struct vfs_cred *cred) +{ + return atomic_read(&cred->count); +} + +#define get_current_vfscred() get_vfscred(current->vfscred) + +extern struct vfs_cred *clone_current_vfscred(void); +extern void set_current_vfscred(struct vfs_cred *); +extern int setfsuid(uid_t); +extern int setfsgid(gid_t); +extern int setgroups(int, gid_t *); +extern int getgroups(int, gid_t *); + +extern struct vfs_cred *get_task_vfscred(struct task_struct *); +extern void set_task_vfscred(struct task_struct *, struct vfs_cred *); + +/* Grrr: Support for oddball functions in security/dummy.c */ +extern int task_setfsuid(struct task_struct *, uid_t); + +#if defined(CONFIG_SPARC64) || defined(CONFIG_ARCH_S390X) +extern int setgroups16(int, gid16_t *); +extern int getgroups16(int, gid16_t *); +#endif + +#endif /* __KERNEL__ */ +#endif /* _LINUX_CRED_H */ diff -u --recursive --new-file linux-2.5.33/include/linux/init_task.h linux-2.5.33-vfscred/include/linux/init_task.h --- linux-2.5.33/include/linux/init_task.h Mon Aug 19 20:12:27 2002 +++ linux-2.5.33-vfscred/include/linux/init_task.h Sun Sep 8 20:05:45 2002 @@ -65,6 +65,7 @@ .real_timer = { \ .function = it_real_fn \ }, \ + .vfscred = &init_vfscred, \ .cap_effective = CAP_INIT_EFF_SET, \ .cap_inheritable = CAP_INIT_INH_SET, \ .cap_permitted = CAP_FULL_SET, \ diff -u --recursive --new-file linux-2.5.33/include/linux/sched.h linux-2.5.33-vfscred/include/linux/sched.h --- linux-2.5.33/include/linux/sched.h Thu Sep 5 12:24:59 2002 +++ linux-2.5.33-vfscred/include/linux/sched.h Sun Sep 8 20:05:45 2002 @@ -27,6 +27,7 @@ #include #include #include +#include struct exec_domain; @@ -327,10 +328,9 @@ unsigned long min_flt, maj_flt, nswap, cmin_flt, cmaj_flt, cnswap; int swappable:1; /* process credentials */ - uid_t uid,euid,suid,fsuid; - gid_t gid,egid,sgid,fsgid; - int ngroups; - gid_t groups[NGROUPS]; + uid_t uid,euid,suid; + gid_t gid,egid,sgid; + struct vfs_cred *vfscred; kernel_cap_t cap_effective, cap_inheritable, cap_permitted; int keep_capabilities:1; struct user_struct *user; diff -u --recursive --new-file linux-2.5.33/init/main.c linux-2.5.33-vfscred/init/main.c --- linux-2.5.33/init/main.c Wed Sep 4 15:33:32 2002 +++ linux-2.5.33-vfscred/init/main.c Sun Sep 8 20:05:45 2002 @@ -438,6 +438,7 @@ kmem_cache_sizes_init(); pgtable_cache_init(); pte_chain_init(); + credentials_init(); fork_init(num_physpages); proc_caches_init(); security_scaffolding_startup(); diff -u --recursive --new-file linux-2.5.33/kernel/Makefile linux-2.5.33-vfscred/kernel/Makefile --- linux-2.5.33/kernel/Makefile Sat Jul 27 16:14:38 2002 +++ linux-2.5.33-vfscred/kernel/Makefile Sun Sep 8 20:05:45 2002 @@ -10,12 +10,13 @@ O_TARGET := kernel.o export-objs = signal.o sys.o kmod.o context.o ksyms.o pm.o exec_domain.o \ - printk.o platform.o suspend.o dma.o + printk.o platform.o suspend.o dma.o cred.o obj-y = sched.o fork.o exec_domain.o panic.o printk.o \ module.o exit.o itimer.o time.o softirq.o resource.o \ sysctl.o capability.o ptrace.o timer.o user.o \ - signal.o sys.o kmod.o context.o futex.o platform.o + signal.o sys.o kmod.o context.o futex.o platform.o \ + cred.o obj-$(CONFIG_GENERIC_ISA_DMA) += dma.o obj-$(CONFIG_SMP) += cpu.o diff -u --recursive --new-file linux-2.5.33/kernel/cred.c linux-2.5.33-vfscred/kernel/cred.c --- linux-2.5.33/kernel/cred.c Thu Jan 1 01:00:00 1970 +++ linux-2.5.33-vfscred/kernel/cred.c Sun Sep 8 20:05:45 2002 @@ -0,0 +1,468 @@ +/* + * linux/kernel/cred.c + * + * Copyright (c) 2001 Trond Myklebust + * + * 'cred.c' contains the helper routines for managing task_cred + * and vfs_cred structures. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * Creds for the init task + */ +struct vfs_cred init_vfscred = { + .count = ATOMIC_INIT(2), + /* .uid = (uid_t)0, */ + /* .gid = (gid_t)0, */ + /* .ngroups = 0, */ + .groups = init_vfscred.__group_storage, +}; + +rwlock_t task_credlock = RW_LOCK_UNLOCKED; + +static kmem_cache_t *vfscred_cache; + +void __init credentials_init(void) +{ + vfscred_cache = kmem_cache_create("vfs_cred", + sizeof(struct vfs_cred), + 0, + SLAB_HWCACHE_ALIGN, + NULL, NULL); + if (!vfscred_cache) + panic("Cannot create vfs credential SLAB cache"); +} + +static inline struct vfs_cred *vfscred_alloc(int gfp) +{ + struct vfs_cred *cred; + cred = (struct vfs_cred *)kmem_cache_alloc(vfscred_cache, gfp); + if (cred) { + atomic_set(&cred->count, 1); + cred->groups = cred->__group_storage; + } + return cred; +} + +static inline void vfscred_freegroups(struct vfs_cred *cred) +{ + if (cred->groups != cred->__group_storage) + kfree(cred->groups); +} + +static int vfscred_growgroups(struct vfs_cred *cred, int ngrp) +{ + gid_t *buf; + int err; + + buf = cred->__group_storage; + if (ngrp <= ARRAY_SIZE(cred->__group_storage)) + goto out; + err = -ENOMEM; + buf = (gid_t *)kmalloc(ngrp * sizeof(gid_t), GFP_KERNEL); + if (!buf) + goto out_err; +out: + vfscred_freegroups(cred); + cred->groups = buf; + return 0; +out_err: + return err; +} + +/** + * put_vfscred - Release a user credential + * @cred: pointer to vfs_cred + */ +void put_vfscred(struct vfs_cred *cred) +{ + if (atomic_dec_and_test(&cred->count)) { + vfscred_freegroups(cred); + kmem_cache_free(vfscred_cache, cred); + } +} + +/** + * vfscred_create - allocate and initialize a new user credential + * @uid: + * @gid: + */ +struct vfs_cred *vfscred_create(uid_t uid, gid_t gid) +{ + struct vfs_cred *cred; + + if (!(cred = vfscred_alloc(SLAB_KERNEL))) + return NULL; + cred->uid = uid; + cred->gid = gid; + cred->ngroups = 0; + return cred; +} + +/** + * vfscred_setgroups - set the supplemental group membership in a vfs_cred + * @cred: pointer to vfs_cred + * @ngrp: number of gids to copy + * @src: pointer to gids + * + * Note: this function does not COW. If you want to set the groups on + * a public vfscred, please ensure that you copy it first... + */ +int vfscred_setgroups(struct vfs_cred *cred, int ngrp, gid_t *src) +{ + int err; + + err = -EINVAL; + if (ngrp < 0) + goto out_err; + err = vfscred_growgroups(cred, ngrp); + if (err) + goto out_err; + memcpy(cred->groups, src, ngrp * sizeof(gid_t)); + cred->ngroups = ngrp; + return 0; +out_err: + return err; +} + +/** + * vfscred_getgroups - return the supplemental groups from a vfs_cred + * @cred: pointer to vfs_cred + * @ngrp: number of gids to copy + * @dst: pointer to dest buffer + * + */ +int vfscred_getgroups(struct vfs_cred *cred, int ngrp, gid_t *dst) +{ + if (ngrp > cred->ngroups) + ngrp = cred->ngroups; + memcpy(dst, cred->groups, ngrp * sizeof(gid_t)); + return cred->ngroups; +} + +/** + * vfscred_match_group - match a gid to a vfs_cred's supplemental groups + * @cred: pointer to vfs_cred + * @gid: gid to match + */ +int vfscred_match_group(struct vfs_cred *cred, gid_t gid) +{ + gid_t *p = cred->groups; + int i; + + for (i = cred->ngroups; i != 0 ; i--) { + if (gid == *p++) + return 1; + } + return 0; +} + +/** + * vfscred_clone - duplicate a user credential + * @cred: pointer to vfs_cred + * + * Allocate a new user credential, and copy the entries in cred. + */ +struct vfs_cred *vfscred_clone(struct vfs_cred *cred) +{ + struct vfs_cred *new; + int err; + + new = vfscred_create(cred->uid, cred->gid); + if (!new) + goto out_nomem; + err = vfscred_setgroups(new, cred->ngroups, cred->groups); + if (err) + goto out_free; + return new; +out_free: + put_vfscred(new); +out_nomem: + return NULL; +} + +/** + * get_task_vfscred - return a reference to a task's user credentials + * @tsk: pointer to task + * + * Note: the rwlock is needed in order to protect against /proc + * grabbing a reference while the task itself is changing + * the vfscred. + * Once CLONE_CRED is introduced it may get worse... + */ +struct vfs_cred *get_task_vfscred(struct task_struct *tsk) +{ + struct vfs_cred *cred; + + read_lock(&task_credlock); + cred = get_vfscred(tsk->vfscred); + read_unlock(&task_credlock); + return cred; +} + +/** + * set_task_vfscred - replace a task's user credentials + * @tsk: pointer to task + * @cred: pointer to vfs_cred + * + * Note: This function does not check capabilities etc. + */ +void set_task_vfscred(struct task_struct *tsk, struct vfs_cred *cred) +{ + struct vfs_cred *old; + + if (tsk->vfscred == cred) + return; + write_lock(&task_credlock); + old = xchg(&tsk->vfscred, get_vfscred(cred)); + write_unlock(&task_credlock); + if (old) + put_vfscred(old); +} + +/** + * set_current_vfscred - replace the current task's user credentials + * @cred: pointer to vfs_cred + */ +void set_current_vfscred(struct vfs_cred *cred) +{ + set_task_vfscred(current, cred); +} + +/** + * clone_current_vfscred - Clone the current task's vfs_cred + */ +struct vfs_cred *clone_current_vfscred(void) +{ + struct vfs_cred *cred, *new; + + cred = get_current_vfscred(); + new = vfscred_clone(cred); + put_vfscred(cred); + return new; +} + +/* + * copy_write_task_vfscred - Conditionally clone a task's vfs_cred. + * @tsk: pointer to task + * + * Clones the task's vfscred if its reference count is > 1, else + * just take a reference. + * Use this in order to ensure that you are free to write to the + * vfscred. + * + */ +static struct vfs_cred *copy_write_task_vfscred(struct task_struct *tsk) +{ + struct vfs_cred *cred; + + cred = get_task_vfscred(tsk); + if (vfscred_count(cred) > 2) { + struct vfs_cred *new; + new = vfscred_clone(cred); + put_vfscred(cred); + return new; + } + return cred; +} + +/** + * setfsuid - set the current task's vfscred->uid + * @uid: new fsuid + */ +int setfsuid(uid_t uid) +{ + struct vfs_cred *cred; + + if (uid == current->vfscred->uid) + goto out; + cred = copy_write_task_vfscred(current); + if (!cred) + return -ENOMEM; + cred->uid = uid; + set_current_vfscred(cred); + put_vfscred(cred); +out: + return 0; +} + +/** + * setfsgid - set the current task's vfscred->gid + * @gid: new fsgid + */ +int setfsgid(gid_t gid) +{ + struct vfs_cred *cred; + + if (gid == current->vfscred->gid) + goto out; + cred = copy_write_task_vfscred(current); + if (!cred) + return -ENOMEM; + cred->gid = gid; + set_current_vfscred(cred); + put_vfscred(cred); +out: + return 0; +} + +/** + * setgroups - set the current task's group list + * @ngrp: number of gids to copy + * @src: pointer to gids + */ +int setgroups(int ngrp, gid_t *src) +{ + struct vfs_cred *cred; + int ret = -ENOMEM; + + cred = copy_write_task_vfscred(current); + if (!cred) + goto out; + ret = vfscred_setgroups(cred, ngrp, src); + if (!ret) + set_current_vfscred(cred); + put_vfscred(cred); +out: + return ret; +} + +/** + * getgroups - return the current task's group list + * @ngrp: number of gids to copy + * @dst: pointer to dest buffer + */ +int getgroups(int ngrp, gid_t *dst) +{ + struct vfs_cred *cred; + int ret; + + cred = get_current_vfscred(); + ret = vfscred_getgroups(cred, ngrp, dst); + put_vfscred(cred); + return ret; +} + +/** + * task_setfsuid - set the current task's vfscred uid + * @uid: new fsuid + * + * Doing this for tasks other than 'current' is usually unsafe, + * so use of this function is deprecated. + */ +int task_setfsuid(struct task_struct *tsk, uid_t uid) +{ + struct vfs_cred *cred; + + cred = copy_write_task_vfscred(tsk); + if (!cred) + return -ENOMEM; + cred->uid = uid; + set_task_vfscred(tsk, cred); + put_vfscred(cred); + return 0; +} + +#if defined(CONFIG_SPARC64) || defined(CONFIG_ARCH_S390X) +/* + * vfscred_setgroups16 - set the supplemental group membership in a vfs_cred + * @cred: pointer to vfs_cred + * @ngrp: number of 16-bit gids to copy + * @src: pointer to gids + * + * Note: this function does not COW. If you want to set the groups on + * a public vfscred, please ensure that you copy it first... + */ +static int vfscred_setgroups16(struct vfs_cred *cred, int ngrp, gid16_t *src) +{ + gid_t *dst; + int i, err; + + err = -EINVAL; + if (ngrp < 0) + goto out_err; + err = vfscred_growgroups(cred, ngrp); + if (err) + goto out_err; + dst = cred->groups; + for (i = ngrp; i != 0; i--) + *dst++ = (gid_t)*src++; + cred->ngroups = ngrp; + return 0; +out_err: + return err; +} + +/** + * vfscred_getgroups16 - return the supplemental groups from a vfs_cred + * @cred: pointer to vfs_cred + * @ngrp: number of 16-bit gids to copy + * @dst: pointer to dest buffer + * + */ +static int vfscred_getgroups16(struct vfs_cred *cred, int ngrp, gid16_t *dst) +{ + gid_t *src = cred->groups; + int i; + if (ngrp > cred->ngroups) + ngrp = cred->ngroups; + for (i = ngrp; i != 0; i--) + *dst++ = (gid16_t)*src++; + return cred->ngroups; +} + +/** + * setgroups16 - set the current task's group list + * @ngrp: number of 16-bit gids to copy + * @src: pointer to 16-bit gids + */ +int setgroups16(int ngrp, gid16_t *src) +{ + struct vfs_cred *cred; + int ret = -ENOMEM; + + cred = copy_write_task_vfscred(current); + if (!cred) + goto out; + ret = vfscred_setgroups16(cred, ngrp, src); + if (!ret) + set_current_vfscred(cred); + put_vfscred(cred); +out: + return ret; +} + +/** + * getgroups16 - return the current task's group list + * @ngrp: number of 16-bit gids to copy + * @dst: pointer to dest buffer + */ +int getgroups16(int ngrp, gid16_t *dst) +{ + struct vfs_cred *cred; + int ret; + + cred = get_current_vfscred(); + ret = vfscred_getgroups16(cred, ngrp, dst); + put_vfscred(cred); + return ret; +} + +#endif /* defined(CONFIG_SPARC64) || defined(CONFIG_ARCH_S390X) */ + +EXPORT_SYMBOL(put_vfscred); +EXPORT_SYMBOL(vfscred_getgroups); +EXPORT_SYMBOL(setfsuid); +EXPORT_SYMBOL(setfsgid); +EXPORT_SYMBOL(setgroups); +EXPORT_SYMBOL(getgroups); +EXPORT_SYMBOL(set_current_vfscred); diff -u --recursive --new-file linux-2.5.33/kernel/fork.c linux-2.5.33-vfscred/kernel/fork.c --- linux-2.5.33/kernel/fork.c Thu Sep 5 12:25:18 2002 +++ linux-2.5.33-vfscred/kernel/fork.c Sun Sep 8 20:05:45 2002 @@ -70,6 +70,7 @@ void __put_task_struct(struct task_struct *tsk) { if (tsk != current) { + put_vfscred(tsk->vfscred); free_thread_info(tsk->thread_info); kmem_cache_free(task_struct_cachep,tsk); } else { @@ -77,6 +78,7 @@ tsk = task_cache[cpu]; if (tsk) { + put_vfscred(tsk->vfscred); free_thread_info(tsk->thread_info); kmem_cache_free(task_struct_cachep,tsk); } @@ -154,6 +156,7 @@ *tsk = *orig; tsk->thread_info = ti; ti->task = tsk; + tsk->vfscred = get_task_vfscred(orig); atomic_set(&tsk->usage,1); return tsk; @@ -508,6 +511,18 @@ return i; } +/* For the moment, we never share credentials between processes */ +static int copy_cred(unsigned long clone_flags, struct task_struct * tsk) +{ + struct vfs_cred *cred; + cred = clone_current_vfscred(); + if (!cred) + return -ENOMEM; + set_task_vfscred(tsk, cred); + put_vfscred(cred); + return 0; +} + static int copy_files(unsigned long clone_flags, struct task_struct * tsk) { struct files_struct *oldf, *newf; @@ -678,6 +693,8 @@ if (!capable(CAP_SYS_ADMIN) && !capable(CAP_SYS_RESOURCE)) goto bad_fork_free; } + if (copy_cred(clone_flags, p)) + goto bad_fork_free; atomic_inc(&p->user->__count); atomic_inc(&p->user->processes); diff -u --recursive --new-file linux-2.5.33/kernel/kmod.c linux-2.5.33-vfscred/kernel/kmod.c --- linux-2.5.33/kernel/kmod.c Fri Aug 16 03:25:31 2002 +++ linux-2.5.33-vfscred/kernel/kmod.c Sun Sep 8 20:05:45 2002 @@ -132,8 +132,10 @@ } /* Give kmod all effective privileges.. */ - curtask->euid = curtask->fsuid = 0; - curtask->egid = curtask->fsgid = 0; + curtask->euid = 0; + curtask->egid = 0; + setfsuid(0); + setfsgid(0); security_ops->task_kmod_set_label(); /* Allow execve args to be in kernel space. */ diff -u --recursive --new-file linux-2.5.33/kernel/sys.c linux-2.5.33-vfscred/kernel/sys.c --- linux-2.5.33/kernel/sys.c Fri Aug 16 06:33:01 2002 +++ linux-2.5.33-vfscred/kernel/sys.c Sun Sep 8 20:05:45 2002 @@ -468,7 +468,7 @@ if (rgid != (gid_t) -1 || (egid != (gid_t) -1 && egid != old_rgid)) current->sgid = new_egid; - current->fsgid = new_egid; + setfsgid(new_egid); current->egid = new_egid; current->gid = new_rgid; return 0; @@ -495,7 +495,8 @@ current->mm->dumpable=0; wmb(); } - current->gid = current->egid = current->sgid = current->fsgid = gid; + current->gid = current->egid = current->sgid = gid; + setfsgid(gid); } else if ((gid == current->gid) || (gid == current->sgid)) { @@ -504,7 +505,8 @@ current->mm->dumpable=0; wmb(); } - current->egid = current->fsgid = gid; + current->egid = gid; + setfsgid(gid); } else return -EPERM; @@ -591,11 +593,11 @@ current->mm->dumpable=0; wmb(); } - current->fsuid = current->euid = new_euid; + current->euid = new_euid; + setfsuid(new_euid); if (ruid != (uid_t) -1 || (euid != (uid_t) -1 && euid != old_ruid)) current->suid = current->euid; - current->fsuid = current->euid; return security_ops->task_post_setuid(old_ruid, old_euid, old_suid, LSM_SETID_RE); } @@ -639,7 +641,8 @@ current->mm->dumpable = 0; wmb(); } - current->fsuid = current->euid = uid; + current->euid = uid; + setfsuid(uid); current->suid = new_suid; return security_ops->task_post_setuid(old_ruid, old_euid, old_suid, LSM_SETID_ID); @@ -684,7 +687,7 @@ } current->euid = euid; } - current->fsuid = current->euid; + setfsuid(current->euid); if (suid != (uid_t) -1) current->suid = suid; @@ -732,7 +735,7 @@ } current->egid = egid; } - current->fsgid = current->egid; + setfsgid(current->egid); if (rgid != (gid_t) -1) current->gid = rgid; if (sgid != (gid_t) -1) @@ -767,9 +770,9 @@ if (retval) return retval; - old_fsuid = current->fsuid; + old_fsuid = current->vfscred->uid; if (uid == current->uid || uid == current->euid || - uid == current->suid || uid == current->fsuid || + uid == current->suid || uid == current->vfscred->uid || capable(CAP_SETUID)) { if (uid != old_fsuid) @@ -777,7 +780,7 @@ current->mm->dumpable = 0; wmb(); } - current->fsuid = uid; + setfsuid(uid); } retval = security_ops->task_post_setuid(old_fsuid, (uid_t)-1, (uid_t)-1, LSM_SETID_FS); @@ -799,9 +802,9 @@ if (retval) return retval; - old_fsgid = current->fsgid; + old_fsgid = current->vfscred->gid; if (gid == current->gid || gid == current->egid || - gid == current->sgid || gid == current->fsgid || + gid == current->sgid || gid == current->vfscred->gid || capable(CAP_SETGID)) { if (gid != old_fsgid) @@ -809,7 +812,7 @@ current->mm->dumpable = 0; wmb(); } - current->fsgid = gid; + setfsgid(gid); } return old_fsgid; } @@ -980,6 +983,7 @@ */ asmlinkage long sys_getgroups(int gidsetsize, gid_t *grouplist) { + gid_t groups[NGROUPS]; int i; /* @@ -989,11 +993,11 @@ if (gidsetsize < 0) return -EINVAL; - i = current->ngroups; + i = getgroups(NGROUPS, groups); if (gidsetsize) { if (i > gidsetsize) return -EINVAL; - if (copy_to_user(grouplist, current->groups, sizeof(gid_t)*i)) + if (copy_to_user(grouplist, groups, sizeof(gid_t)*i)) return -EFAULT; } return i; @@ -1018,25 +1022,18 @@ retval = security_ops->task_setgroups(gidsetsize, groups); if (retval) return retval; - memcpy(current->groups, groups, gidsetsize * sizeof(gid_t)); - current->ngroups = gidsetsize; - return 0; + return setgroups(gidsetsize, groups); } static int supplemental_group_member(gid_t grp) { - int i = current->ngroups; + struct vfs_cred *cred; + int retval; - if (i) { - gid_t *groups = current->groups; - do { - if (*groups == grp) - return 1; - groups++; - i--; - } while (i); - } - return 0; + cred = get_current_vfscred(); + retval = vfscred_match_group(cred, grp); + put_vfscred(cred); + return retval; } /* @@ -1044,9 +1041,13 @@ */ int in_group_p(gid_t grp) { + struct vfs_cred *cred; int retval = 1; - if (grp != current->fsgid) - retval = supplemental_group_member(grp); + + cred = get_current_vfscred(); + if (grp != cred->gid) + retval = vfscred_match_group(cred, grp); + put_vfscred(cred); return retval; } diff -u --recursive --new-file linux-2.5.33/kernel/uid16.c linux-2.5.33-vfscred/kernel/uid16.c --- linux-2.5.33/kernel/uid16.c Sat Jul 20 01:00:55 2002 +++ linux-2.5.33-vfscred/kernel/uid16.c Sun Sep 8 20:05:45 2002 @@ -109,17 +109,18 @@ asmlinkage long sys_getgroups16(int gidsetsize, old_gid_t *grouplist) { + gid_t gids[NGROUPS]; old_gid_t groups[NGROUPS]; int i,j; if (gidsetsize < 0) return -EINVAL; - i = current->ngroups; + i = getgroups(NGROUPS, gids); if (gidsetsize) { if (i > gidsetsize) return -EINVAL; for(j=0;jgroups[j]; + groups[j] = gids[j]; if (copy_to_user(grouplist, groups, sizeof(old_gid_t)*i)) return -EFAULT; } @@ -143,9 +144,7 @@ i = security_ops->task_setgroups(gidsetsize, new_groups); if (i) return i; - memcpy(current->groups, new_groups, gidsetsize * sizeof(gid_t)); - current->ngroups = gidsetsize; - return 0; + return setgroups(gidsetsize, new_groups); } asmlinkage long sys_getuid16(void) diff -u --recursive --new-file linux-2.5.33/mm/shmem.c linux-2.5.33-vfscred/mm/shmem.c --- linux-2.5.33/mm/shmem.c Wed Aug 14 03:09:12 2002 +++ linux-2.5.33-vfscred/mm/shmem.c Sun Sep 8 20:05:45 2002 @@ -783,8 +783,8 @@ inode = new_inode(sb); if (inode) { inode->i_mode = mode; - inode->i_uid = current->fsuid; - inode->i_gid = current->fsgid; + inode->i_uid = current->vfscred->uid; + inode->i_gid = current->vfscred->gid; inode->i_blksize = PAGE_CACHE_SIZE; inode->i_blocks = 0; inode->i_rdev = NODEV; @@ -1408,8 +1408,8 @@ struct dentry * root; unsigned long blocks, inodes; int mode = S_IRWXUGO | S_ISVTX; - uid_t uid = current->fsuid; - gid_t gid = current->fsgid; + uid_t uid = current->vfscred->uid; + gid_t gid = current->vfscred->gid; struct shmem_sb_info *sbinfo; struct sysinfo si; int err; diff -u --recursive --new-file linux-2.5.33/net/socket.c linux-2.5.33-vfscred/net/socket.c --- linux-2.5.33/net/socket.c Tue Sep 3 21:41:00 2002 +++ linux-2.5.33-vfscred/net/socket.c Sun Sep 8 20:05:45 2002 @@ -470,8 +470,8 @@ inode->i_mode = S_IFSOCK|S_IRWXUGO; inode->i_sock = 1; - inode->i_uid = current->fsuid; - inode->i_gid = current->fsgid; + inode->i_uid = current->vfscred->uid; + inode->i_gid = current->vfscred->gid; sockets_in_use[smp_processor_id()].counter++; return sock; diff -u --recursive --new-file linux-2.5.33/net/sunrpc/auth_unix.c linux-2.5.33-vfscred/net/sunrpc/auth_unix.c --- linux-2.5.33/net/sunrpc/auth_unix.c Tue Feb 5 16:23:07 2002 +++ linux-2.5.33-vfscred/net/sunrpc/auth_unix.c Sun Sep 8 20:05:45 2002 @@ -80,16 +80,11 @@ cred->uc_gid = cred->uc_fsgid = 0; cred->uc_gids[0] = NOGROUP; } else { - int groups = current->ngroups; - if (groups > NFS_NGROUPS) - groups = NFS_NGROUPS; - cred->uc_uid = current->uid; cred->uc_gid = current->gid; - cred->uc_fsuid = current->fsuid; - cred->uc_fsgid = current->fsgid; - for (i = 0; i < groups; i++) - cred->uc_gids[i] = (gid_t) current->groups[i]; + cred->uc_fsuid = current->vfscred->uid; + cred->uc_fsgid = current->vfscred->gid; + i = getgroups(NFS_NGROUPS, cred->uc_gids); if (i < NFS_NGROUPS) cred->uc_gids[i] = NOGROUP; } @@ -135,28 +130,33 @@ unx_match(struct rpc_cred *rcred, int taskflags) { struct unx_cred *cred = (struct unx_cred *) rcred; - int i; - - if (!(taskflags & RPC_TASK_ROOTCREDS)) { - int groups; + struct vfs_cred *vfscred; + int groups; - if (cred->uc_uid != current->uid - || cred->uc_gid != current->gid - || cred->uc_fsuid != current->fsuid - || cred->uc_fsgid != current->fsgid) - return 0; - - groups = current->ngroups; - if (groups > NFS_NGROUPS) - groups = NFS_NGROUPS; - for (i = 0; i < groups ; i++) - if (cred->uc_gids[i] != (gid_t) current->groups[i]) - return 0; - return 1; + if ((taskflags & RPC_TASK_ROOTCREDS)) { + return (cred->uc_uid == 0 && cred->uc_fsuid == 0 + && cred->uc_gid == 0 && cred->uc_fsgid == 0 + && cred->uc_gids[0] == (gid_t) NOGROUP); } - return (cred->uc_uid == 0 && cred->uc_fsuid == 0 - && cred->uc_gid == 0 && cred->uc_fsgid == 0 - && cred->uc_gids[0] == (gid_t) NOGROUP); + + vfscred = get_current_vfscred(); + if (cred->uc_uid != current->uid + || cred->uc_gid != current->gid + || cred->uc_fsuid != vfscred->uid + || cred->uc_fsgid != vfscred->gid) + goto out_mismatch; + + groups = vfscred->ngroups; + if (groups > NFS_NGROUPS) + groups = NFS_NGROUPS; + if (memcmp(cred->uc_gids, vfscred->groups, groups*sizeof(gid_t))) + goto out_mismatch; + if (groups < NFS_NGROUPS && cred->uc_gids[groups] != NOGROUP) + goto out_mismatch; + put_vfscred(vfscred); + return 1; +out_mismatch: + return 0; } /* diff -u --recursive --new-file linux-2.5.33/net/sunrpc/sched.c linux-2.5.33-vfscred/net/sunrpc/sched.c --- linux-2.5.33/net/sunrpc/sched.c Wed Aug 28 19:42:50 2002 +++ linux-2.5.33-vfscred/net/sunrpc/sched.c Sun Sep 8 20:05:45 2002 @@ -750,7 +750,7 @@ task->tk_flags = flags; task->tk_exit = callback; init_waitqueue_head(&task->tk_wait); - if (current->uid != current->fsuid || current->gid != current->fsgid) + if (current->uid != current->vfscred->uid || current->gid != current->vfscred->gid) task->tk_flags |= RPC_TASK_SETUID; /* Initialize retry counters */ diff -u --recursive --new-file linux-2.5.33/security/capability.c linux-2.5.33-vfscred/security/capability.c --- linux-2.5.33/security/capability.c Tue Jul 30 00:44:17 2002 +++ linux-2.5.33-vfscred/security/capability.c Sun Sep 8 20:05:45 2002 @@ -583,11 +583,11 @@ */ if (!issecure (SECURE_NO_SETUID_FIXUP)) { - if (old_fsuid == 0 && current->fsuid != 0) { + if (old_fsuid == 0 && current->vfscred->uid != 0) { cap_t (current->cap_effective) &= ~CAP_FS_MASK; } - if (old_fsuid != 0 && current->fsuid == 0) { + if (old_fsuid != 0 && current->vfscred->uid == 0) { cap_t (current->cap_effective) |= (cap_t (current->cap_permitted) & CAP_FS_MASK); diff -u --recursive --new-file linux-2.5.33/security/dummy.c linux-2.5.33-vfscred/security/dummy.c --- linux-2.5.33/security/dummy.c Tue Jul 30 02:24:55 2002 +++ linux-2.5.33-vfscred/security/dummy.c Sun Sep 8 20:05:45 2002 @@ -53,7 +53,7 @@ static int dummy_capable (struct task_struct *tsk, int cap) { - if (cap_is_fs_cap (cap) ? tsk->fsuid == 0 : tsk->euid == 0) + if (cap_is_fs_cap (cap) ? tsk->vfscred->uid == 0 : tsk->euid == 0) /* capability granted */ return 0; @@ -489,7 +489,8 @@ static void dummy_task_reparent_to_init (struct task_struct *p) { - p->euid = p->fsuid = 0; + p->euid = 0; + task_setfsuid(p, 0); return; }