ima: add policy support for file system uuid
The IMA policy permits specifying rules to enable or disable measurement/appraisal/audit based on the file system magic number. If, for example, the policy contains an ext4 measurement rule, the rule is enabled for all ext4 partitions. Sometimes it might be necessary to enable measurement/appraisal/audit only for one partition and disable it for another partition of the same type. With the existing IMA policy syntax, this can not be done. This patch provides support for IMA policy rules to specify the file system by its UUID (eg. fsuuid=397449cd-687d-4145-8698-7fed4a3e0363). For partitions not being appraised, it might be a good idea to mount file systems with the 'noexec' option to prevent executing non-verified binaries. Signed-off-by: Dmitry Kasatkin <dmitry.kasatkin@intel.com> Signed-off-by: Mimi Zohar <zohar@linux.vnet.ibm.com>
This commit is contained in:
parent
74de668424
commit
85865c1fa1
|
@ -19,7 +19,8 @@ Description:
|
||||||
|
|
||||||
action: measure | dont_measure | appraise | dont_appraise | audit
|
action: measure | dont_measure | appraise | dont_appraise | audit
|
||||||
condition:= base | lsm [option]
|
condition:= base | lsm [option]
|
||||||
base: [[func=] [mask=] [fsmagic=] [uid=] [fowner]]
|
base: [[func=] [mask=] [fsmagic=] [fsuuid=] [uid=]
|
||||||
|
[fowner]]
|
||||||
lsm: [[subj_user=] [subj_role=] [subj_type=]
|
lsm: [[subj_user=] [subj_role=] [subj_type=]
|
||||||
[obj_user=] [obj_role=] [obj_type=]]
|
[obj_user=] [obj_role=] [obj_type=]]
|
||||||
option: [[appraise_type=]]
|
option: [[appraise_type=]]
|
||||||
|
@ -27,6 +28,7 @@ Description:
|
||||||
base: func:= [BPRM_CHECK][MMAP_CHECK][FILE_CHECK][MODULE_CHECK]
|
base: func:= [BPRM_CHECK][MMAP_CHECK][FILE_CHECK][MODULE_CHECK]
|
||||||
mask:= [MAY_READ] [MAY_WRITE] [MAY_APPEND] [MAY_EXEC]
|
mask:= [MAY_READ] [MAY_WRITE] [MAY_APPEND] [MAY_EXEC]
|
||||||
fsmagic:= hex value
|
fsmagic:= hex value
|
||||||
|
fsuuid:= file system UUID (e.g 8bcbe394-4f13-4144-be8e-5aa9ea2ce2f6)
|
||||||
uid:= decimal value
|
uid:= decimal value
|
||||||
fowner:=decimal value
|
fowner:=decimal value
|
||||||
lsm: are LSM specific
|
lsm: are LSM specific
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
#include <linux/magic.h>
|
#include <linux/magic.h>
|
||||||
#include <linux/parser.h>
|
#include <linux/parser.h>
|
||||||
#include <linux/slab.h>
|
#include <linux/slab.h>
|
||||||
|
#include <linux/genhd.h>
|
||||||
|
|
||||||
#include "ima.h"
|
#include "ima.h"
|
||||||
|
|
||||||
|
@ -25,6 +26,7 @@
|
||||||
#define IMA_FSMAGIC 0x0004
|
#define IMA_FSMAGIC 0x0004
|
||||||
#define IMA_UID 0x0008
|
#define IMA_UID 0x0008
|
||||||
#define IMA_FOWNER 0x0010
|
#define IMA_FOWNER 0x0010
|
||||||
|
#define IMA_FSUUID 0x0020
|
||||||
|
|
||||||
#define UNKNOWN 0
|
#define UNKNOWN 0
|
||||||
#define MEASURE 0x0001 /* same as IMA_MEASURE */
|
#define MEASURE 0x0001 /* same as IMA_MEASURE */
|
||||||
|
@ -45,6 +47,7 @@ struct ima_rule_entry {
|
||||||
enum ima_hooks func;
|
enum ima_hooks func;
|
||||||
int mask;
|
int mask;
|
||||||
unsigned long fsmagic;
|
unsigned long fsmagic;
|
||||||
|
u8 fsuuid[16];
|
||||||
kuid_t uid;
|
kuid_t uid;
|
||||||
kuid_t fowner;
|
kuid_t fowner;
|
||||||
struct {
|
struct {
|
||||||
|
@ -172,6 +175,9 @@ static bool ima_match_rules(struct ima_rule_entry *rule,
|
||||||
if ((rule->flags & IMA_FSMAGIC)
|
if ((rule->flags & IMA_FSMAGIC)
|
||||||
&& rule->fsmagic != inode->i_sb->s_magic)
|
&& rule->fsmagic != inode->i_sb->s_magic)
|
||||||
return false;
|
return false;
|
||||||
|
if ((rule->flags & IMA_FSUUID) &&
|
||||||
|
memcmp(rule->fsuuid, inode->i_sb->s_uuid, sizeof(rule->fsuuid)))
|
||||||
|
return false;
|
||||||
if ((rule->flags & IMA_UID) && !uid_eq(rule->uid, cred->uid))
|
if ((rule->flags & IMA_UID) && !uid_eq(rule->uid, cred->uid))
|
||||||
return false;
|
return false;
|
||||||
if ((rule->flags & IMA_FOWNER) && !uid_eq(rule->fowner, inode->i_uid))
|
if ((rule->flags & IMA_FOWNER) && !uid_eq(rule->fowner, inode->i_uid))
|
||||||
|
@ -346,7 +352,7 @@ enum {
|
||||||
Opt_obj_user, Opt_obj_role, Opt_obj_type,
|
Opt_obj_user, Opt_obj_role, Opt_obj_type,
|
||||||
Opt_subj_user, Opt_subj_role, Opt_subj_type,
|
Opt_subj_user, Opt_subj_role, Opt_subj_type,
|
||||||
Opt_func, Opt_mask, Opt_fsmagic, Opt_uid, Opt_fowner,
|
Opt_func, Opt_mask, Opt_fsmagic, Opt_uid, Opt_fowner,
|
||||||
Opt_appraise_type
|
Opt_appraise_type, Opt_fsuuid
|
||||||
};
|
};
|
||||||
|
|
||||||
static match_table_t policy_tokens = {
|
static match_table_t policy_tokens = {
|
||||||
|
@ -364,6 +370,7 @@ static match_table_t policy_tokens = {
|
||||||
{Opt_func, "func=%s"},
|
{Opt_func, "func=%s"},
|
||||||
{Opt_mask, "mask=%s"},
|
{Opt_mask, "mask=%s"},
|
||||||
{Opt_fsmagic, "fsmagic=%s"},
|
{Opt_fsmagic, "fsmagic=%s"},
|
||||||
|
{Opt_fsuuid, "fsuuid=%s"},
|
||||||
{Opt_uid, "uid=%s"},
|
{Opt_uid, "uid=%s"},
|
||||||
{Opt_fowner, "fowner=%s"},
|
{Opt_fowner, "fowner=%s"},
|
||||||
{Opt_appraise_type, "appraise_type=%s"},
|
{Opt_appraise_type, "appraise_type=%s"},
|
||||||
|
@ -519,6 +526,19 @@ static int ima_parse_rule(char *rule, struct ima_rule_entry *entry)
|
||||||
if (!result)
|
if (!result)
|
||||||
entry->flags |= IMA_FSMAGIC;
|
entry->flags |= IMA_FSMAGIC;
|
||||||
break;
|
break;
|
||||||
|
case Opt_fsuuid:
|
||||||
|
ima_log_string(ab, "fsuuid", args[0].from);
|
||||||
|
|
||||||
|
if (memchr_inv(entry->fsuuid, 0x00,
|
||||||
|
sizeof(entry->fsuuid))) {
|
||||||
|
result = -EINVAL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
part_pack_uuid(args[0].from, entry->fsuuid);
|
||||||
|
entry->flags |= IMA_FSUUID;
|
||||||
|
result = 0;
|
||||||
|
break;
|
||||||
case Opt_uid:
|
case Opt_uid:
|
||||||
ima_log_string(ab, "uid", args[0].from);
|
ima_log_string(ab, "uid", args[0].from);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue