aboutsummaryrefslogtreecommitdiffstats
path: root/security
diff options
context:
space:
mode:
authorJohn Johansen <john.johansen@canonical.com>2012-02-16 09:20:33 -0500
committerJohn Johansen <john.johansen@canonical.com>2012-03-14 09:15:25 -0400
commit57fa1e18091e66b7e1002816523cb218196a882e (patch)
tree29b4b3484fb17d60d7c6e24d107a74180ec815be /security
parent0fe1212d0539eb6c1e27d388711172d786e299cc (diff)
AppArmor: Move path failure information into aa_get_name and rename
Move the path name lookup failure messages into the main path name lookup routine, as the information is useful in more than just aa_path_perm. Also rename aa_get_name to aa_path_name as it is not getting a reference counted object with a corresponding put fn. Signed-off-by: John Johansen <john.johansen@canonical.com> Acked-by: Kees Cook <kees@ubuntu.com>
Diffstat (limited to 'security')
-rw-r--r--security/apparmor/domain.c5
-rw-r--r--security/apparmor/file.c18
-rw-r--r--security/apparmor/include/path.h3
-rw-r--r--security/apparmor/path.c22
4 files changed, 29 insertions, 19 deletions
diff --git a/security/apparmor/domain.c b/security/apparmor/domain.c
index c1e18ba5bdc0..7c69599a69e1 100644
--- a/security/apparmor/domain.c
+++ b/security/apparmor/domain.c
@@ -372,13 +372,12 @@ int apparmor_bprm_set_creds(struct linux_binprm *bprm)
372 state = profile->file.start; 372 state = profile->file.start;
373 373
374 /* buffer freed below, name is pointer into buffer */ 374 /* buffer freed below, name is pointer into buffer */
375 error = aa_get_name(&bprm->file->f_path, profile->path_flags, &buffer, 375 error = aa_path_name(&bprm->file->f_path, profile->path_flags, &buffer,
376 &name); 376 &name, &info);
377 if (error) { 377 if (error) {
378 if (profile->flags & 378 if (profile->flags &
379 (PFLAG_IX_ON_NAME_ERROR | PFLAG_UNCONFINED)) 379 (PFLAG_IX_ON_NAME_ERROR | PFLAG_UNCONFINED))
380 error = 0; 380 error = 0;
381 info = "Exec failed name resolution";
382 name = bprm->filename; 381 name = bprm->filename;
383 goto audit; 382 goto audit;
384 } 383 }
diff --git a/security/apparmor/file.c b/security/apparmor/file.c
index bba875c4d068..3022c0f4f0db 100644
--- a/security/apparmor/file.c
+++ b/security/apparmor/file.c
@@ -278,22 +278,16 @@ int aa_path_perm(int op, struct aa_profile *profile, struct path *path,
278 int error; 278 int error;
279 279
280 flags |= profile->path_flags | (S_ISDIR(cond->mode) ? PATH_IS_DIR : 0); 280 flags |= profile->path_flags | (S_ISDIR(cond->mode) ? PATH_IS_DIR : 0);
281 error = aa_get_name(path, flags, &buffer, &name); 281 error = aa_path_name(path, flags, &buffer, &name, &info);
282 if (error) { 282 if (error) {
283 if (error == -ENOENT && is_deleted(path->dentry)) { 283 if (error == -ENOENT && is_deleted(path->dentry)) {
284 /* Access to open files that are deleted are 284 /* Access to open files that are deleted are
285 * give a pass (implicit delegation) 285 * give a pass (implicit delegation)
286 */ 286 */
287 error = 0; 287 error = 0;
288 info = NULL;
288 perms.allow = request; 289 perms.allow = request;
289 } else if (error == -ENOENT) 290 }
290 info = "Failed name lookup - deleted entry";
291 else if (error == -ESTALE)
292 info = "Failed name lookup - disconnected path";
293 else if (error == -ENAMETOOLONG)
294 info = "Failed name lookup - name too long";
295 else
296 info = "Failed name lookup";
297 } else { 291 } else {
298 aa_str_perms(profile->file.dfa, profile->file.start, name, cond, 292 aa_str_perms(profile->file.dfa, profile->file.start, name, cond,
299 &perms); 293 &perms);
@@ -364,12 +358,14 @@ int aa_path_link(struct aa_profile *profile, struct dentry *old_dentry,
364 lperms = nullperms; 358 lperms = nullperms;
365 359
366 /* buffer freed below, lname is pointer in buffer */ 360 /* buffer freed below, lname is pointer in buffer */
367 error = aa_get_name(&link, profile->path_flags, &buffer, &lname); 361 error = aa_path_name(&link, profile->path_flags, &buffer, &lname,
362 &info);
368 if (error) 363 if (error)
369 goto audit; 364 goto audit;
370 365
371 /* buffer2 freed below, tname is pointer in buffer2 */ 366 /* buffer2 freed below, tname is pointer in buffer2 */
372 error = aa_get_name(&target, profile->path_flags, &buffer2, &tname); 367 error = aa_path_name(&target, profile->path_flags, &buffer2, &tname,
368 &info);
373 if (error) 369 if (error)
374 goto audit; 370 goto audit;
375 371
diff --git a/security/apparmor/include/path.h b/security/apparmor/include/path.h
index 27b327a7fae5..286ac75dc88b 100644
--- a/security/apparmor/include/path.h
+++ b/security/apparmor/include/path.h
@@ -26,6 +26,7 @@ enum path_flags {
26 PATH_MEDIATE_DELETED = 0x10000, /* mediate deleted paths */ 26 PATH_MEDIATE_DELETED = 0x10000, /* mediate deleted paths */
27}; 27};
28 28
29int aa_get_name(struct path *path, int flags, char **buffer, const char **name); 29int aa_path_name(struct path *path, int flags, char **buffer,
30 const char **name, const char **info);
30 31
31#endif /* __AA_PATH_H */ 32#endif /* __AA_PATH_H */
diff --git a/security/apparmor/path.c b/security/apparmor/path.c
index a7936dfe0e6c..2daeea4f9266 100644
--- a/security/apparmor/path.c
+++ b/security/apparmor/path.c
@@ -157,7 +157,7 @@ out:
157 * Returns: %0 else error on failure 157 * Returns: %0 else error on failure
158 */ 158 */
159static int get_name_to_buffer(struct path *path, int flags, char *buffer, 159static int get_name_to_buffer(struct path *path, int flags, char *buffer,
160 int size, char **name) 160 int size, char **name, const char **info)
161{ 161{
162 int adjust = (flags & PATH_IS_DIR) ? 1 : 0; 162 int adjust = (flags & PATH_IS_DIR) ? 1 : 0;
163 int error = d_namespace_path(path, buffer, size - adjust, name, flags); 163 int error = d_namespace_path(path, buffer, size - adjust, name, flags);
@@ -169,15 +169,27 @@ static int get_name_to_buffer(struct path *path, int flags, char *buffer,
169 */ 169 */
170 strcpy(&buffer[size - 2], "/"); 170 strcpy(&buffer[size - 2], "/");
171 171
172 if (info && error) {
173 if (error == -ENOENT)
174 *info = "Failed name lookup - deleted entry";
175 else if (error == -ESTALE)
176 *info = "Failed name lookup - disconnected path";
177 else if (error == -ENAMETOOLONG)
178 *info = "Failed name lookup - name too long";
179 else
180 *info = "Failed name lookup";
181 }
182
172 return error; 183 return error;
173} 184}
174 185
175/** 186/**
176 * aa_get_name - compute the pathname of a file 187 * aa_path_name - compute the pathname of a file
177 * @path: path the file (NOT NULL) 188 * @path: path the file (NOT NULL)
178 * @flags: flags controlling path name generation 189 * @flags: flags controlling path name generation
179 * @buffer: buffer that aa_get_name() allocated (NOT NULL) 190 * @buffer: buffer that aa_get_name() allocated (NOT NULL)
180 * @name: Returns - the generated path name if !error (NOT NULL) 191 * @name: Returns - the generated path name if !error (NOT NULL)
192 * @info: Returns - information on why the path lookup failed (MAYBE NULL)
181 * 193 *
182 * @name is a pointer to the beginning of the pathname (which usually differs 194 * @name is a pointer to the beginning of the pathname (which usually differs
183 * from the beginning of the buffer), or NULL. If there is an error @name 195 * from the beginning of the buffer), or NULL. If there is an error @name
@@ -190,7 +202,8 @@ static int get_name_to_buffer(struct path *path, int flags, char *buffer,
190 * 202 *
191 * Returns: %0 else error code if could retrieve name 203 * Returns: %0 else error code if could retrieve name
192 */ 204 */
193int aa_get_name(struct path *path, int flags, char **buffer, const char **name) 205int aa_path_name(struct path *path, int flags, char **buffer, const char **name,
206 const char **info)
194{ 207{
195 char *buf, *str = NULL; 208 char *buf, *str = NULL;
196 int size = 256; 209 int size = 256;
@@ -204,7 +217,7 @@ int aa_get_name(struct path *path, int flags, char **buffer, const char **name)
204 if (!buf) 217 if (!buf)
205 return -ENOMEM; 218 return -ENOMEM;
206 219
207 error = get_name_to_buffer(path, flags, buf, size, &str); 220 error = get_name_to_buffer(path, flags, buf, size, &str, info);
208 if (error != -ENAMETOOLONG) 221 if (error != -ENAMETOOLONG)
209 break; 222 break;
210 223
@@ -212,6 +225,7 @@ int aa_get_name(struct path *path, int flags, char **buffer, const char **name)
212 size <<= 1; 225 size <<= 1;
213 if (size > aa_g_path_max) 226 if (size > aa_g_path_max)
214 return -ENAMETOOLONG; 227 return -ENAMETOOLONG;
228 *info = NULL;
215 } 229 }
216 *buffer = buf; 230 *buffer = buf;
217 *name = str; 231 *name = str;