aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/auditsc.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/auditsc.c')
-rw-r--r--kernel/auditsc.c64
1 files changed, 35 insertions, 29 deletions
diff --git a/kernel/auditsc.c b/kernel/auditsc.c
index d147585e9ef3..d4d82319eed5 100644
--- a/kernel/auditsc.c
+++ b/kernel/auditsc.c
@@ -103,28 +103,29 @@ struct audit_cap_data {
103 * we don't let putname() free it (instead we free all of the saved 103 * we don't let putname() free it (instead we free all of the saved
104 * pointers at syscall exit time). 104 * pointers at syscall exit time).
105 * 105 *
106 * Further, in fs/namei.c:path_lookup() we store the inode and device. */ 106 * Further, in fs/namei.c:path_lookup() we store the inode and device.
107 */
107struct audit_names { 108struct audit_names {
108 struct list_head list; /* audit_context->names_list */ 109 struct list_head list; /* audit_context->names_list */
109 const char *name; 110 struct filename *name;
110 unsigned long ino; 111 unsigned long ino;
111 dev_t dev; 112 dev_t dev;
112 umode_t mode; 113 umode_t mode;
113 kuid_t uid; 114 kuid_t uid;
114 kgid_t gid; 115 kgid_t gid;
115 dev_t rdev; 116 dev_t rdev;
116 u32 osid; 117 u32 osid;
117 struct audit_cap_data fcap; 118 struct audit_cap_data fcap;
118 unsigned int fcap_ver; 119 unsigned int fcap_ver;
119 int name_len; /* number of name's characters to log */ 120 int name_len; /* number of name's characters to log */
120 unsigned char type; /* record type */ 121 unsigned char type; /* record type */
121 bool name_put; /* call __putname() for this name */ 122 bool name_put; /* call __putname() for this name */
122 /* 123 /*
123 * This was an allocated audit_names and not from the array of 124 * This was an allocated audit_names and not from the array of
124 * names allocated in the task audit context. Thus this name 125 * names allocated in the task audit context. Thus this name
125 * should be freed on syscall exit 126 * should be freed on syscall exit
126 */ 127 */
127 bool should_free; 128 bool should_free;
128}; 129};
129 130
130struct audit_aux_data { 131struct audit_aux_data {
@@ -996,7 +997,7 @@ static inline void audit_free_names(struct audit_context *context)
996 context->ino_count); 997 context->ino_count);
997 list_for_each_entry(n, &context->names_list, list) { 998 list_for_each_entry(n, &context->names_list, list) {
998 printk(KERN_ERR "names[%d] = %p = %s\n", i, 999 printk(KERN_ERR "names[%d] = %p = %s\n", i,
999 n->name, n->name ?: "(null)"); 1000 n->name, n->name->name ?: "(null)");
1000 } 1001 }
1001 dump_stack(); 1002 dump_stack();
1002 return; 1003 return;
@@ -1553,7 +1554,7 @@ static void audit_log_name(struct audit_context *context, struct audit_names *n,
1553 case AUDIT_NAME_FULL: 1554 case AUDIT_NAME_FULL:
1554 /* log the full path */ 1555 /* log the full path */
1555 audit_log_format(ab, " name="); 1556 audit_log_format(ab, " name=");
1556 audit_log_untrustedstring(ab, n->name); 1557 audit_log_untrustedstring(ab, n->name->name);
1557 break; 1558 break;
1558 case 0: 1559 case 0:
1559 /* name was specified as a relative path and the 1560 /* name was specified as a relative path and the
@@ -1563,7 +1564,7 @@ static void audit_log_name(struct audit_context *context, struct audit_names *n,
1563 default: 1564 default:
1564 /* log the name's directory component */ 1565 /* log the name's directory component */
1565 audit_log_format(ab, " name="); 1566 audit_log_format(ab, " name=");
1566 audit_log_n_untrustedstring(ab, n->name, 1567 audit_log_n_untrustedstring(ab, n->name->name,
1567 n->name_len); 1568 n->name_len);
1568 } 1569 }
1569 } else 1570 } else
@@ -2026,7 +2027,7 @@ static struct audit_names *audit_alloc_name(struct audit_context *context,
2026 * Add a name to the list of audit names for this context. 2027 * Add a name to the list of audit names for this context.
2027 * Called from fs/namei.c:getname(). 2028 * Called from fs/namei.c:getname().
2028 */ 2029 */
2029void __audit_getname(const char *name) 2030void __audit_getname(struct filename *name)
2030{ 2031{
2031 struct audit_context *context = current->audit_context; 2032 struct audit_context *context = current->audit_context;
2032 struct audit_names *n; 2033 struct audit_names *n;
@@ -2040,6 +2041,11 @@ void __audit_getname(const char *name)
2040 return; 2041 return;
2041 } 2042 }
2042 2043
2044#if AUDIT_DEBUG
2045 /* The filename _must_ have a populated ->name */
2046 BUG_ON(!name->name);
2047#endif
2048
2043 n = audit_alloc_name(context, AUDIT_TYPE_UNKNOWN); 2049 n = audit_alloc_name(context, AUDIT_TYPE_UNKNOWN);
2044 if (!n) 2050 if (!n)
2045 return; 2051 return;
@@ -2059,7 +2065,7 @@ void __audit_getname(const char *name)
2059 * then we delay the putname until syscall exit. 2065 * then we delay the putname until syscall exit.
2060 * Called from include/linux/fs.h:putname(). 2066 * Called from include/linux/fs.h:putname().
2061 */ 2067 */
2062void audit_putname(const char *name) 2068void audit_putname(struct filename *name)
2063{ 2069{
2064 struct audit_context *context = current->audit_context; 2070 struct audit_context *context = current->audit_context;
2065 2071
@@ -2074,7 +2080,7 @@ void audit_putname(const char *name)
2074 2080
2075 list_for_each_entry(n, &context->names_list, list) 2081 list_for_each_entry(n, &context->names_list, list)
2076 printk(KERN_ERR "name[%d] = %p = %s\n", i, 2082 printk(KERN_ERR "name[%d] = %p = %s\n", i,
2077 n->name, n->name ?: "(null)"); 2083 n->name, n->name->name ?: "(null)");
2078 } 2084 }
2079#endif 2085#endif
2080 __putname(name); 2086 __putname(name);
@@ -2088,8 +2094,8 @@ void audit_putname(const char *name)
2088 " put_count=%d\n", 2094 " put_count=%d\n",
2089 __FILE__, __LINE__, 2095 __FILE__, __LINE__,
2090 context->serial, context->major, 2096 context->serial, context->major,
2091 context->in_syscall, name, context->name_count, 2097 context->in_syscall, name->name,
2092 context->put_count); 2098 context->name_count, context->put_count);
2093 dump_stack(); 2099 dump_stack();
2094 } 2100 }
2095 } 2101 }
@@ -2152,7 +2158,7 @@ void __audit_inode(const char *name, const struct dentry *dentry,
2152 2158
2153 list_for_each_entry_reverse(n, &context->names_list, list) { 2159 list_for_each_entry_reverse(n, &context->names_list, list) {
2154 /* does the name pointer match? */ 2160 /* does the name pointer match? */
2155 if (n->name != name) 2161 if (!n->name || n->name->name != name)
2156 continue; 2162 continue;
2157 2163
2158 /* match the correct record type */ 2164 /* match the correct record type */
@@ -2175,7 +2181,7 @@ out_alloc:
2175 return; 2181 return;
2176out: 2182out:
2177 if (parent) { 2183 if (parent) {
2178 n->name_len = n->name ? parent_len(n->name) : AUDIT_NAME_FULL; 2184 n->name_len = n->name ? parent_len(n->name->name) : AUDIT_NAME_FULL;
2179 n->type = AUDIT_TYPE_PARENT; 2185 n->type = AUDIT_TYPE_PARENT;
2180 } else { 2186 } else {
2181 n->name_len = AUDIT_NAME_FULL; 2187 n->name_len = AUDIT_NAME_FULL;
@@ -2220,7 +2226,7 @@ void __audit_inode_child(const struct inode *parent,
2220 continue; 2226 continue;
2221 2227
2222 if (n->ino == parent->i_ino && 2228 if (n->ino == parent->i_ino &&
2223 !audit_compare_dname_path(dname, n->name, n->name_len)) { 2229 !audit_compare_dname_path(dname, n->name->name, n->name_len)) {
2224 found_parent = n; 2230 found_parent = n;
2225 break; 2231 break;
2226 } 2232 }
@@ -2236,8 +2242,8 @@ void __audit_inode_child(const struct inode *parent,
2236 if (found_parent && (n->name != found_parent->name)) 2242 if (found_parent && (n->name != found_parent->name))
2237 continue; 2243 continue;
2238 2244
2239 if (!strcmp(dname, n->name) || 2245 if (!strcmp(dname, n->name->name) ||
2240 !audit_compare_dname_path(dname, n->name, 2246 !audit_compare_dname_path(dname, n->name->name,
2241 found_parent ? 2247 found_parent ?
2242 found_parent->name_len : 2248 found_parent->name_len :
2243 AUDIT_NAME_FULL)) { 2249 AUDIT_NAME_FULL)) {