struct aa_perms *perms)
{
int e = 0;
+
if (profile_unconfined(profile) ||
((flags & PATH_SOCK_COND) && !PROFILE_MEDIATES_AF(profile, AF_UNIX)))
return 0;
cond->uid, NULL, e);
}
+
+static int profile_path_perm(const char *op, struct aa_profile *profile,
+ const struct path *path, char *buffer, u32 request,
+ struct path_cond *cond, int flags,
+ struct aa_perms *perms)
+{
+ const char *name;
+ int error;
+
+ if (profile_unconfined(profile))
+ return 0;
+
+ error = path_name(op, &profile->label, path,
+ flags | profile->path_flags, buffer, &name, cond,
+ request);
+ if (error)
+ return error;
+ return __aa_path_perm(op, profile, name, request, cond, flags,
+ perms);
+}
+
/**
* aa_path_perm - do permissions check & audit for @path
* @op: operation being checked
struct path_cond *cond)
{
struct aa_perms perms = {};
- char *buffer = NULL;
- const char *name;
struct aa_profile *profile;
+ char *buffer = NULL;
int error;
- /* TODO: fix path lookup flags */
- flags |= labels_profile(label)->path_flags |
- (S_ISDIR(cond->mode) ? PATH_IS_DIR : 0);
+ flags |= PATH_DELEGATE_DELETED | (S_ISDIR(cond->mode) ? PATH_IS_DIR : 0);
get_buffers(buffer);
-
- error = path_name(op, label, path, flags | PATH_DELEGATE_DELETED,
- buffer, &name, cond, request);
- if (!error)
- error = fn_for_each_confined(label, profile,
- __aa_path_perm(op, profile, name, request, cond,
- flags, &perms));
+ error = fn_for_each_confined(label, profile,
+ profile_path_perm(op, profile, path, buffer, request,
+ cond, flags, &perms));
put_buffers(buffer);
return error;
return 1;
}
-static int profile_path_link(struct aa_profile *profile, const char *lname,
- const char *tname, struct path_cond *cond)
+static int profile_path_link(struct aa_profile *profile,
+ const struct path *link, char *buffer,
+ const struct path *target, char *buffer2,
+ struct path_cond *cond)
{
+ const char *lname, *tname = NULL;
struct aa_perms lperms, perms;
const char *info = NULL;
u32 request = AA_MAY_LINK;
unsigned int state;
- int e = -EACCES;
+ int error;
+ error = path_name(OP_LINK, &profile->label, link, profile->path_flags,
+ buffer, &lname, cond, AA_MAY_LINK);
+ if (error)
+ goto audit;
+
+ /* buffer2 freed below, tname is pointer in buffer2 */
+ error = path_name(OP_LINK, &profile->label, target, profile->path_flags,
+ buffer2, &tname, cond, AA_MAY_LINK);
+ if (error)
+ goto audit;
+
+ error = -EACCES;
/* aa_str_perms - handles the case of the dfa being NULL */
state = aa_str_perms(profile->file.dfa, profile->file.start, lname,
cond, &lperms);
}
done_tests:
- e = 0;
+ error = 0;
audit:
return aa_audit_file(profile, &lperms, OP_LINK, request, lname, tname,
- NULL, cond->uid, info, e);
+ NULL, cond->uid, info, error);
}
/**
d_backing_inode(old_dentry)->i_mode
};
char *buffer = NULL, *buffer2 = NULL;
- const char *lname, *tname = NULL;
struct aa_profile *profile;
int error;
- /* TODO: fix path lookup flags, auditing of failed path for profile */
- profile = labels_profile(label);
/* buffer freed below, lname is pointer in buffer */
get_buffers(buffer, buffer2);
- error = path_name(OP_LINK, label, &link,
- labels_profile(label)->path_flags, buffer,
- &lname, &cond, AA_MAY_LINK);
- if (error)
- goto out;
-
- /* buffer2 freed below, tname is pointer in buffer2 */
- error = path_name(OP_LINK, label, &target,
- labels_profile(label)->path_flags, buffer2, &tname,
- &cond, AA_MAY_LINK);
- if (error)
- goto out;
-
error = fn_for_each_confined(label, profile,
- profile_path_link(profile, lname, tname, &cond));
-
-out:
+ profile_path_link(profile, &link, buffer, &target,
+ buffer2, &cond));
put_buffers(buffer, buffer2);
return error;
.uid = file_inode(file)->i_uid,
.mode = file_inode(file)->i_mode
};
- const char *name;
char *buffer;
int flags, error;
/* TODO: check for revocation on stale profiles */
return 0;
- /* TODO: fix path lookup flags */
- flags = PATH_DELEGATE_DELETED | labels_profile(label)->path_flags |
- (S_ISDIR(cond.mode) ? PATH_IS_DIR : 0);
+ flags = PATH_DELEGATE_DELETED | (S_ISDIR(cond.mode) ? PATH_IS_DIR : 0);
get_buffers(buffer);
- error = path_name(op, label, &file->f_path,
- flags | PATH_DELEGATE_DELETED, buffer, &name, &cond,
- request);
-
/* check every profile in task label not in current cache */
error = fn_for_each_not_in_set(flabel, label, profile,
- __aa_path_perm(op, profile, name, request, &cond, 0,
- &perms));
+ profile_path_perm(op, profile, &file->f_path, buffer,
+ request, &cond, flags, &perms));
if (denied) {
/* check every profile in file label that was not tested
* in the initial check above.
/* TODO: don't audit here */
last_error(error,
fn_for_each_not_in_set(label, flabel, profile,
- __aa_path_perm(op, profile, name, request,
- &cond, 0, &perms)));
+ profile_path_perm(op, profile, &file->f_path,
+ buffer, request, &cond, flags,
+ &perms)));
}
if (!error)
update_file_ctx(file_ctx(file), label, request);