Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

ima: differentiate appraise status only for hook specific rules

Different hooks can require different methods for appraising a
file's integrity. As a result, an integrity appraisal status is
cached on a per hook basis.

Only a hook specific rule, requires the inode to be re-appraised.
This patch eliminates unnecessary appraisals.

Signed-off-by: Mimi Zohar <zohar@linux.vnet.ibm.com>
Signed-off-by: Dmitry Kasatkin <dmitry.kasatkin@intel.com>

+12 -6
+6 -3
security/integrity/ima/ima_main.c
··· 146 146 struct integrity_iint_cache *iint; 147 147 char *pathbuf = NULL; 148 148 const char *pathname = NULL; 149 - int rc = -ENOMEM, action, must_appraise; 149 + int rc = -ENOMEM, action, must_appraise, _func; 150 150 151 151 if (!ima_initialized || !S_ISREG(inode->i_mode)) 152 152 return 0; ··· 160 160 return 0; 161 161 162 162 must_appraise = action & IMA_APPRAISE; 163 + 164 + /* Is the appraise rule hook specific? */ 165 + _func = (action & IMA_FILE_APPRAISE) ? FILE_CHECK : function; 163 166 164 167 mutex_lock(&inode->i_mutex); 165 168 ··· 181 178 /* Nothing to do, just return existing appraised status */ 182 179 if (!action) { 183 180 if (must_appraise) 184 - rc = ima_get_cache_status(iint, function); 181 + rc = ima_get_cache_status(iint, _func); 185 182 goto out_digsig; 186 183 } 187 184 ··· 198 195 if (action & IMA_MEASURE) 199 196 ima_store_measurement(iint, file, pathname); 200 197 if (action & IMA_APPRAISE_SUBMASK) 201 - rc = ima_appraise_measurement(function, iint, file, pathname); 198 + rc = ima_appraise_measurement(_func, iint, file, pathname); 202 199 if (action & IMA_AUDIT) 203 200 ima_audit_measurement(iint, pathname); 204 201 kfree(pathbuf);
+6 -3
security/integrity/ima/ima_policy.c
··· 220 220 221 221 /* 222 222 * In addition to knowing that we need to appraise the file in general, 223 - * we need to differentiate between calling hooks. 223 + * we need to differentiate between calling hooks, for hook specific rules. 224 224 */ 225 - static int get_subaction(int func) 225 + static int get_subaction(struct ima_rule_entry *rule, int func) 226 226 { 227 + if (!(rule->flags & IMA_FUNC)) 228 + return IMA_FILE_APPRAISE; 229 + 227 230 switch(func) { 228 231 case MMAP_CHECK: 229 232 return IMA_MMAP_APPRAISE; ··· 271 268 272 269 action |= entry->action & IMA_DO_MASK; 273 270 if (entry->action & IMA_APPRAISE) 274 - action |= get_subaction(func); 271 + action |= get_subaction(entry, func); 275 272 276 273 if (entry->action & IMA_DO_MASK) 277 274 actmask &= ~(entry->action | entry->action << 1);