diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-10-13 10:04:42 +0900 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-10-13 10:04:42 +0900 |
commit | 8418263e3547ed3816475e4c55a77004f0426ee6 (patch) | |
tree | 97c548b16e6753e1911870d824a07b7e726b6229 /include | |
parent | ccff9b1db693062b0a9c9070f4304deb47ef215c (diff) | |
parent | f81700bd831efcd12eb7f0e66b24b16c2ad00a32 (diff) | |
download | linux-3.10-8418263e3547ed3816475e4c55a77004f0426ee6.tar.gz linux-3.10-8418263e3547ed3816475e4c55a77004f0426ee6.tar.bz2 linux-3.10-8418263e3547ed3816475e4c55a77004f0426ee6.zip |
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
Pull third pile of VFS updates from Al Viro:
"Stuff from Jeff Layton, mostly. Sanitizing interplay between audit
and namei, removing a lot of insanity from audit_inode() mess and
getting things ready for his ESTALE patchset."
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs:
procfs: don't need a PATH_MAX allocation to hold a string representation of an int
vfs: embed struct filename inside of names_cache allocation if possible
audit: make audit_inode take struct filename
vfs: make path_openat take a struct filename pointer
vfs: turn do_path_lookup into wrapper around struct filename variant
audit: allow audit code to satisfy getname requests from its names_list
vfs: define struct filename and have getname() return it
vfs: unexport getname and putname symbols
acct: constify the name arg to acct_on
vfs: allocate page instead of names_cache buffer in mount_block_root
audit: overhaul __audit_inode_child to accomodate retrying
audit: optimize audit_compare_dname_path
audit: make audit_compare_dname_path use parent_len helper
audit: remove dirlen argument to audit_compare_dname_path
audit: set the name_len in audit_inode for parent lookups
audit: add a new "type" field to audit_names struct
audit: reverse arguments to audit_inode_child
audit: no need to walk list in audit_inode if name is NULL
audit: pass in dentry to audit_copy_inode wherever possible
audit: remove unnecessary NULL ptr checks from do_path_lookup
Diffstat (limited to 'include')
-rw-r--r-- | include/linux/audit.h | 69 | ||||
-rw-r--r-- | include/linux/fs.h | 21 | ||||
-rw-r--r-- | include/linux/fsnotify.h | 8 |
3 files changed, 70 insertions, 28 deletions
diff --git a/include/linux/audit.h b/include/linux/audit.h index 2c83e5f7edb..e5884f950b4 100644 --- a/include/linux/audit.h +++ b/include/linux/audit.h @@ -452,6 +452,16 @@ struct audit_field { extern int __init audit_register_class(int class, unsigned *list); extern int audit_classify_syscall(int abi, unsigned syscall); extern int audit_classify_arch(int arch); + +/* audit_names->type values */ +#define AUDIT_TYPE_UNKNOWN 0 /* we don't know yet */ +#define AUDIT_TYPE_NORMAL 1 /* a "normal" audit record */ +#define AUDIT_TYPE_PARENT 2 /* a parent audit record */ +#define AUDIT_TYPE_CHILD_DELETE 3 /* a child being deleted */ +#define AUDIT_TYPE_CHILD_CREATE 4 /* a child being created */ + +struct filename; + #ifdef CONFIG_AUDITSYSCALL /* These are defined in auditsc.c */ /* Public API */ @@ -461,11 +471,14 @@ extern void __audit_syscall_entry(int arch, int major, unsigned long a0, unsigned long a1, unsigned long a2, unsigned long a3); extern void __audit_syscall_exit(int ret_success, long ret_value); -extern void __audit_getname(const char *name); -extern void audit_putname(const char *name); -extern void __audit_inode(const char *name, const struct dentry *dentry); -extern void __audit_inode_child(const struct dentry *dentry, - const struct inode *parent); +extern struct filename *__audit_reusename(const __user char *uptr); +extern void __audit_getname(struct filename *name); +extern void audit_putname(struct filename *name); +extern void __audit_inode(struct filename *name, const struct dentry *dentry, + unsigned int parent); +extern void __audit_inode_child(const struct inode *parent, + const struct dentry *dentry, + const unsigned char type); extern void __audit_seccomp(unsigned long syscall, long signr, int code); extern void __audit_ptrace(struct task_struct *t); @@ -495,19 +508,27 @@ static inline void audit_syscall_exit(void *pt_regs) __audit_syscall_exit(success, return_code); } } -static inline void audit_getname(const char *name) +static inline struct filename *audit_reusename(const __user char *name) +{ + if (unlikely(!audit_dummy_context())) + return __audit_reusename(name); + return NULL; +} +static inline void audit_getname(struct filename *name) { if (unlikely(!audit_dummy_context())) __audit_getname(name); } -static inline void audit_inode(const char *name, const struct dentry *dentry) { +static inline void audit_inode(struct filename *name, const struct dentry *dentry, + unsigned int parent) { if (unlikely(!audit_dummy_context())) - __audit_inode(name, dentry); + __audit_inode(name, dentry, parent); } -static inline void audit_inode_child(const struct dentry *dentry, - const struct inode *parent) { +static inline void audit_inode_child(const struct inode *parent, + const struct dentry *dentry, + const unsigned char type) { if (unlikely(!audit_dummy_context())) - __audit_inode_child(dentry, parent); + __audit_inode_child(parent, dentry, type); } void audit_core_dumps(long signr); @@ -651,19 +672,29 @@ static inline int audit_dummy_context(void) { return 1; } -static inline void audit_getname(const char *name) +static inline struct filename *audit_reusename(const __user char *name) +{ + return NULL; +} +static inline void audit_getname(struct filename *name) { } -static inline void audit_putname(const char *name) +static inline void audit_putname(struct filename *name) { } -static inline void __audit_inode(const char *name, const struct dentry *dentry) +static inline void __audit_inode(struct filename *name, + const struct dentry *dentry, + unsigned int parent) { } -static inline void __audit_inode_child(const struct dentry *dentry, - const struct inode *parent) +static inline void __audit_inode_child(const struct inode *parent, + const struct dentry *dentry, + const unsigned char type) { } -static inline void audit_inode(const char *name, const struct dentry *dentry) +static inline void audit_inode(struct filename *name, + const struct dentry *dentry, + unsigned int parent) { } -static inline void audit_inode_child(const struct dentry *dentry, - const struct inode *parent) +static inline void audit_inode_child(const struct inode *parent, + const struct dentry *dentry, + const unsigned char type) { } static inline void audit_core_dumps(long signr) { } diff --git a/include/linux/fs.h b/include/linux/fs.h index 8ef2fc9f1f0..65fbf571023 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -2196,6 +2196,13 @@ static inline int break_lease(struct inode *inode, unsigned int mode) #endif /* CONFIG_FILE_LOCKING */ /* fs/open.c */ +struct audit_names; +struct filename { + const char *name; /* pointer to actual string */ + const __user char *uptr; /* original userland pointer */ + struct audit_names *aname; + bool separate; /* should "name" be freed? */ +}; extern int do_truncate(struct dentry *, loff_t start, unsigned int time_attrs, struct file *filp); @@ -2203,12 +2210,15 @@ extern int do_fallocate(struct file *file, int mode, loff_t offset, loff_t len); extern long do_sys_open(int dfd, const char __user *filename, int flags, umode_t mode); +extern struct file *file_open_name(struct filename *, int, umode_t); extern struct file *filp_open(const char *, int, umode_t); extern struct file *file_open_root(struct dentry *, struct vfsmount *, const char *, int); extern struct file * dentry_open(const struct path *, int, const struct cred *); extern int filp_close(struct file *, fl_owner_t id); -extern char * getname(const char __user *); + +extern struct filename *getname(const char __user *); + enum { FILE_CREATED = 1, FILE_OPENED = 2 @@ -2228,13 +2238,14 @@ extern void __init vfs_caches_init(unsigned long); extern struct kmem_cache *names_cachep; -#define __getname_gfp(gfp) kmem_cache_alloc(names_cachep, (gfp)) -#define __getname() __getname_gfp(GFP_KERNEL) +extern void final_putname(struct filename *name); + +#define __getname() kmem_cache_alloc(names_cachep, GFP_KERNEL) #define __putname(name) kmem_cache_free(names_cachep, (void *)(name)) #ifndef CONFIG_AUDITSYSCALL -#define putname(name) __putname(name) +#define putname(name) final_putname(name) #else -extern void putname(const char *name); +extern void putname(struct filename *name); #endif #ifdef CONFIG_BLOCK diff --git a/include/linux/fsnotify.h b/include/linux/fsnotify.h index a6dfe694456..0fbfb4646d1 100644 --- a/include/linux/fsnotify.h +++ b/include/linux/fsnotify.h @@ -109,7 +109,7 @@ static inline void fsnotify_move(struct inode *old_dir, struct inode *new_dir, if (source) fsnotify(source, FS_MOVE_SELF, moved->d_inode, FSNOTIFY_EVENT_INODE, NULL, 0); - audit_inode_child(moved, new_dir); + audit_inode_child(new_dir, moved, AUDIT_TYPE_CHILD_CREATE); } /* @@ -155,7 +155,7 @@ static inline void fsnotify_inoderemove(struct inode *inode) */ static inline void fsnotify_create(struct inode *inode, struct dentry *dentry) { - audit_inode_child(dentry, inode); + audit_inode_child(inode, dentry, AUDIT_TYPE_CHILD_CREATE); fsnotify(inode, FS_CREATE, dentry->d_inode, FSNOTIFY_EVENT_INODE, dentry->d_name.name, 0); } @@ -168,7 +168,7 @@ static inline void fsnotify_create(struct inode *inode, struct dentry *dentry) static inline void fsnotify_link(struct inode *dir, struct inode *inode, struct dentry *new_dentry) { fsnotify_link_count(inode); - audit_inode_child(new_dentry, dir); + audit_inode_child(dir, new_dentry, AUDIT_TYPE_CHILD_CREATE); fsnotify(dir, FS_CREATE, inode, FSNOTIFY_EVENT_INODE, new_dentry->d_name.name, 0); } @@ -181,7 +181,7 @@ static inline void fsnotify_mkdir(struct inode *inode, struct dentry *dentry) __u32 mask = (FS_CREATE | FS_ISDIR); struct inode *d_inode = dentry->d_inode; - audit_inode_child(dentry, inode); + audit_inode_child(inode, dentry, AUDIT_TYPE_CHILD_CREATE); fsnotify(inode, mask, d_inode, FSNOTIFY_EVENT_INODE, dentry->d_name.name, 0); } |