diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2009-04-03 00:09:10 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-04-03 00:09:10 -0400 |
| commit | 8fe74cf053de7ad2124a894996f84fa890a81093 (patch) | |
| tree | 77dcd8fbf33ce53a3821942233962fb28c6f2848 /fs | |
| parent | c2eb2fa6d2b6fe122d3479ec5b28d978418b2698 (diff) | |
| parent | ced117c73edc917e96dea7cca98c91383f0792f7 (diff) | |
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs-2.6
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs-2.6:
Remove two unneeded exports and make two symbols static in fs/mpage.c
Cleanup after commit 585d3bc06f4ca57f975a5a1f698f65a45ea66225
Trim includes of fdtable.h
Don't crap into descriptor table in binfmt_som
Trim includes in binfmt_elf
Don't mess with descriptor table in load_elf_binary()
Get rid of indirect include of fs_struct.h
New helper - current_umask()
check_unsafe_exec() doesn't care about signal handlers sharing
New locking/refcounting for fs_struct
Take fs_struct handling to new file (fs/fs_struct.c)
Get rid of bumping fs_struct refcount in pivot_root(2)
Kill unsharing fs_struct in __set_personality()
Diffstat (limited to 'fs')
| -rw-r--r-- | fs/Makefile | 2 | ||||
| -rw-r--r-- | fs/binfmt_elf.c | 22 | ||||
| -rw-r--r-- | fs/binfmt_som.c | 7 | ||||
| -rw-r--r-- | fs/block_dev.c | 1 | ||||
| -rw-r--r-- | fs/btrfs/acl.c | 2 | ||||
| -rw-r--r-- | fs/btrfs/ioctl.c | 2 | ||||
| -rw-r--r-- | fs/buffer.c | 1 | ||||
| -rw-r--r-- | fs/cifs/dir.c | 4 | ||||
| -rw-r--r-- | fs/cifs/inode.c | 4 | ||||
| -rw-r--r-- | fs/compat.c | 16 | ||||
| -rw-r--r-- | fs/dcache.c | 2 | ||||
| -rw-r--r-- | fs/exec.c | 35 | ||||
| -rw-r--r-- | fs/ext2/acl.c | 2 | ||||
| -rw-r--r-- | fs/ext3/acl.c | 2 | ||||
| -rw-r--r-- | fs/ext4/acl.c | 2 | ||||
| -rw-r--r-- | fs/fat/inode.c | 2 | ||||
| -rw-r--r-- | fs/fs_struct.c | 177 | ||||
| -rw-r--r-- | fs/generic_acl.c | 2 | ||||
| -rw-r--r-- | fs/gfs2/acl.c | 2 | ||||
| -rw-r--r-- | fs/hfsplus/options.c | 2 | ||||
| -rw-r--r-- | fs/hpfs/super.c | 2 | ||||
| -rw-r--r-- | fs/internal.h | 8 | ||||
| -rw-r--r-- | fs/jffs2/acl.c | 2 | ||||
| -rw-r--r-- | fs/jfs/acl.c | 2 | ||||
| -rw-r--r-- | fs/mpage.c | 13 | ||||
| -rw-r--r-- | fs/namei.c | 14 | ||||
| -rw-r--r-- | fs/namespace.c | 61 | ||||
| -rw-r--r-- | fs/nfs/nfs3proc.c | 6 | ||||
| -rw-r--r-- | fs/nfs/nfs4proc.c | 2 | ||||
| -rw-r--r-- | fs/nfsd/nfssvc.c | 7 | ||||
| -rw-r--r-- | fs/ocfs2/acl.c | 2 | ||||
| -rw-r--r-- | fs/omfs/inode.c | 2 | ||||
| -rw-r--r-- | fs/open.c | 1 | ||||
| -rw-r--r-- | fs/proc/base.c | 1 | ||||
| -rw-r--r-- | fs/proc/task_nommu.c | 3 | ||||
| -rw-r--r-- | fs/reiserfs/xattr_acl.c | 2 | ||||
| -rw-r--r-- | fs/xfs/linux-2.6/xfs_iops.c | 4 |
37 files changed, 275 insertions, 146 deletions
diff --git a/fs/Makefile b/fs/Makefile index 6e82a307bcd..b5cd8e18dd9 100644 --- a/fs/Makefile +++ b/fs/Makefile | |||
| @@ -11,7 +11,7 @@ obj-y := open.o read_write.o file_table.o super.o \ | |||
| 11 | attr.o bad_inode.o file.o filesystems.o namespace.o \ | 11 | attr.o bad_inode.o file.o filesystems.o namespace.o \ |
| 12 | seq_file.o xattr.o libfs.o fs-writeback.o \ | 12 | seq_file.o xattr.o libfs.o fs-writeback.o \ |
| 13 | pnode.o drop_caches.o splice.o sync.o utimes.o \ | 13 | pnode.o drop_caches.o splice.o sync.o utimes.o \ |
| 14 | stack.o | 14 | stack.o fs_struct.o |
| 15 | 15 | ||
| 16 | ifeq ($(CONFIG_BLOCK),y) | 16 | ifeq ($(CONFIG_BLOCK),y) |
| 17 | obj-y += buffer.o bio.o block_dev.o direct-io.o mpage.o ioprio.o | 17 | obj-y += buffer.o bio.o block_dev.o direct-io.o mpage.o ioprio.o |
diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c index 33b7235f853..40381df3486 100644 --- a/fs/binfmt_elf.c +++ b/fs/binfmt_elf.c | |||
| @@ -12,8 +12,6 @@ | |||
| 12 | #include <linux/module.h> | 12 | #include <linux/module.h> |
| 13 | #include <linux/kernel.h> | 13 | #include <linux/kernel.h> |
| 14 | #include <linux/fs.h> | 14 | #include <linux/fs.h> |
| 15 | #include <linux/stat.h> | ||
| 16 | #include <linux/time.h> | ||
| 17 | #include <linux/mm.h> | 15 | #include <linux/mm.h> |
| 18 | #include <linux/mman.h> | 16 | #include <linux/mman.h> |
| 19 | #include <linux/errno.h> | 17 | #include <linux/errno.h> |
| @@ -21,20 +19,15 @@ | |||
| 21 | #include <linux/binfmts.h> | 19 | #include <linux/binfmts.h> |
| 22 | #include <linux/string.h> | 20 | #include <linux/string.h> |
| 23 | #include <linux/file.h> | 21 | #include <linux/file.h> |
| 24 | #include <linux/fcntl.h> | ||
| 25 | #include <linux/ptrace.h> | ||
| 26 | #include <linux/slab.h> | 22 | #include <linux/slab.h> |
| 27 | #include <linux/shm.h> | ||
| 28 | #include <linux/personality.h> | 23 | #include <linux/personality.h> |
| 29 | #include <linux/elfcore.h> | 24 | #include <linux/elfcore.h> |
| 30 | #include <linux/init.h> | 25 | #include <linux/init.h> |
| 31 | #include <linux/highuid.h> | 26 | #include <linux/highuid.h> |
| 32 | #include <linux/smp.h> | ||
| 33 | #include <linux/compiler.h> | 27 | #include <linux/compiler.h> |
| 34 | #include <linux/highmem.h> | 28 | #include <linux/highmem.h> |
| 35 | #include <linux/pagemap.h> | 29 | #include <linux/pagemap.h> |
| 36 | #include <linux/security.h> | 30 | #include <linux/security.h> |
| 37 | #include <linux/syscalls.h> | ||
| 38 | #include <linux/random.h> | 31 | #include <linux/random.h> |
| 39 | #include <linux/elf.h> | 32 | #include <linux/elf.h> |
| 40 | #include <linux/utsname.h> | 33 | #include <linux/utsname.h> |
| @@ -576,7 +569,6 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs) | |||
| 576 | unsigned long error; | 569 | unsigned long error; |
| 577 | struct elf_phdr *elf_ppnt, *elf_phdata; | 570 | struct elf_phdr *elf_ppnt, *elf_phdata; |
| 578 | unsigned long elf_bss, elf_brk; | 571 | unsigned long elf_bss, elf_brk; |
| 579 | int elf_exec_fileno; | ||
| 580 | int retval, i; | 572 | int retval, i; |
| 581 | unsigned int size; | 573 | unsigned int size; |
| 582 | unsigned long elf_entry; | 574 | unsigned long elf_entry; |
| @@ -631,12 +623,6 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs) | |||
| 631 | goto out_free_ph; | 623 | goto out_free_ph; |
| 632 | } | 624 | } |
| 633 | 625 | ||
| 634 | retval = get_unused_fd(); | ||
| 635 | if (retval < 0) | ||
| 636 | goto out_free_ph; | ||
| 637 | get_file(bprm->file); | ||
| 638 | fd_install(elf_exec_fileno = retval, bprm->file); | ||
| 639 | |||
| 640 | elf_ppnt = elf_phdata; | 626 | elf_ppnt = elf_phdata; |
| 641 | elf_bss = 0; | 627 | elf_bss = 0; |
| 642 | elf_brk = 0; | 628 | elf_brk = 0; |
| @@ -655,13 +641,13 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs) | |||
| 655 | retval = -ENOEXEC; | 641 | retval = -ENOEXEC; |
| 656 | if (elf_ppnt->p_filesz > PATH_MAX || | 642 | if (elf_ppnt->p_filesz > PATH_MAX || |
| 657 | elf_ppnt->p_filesz < 2) | 643 | elf_ppnt->p_filesz < 2) |
| 658 | goto out_free_file; | 644 | goto out_free_ph; |
| 659 | 645 | ||
| 660 | retval = -ENOMEM; | 646 | retval = -ENOMEM; |
| 661 | elf_interpreter = kmalloc(elf_ppnt->p_filesz, | 647 | elf_interpreter = kmalloc(elf_ppnt->p_filesz, |
| 662 | GFP_KERNEL); | 648 | GFP_KERNEL); |
| 663 | if (!elf_interpreter) | 649 | if (!elf_interpreter) |
| 664 | goto out_free_file; | 650 | goto out_free_ph; |
| 665 | 651 | ||
| 666 | retval = kernel_read(bprm->file, elf_ppnt->p_offset, | 652 | retval = kernel_read(bprm->file, elf_ppnt->p_offset, |
| 667 | elf_interpreter, | 653 | elf_interpreter, |
| @@ -956,8 +942,6 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs) | |||
| 956 | 942 | ||
| 957 | kfree(elf_phdata); | 943 | kfree(elf_phdata); |
| 958 | 944 | ||
| 959 | sys_close(elf_exec_fileno); | ||
| 960 | |||
| 961 | set_binfmt(&elf_format); | 945 | set_binfmt(&elf_format); |
| 962 | 946 | ||
| 963 | #ifdef ARCH_HAS_SETUP_ADDITIONAL_PAGES | 947 | #ifdef ARCH_HAS_SETUP_ADDITIONAL_PAGES |
| @@ -1028,8 +1012,6 @@ out_free_dentry: | |||
| 1028 | fput(interpreter); | 1012 | fput(interpreter); |
| 1029 | out_free_interp: | 1013 | out_free_interp: |
| 1030 | kfree(elf_interpreter); | 1014 | kfree(elf_interpreter); |
| 1031 | out_free_file: | ||
| 1032 | sys_close(elf_exec_fileno); | ||
| 1033 | out_free_ph: | 1015 | out_free_ph: |
| 1034 | kfree(elf_phdata); | 1016 | kfree(elf_phdata); |
| 1035 | goto out; | 1017 | goto out; |
diff --git a/fs/binfmt_som.c b/fs/binfmt_som.c index 08644a61616..eff74b9c9e7 100644 --- a/fs/binfmt_som.c +++ b/fs/binfmt_som.c | |||
| @@ -188,7 +188,6 @@ out: | |||
| 188 | static int | 188 | static int |
| 189 | load_som_binary(struct linux_binprm * bprm, struct pt_regs * regs) | 189 | load_som_binary(struct linux_binprm * bprm, struct pt_regs * regs) |
| 190 | { | 190 | { |
| 191 | int som_exec_fileno; | ||
| 192 | int retval; | 191 | int retval; |
| 193 | unsigned int size; | 192 | unsigned int size; |
| 194 | unsigned long som_entry; | 193 | unsigned long som_entry; |
| @@ -220,12 +219,6 @@ load_som_binary(struct linux_binprm * bprm, struct pt_regs * regs) | |||
| 220 | goto out_free; | 219 | goto out_free; |
| 221 | } | 220 | } |
| 222 | 221 | ||
| 223 | retval = get_unused_fd(); | ||
| 224 | if (retval < 0) | ||
| 225 | goto out_free; | ||
| 226 | get_file(bprm->file); | ||
| 227 | fd_install(som_exec_fileno = retval, bprm->file); | ||
| 228 | |||
| 229 | /* Flush all traces of the currently running executable */ | 222 | /* Flush all traces of the currently running executable */ |
| 230 | retval = flush_old_exec(bprm); | 223 | retval = flush_old_exec(bprm); |
| 231 | if (retval) | 224 | if (retval) |
diff --git a/fs/block_dev.c b/fs/block_dev.c index 8c3c6899ccf..f45dbc18dd1 100644 --- a/fs/block_dev.c +++ b/fs/block_dev.c | |||
| @@ -204,6 +204,7 @@ int fsync_bdev(struct block_device *bdev) | |||
| 204 | } | 204 | } |
| 205 | return sync_blockdev(bdev); | 205 | return sync_blockdev(bdev); |
| 206 | } | 206 | } |
| 207 | EXPORT_SYMBOL(fsync_bdev); | ||
| 207 | 208 | ||
| 208 | /** | 209 | /** |
| 209 | * freeze_bdev -- lock a filesystem and force it into a consistent state | 210 | * freeze_bdev -- lock a filesystem and force it into a consistent state |
diff --git a/fs/btrfs/acl.c b/fs/btrfs/acl.c index 1d53b62dbba..7fdd184a528 100644 --- a/fs/btrfs/acl.c +++ b/fs/btrfs/acl.c | |||
| @@ -256,7 +256,7 @@ int btrfs_init_acl(struct inode *inode, struct inode *dir) | |||
| 256 | } | 256 | } |
| 257 | 257 | ||
| 258 | if (!acl) | 258 | if (!acl) |
| 259 | inode->i_mode &= ~current->fs->umask; | 259 | inode->i_mode &= ~current_umask(); |
| 260 | } | 260 | } |
| 261 | 261 | ||
| 262 | if (IS_POSIXACL(dir) && acl) { | 262 | if (IS_POSIXACL(dir) && acl) { |
diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c index bca729fc80c..7594bec1be1 100644 --- a/fs/btrfs/ioctl.c +++ b/fs/btrfs/ioctl.c | |||
| @@ -267,7 +267,7 @@ static noinline int btrfs_mksubvol(struct path *parent, char *name, | |||
| 267 | goto out_dput; | 267 | goto out_dput; |
| 268 | 268 | ||
| 269 | if (!IS_POSIXACL(parent->dentry->d_inode)) | 269 | if (!IS_POSIXACL(parent->dentry->d_inode)) |
| 270 | mode &= ~current->fs->umask; | 270 | mode &= ~current_umask(); |
| 271 | 271 | ||
| 272 | error = mnt_want_write(parent->mnt); | 272 | error = mnt_want_write(parent->mnt); |
| 273 | if (error) | 273 | if (error) |
diff --git a/fs/buffer.c b/fs/buffer.c index 2963858f0f3..c2fa1be4923 100644 --- a/fs/buffer.c +++ b/fs/buffer.c | |||
| @@ -3315,7 +3315,6 @@ EXPORT_SYMBOL(cont_write_begin); | |||
| 3315 | EXPORT_SYMBOL(end_buffer_read_sync); | 3315 | EXPORT_SYMBOL(end_buffer_read_sync); |
| 3316 | EXPORT_SYMBOL(end_buffer_write_sync); | 3316 | EXPORT_SYMBOL(end_buffer_write_sync); |
| 3317 | EXPORT_SYMBOL(file_fsync); | 3317 | EXPORT_SYMBOL(file_fsync); |
| 3318 | EXPORT_SYMBOL(fsync_bdev); | ||
| 3319 | EXPORT_SYMBOL(generic_block_bmap); | 3318 | EXPORT_SYMBOL(generic_block_bmap); |
| 3320 | EXPORT_SYMBOL(generic_cont_expand_simple); | 3319 | EXPORT_SYMBOL(generic_cont_expand_simple); |
| 3321 | EXPORT_SYMBOL(init_buffer); | 3320 | EXPORT_SYMBOL(init_buffer); |
diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c index 2f35cccfcd8..54dce78fbb7 100644 --- a/fs/cifs/dir.c +++ b/fs/cifs/dir.c | |||
| @@ -254,7 +254,7 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode, | |||
| 254 | return -ENOMEM; | 254 | return -ENOMEM; |
| 255 | } | 255 | } |
| 256 | 256 | ||
| 257 | mode &= ~current->fs->umask; | 257 | mode &= ~current_umask(); |
| 258 | if (oplockEnabled) | 258 | if (oplockEnabled) |
| 259 | oplock = REQ_OPLOCK; | 259 | oplock = REQ_OPLOCK; |
| 260 | 260 | ||
| @@ -479,7 +479,7 @@ int cifs_mknod(struct inode *inode, struct dentry *direntry, int mode, | |||
| 479 | rc = -ENOMEM; | 479 | rc = -ENOMEM; |
| 480 | else if (pTcon->unix_ext) { | 480 | else if (pTcon->unix_ext) { |
| 481 | struct cifs_unix_set_info_args args = { | 481 | struct cifs_unix_set_info_args args = { |
| 482 | .mode = mode & ~current->fs->umask, | 482 | .mode = mode & ~current_umask(), |
| 483 | .ctime = NO_CHANGE_64, | 483 | .ctime = NO_CHANGE_64, |
| 484 | .atime = NO_CHANGE_64, | 484 | .atime = NO_CHANGE_64, |
| 485 | .mtime = NO_CHANGE_64, | 485 | .mtime = NO_CHANGE_64, |
diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c index a8797cc6080..f121a80fdd6 100644 --- a/fs/cifs/inode.c +++ b/fs/cifs/inode.c | |||
| @@ -1125,7 +1125,7 @@ int cifs_mkdir(struct inode *inode, struct dentry *direntry, int mode) | |||
| 1125 | goto mkdir_out; | 1125 | goto mkdir_out; |
| 1126 | } | 1126 | } |
| 1127 | 1127 | ||
| 1128 | mode &= ~current->fs->umask; | 1128 | mode &= ~current_umask(); |
| 1129 | rc = CIFSPOSIXCreate(xid, pTcon, SMB_O_DIRECTORY | SMB_O_CREAT, | 1129 | rc = CIFSPOSIXCreate(xid, pTcon, SMB_O_DIRECTORY | SMB_O_CREAT, |
| 1130 | mode, NULL /* netfid */, pInfo, &oplock, | 1130 | mode, NULL /* netfid */, pInfo, &oplock, |
| 1131 | full_path, cifs_sb->local_nls, | 1131 | full_path, cifs_sb->local_nls, |
| @@ -1204,7 +1204,7 @@ mkdir_get_info: | |||
| 1204 | if ((direntry->d_inode) && (direntry->d_inode->i_nlink < 2)) | 1204 | if ((direntry->d_inode) && (direntry->d_inode->i_nlink < 2)) |
| 1205 | direntry->d_inode->i_nlink = 2; | 1205 | direntry->d_inode->i_nlink = 2; |
| 1206 | 1206 | ||
| 1207 | mode &= ~current->fs->umask; | 1207 | mode &= ~current_umask(); |
| 1208 | /* must turn on setgid bit if parent dir has it */ | 1208 | /* must turn on setgid bit if parent dir has it */ |
| 1209 | if (inode->i_mode & S_ISGID) | 1209 | if (inode->i_mode & S_ISGID) |
| 1210 | mode |= S_ISGID; | 1210 | mode |= S_ISGID; |
diff --git a/fs/compat.c b/fs/compat.c index 440a019256d..1c859dae758 100644 --- a/fs/compat.c +++ b/fs/compat.c | |||
| @@ -51,6 +51,7 @@ | |||
| 51 | #include <linux/poll.h> | 51 | #include <linux/poll.h> |
| 52 | #include <linux/mm.h> | 52 | #include <linux/mm.h> |
| 53 | #include <linux/eventpoll.h> | 53 | #include <linux/eventpoll.h> |
| 54 | #include <linux/fs_struct.h> | ||
| 54 | 55 | ||
| 55 | #include <asm/uaccess.h> | 56 | #include <asm/uaccess.h> |
| 56 | #include <asm/mmu_context.h> | 57 | #include <asm/mmu_context.h> |
| @@ -1502,12 +1503,15 @@ int compat_do_execve(char * filename, | |||
| 1502 | bprm->cred = prepare_exec_creds(); | 1503 | bprm->cred = prepare_exec_creds(); |
| 1503 | if (!bprm->cred) | 1504 | if (!bprm->cred) |
| 1504 | goto out_unlock; | 1505 | goto out_unlock; |
| 1505 | check_unsafe_exec(bprm); | 1506 | |
| 1507 | retval = check_unsafe_exec(bprm); | ||
| 1508 | if (retval) | ||
| 1509 | goto out_unlock; | ||
| 1506 | 1510 | ||
| 1507 | file = open_exec(filename); | 1511 | file = open_exec(filename); |
| 1508 | retval = PTR_ERR(file); | 1512 | retval = PTR_ERR(file); |
| 1509 | if (IS_ERR(file)) | 1513 | if (IS_ERR(file)) |
| 1510 | goto out_unlock; | 1514 | goto out_unmark; |
| 1511 | 1515 | ||
| 1512 | sched_exec(); | 1516 | sched_exec(); |
| 1513 | 1517 | ||
| @@ -1549,6 +1553,9 @@ int compat_do_execve(char * filename, | |||
| 1549 | goto out; | 1553 | goto out; |
| 1550 | 1554 | ||
| 1551 | /* execve succeeded */ | 1555 | /* execve succeeded */ |
| 1556 | write_lock(¤t->fs->lock); | ||
| 1557 | current->fs->in_exec = 0; | ||
| 1558 | write_unlock(¤t->fs->lock); | ||
| 1552 | current->in_execve = 0; | 1559 | current->in_execve = 0; |
| 1553 | mutex_unlock(¤t->cred_exec_mutex); | 1560 | mutex_unlock(¤t->cred_exec_mutex); |
| 1554 | acct_update_integrals(current); | 1561 | acct_update_integrals(current); |
| @@ -1567,6 +1574,11 @@ out_file: | |||
| 1567 | fput(bprm->file); | 1574 | fput(bprm->file); |
| 1568 | } | 1575 | } |
| 1569 | 1576 | ||
| 1577 | out_unmark: | ||
| 1578 | write_lock(¤t->fs->lock); | ||
| 1579 | current->fs->in_exec = 0; | ||
| 1580 | write_unlock(¤t->fs->lock); | ||
| 1581 | |||
| 1570 | out_unlock: | 1582 | out_unlock: |
| 1571 | current->in_execve = 0; | 1583 | current->in_execve = 0; |
| 1572 | mutex_unlock(¤t->cred_exec_mutex); | 1584 | mutex_unlock(¤t->cred_exec_mutex); |
diff --git a/fs/dcache.c b/fs/dcache.c index 90bbd7e1b11..761d30be268 100644 --- a/fs/dcache.c +++ b/fs/dcache.c | |||
| @@ -17,7 +17,6 @@ | |||
| 17 | #include <linux/syscalls.h> | 17 | #include <linux/syscalls.h> |
| 18 | #include <linux/string.h> | 18 | #include <linux/string.h> |
| 19 | #include <linux/mm.h> | 19 | #include <linux/mm.h> |
| 20 | #include <linux/fdtable.h> | ||
| 21 | #include <linux/fs.h> | 20 | #include <linux/fs.h> |
| 22 | #include <linux/fsnotify.h> | 21 | #include <linux/fsnotify.h> |
| 23 | #include <linux/slab.h> | 22 | #include <linux/slab.h> |
| @@ -32,6 +31,7 @@ | |||
| 32 | #include <linux/seqlock.h> | 31 | #include <linux/seqlock.h> |
| 33 | #include <linux/swap.h> | 32 | #include <linux/swap.h> |
| 34 | #include <linux/bootmem.h> | 33 | #include <linux/bootmem.h> |
| 34 | #include <linux/fs_struct.h> | ||
| 35 | #include "internal.h" | 35 | #include "internal.h" |
| 36 | 36 | ||
| 37 | int sysctl_vfs_cache_pressure __read_mostly = 100; | 37 | int sysctl_vfs_cache_pressure __read_mostly = 100; |
| @@ -53,6 +53,7 @@ | |||
| 53 | #include <linux/tracehook.h> | 53 | #include <linux/tracehook.h> |
| 54 | #include <linux/kmod.h> | 54 | #include <linux/kmod.h> |
| 55 | #include <linux/fsnotify.h> | 55 | #include <linux/fsnotify.h> |
| 56 | #include <linux/fs_struct.h> | ||
| 56 | 57 | ||
| 57 | #include <asm/uaccess.h> | 58 | #include <asm/uaccess.h> |
| 58 | #include <asm/mmu_context.h> | 59 | #include <asm/mmu_context.h> |
| @@ -1056,28 +1057,35 @@ EXPORT_SYMBOL(install_exec_creds); | |||
| 1056 | * - the caller must hold current->cred_exec_mutex to protect against | 1057 | * - the caller must hold current->cred_exec_mutex to protect against |
| 1057 | * PTRACE_ATTACH | 1058 | * PTRACE_ATTACH |
| 1058 | */ | 1059 | */ |
| 1059 | void check_unsafe_exec(struct linux_binprm *bprm) | 1060 | int check_unsafe_exec(struct linux_binprm *bprm) |
| 1060 | { | 1061 | { |
| 1061 | struct task_struct *p = current, *t; | 1062 | struct task_struct *p = current, *t; |
| 1062 | unsigned long flags; | 1063 | unsigned long flags; |
| 1063 | unsigned n_fs, n_sighand; | 1064 | unsigned n_fs; |
| 1065 | int res = 0; | ||
| 1064 | 1066 | ||
| 1065 | bprm->unsafe = tracehook_unsafe_exec(p); | 1067 | bprm->unsafe = tracehook_unsafe_exec(p); |
| 1066 | 1068 | ||
| 1067 | n_fs = 1; | 1069 | n_fs = 1; |
| 1068 | n_sighand = 1; | 1070 | write_lock(&p->fs->lock); |
| 1069 | lock_task_sighand(p, &flags); | 1071 | lock_task_sighand(p, &flags); |
| 1070 | for (t = next_thread(p); t != p; t = next_thread(t)) { | 1072 | for (t = next_thread(p); t != p; t = next_thread(t)) { |
| 1071 | if (t->fs == p->fs) | 1073 | if (t->fs == p->fs) |
| 1072 | n_fs++; | 1074 | n_fs++; |
| 1073 | n_sighand++; | ||
| 1074 | } | 1075 | } |
| 1075 | 1076 | ||
| 1076 | if (atomic_read(&p->fs->count) > n_fs || | 1077 | if (p->fs->users > n_fs) { |
| 1077 | atomic_read(&p->sighand->count) > n_sighand) | ||
| 1078 | bprm->unsafe |= LSM_UNSAFE_SHARE; | 1078 | bprm->unsafe |= LSM_UNSAFE_SHARE; |
| 1079 | } else { | ||
| 1080 | if (p->fs->in_exec) | ||
| 1081 | res = -EAGAIN; | ||
| 1082 | p->fs->in_exec = 1; | ||
| 1083 | } | ||
| 1079 | 1084 | ||
| 1080 | unlock_task_sighand(p, &flags); | 1085 | unlock_task_sighand(p, &flags); |
| 1086 | write_unlock(&p->fs->lock); | ||
| 1087 | |||
| 1088 | return res; | ||
| 1081 | } | 1089 | } |
| 1082 | 1090 | ||
| 1083 | /* | 1091 | /* |
| @@ -1296,12 +1304,15 @@ int do_execve(char * filename, | |||
| 1296 | bprm->cred = prepare_exec_creds(); | 1304 | bprm->cred = prepare_exec_creds(); |
| 1297 | if (!bprm->cred) | 1305 | if (!bprm->cred) |
| 1298 | goto out_unlock; | 1306 | goto out_unlock; |
| 1299 | check_unsafe_exec(bprm); | 1307 | |
| 1308 | retval = check_unsafe_exec(bprm); | ||
| 1309 | if (retval) | ||
| 1310 | goto out_unlock; | ||
| 1300 | 1311 | ||
| 1301 | file = open_exec(filename); | 1312 | file = open_exec(filename); |
| 1302 | retval = PTR_ERR(file); | 1313 | retval = PTR_ERR(file); |
| 1303 | if (IS_ERR(file)) | 1314 | if (IS_ERR(file)) |
| 1304 | goto out_unlock; | 1315 | goto out_unmark; |
| 1305 | 1316 | ||
| 1306 | sched_exec(); | 1317 | sched_exec(); |
| 1307 | 1318 | ||
| @@ -1344,6 +1355,9 @@ int do_execve(char * filename, | |||
| 1344 | goto out; | 1355 | goto out; |
| 1345 | 1356 | ||
| 1346 | /* execve succeeded */ | 1357 | /* execve succeeded */ |
| 1358 | write_lock(¤t->fs->lock); | ||
| 1359 | current->fs->in_exec = 0; | ||
| 1360 | write_unlock(¤t->fs->lock); | ||
| 1347 | current->in_execve = 0; | 1361 | current->in_execve = 0; |
| 1348 | mutex_unlock(¤t->cred_exec_mutex); | 1362 | mutex_unlock(¤t->cred_exec_mutex); |
| 1349 | acct_update_integrals(current); | 1363 | acct_update_integrals(current); |
| @@ -1362,6 +1376,11 @@ out_file: | |||
| 1362 | fput(bprm->file); | 1376 | fput(bprm->file); |
| 1363 | } | 1377 | } |
| 1364 | 1378 | ||
| 1379 | out_unmark: | ||
| 1380 | write_lock(¤t->fs->lock); | ||
| 1381 | current->fs->in_exec = 0; | ||
| 1382 | write_unlock(¤t->fs->lock); | ||
| 1383 | |||
| 1365 | out_unlock: | 1384 | out_unlock: |
| 1366 | current->in_execve = 0; | 1385 | current->in_execve = 0; |
| 1367 | mutex_unlock(¤t->cred_exec_mutex); | 1386 | mutex_unlock(¤t->cred_exec_mutex); |
diff --git a/fs/ext2/acl.c b/fs/ext2/acl.c index ae8c4f850b2..d46e38cb85c 100644 --- a/fs/ext2/acl.c +++ b/fs/ext2/acl.c | |||
| @@ -318,7 +318,7 @@ ext2_init_acl(struct inode *inode, struct inode *dir) | |||
| 318 | return PTR_ERR(acl); | 318 | return PTR_ERR(acl); |
| 319 | } | 319 | } |
| 320 | if (!acl) | 320 | if (!acl) |
| 321 | inode->i_mode &= ~current->fs->umask; | 321 | inode->i_mode &= ~current_umask(); |
| 322 | } | 322 | } |
| 323 | if (test_opt(inode->i_sb, POSIX_ACL) && acl) { | 323 | if (test_opt(inode->i_sb, POSIX_ACL) && acl) { |
| 324 | struct posix_acl *clone; | 324 | struct posix_acl *clone; |
diff --git a/fs/ext3/acl.c b/fs/ext3/acl.c index b60bb241880..d81ef2fdb08 100644 --- a/fs/ext3/acl.c +++ b/fs/ext3/acl.c | |||
| @@ -323,7 +323,7 @@ ext3_init_acl(handle_t *handle, struct inode *inode, struct inode *dir) | |||
| 323 | return PTR_ERR(acl); | 323 | return PTR_ERR(acl); |
| 324 | } | 324 | } |
| 325 | if (!acl) | 325 | if (!acl) |
| 326 | inode->i_mode &= ~current->fs->umask; | 326 | inode->i_mode &= ~current_umask(); |
| 327 | } | 327 | } |
| 328 | if (test_opt(inode->i_sb, POSIX_ACL) && acl) { | 328 | if (test_opt(inode->i_sb, POSIX_ACL) && acl) { |
| 329 | struct posix_acl *clone; | 329 | struct posix_acl *clone; |
diff --git a/fs/ext4/acl.c b/fs/ext4/acl.c index 694ed6fadcc..647e0d65a28 100644 --- a/fs/ext4/acl.c +++ b/fs/ext4/acl.c | |||
| @@ -323,7 +323,7 @@ ext4_init_acl(handle_t *handle, struct inode *inode, struct inode *dir) | |||
| 323 | return PTR_ERR(acl); | 323 | return PTR_ERR(acl); |
| 324 | } | 324 | } |
| 325 | if (!acl) | 325 | if (!acl) |
| 326 | inode->i_mode &= ~current->fs->umask; | 326 | inode->i_mode &= ~current_umask(); |
| 327 | } | 327 | } |
| 328 | if (test_opt(inode->i_sb, POSIX_ACL) && acl) { | 328 | if (test_opt(inode->i_sb, POSIX_ACL) && acl) { |
| 329 | struct posix_acl *clone; | 329 | struct posix_acl *clone; |
diff --git a/fs/fat/inode.c b/fs/fat/inode.c index 2cc952e4c3d..296785a0dec 100644 --- a/fs/fat/inode.c +++ b/fs/fat/inode.c | |||
| @@ -934,7 +934,7 @@ static int parse_options(char *options, int is_vfat, int silent, int *debug, | |||
| 934 | 934 | ||
| 935 | opts->fs_uid = current_uid(); | 935 | opts->fs_uid = current_uid(); |
| 936 | opts->fs_gid = current_gid(); | 936 | opts->fs_gid = current_gid(); |
| 937 | opts->fs_fmask = opts->fs_dmask = current->fs->umask; | 937 | opts->fs_fmask = current_umask(); |
| 938 | opts->allow_utime = -1; | 938 | opts->allow_utime = -1; |
| 939 | opts->codepage = fat_default_codepage; | 939 | opts->codepage = fat_default_codepage; |
| 940 | opts->iocharset = fat_default_iocharset; | 940 | opts->iocharset = fat_default_iocharset; |
diff --git a/fs/fs_struct.c b/fs/fs_struct.c new file mode 100644 index 00000000000..eee059052db --- /dev/null +++ b/fs/fs_struct.c | |||
| @@ -0,0 +1,177 @@ | |||
| 1 | #include <linux/module.h> | ||
| 2 | #include <linux/sched.h> | ||
| 3 | #include <linux/fs.h> | ||
| 4 | #include <linux/path.h> | ||
| 5 | #include <linux/slab.h> | ||
| 6 | #include <linux/fs_struct.h> | ||
| 7 | |||
| 8 | /* | ||
| 9 | * Replace the fs->{rootmnt,root} with {mnt,dentry}. Put the old values. | ||
| 10 | * It can block. | ||
| 11 | */ | ||
| 12 | void set_fs_root(struct fs_struct *fs, struct path *path) | ||
| 13 | { | ||
| 14 | struct path old_root; | ||
| 15 | |||
| 16 | write_lock(&fs->lock); | ||
| 17 | old_root = fs->root; | ||
| 18 | fs->root = *path; | ||
| 19 | path_get(path); | ||
| 20 | write_unlock(&fs->lock); | ||
| 21 | if (old_root.dentry) | ||
| 22 | path_put(&old_root); | ||
| 23 | } | ||
| 24 | |||
| 25 | /* | ||
| 26 | * Replace the fs->{pwdmnt,pwd} with {mnt,dentry}. Put the old values. | ||
| 27 | * It can block. | ||
| 28 | */ | ||
| 29 | void set_fs_pwd(struct fs_struct *fs, struct path *path) | ||
| 30 | { | ||
| 31 | struct path old_pwd; | ||
| 32 | |||
| 33 | write_lock(&fs->lock); | ||
| 34 | old_pwd = fs->pwd; | ||
| 35 | fs->pwd = *path; | ||
| 36 | path_get(path); | ||
| 37 | write_unlock(&fs->lock); | ||
| 38 | |||
| 39 | if (old_pwd.dentry) | ||
| 40 | path_put(&old_pwd); | ||
| 41 | } | ||
| 42 | |||
| 43 | void chroot_fs_refs(struct path *old_root, struct path *new_root) | ||
| 44 | { | ||
| 45 | struct task_struct *g, *p; | ||
| 46 | struct fs_struct *fs; | ||
| 47 | int count = 0; | ||
| 48 | |||
| 49 | read_lock(&tasklist_lock); | ||
| 50 | do_each_thread(g, p) { | ||
| 51 | task_lock(p); | ||
| 52 | fs = p->fs; | ||
| 53 | if (fs) { | ||
| 54 | write_lock(&fs->lock); | ||
| 55 | if (fs->root.dentry == old_root->dentry | ||
| 56 | && fs->root.mnt == old_root->mnt) { | ||
| 57 | path_get(new_root); | ||
| 58 | fs->root = *new_root; | ||
| 59 | count++; | ||
| 60 | } | ||
| 61 | if (fs->pwd.dentry == old_root->dentry | ||
| 62 | && fs->pwd.mnt == old_root->mnt) { | ||
| 63 | path_get(new_root); | ||
| 64 | fs->pwd = *new_root; | ||
| 65 | count++; | ||
| 66 | } | ||
| 67 | write_unlock(&fs->lock); | ||
| 68 | } | ||
| 69 | task_unlock(p); | ||
| 70 | } while_each_thread(g, p); | ||
| 71 | read_unlock(&tasklist_lock); | ||
| 72 | while (count--) | ||
| 73 | path_put(old_root); | ||
| 74 | } | ||
| 75 | |||
| 76 | void free_fs_struct(struct fs_struct *fs) | ||
| 77 | { | ||
| 78 | path_put(&fs->root); | ||
| 79 | path_put(&fs->pwd); | ||
| 80 | kmem_cache_free(fs_cachep, fs); | ||
| 81 | } | ||
| 82 | |||
| 83 | void exit_fs(struct task_struct *tsk) | ||
| 84 | { | ||
| 85 | struct fs_struct *fs = tsk->fs; | ||
| 86 | |||
| 87 | if (fs) { | ||
| 88 | int kill; | ||
| 89 | task_lock(tsk); | ||
| 90 | write_lock(&fs->lock); | ||
| 91 | tsk->fs = NULL; | ||
| 92 | kill = !--fs->users; | ||
| 93 | write_unlock(&fs->lock); | ||
| 94 | task_unlock(tsk); | ||
| 95 | if (kill) | ||
| 96 | free_fs_struct(fs); | ||
| 97 | } | ||
| 98 | } | ||
| 99 | |||
| 100 | struct fs_struct *copy_fs_struct(struct fs_struct *old) | ||
| 101 | { | ||
| 102 | struct fs_struct *fs = kmem_cache_alloc(fs_cachep, GFP_KERNEL); | ||
| 103 | /* We don't need to lock fs - think why ;-) */ | ||
| 104 | if (fs) { | ||
| 105 | fs->users = 1; | ||
| 106 | fs->in_exec = 0; | ||
| 107 | rwlock_init(&fs->lock); | ||
| 108 | fs->umask = old->umask; | ||
| 109 | read_lock(&old->lock); | ||
| 110 | fs->root = old->root; | ||
| 111 | path_get(&old->root); | ||
| 112 | fs->pwd = old->pwd; | ||
| 113 | path_get(&old->pwd); | ||
| 114 | read_unlock(&old->lock); | ||
| 115 | } | ||
| 116 | return fs; | ||
| 117 | } | ||
| 118 | |||
| 119 | int unshare_fs_struct(void) | ||
| 120 | { | ||
| 121 | struct fs_struct *fs = current->fs; | ||
| 122 | struct fs_struct *new_fs = copy_fs_struct(fs); | ||
| 123 | int kill; | ||
| 124 | |||
| 125 | if (!new_fs) | ||
| 126 | return -ENOMEM; | ||
| 127 | |||
| 128 | task_lock(current); | ||
| 129 | write_lock(&fs->lock); | ||
| 130 | kill = !--fs->users; | ||
| 131 | current->fs = new_fs; | ||
| 132 | write_unlock(&fs->lock); | ||
| 133 | task_unlock(current); | ||
| 134 | |||
| 135 | if (kill) | ||
| 136 | free_fs_struct(fs); | ||
| 137 | |||
| 138 | return 0; | ||
| 139 | } | ||
| 140 | EXPORT_SYMBOL_GPL(unshare_fs_struct); | ||
| 141 | |||
| 142 | int current_umask(void) | ||
| 143 | { | ||
| 144 | return current->fs->umask; | ||
| 145 | } | ||
| 146 | EXPORT_SYMBOL(current_umask); | ||
| 147 | |||
| 148 | /* to be mentioned only in INIT_TASK */ | ||
| 149 | struct fs_struct init_fs = { | ||
| 150 | .users = 1, | ||
| 151 | .lock = __RW_LOCK_UNLOCKED(init_fs.lock), | ||
| 152 | .umask = 0022, | ||
| 153 | }; | ||
| 154 | |||
| 155 | void daemonize_fs_struct(void) | ||
| 156 | { | ||
| 157 | struct fs_struct *fs = current->fs; | ||
| 158 | |||
| 159 | if (fs) { | ||
| 160 | int kill; | ||
| 161 | |||
| 162 | task_lock(current); | ||
| 163 | |||
| 164 | write_lock(&init_fs.lock); | ||
| 165 | init_fs.users++; | ||
| 166 | write_unlock(&init_fs.lock); | ||
| 167 | |||
| 168 | write_lock(&fs->lock); | ||
| 169 | current->fs = &init_fs; | ||
| 170 | kill = !--fs->users; | ||
| 171 | write_unlock(&fs->lock); | ||
| 172 | |||
| 173 | task_unlock(current); | ||
| 174 | if (kill) | ||
| 175 | free_fs_struct(fs); | ||
| 176 | } | ||
| 177 | } | ||
diff --git a/fs/generic_acl.c b/fs/generic_acl.c index 995d63b2e74..e0b53aa7bbe 100644 --- a/fs/generic_acl.c +++ b/fs/generic_acl.c | |||
| @@ -134,7 +134,7 @@ generic_acl_init(struct inode *inode, struct inode *dir, | |||
| 134 | mode_t mode = inode->i_mode; | 134 | mode_t mode = inode->i_mode; |
| 135 | int error; | 135 | int error; |
| 136 | 136 | ||
| 137 | inode->i_mode = mode & ~current->fs->umask; | 137 | inode->i_mode = mode & ~current_umask(); |
| 138 | if (!S_ISLNK(inode->i_mode)) | 138 | if (!S_ISLNK(inode->i_mode)) |
| 139 | acl = ops->getacl(dir, ACL_TYPE_DEFAULT); | 139 | acl = ops->getacl(dir, ACL_TYPE_DEFAULT); |
| 140 | if (acl) { | 140 | if (acl) { |
diff --git a/fs/gfs2/acl.c b/fs/gfs2/acl.c index 43764f4fa76..fa881bdc3d8 100644 --- a/fs/gfs2/acl.c +++ b/fs/gfs2/acl.c | |||
| @@ -215,7 +215,7 @@ int gfs2_acl_create(struct gfs2_inode *dip, struct gfs2_inode *ip) | |||
| 215 | if (error) | 215 | if (error) |
| 216 | return error; | 216 | return error; |
| 217 | if (!acl) { | 217 | if (!acl) { |
| 218 | mode &= ~current->fs->umask; | 218 | mode &= ~current_umask(); |
| 219 | if (mode != ip->i_inode.i_mode) | 219 | if (mode != ip->i_inode.i_mode) |
| 220 | error = munge_mode(ip, mode); | 220 | error = munge_mode(ip, mode); |
| 221 | return error; | 221 | return error; |
diff --git a/fs/hfsplus/options.c b/fs/hfsplus/options.c index bab7f8d1bdf..3fcbb0e1f6f 100644 --- a/fs/hfsplus/options.c +++ b/fs/hfsplus/options.c | |||
| @@ -48,7 +48,7 @@ void hfsplus_fill_defaults(struct hfsplus_sb_info *opts) | |||
| 48 | 48 | ||
| 49 | opts->creator = HFSPLUS_DEF_CR_TYPE; | 49 | opts->creator = HFSPLUS_DEF_CR_TYPE; |
| 50 | opts->type = HFSPLUS_DEF_CR_TYPE; | 50 | opts->type = HFSPLUS_DEF_CR_TYPE; |
| 51 | opts->umask = current->fs->umask; | 51 | opts->umask = current_umask(); |
| 52 | opts->uid = current_uid(); | 52 | opts->uid = current_uid(); |
| 53 | opts->gid = current_gid(); | 53 | opts->gid = current_gid(); |
| 54 | opts->part = -1; | 54 | opts->part = -1; |
diff --git a/fs/hpfs/super.c b/fs/hpfs/super.c index c40f6e24244..fecf402d7b8 100644 --- a/fs/hpfs/super.c +++ b/fs/hpfs/super.c | |||
| @@ -480,7 +480,7 @@ static int hpfs_fill_super(struct super_block *s, void *options, int silent) | |||
| 480 | 480 | ||
| 481 | uid = current_uid(); | 481 | uid = current_uid(); |
| 482 | gid = current_gid(); | 482 | gid = current_gid(); |
| 483 | umask = current->fs->umask; | 483 | umask = current_umask(); |
| 484 | lowercase = 0; | 484 | lowercase = 0; |
| 485 | conv = CONV_BINARY; | 485 | conv = CONV_BINARY; |
| 486 | eas = 2; | 486 | eas = 2; |
diff --git a/fs/internal.h b/fs/internal.h index 53af885f173..b4dac4fb6b6 100644 --- a/fs/internal.h +++ b/fs/internal.h | |||
| @@ -11,6 +11,7 @@ | |||
| 11 | 11 | ||
| 12 | struct super_block; | 12 | struct super_block; |
| 13 | struct linux_binprm; | 13 | struct linux_binprm; |
| 14 | struct path; | ||
| 14 | 15 | ||
| 15 | /* | 16 | /* |
| 16 | * block_dev.c | 17 | * block_dev.c |
| @@ -43,7 +44,7 @@ extern void __init chrdev_init(void); | |||
| 43 | /* | 44 | /* |
| 44 | * exec.c | 45 | * exec.c |
| 45 | */ | 46 | */ |
| 46 | extern void check_unsafe_exec(struct linux_binprm *); | 47 | extern int check_unsafe_exec(struct linux_binprm *); |
| 47 | 48 | ||
| 48 | /* | 49 | /* |
| 49 | * namespace.c | 50 | * namespace.c |
| @@ -60,3 +61,8 @@ extern void umount_tree(struct vfsmount *, int, struct list_head *); | |||
| 60 | extern struct vfsmount *copy_tree(struct vfsmount *, struct dentry *, int); | 61 | extern struct vfsmount *copy_tree(struct vfsmount *, struct dentry *, int); |
| 61 | 62 | ||
| 62 | extern void __init mnt_init(void); | 63 | extern void __init mnt_init(void); |
| 64 | |||
| 65 | /* | ||
| 66 | * fs_struct.c | ||
| 67 | */ | ||
| 68 | extern void chroot_fs_refs(struct path *, struct path *); | ||
diff --git a/fs/jffs2/acl.c b/fs/jffs2/acl.c index d98713777a1..77ccf8cb082 100644 --- a/fs/jffs2/acl.c +++ b/fs/jffs2/acl.c | |||
| @@ -336,7 +336,7 @@ int jffs2_init_acl_pre(struct inode *dir_i, struct inode *inode, int *i_mode) | |||
| 336 | return PTR_ERR(acl); | 336 | return PTR_ERR(acl); |
| 337 | 337 | ||
| 338 | if (!acl) { | 338 | if (!acl) { |
| 339 | *i_mode &= ~current->fs->umask; | 339 | *i_mode &= ~current_umask(); |
| 340 | } else { | 340 | } else { |
| 341 | if (S_ISDIR(*i_mode)) | 341 | if (S_ISDIR(*i_mode)) |
| 342 | jffs2_iset_acl(inode, &f->i_acl_default, acl); | 342 | jffs2_iset_acl(inode, &f->i_acl_default, acl); |
diff --git a/fs/jfs/acl.c b/fs/jfs/acl.c index a166c1669e8..06ca1b8d205 100644 --- a/fs/jfs/acl.c +++ b/fs/jfs/acl.c | |||
| @@ -182,7 +182,7 @@ int jfs_init_acl(tid_t tid, struct inode *inode, struct inode *dir) | |||
| 182 | cleanup: | 182 | cleanup: |
| 183 | posix_acl_release(acl); | 183 | posix_acl_release(acl); |
| 184 | } else | 184 | } else |
| 185 | inode->i_mode &= ~current->fs->umask; | 185 | inode->i_mode &= ~current_umask(); |
| 186 | 186 | ||
| 187 | JFS_IP(inode)->mode2 = (JFS_IP(inode)->mode2 & 0xffff0000) | | 187 | JFS_IP(inode)->mode2 = (JFS_IP(inode)->mode2 & 0xffff0000) | |
| 188 | inode->i_mode; | 188 | inode->i_mode; |
diff --git a/fs/mpage.c b/fs/mpage.c index 16c3ef37eae..680ba60863f 100644 --- a/fs/mpage.c +++ b/fs/mpage.c | |||
| @@ -82,7 +82,7 @@ static void mpage_end_io_write(struct bio *bio, int err) | |||
| 82 | bio_put(bio); | 82 | bio_put(bio); |
| 83 | } | 83 | } |
| 84 | 84 | ||
| 85 | struct bio *mpage_bio_submit(int rw, struct bio *bio) | 85 | static struct bio *mpage_bio_submit(int rw, struct bio *bio) |
| 86 | { | 86 | { |
| 87 | bio->bi_end_io = mpage_end_io_read; | 87 | bio->bi_end_io = mpage_end_io_read; |
| 88 | if (rw == WRITE) | 88 | if (rw == WRITE) |
| @@ -90,7 +90,6 @@ struct bio *mpage_bio_submit(int rw, struct bio *bio) | |||
| 90 | submit_bio(rw, bio); | 90 | submit_bio(rw, bio); |
| 91 | return NULL; | 91 | return NULL; |
| 92 | } | 92 | } |
| 93 | EXPORT_SYMBOL(mpage_bio_submit); | ||
| 94 | 93 | ||
| 95 | static struct bio * | 94 | static struct bio * |
| 96 | mpage_alloc(struct block_device *bdev, | 95 | mpage_alloc(struct block_device *bdev, |
| @@ -439,7 +438,14 @@ EXPORT_SYMBOL(mpage_readpage); | |||
| 439 | * just allocate full-size (16-page) BIOs. | 438 | * just allocate full-size (16-page) BIOs. |
| 440 | */ | 439 | */ |
| 441 | 440 | ||
| 442 | int __mpage_writepage(struct page *page, struct writeback_control *wbc, | 441 | struct mpage_data { |
| 442 | struct bio *bio; | ||
| 443 | sector_t last_block_in_bio; | ||
| 444 | get_block_t *get_block; | ||
| 445 | unsigned use_writepage; | ||
| 446 | }; | ||
| 447 | |||
| 448 | static int __mpage_writepage(struct page *page, struct writeback_control *wbc, | ||
| 443 | void *data) | 449 | void *data) |
| 444 | { | 450 | { |
| 445 | struct mpage_data *mpd = data; | 451 | struct mpage_data *mpd = data; |
| @@ -648,7 +654,6 @@ out: | |||
| 648 | mpd->bio = bio; | 654 | mpd->bio = bio; |
| 649 | return ret; | 655 | return ret; |
| 650 | } | 656 | } |
| 651 | EXPORT_SYMBOL(__mpage_writepage); | ||
| 652 | 657 | ||
| 653 | /** | 658 | /** |
| 654 | * mpage_writepages - walk the list of dirty pages of the given address space & writepage() all of them | 659 | * mpage_writepages - walk the list of dirty pages of the given address space & writepage() all of them |
diff --git a/fs/namei.c b/fs/namei.c index d040ce11785..b8433ebfae0 100644 --- a/fs/namei.c +++ b/fs/namei.c | |||
| @@ -32,6 +32,7 @@ | |||
| 32 | #include <linux/file.h> | 32 | #include <linux/file.h> |
| 33 | #include <linux/fcntl.h> | 33 | #include <linux/fcntl.h> |
| 34 | #include <linux/device_cgroup.h> | 34 | #include <linux/device_cgroup.h> |
| 35 | #include <linux/fs_struct.h> | ||
| 35 | #include <asm/uaccess.h> | 36 | #include <asm/uaccess.h> |
| 36 | 37 | ||
| 37 | #define ACC_MODE(x) ("\000\004\002\006"[(x)&O_ACCMODE]) | 38 | #define ACC_MODE(x) ("\000\004\002\006"[(x)&O_ACCMODE]) |
| @@ -1578,7 +1579,7 @@ static int __open_namei_create(struct nameidata *nd, struct path *path, | |||
| 1578 | struct dentry *dir = nd->path.dentry; | 1579 | struct dentry *dir = nd->path.dentry; |
| 1579 | 1580 | ||
| 1580 | if (!IS_POSIXACL(dir->d_inode)) | 1581 | if (!IS_POSIXACL(dir->d_inode)) |
| 1581 | mode &= ~current->fs->umask; | 1582 | mode &= ~current_umask(); |
| 1582 | error = security_path_mknod(&nd->path, path->dentry, mode, 0); | 1583 | error = security_path_mknod(&nd->path, path->dentry, mode, 0); |
| 1583 | if (error) | 1584 | if (error) |
| 1584 | goto out_unlock; | 1585 | goto out_unlock; |
| @@ -1989,7 +1990,7 @@ SYSCALL_DEFINE4(mknodat, int, dfd, const char __user *, filename, int, mode, | |||
| 1989 | goto out_unlock; | 1990 | goto out_unlock; |
| 1990 | } | 1991 | } |
| 1991 | if (!IS_POSIXACL(nd.path.dentry->d_inode)) | 1992 | if (!IS_POSIXACL(nd.path.dentry->d_inode)) |
| 1992 | mode &= ~current->fs->umask; | 1993 | mode &= ~current_umask(); |
| 1993 | error = may_mknod(mode); | 1994 | error = may_mknod(mode); |
| 1994 | if (error) | 1995 | if (error) |
| 1995 | goto out_dput; | 1996 | goto out_dput; |
| @@ -2067,7 +2068,7 @@ SYSCALL_DEFINE3(mkdirat, int, dfd, const char __user *, pathname, int, mode) | |||
| 2067 | goto out_unlock; | 2068 | goto out_unlock; |
| 2068 | 2069 | ||
| 2069 | if (!IS_POSIXACL(nd.path.dentry->d_inode)) | 2070 | if (!IS_POSIXACL(nd.path.dentry->d_inode)) |
| 2070 | mode &= ~current->fs->umask; | 2071 | mode &= ~current_umask(); |
| 2071 | error = mnt_want_write(nd.path.mnt); | 2072 | error = mnt_want_write(nd.path.mnt); |
| 2072 | if (error) | 2073 | if (error) |
| 2073 | goto out_dput; | 2074 | goto out_dput; |
| @@ -2897,10 +2898,3 @@ EXPORT_SYMBOL(vfs_symlink); | |||
| 2897 | EXPORT_SYMBOL(vfs_unlink); | 2898 | EXPORT_SYMBOL(vfs_unlink); |
| 2898 | EXPORT_SYMBOL(dentry_unhash); | 2899 | EXPORT_SYMBOL(dentry_unhash); |
| 2899 | EXPORT_SYMBOL(generic_readlink); | 2900 | EXPORT_SYMBOL(generic_readlink); |
| 2900 | |||
| 2901 | /* to be mentioned only in INIT_TASK */ | ||
| 2902 | struct fs_struct init_fs = { | ||
| 2903 | .count = ATOMIC_INIT(1), | ||
| 2904 | .lock = __RW_LOCK_UNLOCKED(init_fs.lock), | ||
| 2905 | .umask = 0022, | ||
| 2906 | }; | ||
diff --git a/fs/namespace.c b/fs/namespace.c index 0a42e0e9602..c6f54e4c429 100644 --- a/fs/namespace.c +++ b/fs/namespace.c | |||
| @@ -27,6 +27,7 @@ | |||
| 27 | #include <linux/ramfs.h> | 27 | #include <linux/ramfs.h> |
| 28 | #include <linux/log2.h> | 28 | #include <linux/log2.h> |
| 29 | #include <linux/idr.h> | 29 | #include <linux/idr.h> |
| 30 | #include <linux/fs_struct.h> | ||
| 30 | #include <asm/uaccess.h> | 31 | #include <asm/uaccess.h> |
| 31 | #include <asm/unistd.h> | 32 | #include <asm/unistd.h> |
| 32 | #include "pnode.h" | 33 | #include "pnode.h" |
| @@ -2093,66 +2094,6 @@ out1: | |||
| 2093 | } | 2094 | } |
| 2094 | 2095 | ||
| 2095 | /* | 2096 | /* |
| 2096 | * Replace the fs->{rootmnt,root} with {mnt,dentry}. Put the old values. | ||
| 2097 | * It can block. Requires the big lock held. | ||
| 2098 | */ | ||
| 2099 | void set_fs_root(struct fs_struct *fs, struct path *path) | ||
| 2100 | { | ||
| 2101 | struct path old_root; | ||
| 2102 | |||
| 2103 | write_lock(&fs->lock); | ||
| 2104 | old_root = fs->root; | ||
| 2105 | fs->root = *path; | ||
| 2106 | path_get(path); | ||
| 2107 | write_unlock(&fs->lock); | ||
| 2108 | if (old_root.dentry) | ||
| 2109 | path_put(&old_root); | ||
| 2110 | } | ||
| 2111 | |||
| 2112 | /* | ||
| 2113 | * Replace the fs->{pwdmnt,pwd} with {mnt,dentry}. Put the old values. | ||
| 2114 | * It can block. Requires the big lock held. | ||
| 2115 | */ | ||
| 2116 | void set_fs_pwd(struct fs_struct *fs, struct path *path) | ||
| 2117 | { | ||
| 2118 | struct path old_pwd; | ||
| 2119 | |||
| 2120 | write_lock(&fs->lock); | ||
| 2121 | old_pwd = fs->pwd; | ||
| 2122 | fs->pwd = *path; | ||
| 2123 | path_get(path); | ||
| 2124 | write_unlock(&fs->lock); | ||
| 2125 | |||
| 2126 | if (old_pwd.dentry) | ||
| 2127 | path_put(&old_pwd); | ||
| 2128 | } | ||
| 2129 | |||
| 2130 | static void chroot_fs_refs(struct path *old_root, struct path *new_root) | ||
| 2131 | { | ||
| 2132 | struct task_struct *g, *p; | ||
| 2133 | struct fs_struct *fs; | ||
| 2134 | |||
| 2135 | read_lock(&tasklist_lock); | ||
| 2136 | do_each_thread(g, p) { | ||
| 2137 | task_lock(p); | ||
| 2138 | fs = p->fs; | ||
| 2139 | if (fs) { | ||
| 2140 | atomic_inc(&fs->count); | ||
| 2141 | task_unlock(p); | ||
| 2142 | if (fs->root.dentry == old_root->dentry | ||
| 2143 | && fs->root.mnt == old_root->mnt) | ||
| 2144 | set_fs_root(fs, new_root); | ||
| 2145 | if (fs->pwd.dentry == old_root->dentry | ||
| 2146 | && fs->pwd.mnt == old_root->mnt) | ||
| 2147 | set_fs_pwd(fs, new_root); | ||
| 2148 | put_fs_struct(fs); | ||
| 2149 | } else | ||
| 2150 | task_unlock(p); | ||
| 2151 | } while_each_thread(g, p); | ||
| 2152 | read_unlock(&tasklist_lock); | ||
| 2153 | } | ||
| 2154 | |||
| 2155 | /* | ||
| 2156 | * pivot_root Semantics: | 2097 | * pivot_root Semantics: |
| 2157 | * Moves the root file system of the current process to the directory put_old, | 2098 | * Moves the root file system of the current process to the directory put_old, |
| 2158 | * makes new_root as the new root file system of the current process, and sets | 2099 | * makes new_root as the new root file system of the current process, and sets |
diff --git a/fs/nfs/nfs3proc.c b/fs/nfs/nfs3proc.c index b82fe6847f1..d0cc5ce0edf 100644 --- a/fs/nfs/nfs3proc.c +++ b/fs/nfs/nfs3proc.c | |||
| @@ -328,7 +328,7 @@ nfs3_proc_create(struct inode *dir, struct dentry *dentry, struct iattr *sattr, | |||
| 328 | data->arg.create.verifier[1] = current->pid; | 328 | data->arg.create.verifier[1] = current->pid; |
| 329 | } | 329 | } |
| 330 | 330 | ||
| 331 | sattr->ia_mode &= ~current->fs->umask; | 331 | sattr->ia_mode &= ~current_umask(); |
| 332 | 332 | ||
| 333 | for (;;) { | 333 | for (;;) { |
| 334 | status = nfs3_do_create(dir, dentry, data); | 334 | status = nfs3_do_create(dir, dentry, data); |
| @@ -528,7 +528,7 @@ nfs3_proc_mkdir(struct inode *dir, struct dentry *dentry, struct iattr *sattr) | |||
| 528 | 528 | ||
| 529 | dprintk("NFS call mkdir %s\n", dentry->d_name.name); | 529 | dprintk("NFS call mkdir %s\n", dentry->d_name.name); |
| 530 | 530 | ||
| 531 | sattr->ia_mode &= ~current->fs->umask; | 531 | sattr->ia_mode &= ~current_umask(); |
| 532 | 532 | ||
| 533 | data = nfs3_alloc_createdata(); | 533 | data = nfs3_alloc_createdata(); |
| 534 | if (data == NULL) | 534 | if (data == NULL) |
| @@ -639,7 +639,7 @@ nfs3_proc_mknod(struct inode *dir, struct dentry *dentry, struct iattr *sattr, | |||
| 639 | dprintk("NFS call mknod %s %u:%u\n", dentry->d_name.name, | 639 | dprintk("NFS call mknod %s %u:%u\n", dentry->d_name.name, |
| 640 | MAJOR(rdev), MINOR(rdev)); | 640 | MAJOR(rdev), MINOR(rdev)); |
| 641 | 641 | ||
| 642 | sattr->ia_mode &= ~current->fs->umask; | 642 | sattr->ia_mode &= ~current_umask(); |
| 643 | 643 | ||
| 644 | data = nfs3_alloc_createdata(); | 644 | data = nfs3_alloc_createdata(); |
| 645 | if (data == NULL) | 645 | if (data == NULL) |
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index 97bacccff57..a4d24268029 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c | |||
| @@ -1501,7 +1501,7 @@ nfs4_atomic_open(struct inode *dir, struct dentry *dentry, struct nameidata *nd) | |||
| 1501 | attr.ia_mode = nd->intent.open.create_mode; | 1501 | attr.ia_mode = nd->intent.open.create_mode; |
| 1502 | attr.ia_valid = ATTR_MODE; | 1502 | attr.ia_valid = ATTR_MODE; |
| 1503 | if (!IS_POSIXACL(dir)) | 1503 | if (!IS_POSIXACL(dir)) |
| 1504 | attr.ia_mode &= ~current->fs->umask; | 1504 | attr.ia_mode &= ~current_umask(); |
| 1505 | } else { | 1505 | } else { |
| 1506 | attr.ia_valid = 0; | 1506 | attr.ia_valid = 0; |
| 1507 | BUG_ON(nd->intent.open.flags & O_CREAT); | 1507 | BUG_ON(nd->intent.open.flags & O_CREAT); |
diff --git a/fs/nfsd/nfssvc.c b/fs/nfsd/nfssvc.c index bc3567bab8c..7c09852be71 100644 --- a/fs/nfsd/nfssvc.c +++ b/fs/nfsd/nfssvc.c | |||
| @@ -403,7 +403,6 @@ static int | |||
| 403 | nfsd(void *vrqstp) | 403 | nfsd(void *vrqstp) |
| 404 | { | 404 | { |
| 405 | struct svc_rqst *rqstp = (struct svc_rqst *) vrqstp; | 405 | struct svc_rqst *rqstp = (struct svc_rqst *) vrqstp; |
| 406 | struct fs_struct *fsp; | ||
| 407 | int err, preverr = 0; | 406 | int err, preverr = 0; |
| 408 | 407 | ||
| 409 | /* Lock module and set up kernel thread */ | 408 | /* Lock module and set up kernel thread */ |
| @@ -412,13 +411,11 @@ nfsd(void *vrqstp) | |||
| 412 | /* At this point, the thread shares current->fs | 411 | /* At this point, the thread shares current->fs |
| 413 | * with the init process. We need to create files with a | 412 | * with the init process. We need to create files with a |
| 414 | * umask of 0 instead of init's umask. */ | 413 | * umask of 0 instead of init's umask. */ |
| 415 | fsp = copy_fs_struct(current->fs); | 414 | if (unshare_fs_struct() < 0) { |
| 416 | if (!fsp) { | ||
| 417 | printk("Unable to start nfsd thread: out of memory\n"); | 415 | printk("Unable to start nfsd thread: out of memory\n"); |
| 418 | goto out; | 416 | goto out; |
| 419 | } | 417 | } |
| 420 | exit_fs(current); | 418 | |
| 421 | current->fs = fsp; | ||
| 422 | current->fs->umask = 0; | 419 | current->fs->umask = 0; |
| 423 | 420 | ||
| 424 | /* | 421 | /* |
diff --git a/fs/ocfs2/acl.c b/fs/ocfs2/acl.c index 12dfb44c22e..fbeaec76210 100644 --- a/fs/ocfs2/acl.c +++ b/fs/ocfs2/acl.c | |||
| @@ -296,7 +296,7 @@ int ocfs2_init_acl(handle_t *handle, | |||
| 296 | return PTR_ERR(acl); | 296 | return PTR_ERR(acl); |
| 297 | } | 297 | } |
| 298 | if (!acl) | 298 | if (!acl) |
| 299 | inode->i_mode &= ~current->fs->umask; | 299 | inode->i_mode &= ~current_umask(); |
| 300 | } | 300 | } |
| 301 | if ((osb->s_mount_opt & OCFS2_MOUNT_POSIX_ACL) && acl) { | 301 | if ((osb->s_mount_opt & OCFS2_MOUNT_POSIX_ACL) && acl) { |
| 302 | struct posix_acl *clone; | 302 | struct posix_acl *clone; |
diff --git a/fs/omfs/inode.c b/fs/omfs/inode.c index d79e808fd02..379ae5fb441 100644 --- a/fs/omfs/inode.c +++ b/fs/omfs/inode.c | |||
| @@ -426,7 +426,7 @@ static int omfs_fill_super(struct super_block *sb, void *data, int silent) | |||
| 426 | 426 | ||
| 427 | sbi->s_uid = current_uid(); | 427 | sbi->s_uid = current_uid(); |
| 428 | sbi->s_gid = current_gid(); | 428 | sbi->s_gid = current_gid(); |
| 429 | sbi->s_dmask = sbi->s_fmask = current->fs->umask; | 429 | sbi->s_dmask = sbi->s_fmask = current_umask(); |
| 430 | 430 | ||
| 431 | if (!parse_options((char *) data, sbi)) | 431 | if (!parse_options((char *) data, sbi)) |
| 432 | goto end; | 432 | goto end; |
| @@ -29,6 +29,7 @@ | |||
| 29 | #include <linux/rcupdate.h> | 29 | #include <linux/rcupdate.h> |
| 30 | #include <linux/audit.h> | 30 | #include <linux/audit.h> |
| 31 | #include <linux/falloc.h> | 31 | #include <linux/falloc.h> |
| 32 | #include <linux/fs_struct.h> | ||
| 32 | 33 | ||
| 33 | int vfs_statfs(struct dentry *dentry, struct kstatfs *buf) | 34 | int vfs_statfs(struct dentry *dentry, struct kstatfs *buf) |
| 34 | { | 35 | { |
diff --git a/fs/proc/base.c b/fs/proc/base.c index e0afd326b68..f71559784bf 100644 --- a/fs/proc/base.c +++ b/fs/proc/base.c | |||
| @@ -80,6 +80,7 @@ | |||
| 80 | #include <linux/oom.h> | 80 | #include <linux/oom.h> |
| 81 | #include <linux/elf.h> | 81 | #include <linux/elf.h> |
| 82 | #include <linux/pid_namespace.h> | 82 | #include <linux/pid_namespace.h> |
| 83 | #include <linux/fs_struct.h> | ||
| 83 | #include "internal.h" | 84 | #include "internal.h" |
| 84 | 85 | ||
| 85 | /* NOTE: | 86 | /* NOTE: |
diff --git a/fs/proc/task_nommu.c b/fs/proc/task_nommu.c index 370be0a2c90..863464d5519 100644 --- a/fs/proc/task_nommu.c +++ b/fs/proc/task_nommu.c | |||
| @@ -2,6 +2,7 @@ | |||
| 2 | #include <linux/mm.h> | 2 | #include <linux/mm.h> |
| 3 | #include <linux/file.h> | 3 | #include <linux/file.h> |
| 4 | #include <linux/fdtable.h> | 4 | #include <linux/fdtable.h> |
| 5 | #include <linux/fs_struct.h> | ||
| 5 | #include <linux/mount.h> | 6 | #include <linux/mount.h> |
| 6 | #include <linux/ptrace.h> | 7 | #include <linux/ptrace.h> |
| 7 | #include <linux/seq_file.h> | 8 | #include <linux/seq_file.h> |
| @@ -49,7 +50,7 @@ void task_mem(struct seq_file *m, struct mm_struct *mm) | |||
| 49 | else | 50 | else |
| 50 | bytes += kobjsize(mm); | 51 | bytes += kobjsize(mm); |
| 51 | 52 | ||
| 52 | if (current->fs && atomic_read(¤t->fs->count) > 1) | 53 | if (current->fs && current->fs->users > 1) |
| 53 | sbytes += kobjsize(current->fs); | 54 | sbytes += kobjsize(current->fs); |
| 54 | else | 55 | else |
| 55 | bytes += kobjsize(current->fs); | 56 | bytes += kobjsize(current->fs); |
diff --git a/fs/reiserfs/xattr_acl.c b/fs/reiserfs/xattr_acl.c index d423416d93d..c303c426fe2 100644 --- a/fs/reiserfs/xattr_acl.c +++ b/fs/reiserfs/xattr_acl.c | |||
| @@ -428,7 +428,7 @@ reiserfs_inherit_default_acl(struct reiserfs_transaction_handle *th, | |||
| 428 | } else { | 428 | } else { |
| 429 | apply_umask: | 429 | apply_umask: |
| 430 | /* no ACL, apply umask */ | 430 | /* no ACL, apply umask */ |
| 431 | inode->i_mode &= ~current->fs->umask; | 431 | inode->i_mode &= ~current_umask(); |
| 432 | } | 432 | } |
| 433 | 433 | ||
| 434 | return err; | 434 | return err; |
diff --git a/fs/xfs/linux-2.6/xfs_iops.c b/fs/xfs/linux-2.6/xfs_iops.c index 7aa53fefc67..2940612e3ae 100644 --- a/fs/xfs/linux-2.6/xfs_iops.c +++ b/fs/xfs/linux-2.6/xfs_iops.c | |||
| @@ -227,7 +227,7 @@ xfs_vn_mknod( | |||
| 227 | xfs_dentry_to_name(&name, dentry); | 227 | xfs_dentry_to_name(&name, dentry); |
| 228 | 228 | ||
| 229 | if (IS_POSIXACL(dir) && !default_acl) | 229 | if (IS_POSIXACL(dir) && !default_acl) |
| 230 | mode &= ~current->fs->umask; | 230 | mode &= ~current_umask(); |
| 231 | 231 | ||
| 232 | switch (mode & S_IFMT) { | 232 | switch (mode & S_IFMT) { |
| 233 | case S_IFCHR: | 233 | case S_IFCHR: |
| @@ -416,7 +416,7 @@ xfs_vn_symlink( | |||
| 416 | mode_t mode; | 416 | mode_t mode; |
| 417 | 417 | ||
| 418 | mode = S_IFLNK | | 418 | mode = S_IFLNK | |
| 419 | (irix_symlink_mode ? 0777 & ~current->fs->umask : S_IRWXUGO); | 419 | (irix_symlink_mode ? 0777 & ~current_umask() : S_IRWXUGO); |
| 420 | xfs_dentry_to_name(&name, dentry); | 420 | xfs_dentry_to_name(&name, dentry); |
| 421 | 421 | ||
| 422 | error = xfs_symlink(XFS_I(dir), &name, symname, mode, &cip, NULL); | 422 | error = xfs_symlink(XFS_I(dir), &name, symname, mode, &cip, NULL); |
