diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-10-12 21:04:42 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-10-12 21:04:42 -0400 |
| commit | 8418263e3547ed3816475e4c55a77004f0426ee6 (patch) | |
| tree | 97c548b16e6753e1911870d824a07b7e726b6229 /include/linux | |
| parent | ccff9b1db693062b0a9c9070f4304deb47ef215c (diff) | |
| parent | f81700bd831efcd12eb7f0e66b24b16c2ad00a32 (diff) | |
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/linux')
| -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 2c83e5f7edb1..e5884f950b4b 100644 --- a/include/linux/audit.h +++ b/include/linux/audit.h | |||
| @@ -452,6 +452,16 @@ struct audit_field { | |||
| 452 | extern int __init audit_register_class(int class, unsigned *list); | 452 | extern int __init audit_register_class(int class, unsigned *list); |
| 453 | extern int audit_classify_syscall(int abi, unsigned syscall); | 453 | extern int audit_classify_syscall(int abi, unsigned syscall); |
| 454 | extern int audit_classify_arch(int arch); | 454 | extern int audit_classify_arch(int arch); |
| 455 | |||
| 456 | /* audit_names->type values */ | ||
| 457 | #define AUDIT_TYPE_UNKNOWN 0 /* we don't know yet */ | ||
| 458 | #define AUDIT_TYPE_NORMAL 1 /* a "normal" audit record */ | ||
| 459 | #define AUDIT_TYPE_PARENT 2 /* a parent audit record */ | ||
| 460 | #define AUDIT_TYPE_CHILD_DELETE 3 /* a child being deleted */ | ||
| 461 | #define AUDIT_TYPE_CHILD_CREATE 4 /* a child being created */ | ||
| 462 | |||
| 463 | struct filename; | ||
| 464 | |||
| 455 | #ifdef CONFIG_AUDITSYSCALL | 465 | #ifdef CONFIG_AUDITSYSCALL |
| 456 | /* These are defined in auditsc.c */ | 466 | /* These are defined in auditsc.c */ |
| 457 | /* Public API */ | 467 | /* Public API */ |
| @@ -461,11 +471,14 @@ extern void __audit_syscall_entry(int arch, | |||
| 461 | int major, unsigned long a0, unsigned long a1, | 471 | int major, unsigned long a0, unsigned long a1, |
| 462 | unsigned long a2, unsigned long a3); | 472 | unsigned long a2, unsigned long a3); |
| 463 | extern void __audit_syscall_exit(int ret_success, long ret_value); | 473 | extern void __audit_syscall_exit(int ret_success, long ret_value); |
| 464 | extern void __audit_getname(const char *name); | 474 | extern struct filename *__audit_reusename(const __user char *uptr); |
| 465 | extern void audit_putname(const char *name); | 475 | extern void __audit_getname(struct filename *name); |
| 466 | extern void __audit_inode(const char *name, const struct dentry *dentry); | 476 | extern void audit_putname(struct filename *name); |
| 467 | extern void __audit_inode_child(const struct dentry *dentry, | 477 | extern void __audit_inode(struct filename *name, const struct dentry *dentry, |
| 468 | const struct inode *parent); | 478 | unsigned int parent); |
| 479 | extern void __audit_inode_child(const struct inode *parent, | ||
| 480 | const struct dentry *dentry, | ||
| 481 | const unsigned char type); | ||
| 469 | extern void __audit_seccomp(unsigned long syscall, long signr, int code); | 482 | extern void __audit_seccomp(unsigned long syscall, long signr, int code); |
| 470 | extern void __audit_ptrace(struct task_struct *t); | 483 | extern void __audit_ptrace(struct task_struct *t); |
| 471 | 484 | ||
| @@ -495,19 +508,27 @@ static inline void audit_syscall_exit(void *pt_regs) | |||
| 495 | __audit_syscall_exit(success, return_code); | 508 | __audit_syscall_exit(success, return_code); |
| 496 | } | 509 | } |
| 497 | } | 510 | } |
| 498 | static inline void audit_getname(const char *name) | 511 | static inline struct filename *audit_reusename(const __user char *name) |
| 512 | { | ||
| 513 | if (unlikely(!audit_dummy_context())) | ||
| 514 | return __audit_reusename(name); | ||
| 515 | return NULL; | ||
| 516 | } | ||
| 517 | static inline void audit_getname(struct filename *name) | ||
| 499 | { | 518 | { |
| 500 | if (unlikely(!audit_dummy_context())) | 519 | if (unlikely(!audit_dummy_context())) |
| 501 | __audit_getname(name); | 520 | __audit_getname(name); |
| 502 | } | 521 | } |
| 503 | static inline void audit_inode(const char *name, const struct dentry *dentry) { | 522 | static inline void audit_inode(struct filename *name, const struct dentry *dentry, |
| 523 | unsigned int parent) { | ||
| 504 | if (unlikely(!audit_dummy_context())) | 524 | if (unlikely(!audit_dummy_context())) |
| 505 | __audit_inode(name, dentry); | 525 | __audit_inode(name, dentry, parent); |
| 506 | } | 526 | } |
| 507 | static inline void audit_inode_child(const struct dentry *dentry, | 527 | static inline void audit_inode_child(const struct inode *parent, |
| 508 | const struct inode *parent) { | 528 | const struct dentry *dentry, |
| 529 | const unsigned char type) { | ||
| 509 | if (unlikely(!audit_dummy_context())) | 530 | if (unlikely(!audit_dummy_context())) |
| 510 | __audit_inode_child(dentry, parent); | 531 | __audit_inode_child(parent, dentry, type); |
| 511 | } | 532 | } |
| 512 | void audit_core_dumps(long signr); | 533 | void audit_core_dumps(long signr); |
| 513 | 534 | ||
| @@ -651,19 +672,29 @@ static inline int audit_dummy_context(void) | |||
| 651 | { | 672 | { |
| 652 | return 1; | 673 | return 1; |
| 653 | } | 674 | } |
| 654 | static inline void audit_getname(const char *name) | 675 | static inline struct filename *audit_reusename(const __user char *name) |
| 676 | { | ||
| 677 | return NULL; | ||
| 678 | } | ||
| 679 | static inline void audit_getname(struct filename *name) | ||
| 655 | { } | 680 | { } |
| 656 | static inline void audit_putname(const char *name) | 681 | static inline void audit_putname(struct filename *name) |
| 657 | { } | 682 | { } |
| 658 | static inline void __audit_inode(const char *name, const struct dentry *dentry) | 683 | static inline void __audit_inode(struct filename *name, |
| 684 | const struct dentry *dentry, | ||
| 685 | unsigned int parent) | ||
| 659 | { } | 686 | { } |
| 660 | static inline void __audit_inode_child(const struct dentry *dentry, | 687 | static inline void __audit_inode_child(const struct inode *parent, |
| 661 | const struct inode *parent) | 688 | const struct dentry *dentry, |
| 689 | const unsigned char type) | ||
| 662 | { } | 690 | { } |
| 663 | static inline void audit_inode(const char *name, const struct dentry *dentry) | 691 | static inline void audit_inode(struct filename *name, |
| 692 | const struct dentry *dentry, | ||
| 693 | unsigned int parent) | ||
| 664 | { } | 694 | { } |
| 665 | static inline void audit_inode_child(const struct dentry *dentry, | 695 | static inline void audit_inode_child(const struct inode *parent, |
| 666 | const struct inode *parent) | 696 | const struct dentry *dentry, |
| 697 | const unsigned char type) | ||
| 667 | { } | 698 | { } |
| 668 | static inline void audit_core_dumps(long signr) | 699 | static inline void audit_core_dumps(long signr) |
| 669 | { } | 700 | { } |
diff --git a/include/linux/fs.h b/include/linux/fs.h index 8ef2fc9f1f08..65fbf571023f 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) | |||
| 2196 | #endif /* CONFIG_FILE_LOCKING */ | 2196 | #endif /* CONFIG_FILE_LOCKING */ |
| 2197 | 2197 | ||
| 2198 | /* fs/open.c */ | 2198 | /* fs/open.c */ |
| 2199 | struct audit_names; | ||
| 2200 | struct filename { | ||
| 2201 | const char *name; /* pointer to actual string */ | ||
| 2202 | const __user char *uptr; /* original userland pointer */ | ||
| 2203 | struct audit_names *aname; | ||
| 2204 | bool separate; /* should "name" be freed? */ | ||
| 2205 | }; | ||
| 2199 | 2206 | ||
| 2200 | extern int do_truncate(struct dentry *, loff_t start, unsigned int time_attrs, | 2207 | extern int do_truncate(struct dentry *, loff_t start, unsigned int time_attrs, |
| 2201 | struct file *filp); | 2208 | struct file *filp); |
| @@ -2203,12 +2210,15 @@ extern int do_fallocate(struct file *file, int mode, loff_t offset, | |||
| 2203 | loff_t len); | 2210 | loff_t len); |
| 2204 | extern long do_sys_open(int dfd, const char __user *filename, int flags, | 2211 | extern long do_sys_open(int dfd, const char __user *filename, int flags, |
| 2205 | umode_t mode); | 2212 | umode_t mode); |
| 2213 | extern struct file *file_open_name(struct filename *, int, umode_t); | ||
| 2206 | extern struct file *filp_open(const char *, int, umode_t); | 2214 | extern struct file *filp_open(const char *, int, umode_t); |
| 2207 | extern struct file *file_open_root(struct dentry *, struct vfsmount *, | 2215 | extern struct file *file_open_root(struct dentry *, struct vfsmount *, |
| 2208 | const char *, int); | 2216 | const char *, int); |
| 2209 | extern struct file * dentry_open(const struct path *, int, const struct cred *); | 2217 | extern struct file * dentry_open(const struct path *, int, const struct cred *); |
| 2210 | extern int filp_close(struct file *, fl_owner_t id); | 2218 | extern int filp_close(struct file *, fl_owner_t id); |
| 2211 | extern char * getname(const char __user *); | 2219 | |
| 2220 | extern struct filename *getname(const char __user *); | ||
| 2221 | |||
| 2212 | enum { | 2222 | enum { |
| 2213 | FILE_CREATED = 1, | 2223 | FILE_CREATED = 1, |
| 2214 | FILE_OPENED = 2 | 2224 | FILE_OPENED = 2 |
| @@ -2228,13 +2238,14 @@ extern void __init vfs_caches_init(unsigned long); | |||
| 2228 | 2238 | ||
| 2229 | extern struct kmem_cache *names_cachep; | 2239 | extern struct kmem_cache *names_cachep; |
| 2230 | 2240 | ||
| 2231 | #define __getname_gfp(gfp) kmem_cache_alloc(names_cachep, (gfp)) | 2241 | extern void final_putname(struct filename *name); |
| 2232 | #define __getname() __getname_gfp(GFP_KERNEL) | 2242 | |
| 2243 | #define __getname() kmem_cache_alloc(names_cachep, GFP_KERNEL) | ||
| 2233 | #define __putname(name) kmem_cache_free(names_cachep, (void *)(name)) | 2244 | #define __putname(name) kmem_cache_free(names_cachep, (void *)(name)) |
| 2234 | #ifndef CONFIG_AUDITSYSCALL | 2245 | #ifndef CONFIG_AUDITSYSCALL |
| 2235 | #define putname(name) __putname(name) | 2246 | #define putname(name) final_putname(name) |
| 2236 | #else | 2247 | #else |
| 2237 | extern void putname(const char *name); | 2248 | extern void putname(struct filename *name); |
| 2238 | #endif | 2249 | #endif |
| 2239 | 2250 | ||
| 2240 | #ifdef CONFIG_BLOCK | 2251 | #ifdef CONFIG_BLOCK |
diff --git a/include/linux/fsnotify.h b/include/linux/fsnotify.h index a6dfe6944564..0fbfb4646d1b 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, | |||
| 109 | 109 | ||
| 110 | if (source) | 110 | if (source) |
| 111 | fsnotify(source, FS_MOVE_SELF, moved->d_inode, FSNOTIFY_EVENT_INODE, NULL, 0); | 111 | fsnotify(source, FS_MOVE_SELF, moved->d_inode, FSNOTIFY_EVENT_INODE, NULL, 0); |
| 112 | audit_inode_child(moved, new_dir); | 112 | audit_inode_child(new_dir, moved, AUDIT_TYPE_CHILD_CREATE); |
| 113 | } | 113 | } |
| 114 | 114 | ||
| 115 | /* | 115 | /* |
| @@ -155,7 +155,7 @@ static inline void fsnotify_inoderemove(struct inode *inode) | |||
| 155 | */ | 155 | */ |
| 156 | static inline void fsnotify_create(struct inode *inode, struct dentry *dentry) | 156 | static inline void fsnotify_create(struct inode *inode, struct dentry *dentry) |
| 157 | { | 157 | { |
| 158 | audit_inode_child(dentry, inode); | 158 | audit_inode_child(inode, dentry, AUDIT_TYPE_CHILD_CREATE); |
| 159 | 159 | ||
| 160 | fsnotify(inode, FS_CREATE, dentry->d_inode, FSNOTIFY_EVENT_INODE, dentry->d_name.name, 0); | 160 | fsnotify(inode, FS_CREATE, dentry->d_inode, FSNOTIFY_EVENT_INODE, dentry->d_name.name, 0); |
| 161 | } | 161 | } |
| @@ -168,7 +168,7 @@ static inline void fsnotify_create(struct inode *inode, struct dentry *dentry) | |||
| 168 | static inline void fsnotify_link(struct inode *dir, struct inode *inode, struct dentry *new_dentry) | 168 | static inline void fsnotify_link(struct inode *dir, struct inode *inode, struct dentry *new_dentry) |
| 169 | { | 169 | { |
| 170 | fsnotify_link_count(inode); | 170 | fsnotify_link_count(inode); |
| 171 | audit_inode_child(new_dentry, dir); | 171 | audit_inode_child(dir, new_dentry, AUDIT_TYPE_CHILD_CREATE); |
| 172 | 172 | ||
| 173 | fsnotify(dir, FS_CREATE, inode, FSNOTIFY_EVENT_INODE, new_dentry->d_name.name, 0); | 173 | fsnotify(dir, FS_CREATE, inode, FSNOTIFY_EVENT_INODE, new_dentry->d_name.name, 0); |
| 174 | } | 174 | } |
| @@ -181,7 +181,7 @@ static inline void fsnotify_mkdir(struct inode *inode, struct dentry *dentry) | |||
| 181 | __u32 mask = (FS_CREATE | FS_ISDIR); | 181 | __u32 mask = (FS_CREATE | FS_ISDIR); |
| 182 | struct inode *d_inode = dentry->d_inode; | 182 | struct inode *d_inode = dentry->d_inode; |
| 183 | 183 | ||
| 184 | audit_inode_child(dentry, inode); | 184 | audit_inode_child(inode, dentry, AUDIT_TYPE_CHILD_CREATE); |
| 185 | 185 | ||
| 186 | fsnotify(inode, mask, d_inode, FSNOTIFY_EVENT_INODE, dentry->d_name.name, 0); | 186 | fsnotify(inode, mask, d_inode, FSNOTIFY_EVENT_INODE, dentry->d_name.name, 0); |
| 187 | } | 187 | } |
