Commit 94bc891b authored by Linus Torvalds's avatar Linus Torvalds

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:
  [PATCH] get rid of __exit_files(), __exit_fs() and __put_fs_struct()
  [PATCH] proc_readfd_common() race fix
  [PATCH] double-free of inode on alloc_file() failure exit in create_write_pipe()
  [PATCH] teach seq_file to discard entries
  [PATCH] umount_tree() will unhash everything itself
  [PATCH] get rid of more nameidata passing in namespace.c
  [PATCH] switch a bunch of LSM hooks from nameidata to path
  [PATCH] lock exclusively in collect_mounts() and drop_collected_mounts()
  [PATCH] move a bunch of declarations to fs/internal.h
parents 934b7024 1ec7f1dd
...@@ -43,3 +43,14 @@ extern void __init chrdev_init(void); ...@@ -43,3 +43,14 @@ extern void __init chrdev_init(void);
* namespace.c * namespace.c
*/ */
extern int copy_mount_options(const void __user *, unsigned long *); extern int copy_mount_options(const void __user *, unsigned long *);
extern void free_vfsmnt(struct vfsmount *);
extern struct vfsmount *alloc_vfsmnt(const char *);
extern struct vfsmount *__lookup_mnt(struct vfsmount *, struct dentry *, int);
extern void mnt_set_mountpoint(struct vfsmount *, struct dentry *,
struct vfsmount *);
extern void release_mounts(struct list_head *);
extern void umount_tree(struct vfsmount *, int, struct list_head *);
extern struct vfsmount *copy_tree(struct vfsmount *, struct dentry *, int);
extern void __init mnt_init(void);
...@@ -1091,20 +1091,20 @@ Enomem: ...@@ -1091,20 +1091,20 @@ Enomem:
struct vfsmount *collect_mounts(struct vfsmount *mnt, struct dentry *dentry) struct vfsmount *collect_mounts(struct vfsmount *mnt, struct dentry *dentry)
{ {
struct vfsmount *tree; struct vfsmount *tree;
down_read(&namespace_sem); down_write(&namespace_sem);
tree = copy_tree(mnt, dentry, CL_COPY_ALL | CL_PRIVATE); tree = copy_tree(mnt, dentry, CL_COPY_ALL | CL_PRIVATE);
up_read(&namespace_sem); up_write(&namespace_sem);
return tree; return tree;
} }
void drop_collected_mounts(struct vfsmount *mnt) void drop_collected_mounts(struct vfsmount *mnt)
{ {
LIST_HEAD(umount_list); LIST_HEAD(umount_list);
down_read(&namespace_sem); down_write(&namespace_sem);
spin_lock(&vfsmount_lock); spin_lock(&vfsmount_lock);
umount_tree(mnt, 0, &umount_list); umount_tree(mnt, 0, &umount_list);
spin_unlock(&vfsmount_lock); spin_unlock(&vfsmount_lock);
up_read(&namespace_sem); up_write(&namespace_sem);
release_mounts(&umount_list); release_mounts(&umount_list);
} }
...@@ -1205,32 +1205,32 @@ static int attach_recursive_mnt(struct vfsmount *source_mnt, ...@@ -1205,32 +1205,32 @@ static int attach_recursive_mnt(struct vfsmount *source_mnt,
return 0; return 0;
} }
static int graft_tree(struct vfsmount *mnt, struct nameidata *nd) static int graft_tree(struct vfsmount *mnt, struct path *path)
{ {
int err; int err;
if (mnt->mnt_sb->s_flags & MS_NOUSER) if (mnt->mnt_sb->s_flags & MS_NOUSER)
return -EINVAL; return -EINVAL;
if (S_ISDIR(nd->path.dentry->d_inode->i_mode) != if (S_ISDIR(path->dentry->d_inode->i_mode) !=
S_ISDIR(mnt->mnt_root->d_inode->i_mode)) S_ISDIR(mnt->mnt_root->d_inode->i_mode))
return -ENOTDIR; return -ENOTDIR;
err = -ENOENT; err = -ENOENT;
mutex_lock(&nd->path.dentry->d_inode->i_mutex); mutex_lock(&path->dentry->d_inode->i_mutex);
if (IS_DEADDIR(nd->path.dentry->d_inode)) if (IS_DEADDIR(path->dentry->d_inode))
goto out_unlock; goto out_unlock;
err = security_sb_check_sb(mnt, nd); err = security_sb_check_sb(mnt, path);
if (err) if (err)
goto out_unlock; goto out_unlock;
err = -ENOENT; err = -ENOENT;
if (IS_ROOT(nd->path.dentry) || !d_unhashed(nd->path.dentry)) if (IS_ROOT(path->dentry) || !d_unhashed(path->dentry))
err = attach_recursive_mnt(mnt, &nd->path, NULL); err = attach_recursive_mnt(mnt, path, NULL);
out_unlock: out_unlock:
mutex_unlock(&nd->path.dentry->d_inode->i_mutex); mutex_unlock(&path->dentry->d_inode->i_mutex);
if (!err) if (!err)
security_sb_post_addmount(mnt, nd); security_sb_post_addmount(mnt, path);
return err; return err;
} }
...@@ -1294,7 +1294,7 @@ static noinline int do_loopback(struct nameidata *nd, char *old_name, ...@@ -1294,7 +1294,7 @@ static noinline int do_loopback(struct nameidata *nd, char *old_name,
if (!mnt) if (!mnt)
goto out; goto out;
err = graft_tree(mnt, nd); err = graft_tree(mnt, &nd->path);
if (err) { if (err) {
LIST_HEAD(umount_list); LIST_HEAD(umount_list);
spin_lock(&vfsmount_lock); spin_lock(&vfsmount_lock);
...@@ -1501,7 +1501,7 @@ int do_add_mount(struct vfsmount *newmnt, struct nameidata *nd, ...@@ -1501,7 +1501,7 @@ int do_add_mount(struct vfsmount *newmnt, struct nameidata *nd,
goto unlock; goto unlock;
newmnt->mnt_flags = mnt_flags; newmnt->mnt_flags = mnt_flags;
if ((err = graft_tree(newmnt, nd))) if ((err = graft_tree(newmnt, &nd->path)))
goto unlock; goto unlock;
if (fslist) /* add to the specified expiration list */ if (fslist) /* add to the specified expiration list */
...@@ -1746,7 +1746,8 @@ long do_mount(char *dev_name, char *dir_name, char *type_page, ...@@ -1746,7 +1746,8 @@ long do_mount(char *dev_name, char *dir_name, char *type_page,
if (retval) if (retval)
return retval; return retval;
retval = security_sb_mount(dev_name, &nd, type_page, flags, data_page); retval = security_sb_mount(dev_name, &nd.path,
type_page, flags, data_page);
if (retval) if (retval)
goto dput_out; goto dput_out;
...@@ -1986,15 +1987,13 @@ asmlinkage long sys_pivot_root(const char __user * new_root, ...@@ -1986,15 +1987,13 @@ asmlinkage long sys_pivot_root(const char __user * new_root,
const char __user * put_old) const char __user * put_old)
{ {
struct vfsmount *tmp; struct vfsmount *tmp;
struct nameidata new_nd, old_nd, user_nd; struct nameidata new_nd, old_nd;
struct path parent_path, root_parent; struct path parent_path, root_parent, root;
int error; int error;
if (!capable(CAP_SYS_ADMIN)) if (!capable(CAP_SYS_ADMIN))
return -EPERM; return -EPERM;
lock_kernel();
error = __user_walk(new_root, LOOKUP_FOLLOW | LOOKUP_DIRECTORY, error = __user_walk(new_root, LOOKUP_FOLLOW | LOOKUP_DIRECTORY,
&new_nd); &new_nd);
if (error) if (error)
...@@ -2007,14 +2006,14 @@ asmlinkage long sys_pivot_root(const char __user * new_root, ...@@ -2007,14 +2006,14 @@ asmlinkage long sys_pivot_root(const char __user * new_root,
if (error) if (error)
goto out1; goto out1;
error = security_sb_pivotroot(&old_nd, &new_nd); error = security_sb_pivotroot(&old_nd.path, &new_nd.path);
if (error) { if (error) {
path_put(&old_nd.path); path_put(&old_nd.path);
goto out1; goto out1;
} }
read_lock(&current->fs->lock); read_lock(&current->fs->lock);
user_nd.path = current->fs->root; root = current->fs->root;
path_get(&current->fs->root); path_get(&current->fs->root);
read_unlock(&current->fs->lock); read_unlock(&current->fs->lock);
down_write(&namespace_sem); down_write(&namespace_sem);
...@@ -2022,9 +2021,9 @@ asmlinkage long sys_pivot_root(const char __user * new_root, ...@@ -2022,9 +2021,9 @@ asmlinkage long sys_pivot_root(const char __user * new_root,
error = -EINVAL; error = -EINVAL;
if (IS_MNT_SHARED(old_nd.path.mnt) || if (IS_MNT_SHARED(old_nd.path.mnt) ||
IS_MNT_SHARED(new_nd.path.mnt->mnt_parent) || IS_MNT_SHARED(new_nd.path.mnt->mnt_parent) ||
IS_MNT_SHARED(user_nd.path.mnt->mnt_parent)) IS_MNT_SHARED(root.mnt->mnt_parent))
goto out2; goto out2;
if (!check_mnt(user_nd.path.mnt)) if (!check_mnt(root.mnt))
goto out2; goto out2;
error = -ENOENT; error = -ENOENT;
if (IS_DEADDIR(new_nd.path.dentry->d_inode)) if (IS_DEADDIR(new_nd.path.dentry->d_inode))
...@@ -2034,13 +2033,13 @@ asmlinkage long sys_pivot_root(const char __user * new_root, ...@@ -2034,13 +2033,13 @@ asmlinkage long sys_pivot_root(const char __user * new_root,
if (d_unhashed(old_nd.path.dentry) && !IS_ROOT(old_nd.path.dentry)) if (d_unhashed(old_nd.path.dentry) && !IS_ROOT(old_nd.path.dentry))
goto out2; goto out2;
error = -EBUSY; error = -EBUSY;
if (new_nd.path.mnt == user_nd.path.mnt || if (new_nd.path.mnt == root.mnt ||
old_nd.path.mnt == user_nd.path.mnt) old_nd.path.mnt == root.mnt)
goto out2; /* loop, on the same file system */ goto out2; /* loop, on the same file system */
error = -EINVAL; error = -EINVAL;
if (user_nd.path.mnt->mnt_root != user_nd.path.dentry) if (root.mnt->mnt_root != root.dentry)
goto out2; /* not a mountpoint */ goto out2; /* not a mountpoint */
if (user_nd.path.mnt->mnt_parent == user_nd.path.mnt) if (root.mnt->mnt_parent == root.mnt)
goto out2; /* not attached */ goto out2; /* not attached */
if (new_nd.path.mnt->mnt_root != new_nd.path.dentry) if (new_nd.path.mnt->mnt_root != new_nd.path.dentry)
goto out2; /* not a mountpoint */ goto out2; /* not a mountpoint */
...@@ -2062,27 +2061,26 @@ asmlinkage long sys_pivot_root(const char __user * new_root, ...@@ -2062,27 +2061,26 @@ asmlinkage long sys_pivot_root(const char __user * new_root,
} else if (!is_subdir(old_nd.path.dentry, new_nd.path.dentry)) } else if (!is_subdir(old_nd.path.dentry, new_nd.path.dentry))
goto out3; goto out3;
detach_mnt(new_nd.path.mnt, &parent_path); detach_mnt(new_nd.path.mnt, &parent_path);
detach_mnt(user_nd.path.mnt, &root_parent); detach_mnt(root.mnt, &root_parent);
/* mount old root on put_old */ /* mount old root on put_old */
attach_mnt(user_nd.path.mnt, &old_nd.path); attach_mnt(root.mnt, &old_nd.path);
/* mount new_root on / */ /* mount new_root on / */
attach_mnt(new_nd.path.mnt, &root_parent); attach_mnt(new_nd.path.mnt, &root_parent);
touch_mnt_namespace(current->nsproxy->mnt_ns); touch_mnt_namespace(current->nsproxy->mnt_ns);
spin_unlock(&vfsmount_lock); spin_unlock(&vfsmount_lock);
chroot_fs_refs(&user_nd.path, &new_nd.path); chroot_fs_refs(&root, &new_nd.path);
security_sb_post_pivotroot(&user_nd, &new_nd); security_sb_post_pivotroot(&root, &new_nd.path);
error = 0; error = 0;
path_put(&root_parent); path_put(&root_parent);
path_put(&parent_path); path_put(&parent_path);
out2: out2:
mutex_unlock(&old_nd.path.dentry->d_inode->i_mutex); mutex_unlock(&old_nd.path.dentry->d_inode->i_mutex);
up_write(&namespace_sem); up_write(&namespace_sem);
path_put(&user_nd.path); path_put(&root);
path_put(&old_nd.path); path_put(&old_nd.path);
out1: out1:
path_put(&new_nd.path); path_put(&new_nd.path);
out0: out0:
unlock_kernel();
return error; return error;
out3: out3:
spin_unlock(&vfsmount_lock); spin_unlock(&vfsmount_lock);
......
...@@ -988,7 +988,10 @@ struct file *create_write_pipe(void) ...@@ -988,7 +988,10 @@ struct file *create_write_pipe(void)
return f; return f;
err_dentry: err_dentry:
free_pipe_info(inode);
dput(dentry); dput(dentry);
return ERR_PTR(err);
err_inode: err_inode:
free_pipe_info(inode); free_pipe_info(inode);
iput(inode); iput(inode);
......
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
#include <linux/mnt_namespace.h> #include <linux/mnt_namespace.h>
#include <linux/mount.h> #include <linux/mount.h>
#include <linux/fs.h> #include <linux/fs.h>
#include "internal.h"
#include "pnode.h" #include "pnode.h"
/* return the next shared peer mount of @p */ /* return the next shared peer mount of @p */
...@@ -211,8 +212,7 @@ int propagate_mnt(struct vfsmount *dest_mnt, struct dentry *dest_dentry, ...@@ -211,8 +212,7 @@ int propagate_mnt(struct vfsmount *dest_mnt, struct dentry *dest_dentry,
out: out:
spin_lock(&vfsmount_lock); spin_lock(&vfsmount_lock);
while (!list_empty(&tmp_list)) { while (!list_empty(&tmp_list)) {
child = list_entry(tmp_list.next, struct vfsmount, mnt_hash); child = list_first_entry(&tmp_list, struct vfsmount, mnt_hash);
list_del_init(&child->mnt_hash);
umount_tree(child, 0, &umount_list); umount_tree(child, 0, &umount_list);
} }
spin_unlock(&vfsmount_lock); spin_unlock(&vfsmount_lock);
......
...@@ -35,4 +35,5 @@ int propagate_mnt(struct vfsmount *, struct dentry *, struct vfsmount *, ...@@ -35,4 +35,5 @@ int propagate_mnt(struct vfsmount *, struct dentry *, struct vfsmount *,
struct list_head *); struct list_head *);
int propagate_umount(struct list_head *); int propagate_umount(struct list_head *);
int propagate_mount_busy(struct vfsmount *, int); int propagate_mount_busy(struct vfsmount *, int);
void mnt_release_group_id(struct vfsmount *);
#endif /* _LINUX_PNODE_H */ #endif /* _LINUX_PNODE_H */
...@@ -1626,7 +1626,6 @@ static int proc_readfd_common(struct file * filp, void * dirent, ...@@ -1626,7 +1626,6 @@ static int proc_readfd_common(struct file * filp, void * dirent,
unsigned int fd, ino; unsigned int fd, ino;
int retval; int retval;
struct files_struct * files; struct files_struct * files;
struct fdtable *fdt;
retval = -ENOENT; retval = -ENOENT;
if (!p) if (!p)
...@@ -1649,9 +1648,8 @@ static int proc_readfd_common(struct file * filp, void * dirent, ...@@ -1649,9 +1648,8 @@ static int proc_readfd_common(struct file * filp, void * dirent,
if (!files) if (!files)
goto out; goto out;
rcu_read_lock(); rcu_read_lock();
fdt = files_fdtable(files);
for (fd = filp->f_pos-2; for (fd = filp->f_pos-2;
fd < fdt->max_fds; fd < files_fdtable(files)->max_fds;
fd++, filp->f_pos++) { fd++, filp->f_pos++) {
char name[PROC_NUMBUF]; char name[PROC_NUMBUF];
int len; int len;
......
...@@ -25,6 +25,7 @@ ...@@ -25,6 +25,7 @@
* into the buffer. In case of error ->start() and ->next() return * into the buffer. In case of error ->start() and ->next() return
* ERR_PTR(error). In the end of sequence they return %NULL. ->show() * ERR_PTR(error). In the end of sequence they return %NULL. ->show()
* returns 0 in case of success and negative number in case of error. * returns 0 in case of success and negative number in case of error.
* Returning SEQ_SKIP means "discard this element and move on".
*/ */
int seq_open(struct file *file, const struct seq_operations *op) int seq_open(struct file *file, const struct seq_operations *op)
{ {
...@@ -114,8 +115,10 @@ ssize_t seq_read(struct file *file, char __user *buf, size_t size, loff_t *ppos) ...@@ -114,8 +115,10 @@ ssize_t seq_read(struct file *file, char __user *buf, size_t size, loff_t *ppos)
if (!p || IS_ERR(p)) if (!p || IS_ERR(p))
break; break;
err = m->op->show(m, p); err = m->op->show(m, p);
if (err) if (err < 0)
break; break;
if (unlikely(err))
m->count = 0;
if (m->count < m->size) if (m->count < m->size)
goto Fill; goto Fill;
m->op->stop(m, p); m->op->stop(m, p);
...@@ -140,9 +143,10 @@ Fill: ...@@ -140,9 +143,10 @@ Fill:
break; break;
} }
err = m->op->show(m, p); err = m->op->show(m, p);
if (err || m->count == m->size) { if (m->count == m->size || err) {
m->count = offs; m->count = offs;
break; if (likely(err <= 0))
break;
} }
pos = next; pos = next;
} }
...@@ -199,8 +203,12 @@ static int traverse(struct seq_file *m, loff_t offset) ...@@ -199,8 +203,12 @@ static int traverse(struct seq_file *m, loff_t offset)
if (IS_ERR(p)) if (IS_ERR(p))
break; break;
error = m->op->show(m, p); error = m->op->show(m, p);
if (error) if (error < 0)
break; break;
if (unlikely(error)) {
error = 0;
m->count = 0;
}
if (m->count == m->size) if (m->count == m->size)
goto Eoverflow; goto Eoverflow;
if (pos + m->count > offset) { if (pos + m->count > offset) {
......
...@@ -39,6 +39,7 @@ ...@@ -39,6 +39,7 @@
#include <linux/mutex.h> #include <linux/mutex.h>
#include <linux/file.h> #include <linux/file.h>
#include <asm/uaccess.h> #include <asm/uaccess.h>
#include "internal.h"
LIST_HEAD(super_blocks); LIST_HEAD(super_blocks);
......
...@@ -359,7 +359,6 @@ static inline int d_mountpoint(struct dentry *dentry) ...@@ -359,7 +359,6 @@ static inline int d_mountpoint(struct dentry *dentry)
} }
extern struct vfsmount *lookup_mnt(struct vfsmount *, struct dentry *); extern struct vfsmount *lookup_mnt(struct vfsmount *, struct dentry *);
extern struct vfsmount *__lookup_mnt(struct vfsmount *, struct dentry *, int);
extern struct dentry *lookup_create(struct nameidata *nd, int is_dir); extern struct dentry *lookup_create(struct nameidata *nd, int is_dir);
extern int sysctl_vfs_cache_pressure; extern int sysctl_vfs_cache_pressure;
......
...@@ -305,7 +305,6 @@ struct vfsmount; ...@@ -305,7 +305,6 @@ struct vfsmount;
extern void __init inode_init(void); extern void __init inode_init(void);
extern void __init inode_init_early(void); extern void __init inode_init_early(void);
extern void __init mnt_init(void);
extern void __init files_init(unsigned long); extern void __init files_init(unsigned long);
struct buffer_head; struct buffer_head;
...@@ -1536,12 +1535,7 @@ extern struct vfsmount *kern_mount_data(struct file_system_type *, void *data); ...@@ -1536,12 +1535,7 @@ extern struct vfsmount *kern_mount_data(struct file_system_type *, void *data);
#define kern_mount(type) kern_mount_data(type, NULL) #define kern_mount(type) kern_mount_data(type, NULL)
extern int may_umount_tree(struct vfsmount *); extern int may_umount_tree(struct vfsmount *);
extern int may_umount(struct vfsmount *); extern int may_umount(struct vfsmount *);
extern void umount_tree(struct vfsmount *, int, struct list_head *);
extern void release_mounts(struct list_head *);
extern long do_mount(char *, char *, char *, unsigned long, void *); extern long do_mount(char *, char *, char *, unsigned long, void *);
extern struct vfsmount *copy_tree(struct vfsmount *, struct dentry *, int);
extern void mnt_set_mountpoint(struct vfsmount *, struct dentry *,
struct vfsmount *);
extern struct vfsmount *collect_mounts(struct vfsmount *, struct dentry *); extern struct vfsmount *collect_mounts(struct vfsmount *, struct dentry *);
extern void drop_collected_mounts(struct vfsmount *); extern void drop_collected_mounts(struct vfsmount *);
......
...@@ -94,8 +94,6 @@ static inline void mntput(struct vfsmount *mnt) ...@@ -94,8 +94,6 @@ static inline void mntput(struct vfsmount *mnt)
} }
} }
extern void free_vfsmnt(struct vfsmount *mnt);
extern struct vfsmount *alloc_vfsmnt(const char *name);
extern struct vfsmount *do_kern_mount(const char *fstype, int flags, extern struct vfsmount *do_kern_mount(const char *fstype, int flags,
const char *name, void *data); const char *name, void *data);
......
...@@ -230,7 +230,7 @@ static inline void security_free_mnt_opts(struct security_mnt_opts *opts) ...@@ -230,7 +230,7 @@ static inline void security_free_mnt_opts(struct security_mnt_opts *opts)
* loopback/bind mount (@flags & MS_BIND), @dev_name identifies the * loopback/bind mount (@flags & MS_BIND), @dev_name identifies the
* pathname of the object being mounted. * pathname of the object being mounted.
* @dev_name contains the name for object being mounted. * @dev_name contains the name for object being mounted.
* @nd contains the nameidata structure for mount point object. * @path contains the path for mount point object.
* @type contains the filesystem type. * @type contains the filesystem type.
* @flags contains the mount flags. * @flags contains the mount flags.
* @data contains the filesystem-specific data. * @data contains the filesystem-specific data.
...@@ -249,7 +249,7 @@ static inline void security_free_mnt_opts(struct security_mnt_opts *opts) ...@@ -249,7 +249,7 @@ static inline void security_free_mnt_opts(struct security_mnt_opts *opts)
* Check permission before the device with superblock @mnt->sb is mounted * Check permission before the device with superblock @mnt->sb is mounted
* on the mount point named by @nd. * on the mount point named by @nd.
* @mnt contains the vfsmount for device being mounted. * @mnt contains the vfsmount for device being mounted.
* @nd contains the nameidata object for the mount point. * @path contains the path for the mount point.
* Return 0 if permission is granted. * Return 0 if permission is granted.
* @sb_umount: * @sb_umount:
* Check permission before the @mnt file system is unmounted. * Check permission before the @mnt file system is unmounted.
...@@ -278,16 +278,16 @@ static inline void security_free_mnt_opts(struct security_mnt_opts *opts) ...@@ -278,16 +278,16 @@ static inline void security_free_mnt_opts(struct security_mnt_opts *opts)
* This hook is called any time a mount is successfully grafetd to * This hook is called any time a mount is successfully grafetd to
* the tree. * the tree.
* @mnt contains the mounted filesystem. * @mnt contains the mounted filesystem.
* @mountpoint_nd contains the nameidata structure for the mount point. * @mountpoint contains the path for the mount point.
* @sb_pivotroot: * @sb_pivotroot:
* Check permission before pivoting the root filesystem. * Check permission before pivoting the root filesystem.
* @old_nd contains the nameidata structure for the new location of the current root (put_old). * @old_path contains the path for the new location of the current root (put_old).
* @new_nd contains the nameidata structure for the new root (new_root). * @new_path contains the path for the new root (new_root).
* Return 0 if permission is granted. * Return 0 if permission is granted.
* @sb_post_pivotroot: * @sb_post_pivotroot:
* Update module state after a successful pivot. * Update module state after a successful pivot.
* @old_nd contains the nameidata structure for the old root. * @old_path contains the path for the old root.
* @new_nd contains the nameidata structure for the new root. * @new_path contains the path for the new root.
* @sb_get_mnt_opts: * @sb_get_mnt_opts:
* Get the security relevant mount options used for a superblock * Get the security relevant mount options used for a superblock
* @sb the superblock to get security mount options from * @sb the superblock to get security mount options from
...@@ -1315,20 +1315,20 @@ struct security_operations { ...@@ -1315,20 +1315,20 @@ struct security_operations {
int (*sb_copy_data)(char *orig, char *copy); int (*sb_copy_data)(char *orig, char *copy);
int (*sb_kern_mount) (struct super_block *sb, void *data); int (*sb_kern_mount) (struct super_block *sb, void *data);
int (*sb_statfs) (struct dentry *dentry); int (*sb_statfs) (struct dentry *dentry);
int (*sb_mount) (char *dev_name, struct nameidata * nd, int (*sb_mount) (char *dev_name, struct path *path,
char *type, unsigned long flags, void *data); char *type, unsigned long flags, void *data);
int (*sb_check_sb) (struct vfsmount * mnt, struct nameidata * nd); int (*sb_check_sb) (struct vfsmount * mnt, struct path *path);
int (*sb_umount) (struct vfsmount * mnt, int flags); int (*sb_umount) (struct vfsmount * mnt, int flags);
void (*sb_umount_close) (struct vfsmount * mnt); void (*sb_umount_close) (struct vfsmount * mnt);
void (*sb_umount_busy) (struct vfsmount * mnt); void (*sb_umount_busy) (struct vfsmount * mnt);
void (*sb_post_remount) (struct vfsmount * mnt, void (*sb_post_remount) (struct vfsmount * mnt,
unsigned long flags, void *data); unsigned long flags, void *data);
void (*sb_post_addmount) (struct vfsmount * mnt, void (*sb_post_addmount) (struct vfsmount * mnt,
struct nameidata * mountpoint_nd); struct path *mountpoint);
int (*sb_pivotroot) (struct nameidata * old_nd, int (*sb_pivotroot) (struct path *old_path,
struct nameidata * new_nd); struct path *new_path);
void (*sb_post_pivotroot) (struct nameidata * old_nd, void (*sb_post_pivotroot) (struct path *old_path,
struct nameidata * new_nd); struct path *new_path);
int (*sb_get_mnt_opts) (const struct super_block *sb, int (*sb_get_mnt_opts) (const struct super_block *sb,
struct security_mnt_opts *opts); struct security_mnt_opts *opts);
int (*sb_set_mnt_opts) (struct super_block *sb, int (*sb_set_mnt_opts) (struct super_block *sb,
...@@ -1593,16 +1593,16 @@ void security_sb_free(struct super_block *sb); ...@@ -1593,16 +1593,16 @@ void security_sb_free(struct super_block *sb);
int security_sb_copy_data(char *orig, char *copy); int security_sb_copy_data(char *orig, char *copy);
int security_sb_kern_mount(struct super_block *sb, void *data); int security_sb_kern_mount(struct super_block *sb, void *data);
int security_sb_statfs(struct dentry *dentry); int security_sb_statfs(struct dentry *dentry);
int security_sb_mount(char *dev_name, struct nameidata *nd, int security_sb_mount(char *dev_name, struct path *path,
char *type, unsigned long flags, void *data); char *type, unsigned long flags, void *data);
int security_sb_check_sb(struct vfsmount *mnt, struct nameidata *nd); int security_sb_check_sb(struct vfsmount *mnt, struct path *path);
int security_sb_umount(struct vfsmount *mnt, int flags); int security_sb_umount(struct vfsmount *mnt, int flags);
void security_sb_umount_close(struct vfsmount *mnt); void security_sb_umount_close(struct vfsmount *mnt);
void security_sb_umount_busy(struct vfsmount *mnt); void security_sb_umount_busy(struct vfsmount *mnt);
void security_sb_post_remount(struct vfsmount *mnt, unsigned long flags, void *data); void security_sb_post_remount(struct vfsmount *mnt, unsigned long flags, void *data);
void security_sb_post_addmount(struct vfsmount *mnt, struct nameidata *mountpoint_nd); void security_sb_post_addmount(struct vfsmount *mnt, struct path *mountpoint);
int security_sb_pivotroot(struct nameidata *old_nd, struct nameidata *new_nd); int security_sb_pivotroot(struct path *old_path, struct path *new_path);
void security_sb_post_pivotroot(struct nameidata *old_nd, struct nameidata *new_nd); void security_sb_post_pivotroot(struct path *old_path, struct path *new_path);
int security_sb_get_mnt_opts(const struct super_block *sb, int security_sb_get_mnt_opts(const struct super_block *sb,
struct security_mnt_opts *opts); struct security_mnt_opts *opts);
int security_sb_set_mnt_opts(struct super_block *sb, struct security_mnt_opts *opts); int security_sb_set_mnt_opts(struct super_block *sb, struct security_mnt_opts *opts);
...@@ -1872,7 +1872,7 @@ static inline int security_sb_statfs (struct dentry *dentry) ...@@ -1872,7 +1872,7 @@ static inline int security_sb_statfs (struct dentry *dentry)
return 0; return 0;
} }
static inline int security_sb_mount (char *dev_name, struct nameidata *nd, static inline int security_sb_mount (char *dev_name, struct path *path,
char *type, unsigned long flags, char *type, unsigned long flags,
void *data) void *data)
{ {
...@@ -1880,7 +1880,7 @@ static inline int security_sb_mount (char *dev_name, struct nameidata *nd, ...@@ -1880,7 +1880,7 @@ static inline int security_sb_mount (char *dev_name, struct nameidata *nd,
} }
static inline int security_sb_check_sb (struct vfsmount *mnt, static inline int security_sb_check_sb (struct vfsmount *mnt,
struct nameidata *nd) struct path *path)
{ {
return 0; return 0;
} }
...@@ -1901,17 +1901,17 @@ static inline void security_sb_post_remount (struct vfsmount *mnt, ...@@ -1901,17 +1901,17 @@ static inline void security_sb_post_remount (struct vfsmount *mnt,
{ } { }
static inline void security_sb_post_addmount (struct vfsmount *mnt, static inline void security_sb_post_addmount (struct vfsmount *mnt,
struct nameidata *mountpoint_nd) struct path *mountpoint)
{ } { }
static inline int security_sb_pivotroot (struct nameidata *old_nd, static inline int security_sb_pivotroot (struct path *old_path,
struct nameidata *new_nd) struct path *new_path)
{ {
return 0; return 0;
} }
static inline void security_sb_post_pivotroot (struct nameidata *old_nd, static inline void security_sb_post_pivotroot (struct path *old_path,
struct nameidata *new_nd) struct path *new_path)
{ } { }
static inline int security_sb_get_mnt_opts(const struct super_block *sb, static inline int security_sb_get_mnt_opts(const struct super_block *sb,
struct security_mnt_opts *opts) struct security_mnt_opts *opts)
......
...@@ -30,6 +30,8 @@ struct seq_operations { ...@@ -30,6 +30,8 @@ struct seq_operations {
int (*show) (struct seq_file *m, void *v); int (*show) (struct seq_file *m, void *v);
}; };
#define SEQ_SKIP 1
int seq_open(struct file *, const struct seq_operations *); int seq_open(struct file *, const struct seq_operations *);
ssize_t seq_read(struct file *, char __user *, size_t, loff_t *); ssize_t seq_read(struct file *, char __user *, size_t, loff_t *);
loff_t seq_lseek(struct file *, loff_t, int); loff_t seq_lseek(struct file *, loff_t, int);
......
...@@ -521,7 +521,7 @@ void reset_files_struct(struct task_struct *tsk, struct files_struct *files) ...@@ -521,7 +521,7 @@ void reset_files_struct(struct task_struct *tsk, struct files_struct *files)
} }
EXPORT_SYMBOL(reset_files_struct); EXPORT_SYMBOL(reset_files_struct);
static void __exit_files(struct task_struct *tsk) void exit_files(struct task_struct *tsk)
{ {
struct files_struct * files = tsk->files; struct files_struct * files = tsk->files;
...@@ -533,12 +533,7 @@ static void __exit_files(struct task_struct *tsk) ...@@ -533,12 +533,7 @@ static void __exit_files(struct task_struct *tsk)
} }
} }
void exit_files(struct task_struct *tsk) void put_fs_struct(struct fs_struct *fs)
{
__exit_files(tsk);
}
static void __put_fs_struct(struct fs_struct *fs)
{ {
/* No need to hold fs->lock if we are killing it */ /* No need to hold fs->lock if we are killing it */
if (atomic_dec_and_test(&fs->count)) { if (atomic_dec_and_test(&fs->count)) {
...@@ -550,12 +545,7 @@ static void __put_fs_struct(struct fs_struct *fs) ...@@ -550,12 +545,7 @@ static void __put_fs_struct(struct fs_struct *fs)
} }
} }
void put_fs_struct(struct fs_struct *fs) void exit_fs(struct task_struct *tsk)
{
__put_fs_struct(fs);
}
static void __exit_fs(struct task_struct *tsk)
{ {
struct fs_struct * fs = tsk->fs; struct fs_struct * fs = tsk->fs;
...@@ -563,15 +553,10 @@ static void __exit_fs(struct task_struct *tsk) ...@@ -563,15 +553,10 @@ static void __exit_fs(struct task_struct *tsk)
task_lock(tsk); task_lock(tsk);
tsk->fs = NULL; tsk->fs = NULL;
task_unlock(tsk); task_unlock(tsk);
__put_fs_struct(fs); put_fs_struct(fs);
} }
} }
void exit_fs(struct task_struct *tsk)
{
__exit_fs(tsk);
}
EXPORT_SYMBOL_GPL(exit_fs); EXPORT_SYMBOL_GPL(exit_fs);
/* /*
...@@ -967,8 +952,8 @@ NORET_TYPE void do_exit(long code) ...@@ -967,8 +952,8 @@ NORET_TYPE void do_exit(long code)
if (group_dead) if (group_dead)
acct_process(); acct_process();
exit_sem(tsk); exit_sem(tsk);
__exit_files(tsk); exit_files(tsk);
__exit_fs(tsk); exit_fs(tsk);
check_stack_usage(); check_stack_usage();
exit_thread(); exit_thread();
cgroup_exit(tsk, 1); cgroup_exit(tsk, 1);
......
...@@ -196,13 +196,13 @@ static int dummy_sb_statfs (struct dentry *dentry) ...@@ -196,13 +196,13 @@ static int dummy_sb_statfs (struct dentry *dentry)
return 0; return 0;
} }
static int dummy_sb_mount (char *dev_name, struct nameidata *nd, char *type, static int dummy_sb_mount (char *dev_name, struct path *path, char *type,
unsigned long flags, void *data) unsigned long flags, void *data)
{ {
return 0; return 0;
} }
static int dummy_sb_check_sb (struct vfsmount *mnt, struct nameidata *nd) static int dummy_sb_check_sb (struct vfsmount *mnt, struct path *path)
{ {
return 0; return 0;
} }
...@@ -229,17 +229,17 @@ static void dummy_sb_post_remount (struct vfsmount *mnt, unsigned long flags, ...@@ -229,17 +229,17 @@ static void dummy_sb_post_remount (struct vfsmount *mnt, unsigned long flags,
} }
static void dummy_sb_post_addmount (struct vfsmount *mnt, struct nameidata *nd) static void dummy_sb_post_addmount (struct vfsmount *mnt, struct path *path)
{ {
return; return;
} }
static int dummy_sb_pivotroot (struct nameidata *old_nd, struct nameidata *new_nd) static int dummy_sb_pivotroot (struct path *old_path, struct path *new_path)
{ {
return 0; return 0;
} }
static void dummy_sb_post_pivotroot (struct nameidata *old_nd, struct nameidata *new_nd) static void dummy_sb_post_pivotroot (struct path *old_path, struct path *new_path)
{ {
return; return;
} }
......
...@@ -296,15 +296,15 @@ int security_sb_statfs(struct dentry *dentry) ...@@ -296,15 +296,15 @@ int security_sb_statfs(struct dentry *dentry)
return security_ops->sb_statfs(dentry); return security_ops->sb_statfs(dentry);
} }
int security_sb_mount(char *dev_name, struct nameidata *nd, int security_sb_mount(char *dev_name, struct path *path,
char *type, unsigned long flags, void *data) char *type, unsigned long flags, void *data)
{ {
return security_ops->sb_mount(dev_name, nd, type, flags, data); return security_ops->sb_mount(dev_name, path, type, flags, data);
} }
int security_sb_check_sb(struct vfsmount *mnt, struct nameidata *nd) int security_sb_check_sb(struct vfsmount *mnt, struct path *path)
{ {
return security_ops->sb_check_sb(mnt, nd); return security_ops->sb_check_sb(mnt, path);
} }
int security_sb_umount(struct vfsmount *mnt, int flags) int security_sb_umount(struct vfsmount *mnt, int flags)
...@@ -327,19 +327,19 @@ void security_sb_post_remount(struct vfsmount *mnt, unsigned long flags, void *d ...@@ -327,19 +327,19 @@ void security_sb_post_remount(struct vfsmount *mnt, unsigned long flags, void *d
security_ops->sb_post_remount(mnt, flags, data); security_ops->sb_post_remount(mnt, flags, data);
} }
void security_sb_post_addmount(struct vfsmount *mnt, struct nameidata *mountpoint_nd) void security_sb_post_addmount(struct vfsmount *mnt, struct path *mountpoint)
{ {
security_ops->sb_post_addmount(mnt, mountpoint_nd); security_ops->sb_post_addmount(mnt, mountpoint);
} }
int security_sb_pivotroot(struct nameidata *old_nd, struct nameidata *new_nd) int security_sb_pivotroot(struct path *old_path, struct path *new_path)
{ {
return security_ops->sb_pivotroot(old_nd, new_nd); return security_ops->sb_pivotroot(old_path, new_path);
} }
void security_sb_post_pivotroot(struct nameidata *old_nd, struct nameidata *new_nd) void security_sb_post_pivotroot(struct path *old_path, struct path *new_path)
{ {
security_ops->sb_post_pivotroot(old_nd, new_nd); security_ops->sb_post_pivotroot(old_path, new_path);
} }
int security_sb_get_mnt_opts(const struct super_block *sb, int security_sb_get_mnt_opts(const struct super_block *sb,
......
...@@ -2401,22 +2401,22 @@ static int selinux_sb_statfs(struct dentry *dentry) ...@@ -2401,22 +2401,22 @@ static int selinux_sb_statfs(struct dentry *dentry)
} }
static int selinux_mount(char *dev_name, static int selinux_mount(char *dev_name,
struct nameidata *nd, struct path *path,
char *type, char *type,
unsigned long flags, unsigned long flags,
void *data) void *data)
{ {
int rc; int rc;
rc = secondary_ops->sb_mount(dev_name, nd, type, flags, data); rc = secondary_ops->sb_mount(dev_name, path, type, flags, data);
if (rc) if (rc)
return rc; return rc;
if (flags & MS_REMOUNT) if (flags & MS_REMOUNT)
return superblock_has_perm(current, nd->path.mnt->mnt_sb, return superblock_has_perm(current, path->mnt->mnt_sb,
FILESYSTEM__REMOUNT, NULL); FILESYSTEM__REMOUNT, NULL);
else else
return dentry_has_perm(current, nd->path.mnt, nd->path.dentry, return dentry_has_perm(current, path->mnt, path->dentry,
FILE__MOUNTON); FILE__MOUNTON);
} }
......
...@@ -315,10 +315,10 @@ static int smack_sb_statfs(struct dentry *dentry) ...@@ -315,10 +315,10 @@ static int smack_sb_statfs(struct dentry *dentry)
* Returns 0 if current can write the floor of the filesystem * Returns 0 if current can write the floor of the filesystem
* being mounted on, an error code otherwise. * being mounted on, an error code otherwise.
*/ */
static int smack_sb_mount(char *dev_name, struct nameidata *nd, static int smack_sb_mount(char *dev_name, struct path *path,
char *type, unsigned long flags, void *data) char *type, unsigned long flags, void *data)
{ {
struct superblock_smack *sbp = nd->path.mnt->mnt_sb->s_security; struct superblock_smack *sbp = path->mnt->mnt_sb->s_security;
return smk_curacc(sbp->smk_floor, MAY_WRITE); return smk_curacc(sbp->smk_floor, MAY_WRITE);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment