aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/namei.c16
-rw-r--r--include/linux/audit.h10
-rw-r--r--include/linux/fs.h6
-rw-r--r--ipc/mqueue.c4
-rw-r--r--kernel/auditsc.c25
5 files changed, 42 insertions, 19 deletions
diff --git a/fs/namei.c b/fs/namei.c
index 6bbd8fdfb1f5..80b162b142f9 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -1999,8 +1999,7 @@ static int filename_lookup(int dfd, struct filename *name,
1999 flags | LOOKUP_REVAL, nd); 1999 flags | LOOKUP_REVAL, nd);
2000 2000
2001 if (likely(!retval)) 2001 if (likely(!retval))
2002 audit_inode(name->name, nd->path.dentry, 2002 audit_inode(name, nd->path.dentry, flags & LOOKUP_PARENT);
2003 flags & LOOKUP_PARENT);
2004 return retval; 2003 return retval;
2005} 2004}
2006 2005
@@ -2674,7 +2673,6 @@ static int do_last(struct nameidata *nd, struct path *path,
2674 struct path save_parent = { .dentry = NULL, .mnt = NULL }; 2673 struct path save_parent = { .dentry = NULL, .mnt = NULL };
2675 bool retried = false; 2674 bool retried = false;
2676 int error; 2675 int error;
2677 const char *pathname = name->name;
2678 2676
2679 nd->flags &= ~LOOKUP_PARENT; 2677 nd->flags &= ~LOOKUP_PARENT;
2680 nd->flags |= op->intent; 2678 nd->flags |= op->intent;
@@ -2690,7 +2688,7 @@ static int do_last(struct nameidata *nd, struct path *path,
2690 error = complete_walk(nd); 2688 error = complete_walk(nd);
2691 if (error) 2689 if (error)
2692 return error; 2690 return error;
2693 audit_inode(pathname, nd->path.dentry, 0); 2691 audit_inode(name, nd->path.dentry, 0);
2694 if (open_flag & O_CREAT) { 2692 if (open_flag & O_CREAT) {
2695 error = -EISDIR; 2693 error = -EISDIR;
2696 goto out; 2694 goto out;
@@ -2700,7 +2698,7 @@ static int do_last(struct nameidata *nd, struct path *path,
2700 error = complete_walk(nd); 2698 error = complete_walk(nd);
2701 if (error) 2699 if (error)
2702 return error; 2700 return error;
2703 audit_inode(pathname, dir, 0); 2701 audit_inode(name, dir, 0);
2704 goto finish_open; 2702 goto finish_open;
2705 } 2703 }
2706 2704
@@ -2729,7 +2727,7 @@ static int do_last(struct nameidata *nd, struct path *path,
2729 if (error) 2727 if (error)
2730 return error; 2728 return error;
2731 2729
2732 audit_inode(pathname, dir, 0); 2730 audit_inode(name, dir, 0);
2733 error = -EISDIR; 2731 error = -EISDIR;
2734 /* trailing slashes? */ 2732 /* trailing slashes? */
2735 if (nd->last.name[nd->last.len]) 2733 if (nd->last.name[nd->last.len])
@@ -2759,7 +2757,7 @@ retry_lookup:
2759 !S_ISREG(file->f_path.dentry->d_inode->i_mode)) 2757 !S_ISREG(file->f_path.dentry->d_inode->i_mode))
2760 will_truncate = false; 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 goto opened; 2761 goto opened;
2764 } 2762 }
2765 2763
@@ -2776,7 +2774,7 @@ retry_lookup:
2776 * create/update audit record if it already exists. 2774 * create/update audit record if it already exists.
2777 */ 2775 */
2778 if (path->dentry->d_inode) 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 * If atomic_open() acquired write access it is dropped now due to 2780 * If atomic_open() acquired write access it is dropped now due to
@@ -2841,7 +2839,7 @@ finish_lookup:
2841 error = -ENOTDIR; 2839 error = -ENOTDIR;
2842 if ((nd->flags & LOOKUP_DIRECTORY) && !nd->inode->i_op->lookup) 2840 if ((nd->flags & LOOKUP_DIRECTORY) && !nd->inode->i_op->lookup)
2843 goto out; 2841 goto out;
2844 audit_inode(pathname, nd->path.dentry, 0); 2842 audit_inode(name, nd->path.dentry, 0);
2845finish_open: 2843finish_open:
2846 if (!S_ISREG(nd->inode->i_mode)) 2844 if (!S_ISREG(nd->inode->i_mode))
2847 will_truncate = false; 2845 will_truncate = false;
diff --git a/include/linux/audit.h b/include/linux/audit.h
index d5d7952ab7d8..e5884f950b4b 100644
--- a/include/linux/audit.h
+++ b/include/linux/audit.h
@@ -474,7 +474,7 @@ extern void __audit_syscall_exit(int ret_success, long ret_value);
474extern struct filename *__audit_reusename(const __user char *uptr); 474extern struct filename *__audit_reusename(const __user char *uptr);
475extern void __audit_getname(struct filename *name); 475extern void __audit_getname(struct filename *name);
476extern void audit_putname(struct filename *name); 476extern void audit_putname(struct filename *name);
477extern void __audit_inode(const char *name, const struct dentry *dentry, 477extern void __audit_inode(struct filename *name, const struct dentry *dentry,
478 unsigned int parent); 478 unsigned int parent);
479extern void __audit_inode_child(const struct inode *parent, 479extern void __audit_inode_child(const struct inode *parent,
480 const struct dentry *dentry, 480 const struct dentry *dentry,
@@ -519,7 +519,7 @@ static inline void audit_getname(struct filename *name)
519 if (unlikely(!audit_dummy_context())) 519 if (unlikely(!audit_dummy_context()))
520 __audit_getname(name); 520 __audit_getname(name);
521} 521}
522static inline void audit_inode(const char *name, const struct dentry *dentry, 522static inline void audit_inode(struct filename *name, const struct dentry *dentry,
523 unsigned int parent) { 523 unsigned int parent) {
524 if (unlikely(!audit_dummy_context())) 524 if (unlikely(!audit_dummy_context()))
525 __audit_inode(name, dentry, parent); 525 __audit_inode(name, dentry, parent);
@@ -680,14 +680,16 @@ static inline void audit_getname(struct filename *name)
680{ } 680{ }
681static inline void audit_putname(struct filename *name) 681static inline void audit_putname(struct filename *name)
682{ } 682{ }
683static inline void __audit_inode(const char *name, const struct dentry *dentry, 683static inline void __audit_inode(struct filename *name,
684 const struct dentry *dentry,
684 unsigned int parent) 685 unsigned int parent)
685{ } 686{ }
686static inline void __audit_inode_child(const struct inode *parent, 687static inline void __audit_inode_child(const struct inode *parent,
687 const struct dentry *dentry, 688 const struct dentry *dentry,
688 const unsigned char type) 689 const unsigned char type)
689{ } 690{ }
690static inline void audit_inode(const char *name, const struct dentry *dentry, 691static inline void audit_inode(struct filename *name,
692 const struct dentry *dentry,
691 unsigned int parent) 693 unsigned int parent)
692{ } 694{ }
693static inline void audit_inode_child(const struct inode *parent, 695static inline void audit_inode_child(const struct inode *parent,
diff --git a/include/linux/fs.h b/include/linux/fs.h
index b6b10e7f0ac0..4aa7160a51ce 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -2196,9 +2196,11 @@ 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 */
2199struct audit_names;
2199struct filename { 2200struct filename {
2200 const char *name; /* pointer to actual string */ 2201 const char *name; /* pointer to actual string */
2201 const __user char *uptr; /* original userland pointer */ 2202 const __user char *uptr; /* original userland pointer */
2203 struct audit_names *aname;
2202}; 2204};
2203 2205
2204extern int do_truncate(struct dentry *, loff_t start, unsigned int time_attrs, 2206extern int do_truncate(struct dentry *, loff_t start, unsigned int time_attrs,
diff --git a/ipc/mqueue.c b/ipc/mqueue.c
index 6c5d9dcc9030..71a3ca18c873 100644
--- a/ipc/mqueue.c
+++ b/ipc/mqueue.c
@@ -804,7 +804,7 @@ SYSCALL_DEFINE4(mq_open, const char __user *, u_name, int, oflag, umode_t, mode,
804 804
805 if (oflag & O_CREAT) { 805 if (oflag & O_CREAT) {
806 if (path.dentry->d_inode) { /* entry already exists */ 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 if (oflag & O_EXCL) { 808 if (oflag & O_EXCL) {
809 error = -EEXIST; 809 error = -EEXIST;
810 goto out; 810 goto out;
@@ -824,7 +824,7 @@ SYSCALL_DEFINE4(mq_open, const char __user *, u_name, int, oflag, umode_t, mode,
824 error = -ENOENT; 824 error = -ENOENT;
825 goto out; 825 goto out;
826 } 826 }
827 audit_inode(name->name, path.dentry, 0); 827 audit_inode(name, path.dentry, 0);
828 filp = do_open(&path, oflag); 828 filp = do_open(&path, oflag);
829 } 829 }
830 830
diff --git a/kernel/auditsc.c b/kernel/auditsc.c
index 521163a5d65f..2f186ed80c40 100644
--- a/kernel/auditsc.c
+++ b/kernel/auditsc.c
@@ -2076,6 +2076,7 @@ void __audit_getname(struct filename *name)
2076 n->name = name; 2076 n->name = name;
2077 n->name_len = AUDIT_NAME_FULL; 2077 n->name_len = AUDIT_NAME_FULL;
2078 n->name_put = true; 2078 n->name_put = true;
2079 name->aname = n;
2079 2080
2080 if (!context->pwd.dentry) 2081 if (!context->pwd.dentry)
2081 get_fs_pwd(current->fs, &context->pwd); 2082 get_fs_pwd(current->fs, &context->pwd);
@@ -2166,7 +2167,7 @@ static void audit_copy_inode(struct audit_names *name, const struct dentry *dent
2166 * @dentry: dentry being audited 2167 * @dentry: dentry being audited
2167 * @parent: does this dentry represent the parent? 2168 * @parent: does this dentry represent the parent?
2168 */ 2169 */
2169void __audit_inode(const char *name, const struct dentry *dentry, 2170void __audit_inode(struct filename *name, const struct dentry *dentry,
2170 unsigned int parent) 2171 unsigned int parent)
2171{ 2172{
2172 struct audit_context *context = current->audit_context; 2173 struct audit_context *context = current->audit_context;
@@ -2179,9 +2180,29 @@ void __audit_inode(const char *name, const struct dentry *dentry,
2179 if (!name) 2180 if (!name)
2180 goto out_alloc; 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 list_for_each_entry_reverse(n, &context->names_list, list) { 2203 list_for_each_entry_reverse(n, &context->names_list, list) {
2183 /* does the name pointer match? */ 2204 /* does the name pointer match? */
2184 if (!n->name || n->name->name != name) 2205 if (!n->name || n->name->name != name->name)
2185 continue; 2206 continue;
2186 2207
2187 /* match the correct record type */ 2208 /* match the correct record type */