Merge branch 'master' into next
Conflicts: fs/namei.c Manually merged per: diff --cc fs/namei.c index 734f2b5,bbc15c2..0000000 --- a/fs/namei.c +++ b/fs/namei.c @@@ -860,9 -848,8 +849,10 @@@ static int __link_path_walk(const char nd->flags |= LOOKUP_CONTINUE; err = exec_permission_lite(inode); if (err == -EAGAIN) - err = vfs_permission(nd, MAY_EXEC); + err = inode_permission(nd->path.dentry->d_inode, + MAY_EXEC); + if (!err) + err = ima_path_check(&nd->path, MAY_EXEC); if (err) break; @@@ -1525,14 -1506,9 +1509,14 @@@ int may_open(struct path *path, int acc flag &= ~O_TRUNC; } - error = vfs_permission(nd, acc_mode); + error = inode_permission(inode, acc_mode); if (error) return error; + - error = ima_path_check(&nd->path, ++ error = ima_path_check(path, + acc_mode & (MAY_READ | MAY_WRITE | MAY_EXEC)); + if (error) + return error; /* * An append-only file must be opened in append mode for writing. */ Signed-off-by: James Morris <jmorris@namei.org>
This commit is contained in:
74
fs/inode.c
74
fs/inode.c
@@ -23,6 +23,7 @@
|
||||
#include <linux/bootmem.h>
|
||||
#include <linux/inotify.h>
|
||||
#include <linux/mount.h>
|
||||
#include <linux/async.h>
|
||||
|
||||
/*
|
||||
* This is needed for the following functions:
|
||||
@@ -111,8 +112,8 @@ static void wake_up_inode(struct inode *inode)
|
||||
|
||||
/**
|
||||
* inode_init_always - perform inode structure intialisation
|
||||
* @sb - superblock inode belongs to.
|
||||
* @inode - inode to initialise
|
||||
* @sb: superblock inode belongs to
|
||||
* @inode: inode to initialise
|
||||
*
|
||||
* These are initializations that need to be done on every inode
|
||||
* allocation as the fields are not initialised by slab allocation.
|
||||
@@ -132,6 +133,8 @@ struct inode *inode_init_always(struct super_block *sb, struct inode *inode)
|
||||
inode->i_op = &empty_iops;
|
||||
inode->i_fop = &empty_fops;
|
||||
inode->i_nlink = 1;
|
||||
inode->i_uid = 0;
|
||||
inode->i_gid = 0;
|
||||
atomic_set(&inode->i_writecount, 0);
|
||||
inode->i_size = 0;
|
||||
inode->i_blocks = 0;
|
||||
@@ -165,7 +168,7 @@ struct inode *inode_init_always(struct super_block *sb, struct inode *inode)
|
||||
mapping->a_ops = &empty_aops;
|
||||
mapping->host = inode;
|
||||
mapping->flags = 0;
|
||||
mapping_set_gfp_mask(mapping, GFP_HIGHUSER_PAGECACHE);
|
||||
mapping_set_gfp_mask(mapping, GFP_HIGHUSER_MOVABLE);
|
||||
mapping->assoc_mapping = NULL;
|
||||
mapping->backing_dev_info = &default_backing_dev_info;
|
||||
mapping->writeback_index = 0;
|
||||
@@ -584,8 +587,8 @@ __inode_add_to_lists(struct super_block *sb, struct hlist_head *head,
|
||||
|
||||
/**
|
||||
* inode_add_to_lists - add a new inode to relevant lists
|
||||
* @sb - superblock inode belongs to.
|
||||
* @inode - inode to mark in use
|
||||
* @sb: superblock inode belongs to
|
||||
* @inode: inode to mark in use
|
||||
*
|
||||
* When an inode is allocated it needs to be accounted for, added to the in use
|
||||
* list, the owning superblock and the inode hash. This needs to be done under
|
||||
@@ -609,7 +612,7 @@ EXPORT_SYMBOL_GPL(inode_add_to_lists);
|
||||
* @sb: superblock
|
||||
*
|
||||
* Allocates a new inode for given superblock. The default gfp_mask
|
||||
* for allocations related to inode->i_mapping is GFP_HIGHUSER_PAGECACHE.
|
||||
* for allocations related to inode->i_mapping is GFP_HIGHUSER_MOVABLE.
|
||||
* If HIGHMEM pages are unsuitable or it is known that pages allocated
|
||||
* for the page cache are not reclaimable or migratable,
|
||||
* mapping_set_gfp_mask() must be called with suitable flags on the
|
||||
@@ -1042,6 +1045,65 @@ struct inode *iget_locked(struct super_block *sb, unsigned long ino)
|
||||
|
||||
EXPORT_SYMBOL(iget_locked);
|
||||
|
||||
int insert_inode_locked(struct inode *inode)
|
||||
{
|
||||
struct super_block *sb = inode->i_sb;
|
||||
ino_t ino = inode->i_ino;
|
||||
struct hlist_head *head = inode_hashtable + hash(sb, ino);
|
||||
struct inode *old;
|
||||
|
||||
inode->i_state |= I_LOCK|I_NEW;
|
||||
while (1) {
|
||||
spin_lock(&inode_lock);
|
||||
old = find_inode_fast(sb, head, ino);
|
||||
if (likely(!old)) {
|
||||
hlist_add_head(&inode->i_hash, head);
|
||||
spin_unlock(&inode_lock);
|
||||
return 0;
|
||||
}
|
||||
__iget(old);
|
||||
spin_unlock(&inode_lock);
|
||||
wait_on_inode(old);
|
||||
if (unlikely(!hlist_unhashed(&old->i_hash))) {
|
||||
iput(old);
|
||||
return -EBUSY;
|
||||
}
|
||||
iput(old);
|
||||
}
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(insert_inode_locked);
|
||||
|
||||
int insert_inode_locked4(struct inode *inode, unsigned long hashval,
|
||||
int (*test)(struct inode *, void *), void *data)
|
||||
{
|
||||
struct super_block *sb = inode->i_sb;
|
||||
struct hlist_head *head = inode_hashtable + hash(sb, hashval);
|
||||
struct inode *old;
|
||||
|
||||
inode->i_state |= I_LOCK|I_NEW;
|
||||
|
||||
while (1) {
|
||||
spin_lock(&inode_lock);
|
||||
old = find_inode(sb, head, test, data);
|
||||
if (likely(!old)) {
|
||||
hlist_add_head(&inode->i_hash, head);
|
||||
spin_unlock(&inode_lock);
|
||||
return 0;
|
||||
}
|
||||
__iget(old);
|
||||
spin_unlock(&inode_lock);
|
||||
wait_on_inode(old);
|
||||
if (unlikely(!hlist_unhashed(&old->i_hash))) {
|
||||
iput(old);
|
||||
return -EBUSY;
|
||||
}
|
||||
iput(old);
|
||||
}
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(insert_inode_locked4);
|
||||
|
||||
/**
|
||||
* __insert_inode_hash - hash an inode
|
||||
* @inode: unhashed inode
|
||||
|
Reference in New Issue
Block a user