Skip to content

Commit

Permalink
AppArmor: Move path failure information into aa_get_name and rename
Browse files Browse the repository at this point in the history
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 <[email protected]>
Acked-by: Kees Cook <[email protected]>
  • Loading branch information
John Johansen committed Mar 14, 2012
1 parent 0fe1212 commit 57fa1e1
Show file tree
Hide file tree
Showing 4 changed files with 29 additions and 19 deletions.
5 changes: 2 additions & 3 deletions security/apparmor/domain.c
Original file line number Diff line number Diff line change
Expand Up @@ -372,13 +372,12 @@ int apparmor_bprm_set_creds(struct linux_binprm *bprm)
state = profile->file.start;

/* buffer freed below, name is pointer into buffer */
error = aa_get_name(&bprm->file->f_path, profile->path_flags, &buffer,
&name);
error = aa_path_name(&bprm->file->f_path, profile->path_flags, &buffer,
&name, &info);
if (error) {
if (profile->flags &
(PFLAG_IX_ON_NAME_ERROR | PFLAG_UNCONFINED))
error = 0;
info = "Exec failed name resolution";
name = bprm->filename;
goto audit;
}
Expand Down
18 changes: 7 additions & 11 deletions security/apparmor/file.c
Original file line number Diff line number Diff line change
Expand Up @@ -278,22 +278,16 @@ int aa_path_perm(int op, struct aa_profile *profile, struct path *path,
int error;

flags |= profile->path_flags | (S_ISDIR(cond->mode) ? PATH_IS_DIR : 0);
error = aa_get_name(path, flags, &buffer, &name);
error = aa_path_name(path, flags, &buffer, &name, &info);
if (error) {
if (error == -ENOENT && is_deleted(path->dentry)) {
/* Access to open files that are deleted are
* give a pass (implicit delegation)
*/
error = 0;
info = NULL;
perms.allow = request;
} else if (error == -ENOENT)
info = "Failed name lookup - deleted entry";
else if (error == -ESTALE)
info = "Failed name lookup - disconnected path";
else if (error == -ENAMETOOLONG)
info = "Failed name lookup - name too long";
else
info = "Failed name lookup";
}
} else {
aa_str_perms(profile->file.dfa, profile->file.start, name, cond,
&perms);
Expand Down Expand Up @@ -364,12 +358,14 @@ int aa_path_link(struct aa_profile *profile, struct dentry *old_dentry,
lperms = nullperms;

/* buffer freed below, lname is pointer in buffer */
error = aa_get_name(&link, profile->path_flags, &buffer, &lname);
error = aa_path_name(&link, profile->path_flags, &buffer, &lname,
&info);
if (error)
goto audit;

/* buffer2 freed below, tname is pointer in buffer2 */
error = aa_get_name(&target, profile->path_flags, &buffer2, &tname);
error = aa_path_name(&target, profile->path_flags, &buffer2, &tname,
&info);
if (error)
goto audit;

Expand Down
3 changes: 2 additions & 1 deletion security/apparmor/include/path.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ enum path_flags {
PATH_MEDIATE_DELETED = 0x10000, /* mediate deleted paths */
};

int aa_get_name(struct path *path, int flags, char **buffer, const char **name);
int aa_path_name(struct path *path, int flags, char **buffer,
const char **name, const char **info);

#endif /* __AA_PATH_H */
22 changes: 18 additions & 4 deletions security/apparmor/path.c
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@ static int d_namespace_path(struct path *path, char *buf, int buflen,
* Returns: %0 else error on failure
*/
static int get_name_to_buffer(struct path *path, int flags, char *buffer,
int size, char **name)
int size, char **name, const char **info)
{
int adjust = (flags & PATH_IS_DIR) ? 1 : 0;
int error = d_namespace_path(path, buffer, size - adjust, name, flags);
Expand All @@ -169,15 +169,27 @@ static int get_name_to_buffer(struct path *path, int flags, char *buffer,
*/
strcpy(&buffer[size - 2], "/");

if (info && error) {
if (error == -ENOENT)
*info = "Failed name lookup - deleted entry";
else if (error == -ESTALE)
*info = "Failed name lookup - disconnected path";
else if (error == -ENAMETOOLONG)
*info = "Failed name lookup - name too long";
else
*info = "Failed name lookup";
}

return error;
}

/**
* aa_get_name - compute the pathname of a file
* aa_path_name - compute the pathname of a file
* @path: path the file (NOT NULL)
* @flags: flags controlling path name generation
* @buffer: buffer that aa_get_name() allocated (NOT NULL)
* @name: Returns - the generated path name if !error (NOT NULL)
* @info: Returns - information on why the path lookup failed (MAYBE NULL)
*
* @name is a pointer to the beginning of the pathname (which usually differs
* from the beginning of the buffer), or NULL. If there is an error @name
Expand All @@ -190,7 +202,8 @@ static int get_name_to_buffer(struct path *path, int flags, char *buffer,
*
* Returns: %0 else error code if could retrieve name
*/
int aa_get_name(struct path *path, int flags, char **buffer, const char **name)
int aa_path_name(struct path *path, int flags, char **buffer, const char **name,
const char **info)
{
char *buf, *str = NULL;
int size = 256;
Expand All @@ -204,14 +217,15 @@ int aa_get_name(struct path *path, int flags, char **buffer, const char **name)
if (!buf)
return -ENOMEM;

error = get_name_to_buffer(path, flags, buf, size, &str);
error = get_name_to_buffer(path, flags, buf, size, &str, info);
if (error != -ENAMETOOLONG)
break;

kfree(buf);
size <<= 1;
if (size > aa_g_path_max)
return -ENAMETOOLONG;
*info = NULL;
}
*buffer = buf;
*name = str;
Expand Down

0 comments on commit 57fa1e1

Please sign in to comment.