diff options
Diffstat (limited to 'kernel/auditsc.c')
-rw-r--r-- | kernel/auditsc.c | 41 |
1 files changed, 29 insertions, 12 deletions
diff --git a/kernel/auditsc.c b/kernel/auditsc.c index 19b232f86d70..b87b28947acc 100644 --- a/kernel/auditsc.c +++ b/kernel/auditsc.c | |||
@@ -2135,13 +2135,13 @@ static void audit_copy_inode(struct audit_names *name, const struct dentry *dent | |||
2135 | } | 2135 | } |
2136 | 2136 | ||
2137 | /** | 2137 | /** |
2138 | * audit_inode - store the inode and device from a lookup | 2138 | * __audit_inode - store the inode and device from a lookup |
2139 | * @name: name being audited | 2139 | * @name: name being audited |
2140 | * @dentry: dentry being audited | 2140 | * @dentry: dentry being audited |
2141 | * | 2141 | * @parent: does this dentry represent the parent? |
2142 | * Called from fs/namei.c:path_lookup(). | ||
2143 | */ | 2142 | */ |
2144 | void __audit_inode(const char *name, const struct dentry *dentry) | 2143 | void __audit_inode(const char *name, const struct dentry *dentry, |
2144 | unsigned int parent) | ||
2145 | { | 2145 | { |
2146 | struct audit_context *context = current->audit_context; | 2146 | struct audit_context *context = current->audit_context; |
2147 | const struct inode *inode = dentry->d_inode; | 2147 | const struct inode *inode = dentry->d_inode; |
@@ -2154,19 +2154,38 @@ void __audit_inode(const char *name, const struct dentry *dentry) | |||
2154 | goto out_alloc; | 2154 | goto out_alloc; |
2155 | 2155 | ||
2156 | list_for_each_entry_reverse(n, &context->names_list, list) { | 2156 | list_for_each_entry_reverse(n, &context->names_list, list) { |
2157 | if (n->name == name) | 2157 | /* does the name pointer match? */ |
2158 | goto out; | 2158 | if (n->name != name) |
2159 | continue; | ||
2160 | |||
2161 | /* match the correct record type */ | ||
2162 | if (parent) { | ||
2163 | if (n->type == AUDIT_TYPE_PARENT || | ||
2164 | n->type == AUDIT_TYPE_UNKNOWN) | ||
2165 | goto out; | ||
2166 | } else { | ||
2167 | if (n->type != AUDIT_TYPE_PARENT) | ||
2168 | goto out; | ||
2169 | } | ||
2159 | } | 2170 | } |
2160 | 2171 | ||
2161 | out_alloc: | 2172 | out_alloc: |
2162 | /* unable to find the name from a previous getname() */ | 2173 | /* unable to find the name from a previous getname(). Allocate a new |
2174 | * anonymous entry. | ||
2175 | */ | ||
2163 | n = audit_alloc_name(context, AUDIT_TYPE_NORMAL); | 2176 | n = audit_alloc_name(context, AUDIT_TYPE_NORMAL); |
2164 | if (!n) | 2177 | if (!n) |
2165 | return; | 2178 | return; |
2166 | out: | 2179 | out: |
2180 | if (parent) { | ||
2181 | n->name_len = n->name ? parent_len(n->name) : AUDIT_NAME_FULL; | ||
2182 | n->type = AUDIT_TYPE_PARENT; | ||
2183 | } else { | ||
2184 | n->name_len = AUDIT_NAME_FULL; | ||
2185 | n->type = AUDIT_TYPE_NORMAL; | ||
2186 | } | ||
2167 | handle_path(dentry); | 2187 | handle_path(dentry); |
2168 | audit_copy_inode(n, dentry, inode); | 2188 | audit_copy_inode(n, dentry, inode); |
2169 | n->type = AUDIT_TYPE_NORMAL; | ||
2170 | } | 2189 | } |
2171 | 2190 | ||
2172 | /** | 2191 | /** |
@@ -2190,7 +2209,6 @@ void __audit_inode_child(const struct inode *parent, | |||
2190 | const struct inode *inode = dentry->d_inode; | 2209 | const struct inode *inode = dentry->d_inode; |
2191 | const char *dname = dentry->d_name.name; | 2210 | const char *dname = dentry->d_name.name; |
2192 | struct audit_names *n; | 2211 | struct audit_names *n; |
2193 | int dirlen = 0; | ||
2194 | 2212 | ||
2195 | if (!context->in_syscall) | 2213 | if (!context->in_syscall) |
2196 | return; | 2214 | return; |
@@ -2204,8 +2222,7 @@ void __audit_inode_child(const struct inode *parent, | |||
2204 | continue; | 2222 | continue; |
2205 | 2223 | ||
2206 | if (n->ino == parent->i_ino && | 2224 | if (n->ino == parent->i_ino && |
2207 | !audit_compare_dname_path(dname, n->name, &dirlen)) { | 2225 | !audit_compare_dname_path(dname, n->name, NULL)) { |
2208 | n->name_len = dirlen; /* update parent data in place */ | ||
2209 | found_parent = n->name; | 2226 | found_parent = n->name; |
2210 | goto add_names; | 2227 | goto add_names; |
2211 | } | 2228 | } |
@@ -2218,7 +2235,7 @@ void __audit_inode_child(const struct inode *parent, | |||
2218 | 2235 | ||
2219 | /* strcmp() is the more likely scenario */ | 2236 | /* strcmp() is the more likely scenario */ |
2220 | if (!strcmp(dname, n->name) || | 2237 | if (!strcmp(dname, n->name) || |
2221 | !audit_compare_dname_path(dname, n->name, &dirlen)) { | 2238 | !audit_compare_dname_path(dname, n->name, NULL)) { |
2222 | if (inode) | 2239 | if (inode) |
2223 | audit_copy_inode(n, dentry, inode); | 2240 | audit_copy_inode(n, dentry, inode); |
2224 | else | 2241 | else |