The 'security.ima' extended attribute may contain either the file data's
hash or a digital signature. This patch adds support for requiring a
specific extended attribute type. It extends the IMA policy with a new
keyword 'appraise_type=imasig'. (Default is hash.)
Changelog v2:
- Fixed Documentation/ABI/testing/ima_policy option syntax
Changelog v1:
- Differentiate between 'required' vs. 'actual' extended attribute
Signed-off-by: Dmitry Kasatkin <dmitry.kasatkin@intel.com>
Signed-off-by: Mimi Zohar <zohar@linux.vnet.ibm.com>
rule format: action [condition ...]
action: measure | dont_measure | appraise | dont_appraise | audit
rule format: action [condition ...]
action: measure | dont_measure | appraise | dont_appraise | audit
+ condition:= base | lsm [option]
base: [[func=] [mask=] [fsmagic=] [uid=] [fowner]]
lsm: [[subj_user=] [subj_role=] [subj_type=]
[obj_user=] [obj_role=] [obj_type=]]
base: [[func=] [mask=] [fsmagic=] [uid=] [fowner]]
lsm: [[subj_user=] [subj_role=] [subj_type=]
[obj_user=] [obj_role=] [obj_type=]]
+ option: [[appraise_type=]]
base: func:= [BPRM_CHECK][MMAP_CHECK][FILE_CHECK][MODULE_CHECK]
mask:= [MAY_READ] [MAY_WRITE] [MAY_APPEND] [MAY_EXEC]
base: func:= [BPRM_CHECK][MMAP_CHECK][FILE_CHECK][MODULE_CHECK]
mask:= [MAY_READ] [MAY_WRITE] [MAY_APPEND] [MAY_EXEC]
uid:= decimal value
fowner:=decimal value
lsm: are LSM specific
uid:= decimal value
fowner:=decimal value
lsm: are LSM specific
+ option: appraise_type:= [imasig]
default policy:
# PROC_SUPER_MAGIC
default policy:
# PROC_SUPER_MAGIC
switch (xattr_value->type) {
case IMA_XATTR_DIGEST:
switch (xattr_value->type) {
case IMA_XATTR_DIGEST:
+ if (iint->flags & IMA_DIGSIG_REQUIRED) {
+ cause = "IMA signature required";
+ status = INTEGRITY_FAIL;
+ break;
+ }
rc = memcmp(xattr_value->digest, iint->ima_xattr.digest,
IMA_DIGEST_SIZE);
if (rc) {
rc = memcmp(xattr_value->digest, iint->ima_xattr.digest,
IMA_DIGEST_SIZE);
if (rc) {
* (IMA_MEASURE, IMA_MEASURED, IMA_APPRAISE, IMA_APPRAISED,
* IMA_AUDIT, IMA_AUDITED) */
iint->flags |= action;
* (IMA_MEASURE, IMA_MEASURED, IMA_APPRAISE, IMA_APPRAISED,
* IMA_AUDIT, IMA_AUDITED) */
iint->flags |= action;
action &= ~((iint->flags & IMA_DONE_MASK) >> 1);
/* Nothing to do, just return existing appraised status */
action &= ~((iint->flags & IMA_DONE_MASK) >> 1);
/* Nothing to do, just return existing appraised status */
if (!ima_match_rules(entry, inode, func, mask))
continue;
if (!ima_match_rules(entry, inode, func, mask))
continue;
+ action |= entry->flags & IMA_ACTION_FLAGS;
+
action |= entry->action & IMA_DO_MASK;
if (entry->action & IMA_DO_MASK)
actmask &= ~(entry->action | entry->action << 1);
action |= entry->action & IMA_DO_MASK;
if (entry->action & IMA_DO_MASK)
actmask &= ~(entry->action | entry->action << 1);
Opt_audit,
Opt_obj_user, Opt_obj_role, Opt_obj_type,
Opt_subj_user, Opt_subj_role, Opt_subj_type,
Opt_audit,
Opt_obj_user, Opt_obj_role, Opt_obj_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
};
static match_table_t policy_tokens = {
};
static match_table_t policy_tokens = {
{Opt_fsmagic, "fsmagic=%s"},
{Opt_uid, "uid=%s"},
{Opt_fowner, "fowner=%s"},
{Opt_fsmagic, "fsmagic=%s"},
{Opt_uid, "uid=%s"},
{Opt_fowner, "fowner=%s"},
+ {Opt_appraise_type, "appraise_type=%s"},
LSM_SUBJ_TYPE,
AUDIT_SUBJ_TYPE);
break;
LSM_SUBJ_TYPE,
AUDIT_SUBJ_TYPE);
break;
+ case Opt_appraise_type:
+ if (entry->action != APPRAISE) {
+ result = -EINVAL;
+ break;
+ }
+
+ ima_log_string(ab, "appraise_type", args[0].from);
+ if ((strcmp(args[0].from, "imasig")) == 0)
+ entry->flags |= IMA_DIGSIG_REQUIRED;
+ else
+ result = -EINVAL;
+ break;
case Opt_err:
ima_log_string(ab, "UNKNOWN", p);
result = -EINVAL;
case Opt_err:
ima_log_string(ab, "UNKNOWN", p);
result = -EINVAL;
#define IMA_AUDITED 0x0080
/* iint cache flags */
#define IMA_AUDITED 0x0080
/* iint cache flags */
+#define IMA_ACTION_FLAGS 0xff00
#define IMA_DIGSIG 0x0100
#define IMA_DIGSIG 0x0100
+#define IMA_DIGSIG_REQUIRED 0x0200
#define IMA_DO_MASK (IMA_MEASURE | IMA_APPRAISE | IMA_AUDIT)
#define IMA_DONE_MASK (IMA_MEASURED | IMA_APPRAISED | IMA_AUDITED \
#define IMA_DO_MASK (IMA_MEASURE | IMA_APPRAISE | IMA_AUDIT)
#define IMA_DONE_MASK (IMA_MEASURED | IMA_APPRAISED | IMA_AUDITED \