Commit adb5c2473d3f91526c79db972aafb20a56d3fbb3
Committed by
Al Viro
1 parent
669abf4e55
Exists in
master
and in
20 other branches
audit: make audit_inode take struct filename
Keep a pointer to the audit_names "slot" in struct filename. Have all of the audit_inode callers pass a struct filename ponter to audit_inode instead of a string pointer. If the aname field is already populated, then we can skip walking the list altogether and just use it directly. Signed-off-by: Jeff Layton <jlayton@redhat.com> Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Showing 5 changed files with 42 additions and 19 deletions Side-by-side Diff
fs/namei.c
... | ... | @@ -1999,8 +1999,7 @@ |
1999 | 1999 | flags | LOOKUP_REVAL, nd); |
2000 | 2000 | |
2001 | 2001 | if (likely(!retval)) |
2002 | - audit_inode(name->name, nd->path.dentry, | |
2003 | - flags & LOOKUP_PARENT); | |
2002 | + audit_inode(name, nd->path.dentry, flags & LOOKUP_PARENT); | |
2004 | 2003 | return retval; |
2005 | 2004 | } |
2006 | 2005 | |
... | ... | @@ -2674,7 +2673,6 @@ |
2674 | 2673 | struct path save_parent = { .dentry = NULL, .mnt = NULL }; |
2675 | 2674 | bool retried = false; |
2676 | 2675 | int error; |
2677 | - const char *pathname = name->name; | |
2678 | 2676 | |
2679 | 2677 | nd->flags &= ~LOOKUP_PARENT; |
2680 | 2678 | nd->flags |= op->intent; |
... | ... | @@ -2690,7 +2688,7 @@ |
2690 | 2688 | error = complete_walk(nd); |
2691 | 2689 | if (error) |
2692 | 2690 | return error; |
2693 | - audit_inode(pathname, nd->path.dentry, 0); | |
2691 | + audit_inode(name, nd->path.dentry, 0); | |
2694 | 2692 | if (open_flag & O_CREAT) { |
2695 | 2693 | error = -EISDIR; |
2696 | 2694 | goto out; |
... | ... | @@ -2700,7 +2698,7 @@ |
2700 | 2698 | error = complete_walk(nd); |
2701 | 2699 | if (error) |
2702 | 2700 | return error; |
2703 | - audit_inode(pathname, dir, 0); | |
2701 | + audit_inode(name, dir, 0); | |
2704 | 2702 | goto finish_open; |
2705 | 2703 | } |
2706 | 2704 | |
... | ... | @@ -2729,7 +2727,7 @@ |
2729 | 2727 | if (error) |
2730 | 2728 | return error; |
2731 | 2729 | |
2732 | - audit_inode(pathname, dir, 0); | |
2730 | + audit_inode(name, dir, 0); | |
2733 | 2731 | error = -EISDIR; |
2734 | 2732 | /* trailing slashes? */ |
2735 | 2733 | if (nd->last.name[nd->last.len]) |
... | ... | @@ -2759,7 +2757,7 @@ |
2759 | 2757 | !S_ISREG(file->f_path.dentry->d_inode->i_mode)) |
2760 | 2758 | will_truncate = false; |
2761 | 2759 | |
2762 | - audit_inode(pathname, file->f_path.dentry, 0); | |
2760 | + audit_inode(name, file->f_path.dentry, 0); | |
2763 | 2761 | goto opened; |
2764 | 2762 | } |
2765 | 2763 | |
... | ... | @@ -2776,7 +2774,7 @@ |
2776 | 2774 | * create/update audit record if it already exists. |
2777 | 2775 | */ |
2778 | 2776 | if (path->dentry->d_inode) |
2779 | - audit_inode(pathname, path->dentry, 0); | |
2777 | + audit_inode(name, path->dentry, 0); | |
2780 | 2778 | |
2781 | 2779 | /* |
2782 | 2780 | * If atomic_open() acquired write access it is dropped now due to |
... | ... | @@ -2841,7 +2839,7 @@ |
2841 | 2839 | error = -ENOTDIR; |
2842 | 2840 | if ((nd->flags & LOOKUP_DIRECTORY) && !nd->inode->i_op->lookup) |
2843 | 2841 | goto out; |
2844 | - audit_inode(pathname, nd->path.dentry, 0); | |
2842 | + audit_inode(name, nd->path.dentry, 0); | |
2845 | 2843 | finish_open: |
2846 | 2844 | if (!S_ISREG(nd->inode->i_mode)) |
2847 | 2845 | will_truncate = false; |
include/linux/audit.h
... | ... | @@ -474,7 +474,7 @@ |
474 | 474 | extern struct filename *__audit_reusename(const __user char *uptr); |
475 | 475 | extern void __audit_getname(struct filename *name); |
476 | 476 | extern void audit_putname(struct filename *name); |
477 | -extern void __audit_inode(const char *name, const struct dentry *dentry, | |
477 | +extern void __audit_inode(struct filename *name, const struct dentry *dentry, | |
478 | 478 | unsigned int parent); |
479 | 479 | extern void __audit_inode_child(const struct inode *parent, |
480 | 480 | const struct dentry *dentry, |
... | ... | @@ -519,7 +519,7 @@ |
519 | 519 | if (unlikely(!audit_dummy_context())) |
520 | 520 | __audit_getname(name); |
521 | 521 | } |
522 | -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 | 523 | unsigned int parent) { |
524 | 524 | if (unlikely(!audit_dummy_context())) |
525 | 525 | __audit_inode(name, dentry, parent); |
526 | 526 | |
... | ... | @@ -680,14 +680,16 @@ |
680 | 680 | { } |
681 | 681 | static inline void audit_putname(struct filename *name) |
682 | 682 | { } |
683 | -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, | |
684 | 685 | unsigned int parent) |
685 | 686 | { } |
686 | 687 | static inline void __audit_inode_child(const struct inode *parent, |
687 | 688 | const struct dentry *dentry, |
688 | 689 | const unsigned char type) |
689 | 690 | { } |
690 | -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, | |
691 | 693 | unsigned int parent) |
692 | 694 | { } |
693 | 695 | static inline void audit_inode_child(const struct inode *parent, |
include/linux/fs.h
... | ... | @@ -2196,9 +2196,11 @@ |
2196 | 2196 | #endif /* CONFIG_FILE_LOCKING */ |
2197 | 2197 | |
2198 | 2198 | /* fs/open.c */ |
2199 | +struct audit_names; | |
2199 | 2200 | struct filename { |
2200 | - const char *name; /* pointer to actual string */ | |
2201 | - const __user char *uptr; /* original userland pointer */ | |
2201 | + const char *name; /* pointer to actual string */ | |
2202 | + const __user char *uptr; /* original userland pointer */ | |
2203 | + struct audit_names *aname; | |
2202 | 2204 | }; |
2203 | 2205 | |
2204 | 2206 | extern int do_truncate(struct dentry *, loff_t start, unsigned int time_attrs, |
ipc/mqueue.c
... | ... | @@ -804,7 +804,7 @@ |
804 | 804 | |
805 | 805 | if (oflag & O_CREAT) { |
806 | 806 | if (path.dentry->d_inode) { /* entry already exists */ |
807 | - audit_inode(name->name, path.dentry, 0); | |
807 | + audit_inode(name, path.dentry, 0); | |
808 | 808 | if (oflag & O_EXCL) { |
809 | 809 | error = -EEXIST; |
810 | 810 | goto out; |
... | ... | @@ -824,7 +824,7 @@ |
824 | 824 | error = -ENOENT; |
825 | 825 | goto out; |
826 | 826 | } |
827 | - audit_inode(name->name, path.dentry, 0); | |
827 | + audit_inode(name, path.dentry, 0); | |
828 | 828 | filp = do_open(&path, oflag); |
829 | 829 | } |
830 | 830 |
kernel/auditsc.c
... | ... | @@ -2076,6 +2076,7 @@ |
2076 | 2076 | n->name = name; |
2077 | 2077 | n->name_len = AUDIT_NAME_FULL; |
2078 | 2078 | n->name_put = true; |
2079 | + name->aname = n; | |
2079 | 2080 | |
2080 | 2081 | if (!context->pwd.dentry) |
2081 | 2082 | get_fs_pwd(current->fs, &context->pwd); |
... | ... | @@ -2166,7 +2167,7 @@ |
2166 | 2167 | * @dentry: dentry being audited |
2167 | 2168 | * @parent: does this dentry represent the parent? |
2168 | 2169 | */ |
2169 | -void __audit_inode(const char *name, const struct dentry *dentry, | |
2170 | +void __audit_inode(struct filename *name, const struct dentry *dentry, | |
2170 | 2171 | unsigned int parent) |
2171 | 2172 | { |
2172 | 2173 | struct audit_context *context = current->audit_context; |
2173 | 2174 | |
... | ... | @@ -2179,9 +2180,29 @@ |
2179 | 2180 | if (!name) |
2180 | 2181 | goto out_alloc; |
2181 | 2182 | |
2183 | +#if AUDIT_DEBUG | |
2184 | + /* The struct filename _must_ have a populated ->name */ | |
2185 | + BUG_ON(!name->name); | |
2186 | +#endif | |
2187 | + /* | |
2188 | + * If we have a pointer to an audit_names entry already, then we can | |
2189 | + * just use it directly if the type is correct. | |
2190 | + */ | |
2191 | + n = name->aname; | |
2192 | + if (n) { | |
2193 | + if (parent) { | |
2194 | + if (n->type == AUDIT_TYPE_PARENT || | |
2195 | + n->type == AUDIT_TYPE_UNKNOWN) | |
2196 | + goto out; | |
2197 | + } else { | |
2198 | + if (n->type != AUDIT_TYPE_PARENT) | |
2199 | + goto out; | |
2200 | + } | |
2201 | + } | |
2202 | + | |
2182 | 2203 | list_for_each_entry_reverse(n, &context->names_list, list) { |
2183 | 2204 | /* does the name pointer match? */ |
2184 | - if (!n->name || n->name->name != name) | |
2205 | + if (!n->name || n->name->name != name->name) | |
2185 | 2206 | continue; |
2186 | 2207 | |
2187 | 2208 | /* match the correct record type */ |