diff options
Diffstat (limited to 'kernel/auditsc.c')
-rw-r--r-- | kernel/auditsc.c | 64 |
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 | */ | ||
107 | struct audit_names { | 108 | struct 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 | ||
130 | struct audit_aux_data { | 131 | struct 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 | */ |
2029 | void __audit_getname(const char *name) | 2030 | void __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 | */ |
2062 | void audit_putname(const char *name) | 2068 | void 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; |
2176 | out: | 2182 | out: |
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)) { |