forked from Minki/linux
TOMOYO: Use callback for permission check.
We can use callback function since parameters are passed via "const struct tomoyo_request_info". Signed-off-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp> Signed-off-by: James Morris <jmorris@namei.org>
This commit is contained in:
parent
cf6e9a6468
commit
99a852596b
@ -952,6 +952,9 @@ int tomoyo_update_policy(struct tomoyo_acl_head *new_entry, const int size,
|
||||
*,
|
||||
const struct tomoyo_acl_head
|
||||
*));
|
||||
void tomoyo_check_acl(struct tomoyo_request_info *r,
|
||||
bool (*check_entry) (const struct tomoyo_request_info *,
|
||||
const struct tomoyo_acl_info *));
|
||||
|
||||
/********** External variable definitions. **********/
|
||||
|
||||
|
@ -109,6 +109,24 @@ int tomoyo_update_domain(struct tomoyo_acl_info *new_entry, const int size,
|
||||
return error;
|
||||
}
|
||||
|
||||
void tomoyo_check_acl(struct tomoyo_request_info *r,
|
||||
bool (*check_entry) (const struct tomoyo_request_info *,
|
||||
const struct tomoyo_acl_info *))
|
||||
{
|
||||
const struct tomoyo_domain_info *domain = r->domain;
|
||||
struct tomoyo_acl_info *ptr;
|
||||
|
||||
list_for_each_entry_rcu(ptr, &domain->acl_info_list, list) {
|
||||
if (ptr->is_deleted || ptr->type != r->param_type)
|
||||
continue;
|
||||
if (check_entry(r, ptr)) {
|
||||
r->granted = true;
|
||||
return;
|
||||
}
|
||||
}
|
||||
r->granted = false;
|
||||
}
|
||||
|
||||
/*
|
||||
* tomoyo_domain_list is used for holding list of domains.
|
||||
* The ->acl_info_list of "struct tomoyo_domain_info" is used for holding
|
||||
|
@ -218,6 +218,108 @@ static bool tomoyo_get_realpath(struct tomoyo_path_info *buf, struct path *path)
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* tomoyo_audit_path_log - Audit path request log.
|
||||
*
|
||||
* @r: Pointer to "struct tomoyo_request_info".
|
||||
*
|
||||
* Returns 0 on success, negative value otherwise.
|
||||
*/
|
||||
static int tomoyo_audit_path_log(struct tomoyo_request_info *r)
|
||||
{
|
||||
const char *operation = tomoyo_path_keyword[r->param.path.operation];
|
||||
const struct tomoyo_path_info *filename = r->param.path.filename;
|
||||
if (r->granted)
|
||||
return 0;
|
||||
tomoyo_warn_log(r, "%s %s", operation, filename->name);
|
||||
return tomoyo_supervisor(r, "allow_%s %s\n", operation,
|
||||
tomoyo_file_pattern(filename));
|
||||
}
|
||||
|
||||
/**
|
||||
* tomoyo_audit_path2_log - Audit path/path request log.
|
||||
*
|
||||
* @r: Pointer to "struct tomoyo_request_info".
|
||||
*
|
||||
* Returns 0 on success, negative value otherwise.
|
||||
*/
|
||||
static int tomoyo_audit_path2_log(struct tomoyo_request_info *r)
|
||||
{
|
||||
const char *operation = tomoyo_path2_keyword[r->param.path2.operation];
|
||||
const struct tomoyo_path_info *filename1 = r->param.path2.filename1;
|
||||
const struct tomoyo_path_info *filename2 = r->param.path2.filename2;
|
||||
if (r->granted)
|
||||
return 0;
|
||||
tomoyo_warn_log(r, "%s %s %s", operation, filename1->name,
|
||||
filename2->name);
|
||||
return tomoyo_supervisor(r, "allow_%s %s %s\n", operation,
|
||||
tomoyo_file_pattern(filename1),
|
||||
tomoyo_file_pattern(filename2));
|
||||
}
|
||||
|
||||
/**
|
||||
* tomoyo_audit_mkdev_log - Audit path/number/number/number request log.
|
||||
*
|
||||
* @r: Pointer to "struct tomoyo_request_info".
|
||||
*
|
||||
* Returns 0 on success, negative value otherwise.
|
||||
*/
|
||||
static int tomoyo_audit_mkdev_log(struct tomoyo_request_info *r)
|
||||
{
|
||||
const char *operation = tomoyo_path_number32keyword(r->param.mkdev.
|
||||
operation);
|
||||
const struct tomoyo_path_info *filename = r->param.mkdev.filename;
|
||||
const unsigned int major = r->param.mkdev.major;
|
||||
const unsigned int minor = r->param.mkdev.minor;
|
||||
const unsigned int mode = r->param.mkdev.mode;
|
||||
if (r->granted)
|
||||
return 0;
|
||||
tomoyo_warn_log(r, "%s %s 0%o %u %u", operation, filename->name, mode,
|
||||
major, minor);
|
||||
return tomoyo_supervisor(r, "allow_%s %s 0%o %u %u\n", operation,
|
||||
tomoyo_file_pattern(filename), mode, major,
|
||||
minor);
|
||||
}
|
||||
|
||||
/**
|
||||
* tomoyo_audit_path_number_log - Audit path/number request log.
|
||||
*
|
||||
* @r: Pointer to "struct tomoyo_request_info".
|
||||
* @error: Error code.
|
||||
*
|
||||
* Returns 0 on success, negative value otherwise.
|
||||
*/
|
||||
static int tomoyo_audit_path_number_log(struct tomoyo_request_info *r)
|
||||
{
|
||||
const u8 type = r->param.path_number.operation;
|
||||
u8 radix;
|
||||
const struct tomoyo_path_info *filename = r->param.path_number.filename;
|
||||
const char *operation = tomoyo_path_number_keyword[type];
|
||||
char buffer[64];
|
||||
if (r->granted)
|
||||
return 0;
|
||||
switch (type) {
|
||||
case TOMOYO_TYPE_CREATE:
|
||||
case TOMOYO_TYPE_MKDIR:
|
||||
case TOMOYO_TYPE_MKFIFO:
|
||||
case TOMOYO_TYPE_MKSOCK:
|
||||
case TOMOYO_TYPE_CHMOD:
|
||||
radix = TOMOYO_VALUE_TYPE_OCTAL;
|
||||
break;
|
||||
case TOMOYO_TYPE_IOCTL:
|
||||
radix = TOMOYO_VALUE_TYPE_HEXADECIMAL;
|
||||
break;
|
||||
default:
|
||||
radix = TOMOYO_VALUE_TYPE_DECIMAL;
|
||||
break;
|
||||
}
|
||||
tomoyo_print_ulong(buffer, sizeof(buffer), r->param.path_number.number,
|
||||
radix);
|
||||
tomoyo_warn_log(r, "%s %s %s", operation, filename->name, buffer);
|
||||
return tomoyo_supervisor(r, "allow_%s %s %s\n", operation,
|
||||
tomoyo_file_pattern(filename), buffer);
|
||||
}
|
||||
|
||||
static int tomoyo_update_path2_acl(const u8 type, const char *filename1,
|
||||
const char *filename2,
|
||||
struct tomoyo_domain_info *const domain,
|
||||
@ -637,37 +739,52 @@ bool tomoyo_read_no_rewrite_policy(struct tomoyo_io_buffer *head)
|
||||
return done;
|
||||
}
|
||||
|
||||
/**
|
||||
* tomoyo_path_acl - Check permission for single path operation.
|
||||
*
|
||||
* @r: Pointer to "struct tomoyo_request_info".
|
||||
* @filename: Filename to check.
|
||||
* @perm: Permission.
|
||||
*
|
||||
* Returns 0 on success, -EPERM otherwise.
|
||||
*
|
||||
* Caller holds tomoyo_read_lock().
|
||||
*/
|
||||
static int tomoyo_path_acl(const struct tomoyo_request_info *r,
|
||||
const struct tomoyo_path_info *filename,
|
||||
const u32 perm)
|
||||
static bool tomoyo_check_path_acl(const struct tomoyo_request_info *r,
|
||||
const struct tomoyo_acl_info *ptr)
|
||||
{
|
||||
struct tomoyo_domain_info *domain = r->domain;
|
||||
struct tomoyo_acl_info *ptr;
|
||||
int error = -EPERM;
|
||||
const struct tomoyo_path_acl *acl = container_of(ptr, typeof(*acl),
|
||||
head);
|
||||
return (acl->perm & (1 << r->param.path.operation)) &&
|
||||
tomoyo_compare_name_union(r->param.path.filename, &acl->name);
|
||||
}
|
||||
|
||||
list_for_each_entry_rcu(ptr, &domain->acl_info_list, list) {
|
||||
struct tomoyo_path_acl *acl;
|
||||
if (ptr->type != TOMOYO_TYPE_PATH_ACL)
|
||||
continue;
|
||||
acl = container_of(ptr, struct tomoyo_path_acl, head);
|
||||
if (!(acl->perm & perm) ||
|
||||
!tomoyo_compare_name_union(filename, &acl->name))
|
||||
continue;
|
||||
error = 0;
|
||||
break;
|
||||
}
|
||||
return error;
|
||||
static bool tomoyo_check_path_number_acl(const struct tomoyo_request_info *r,
|
||||
const struct tomoyo_acl_info *ptr)
|
||||
{
|
||||
const struct tomoyo_path_number_acl *acl =
|
||||
container_of(ptr, typeof(*acl), head);
|
||||
return (acl->perm & (1 << r->param.path_number.operation)) &&
|
||||
tomoyo_compare_number_union(r->param.path_number.number,
|
||||
&acl->number) &&
|
||||
tomoyo_compare_name_union(r->param.path_number.filename,
|
||||
&acl->name);
|
||||
}
|
||||
|
||||
static bool tomoyo_check_path2_acl(const struct tomoyo_request_info *r,
|
||||
const struct tomoyo_acl_info *ptr)
|
||||
{
|
||||
const struct tomoyo_path2_acl *acl =
|
||||
container_of(ptr, typeof(*acl), head);
|
||||
return (acl->perm & (1 << r->param.path2.operation)) &&
|
||||
tomoyo_compare_name_union(r->param.path2.filename1, &acl->name1)
|
||||
&& tomoyo_compare_name_union(r->param.path2.filename2,
|
||||
&acl->name2);
|
||||
}
|
||||
|
||||
static bool tomoyo_check_mkdev_acl(const struct tomoyo_request_info *r,
|
||||
const struct tomoyo_acl_info *ptr)
|
||||
{
|
||||
const struct tomoyo_path_number3_acl *acl =
|
||||
container_of(ptr, typeof(*acl), head);
|
||||
return (acl->perm & (1 << r->param.mkdev.operation)) &&
|
||||
tomoyo_compare_number_union(r->param.mkdev.mode,
|
||||
&acl->mode) &&
|
||||
tomoyo_compare_number_union(r->param.mkdev.major,
|
||||
&acl->major) &&
|
||||
tomoyo_compare_number_union(r->param.mkdev.minor,
|
||||
&acl->minor) &&
|
||||
tomoyo_compare_name_union(r->param.mkdev.filename,
|
||||
&acl->name);
|
||||
}
|
||||
|
||||
static bool tomoyo_same_path_acl(const struct tomoyo_acl_info *a,
|
||||
@ -869,88 +986,6 @@ static int tomoyo_update_path2_acl(const u8 type, const char *filename1,
|
||||
return error;
|
||||
}
|
||||
|
||||
/**
|
||||
* tomoyo_path_number3_acl - Check permission for path/number/number/number operation.
|
||||
*
|
||||
* @r: Pointer to "struct tomoyo_request_info".
|
||||
* @filename: Filename to check.
|
||||
* @perm: Permission.
|
||||
* @mode: Create mode.
|
||||
* @major: Device major number.
|
||||
* @minor: Device minor number.
|
||||
*
|
||||
* Returns 0 on success, -EPERM otherwise.
|
||||
*
|
||||
* Caller holds tomoyo_read_lock().
|
||||
*/
|
||||
static int tomoyo_path_number3_acl(struct tomoyo_request_info *r,
|
||||
const struct tomoyo_path_info *filename,
|
||||
const u16 perm, const unsigned int mode,
|
||||
const unsigned int major,
|
||||
const unsigned int minor)
|
||||
{
|
||||
struct tomoyo_domain_info *domain = r->domain;
|
||||
struct tomoyo_acl_info *ptr;
|
||||
int error = -EPERM;
|
||||
list_for_each_entry_rcu(ptr, &domain->acl_info_list, list) {
|
||||
struct tomoyo_path_number3_acl *acl;
|
||||
if (ptr->type != TOMOYO_TYPE_PATH_NUMBER3_ACL)
|
||||
continue;
|
||||
acl = container_of(ptr, struct tomoyo_path_number3_acl, head);
|
||||
if (!tomoyo_compare_number_union(mode, &acl->mode))
|
||||
continue;
|
||||
if (!tomoyo_compare_number_union(major, &acl->major))
|
||||
continue;
|
||||
if (!tomoyo_compare_number_union(minor, &acl->minor))
|
||||
continue;
|
||||
if (!(acl->perm & perm))
|
||||
continue;
|
||||
if (!tomoyo_compare_name_union(filename, &acl->name))
|
||||
continue;
|
||||
error = 0;
|
||||
break;
|
||||
}
|
||||
return error;
|
||||
}
|
||||
|
||||
/**
|
||||
* tomoyo_path2_acl - Check permission for double path operation.
|
||||
*
|
||||
* @r: Pointer to "struct tomoyo_request_info".
|
||||
* @type: Type of operation.
|
||||
* @filename1: First filename to check.
|
||||
* @filename2: Second filename to check.
|
||||
*
|
||||
* Returns 0 on success, -EPERM otherwise.
|
||||
*
|
||||
* Caller holds tomoyo_read_lock().
|
||||
*/
|
||||
static int tomoyo_path2_acl(const struct tomoyo_request_info *r, const u8 type,
|
||||
const struct tomoyo_path_info *filename1,
|
||||
const struct tomoyo_path_info *filename2)
|
||||
{
|
||||
const struct tomoyo_domain_info *domain = r->domain;
|
||||
struct tomoyo_acl_info *ptr;
|
||||
const u8 perm = 1 << type;
|
||||
int error = -EPERM;
|
||||
|
||||
list_for_each_entry_rcu(ptr, &domain->acl_info_list, list) {
|
||||
struct tomoyo_path2_acl *acl;
|
||||
if (ptr->type != TOMOYO_TYPE_PATH2_ACL)
|
||||
continue;
|
||||
acl = container_of(ptr, struct tomoyo_path2_acl, head);
|
||||
if (!(acl->perm & perm))
|
||||
continue;
|
||||
if (!tomoyo_compare_name_union(filename1, &acl->name1))
|
||||
continue;
|
||||
if (!tomoyo_compare_name_union(filename2, &acl->name2))
|
||||
continue;
|
||||
error = 0;
|
||||
break;
|
||||
}
|
||||
return error;
|
||||
}
|
||||
|
||||
/**
|
||||
* tomoyo_path_permission - Check permission for single path operation.
|
||||
*
|
||||
@ -965,7 +1000,6 @@ static int tomoyo_path2_acl(const struct tomoyo_request_info *r, const u8 type,
|
||||
int tomoyo_path_permission(struct tomoyo_request_info *r, u8 operation,
|
||||
const struct tomoyo_path_info *filename)
|
||||
{
|
||||
const char *msg;
|
||||
int error;
|
||||
|
||||
next:
|
||||
@ -977,17 +1011,12 @@ int tomoyo_path_permission(struct tomoyo_request_info *r, u8 operation,
|
||||
r->param.path.filename = filename;
|
||||
r->param.path.operation = operation;
|
||||
do {
|
||||
error = tomoyo_path_acl(r, filename, 1 << operation);
|
||||
if (error && operation == TOMOYO_TYPE_READ &&
|
||||
tomoyo_check_acl(r, tomoyo_check_path_acl);
|
||||
if (!r->granted && operation == TOMOYO_TYPE_READ &&
|
||||
!r->domain->ignore_global_allow_read &&
|
||||
tomoyo_is_globally_readable_file(filename))
|
||||
error = 0;
|
||||
if (!error)
|
||||
break;
|
||||
msg = tomoyo_path2keyword(operation);
|
||||
tomoyo_warn_log(r, "%s %s", msg, filename->name);
|
||||
error = tomoyo_supervisor(r, "allow_%s %s\n", msg,
|
||||
tomoyo_file_pattern(filename));
|
||||
r->granted = true;
|
||||
error = tomoyo_audit_path_log(r);
|
||||
/*
|
||||
* Do not retry for execute request, for alias may have
|
||||
* changed.
|
||||
@ -1007,42 +1036,6 @@ int tomoyo_path_permission(struct tomoyo_request_info *r, u8 operation,
|
||||
return error;
|
||||
}
|
||||
|
||||
/**
|
||||
* tomoyo_path_number_acl - Check permission for ioctl/chmod/chown/chgrp operation.
|
||||
*
|
||||
* @r: Pointer to "struct tomoyo_request_info".
|
||||
* @type: Operation.
|
||||
* @filename: Filename to check.
|
||||
* @number: Number.
|
||||
*
|
||||
* Returns 0 on success, -EPERM otherwise.
|
||||
*
|
||||
* Caller holds tomoyo_read_lock().
|
||||
*/
|
||||
static int tomoyo_path_number_acl(struct tomoyo_request_info *r, const u8 type,
|
||||
const struct tomoyo_path_info *filename,
|
||||
const unsigned long number)
|
||||
{
|
||||
struct tomoyo_domain_info *domain = r->domain;
|
||||
struct tomoyo_acl_info *ptr;
|
||||
const u8 perm = 1 << type;
|
||||
int error = -EPERM;
|
||||
list_for_each_entry_rcu(ptr, &domain->acl_info_list, list) {
|
||||
struct tomoyo_path_number_acl *acl;
|
||||
if (ptr->type != TOMOYO_TYPE_PATH_NUMBER_ACL)
|
||||
continue;
|
||||
acl = container_of(ptr, struct tomoyo_path_number_acl,
|
||||
head);
|
||||
if (!(acl->perm & perm) ||
|
||||
!tomoyo_compare_number_union(number, &acl->number) ||
|
||||
!tomoyo_compare_name_union(filename, &acl->name))
|
||||
continue;
|
||||
error = 0;
|
||||
break;
|
||||
}
|
||||
return error;
|
||||
}
|
||||
|
||||
static bool tomoyo_same_path_number_acl(const struct tomoyo_acl_info *a,
|
||||
const struct tomoyo_acl_info *b)
|
||||
{
|
||||
@ -1123,42 +1116,17 @@ static int tomoyo_path_number_perm2(struct tomoyo_request_info *r,
|
||||
const struct tomoyo_path_info *filename,
|
||||
const unsigned long number)
|
||||
{
|
||||
char buffer[64];
|
||||
int error;
|
||||
u8 radix;
|
||||
const char *msg;
|
||||
|
||||
if (!filename)
|
||||
return 0;
|
||||
switch (type) {
|
||||
case TOMOYO_TYPE_CREATE:
|
||||
case TOMOYO_TYPE_MKDIR:
|
||||
case TOMOYO_TYPE_MKFIFO:
|
||||
case TOMOYO_TYPE_MKSOCK:
|
||||
case TOMOYO_TYPE_CHMOD:
|
||||
radix = TOMOYO_VALUE_TYPE_OCTAL;
|
||||
break;
|
||||
case TOMOYO_TYPE_IOCTL:
|
||||
radix = TOMOYO_VALUE_TYPE_HEXADECIMAL;
|
||||
break;
|
||||
default:
|
||||
radix = TOMOYO_VALUE_TYPE_DECIMAL;
|
||||
break;
|
||||
}
|
||||
tomoyo_print_ulong(buffer, sizeof(buffer), number, radix);
|
||||
r->param_type = TOMOYO_TYPE_PATH_NUMBER_ACL;
|
||||
r->param.path_number.operation = type;
|
||||
r->param.path_number.filename = filename;
|
||||
r->param.path_number.number = number;
|
||||
do {
|
||||
error = tomoyo_path_number_acl(r, type, filename, number);
|
||||
if (!error)
|
||||
break;
|
||||
msg = tomoyo_path_number2keyword(type);
|
||||
tomoyo_warn_log(r, "%s %s %s", msg, filename->name, buffer);
|
||||
error = tomoyo_supervisor(r, "allow_%s %s %s\n", msg,
|
||||
tomoyo_file_pattern(filename),
|
||||
buffer);
|
||||
tomoyo_check_acl(r, tomoyo_check_path_number_acl);
|
||||
error = tomoyo_audit_path_number_log(r);
|
||||
} while (error == TOMOYO_RETRY_REQUEST);
|
||||
return error;
|
||||
}
|
||||
@ -1310,47 +1278,6 @@ int tomoyo_path_perm(const u8 operation, struct path *path)
|
||||
return error;
|
||||
}
|
||||
|
||||
/**
|
||||
* tomoyo_path_number3_perm2 - Check permission for path/number/number/number operation.
|
||||
*
|
||||
* @r: Pointer to "struct tomoyo_request_info".
|
||||
* @operation: Type of operation.
|
||||
* @filename: Filename to check.
|
||||
* @mode: Create mode.
|
||||
* @dev: Device number.
|
||||
*
|
||||
* Returns 0 on success, negative value otherwise.
|
||||
*
|
||||
* Caller holds tomoyo_read_lock().
|
||||
*/
|
||||
static int tomoyo_path_number3_perm2(struct tomoyo_request_info *r,
|
||||
const u8 operation,
|
||||
const struct tomoyo_path_info *filename,
|
||||
const unsigned int mode,
|
||||
const unsigned int dev)
|
||||
{
|
||||
int error;
|
||||
const char *msg;
|
||||
const unsigned int major = MAJOR(dev);
|
||||
const unsigned int minor = MINOR(dev);
|
||||
|
||||
do {
|
||||
error = tomoyo_path_number3_acl(r, filename, 1 << operation,
|
||||
mode, major, minor);
|
||||
if (!error)
|
||||
break;
|
||||
msg = tomoyo_path_number32keyword(operation);
|
||||
tomoyo_warn_log(r, "%s %s 0%o %u %u", msg, filename->name,
|
||||
mode, major, minor);
|
||||
error = tomoyo_supervisor(r, "allow_%s %s 0%o %u %u\n", msg,
|
||||
tomoyo_file_pattern(filename), mode,
|
||||
major, minor);
|
||||
} while (error == TOMOYO_RETRY_REQUEST);
|
||||
if (r->mode != TOMOYO_CONFIG_ENFORCING)
|
||||
error = 0;
|
||||
return error;
|
||||
}
|
||||
|
||||
/**
|
||||
* tomoyo_path_number3_perm - Check permission for "mkblock" and "mkchar".
|
||||
*
|
||||
@ -1383,8 +1310,8 @@ int tomoyo_path_number3_perm(const u8 operation, struct path *path,
|
||||
r.param.mkdev.mode = mode;
|
||||
r.param.mkdev.major = MAJOR(dev);
|
||||
r.param.mkdev.minor = MINOR(dev);
|
||||
error = tomoyo_path_number3_perm2(&r, operation, &buf, mode,
|
||||
dev);
|
||||
tomoyo_check_acl(&r, tomoyo_check_mkdev_acl);
|
||||
error = tomoyo_audit_mkdev_log(&r);
|
||||
kfree(buf.name);
|
||||
}
|
||||
tomoyo_read_unlock(idx);
|
||||
@ -1406,7 +1333,6 @@ int tomoyo_path2_perm(const u8 operation, struct path *path1,
|
||||
struct path *path2)
|
||||
{
|
||||
int error = -ENOMEM;
|
||||
const char *msg;
|
||||
struct tomoyo_path_info buf1;
|
||||
struct tomoyo_path_info buf2;
|
||||
struct tomoyo_request_info r;
|
||||
@ -1440,15 +1366,9 @@ int tomoyo_path2_perm(const u8 operation, struct path *path1,
|
||||
r.param.path2.filename1 = &buf1;
|
||||
r.param.path2.filename2 = &buf2;
|
||||
do {
|
||||
error = tomoyo_path2_acl(&r, operation, &buf1, &buf2);
|
||||
if (!error)
|
||||
break;
|
||||
msg = tomoyo_path22keyword(operation);
|
||||
tomoyo_warn_log(&r, "%s %s %s", msg, buf1.name, buf2.name);
|
||||
error = tomoyo_supervisor(&r, "allow_%s %s %s\n", msg,
|
||||
tomoyo_file_pattern(&buf1),
|
||||
tomoyo_file_pattern(&buf2));
|
||||
} while (error == TOMOYO_RETRY_REQUEST);
|
||||
tomoyo_check_acl(&r, tomoyo_check_path2_acl);
|
||||
error = tomoyo_audit_path2_log(&r);
|
||||
} while (error == TOMOYO_RETRY_REQUEST);
|
||||
out:
|
||||
kfree(buf1.name);
|
||||
kfree(buf2.name);
|
||||
|
@ -24,6 +24,54 @@
|
||||
/* Allow to call 'mount --make-shared /dir' */
|
||||
#define TOMOYO_MOUNT_MAKE_SHARED_KEYWORD "--make-shared"
|
||||
|
||||
/**
|
||||
* tomoyo_audit_mount_log - Audit mount log.
|
||||
*
|
||||
* @r: Pointer to "struct tomoyo_request_info".
|
||||
*
|
||||
* Returns 0 on success, negative value otherwise.
|
||||
*/
|
||||
static int tomoyo_audit_mount_log(struct tomoyo_request_info *r)
|
||||
{
|
||||
const char *dev = r->param.mount.dev->name;
|
||||
const char *dir = r->param.mount.dir->name;
|
||||
const char *type = r->param.mount.type->name;
|
||||
const unsigned long flags = r->param.mount.flags;
|
||||
if (r->granted)
|
||||
return 0;
|
||||
if (!strcmp(type, TOMOYO_MOUNT_REMOUNT_KEYWORD))
|
||||
tomoyo_warn_log(r, "mount -o remount %s 0x%lX", dir, flags);
|
||||
else if (!strcmp(type, TOMOYO_MOUNT_BIND_KEYWORD)
|
||||
|| !strcmp(type, TOMOYO_MOUNT_MOVE_KEYWORD))
|
||||
tomoyo_warn_log(r, "mount %s %s %s 0x%lX", type, dev, dir,
|
||||
flags);
|
||||
else if (!strcmp(type, TOMOYO_MOUNT_MAKE_UNBINDABLE_KEYWORD) ||
|
||||
!strcmp(type, TOMOYO_MOUNT_MAKE_PRIVATE_KEYWORD) ||
|
||||
!strcmp(type, TOMOYO_MOUNT_MAKE_SLAVE_KEYWORD) ||
|
||||
!strcmp(type, TOMOYO_MOUNT_MAKE_SHARED_KEYWORD))
|
||||
tomoyo_warn_log(r, "mount %s %s 0x%lX", type, dir, flags);
|
||||
else
|
||||
tomoyo_warn_log(r, "mount -t %s %s %s 0x%lX", type, dev, dir,
|
||||
flags);
|
||||
return tomoyo_supervisor(r,
|
||||
TOMOYO_KEYWORD_ALLOW_MOUNT "%s %s %s 0x%lX\n",
|
||||
tomoyo_file_pattern(r->param.mount.dev),
|
||||
tomoyo_file_pattern(r->param.mount.dir), type,
|
||||
flags);
|
||||
}
|
||||
|
||||
static bool tomoyo_check_mount_acl(const struct tomoyo_request_info *r,
|
||||
const struct tomoyo_acl_info *ptr)
|
||||
{
|
||||
const struct tomoyo_mount_acl *acl =
|
||||
container_of(ptr, typeof(*acl), head);
|
||||
return tomoyo_compare_number_union(r->param.mount.flags, &acl->flags) &&
|
||||
tomoyo_compare_name_union(r->param.mount.type, &acl->fs_type) &&
|
||||
tomoyo_compare_name_union(r->param.mount.dir, &acl->dir_name) &&
|
||||
(!r->param.mount.need_dev ||
|
||||
tomoyo_compare_name_union(r->param.mount.dev, &acl->dev_name));
|
||||
}
|
||||
|
||||
/**
|
||||
* tomoyo_mount_acl2 - Check permission for mount() operation.
|
||||
*
|
||||
@ -41,7 +89,6 @@ static int tomoyo_mount_acl2(struct tomoyo_request_info *r, char *dev_name,
|
||||
struct path *dir, char *type, unsigned long flags)
|
||||
{
|
||||
struct path path;
|
||||
struct tomoyo_acl_info *ptr;
|
||||
struct file_system_type *fstype = NULL;
|
||||
const char *requested_type = NULL;
|
||||
const char *requested_dir_name = NULL;
|
||||
@ -118,26 +165,10 @@ static int tomoyo_mount_acl2(struct tomoyo_request_info *r, char *dev_name,
|
||||
r->param.mount.dir = &rdir;
|
||||
r->param.mount.type = &rtype;
|
||||
r->param.mount.flags = flags;
|
||||
list_for_each_entry_rcu(ptr, &r->domain->acl_info_list, list) {
|
||||
struct tomoyo_mount_acl *acl;
|
||||
if (ptr->is_deleted || ptr->type != TOMOYO_TYPE_MOUNT_ACL)
|
||||
continue;
|
||||
acl = container_of(ptr, struct tomoyo_mount_acl, head);
|
||||
if (!tomoyo_compare_number_union(flags, &acl->flags) ||
|
||||
!tomoyo_compare_name_union(&rtype, &acl->fs_type) ||
|
||||
!tomoyo_compare_name_union(&rdir, &acl->dir_name) ||
|
||||
(need_dev &&
|
||||
!tomoyo_compare_name_union(&rdev, &acl->dev_name)))
|
||||
continue;
|
||||
error = 0;
|
||||
break;
|
||||
}
|
||||
if (error)
|
||||
error = tomoyo_supervisor(r, TOMOYO_KEYWORD_ALLOW_MOUNT
|
||||
"%s %s %s 0x%lX\n",
|
||||
tomoyo_file_pattern(&rdev),
|
||||
tomoyo_file_pattern(&rdir),
|
||||
requested_type, flags);
|
||||
do {
|
||||
tomoyo_check_acl(r, tomoyo_check_mount_acl);
|
||||
error = tomoyo_audit_mount_log(r);
|
||||
} while (error == TOMOYO_RETRY_REQUEST);
|
||||
out:
|
||||
kfree(requested_dev_name);
|
||||
kfree(requested_dir_name);
|
||||
|
Loading…
Reference in New Issue
Block a user