summaryrefslogtreecommitdiffstats
path: root/security/integrity/integrity.h
diff options
context:
space:
mode:
authorDmitry Kasatkin <dmitry.kasatkin@gmail.com>2017-12-05 21:06:34 +0200
committerMimi Zohar <zohar@linux.vnet.ibm.com>2017-12-11 17:20:47 -0500
commit0d73a55208e94fc9fb6deaeea61438cd3280d4c0 (patch)
tree7f32904e7fadf1c5721aca841f12b43287c5181b /security/integrity/integrity.h
parent50b977481fce90aa5fbda55e330b9d722733e358 (diff)
downloadop-kernel-dev-0d73a55208e94fc9fb6deaeea61438cd3280d4c0.zip
op-kernel-dev-0d73a55208e94fc9fb6deaeea61438cd3280d4c0.tar.gz
ima: re-introduce own integrity cache lock
Before IMA appraisal was introduced, IMA was using own integrity cache lock along with i_mutex. process_measurement and ima_file_free took the iint->mutex first and then the i_mutex, while setxattr, chmod and chown took the locks in reverse order. To resolve the potential deadlock, i_mutex was moved to protect entire IMA functionality and the redundant iint->mutex was eliminated. Solution was based on the assumption that filesystem code does not take i_mutex further. But when file is opened with O_DIRECT flag, direct-io implementation takes i_mutex and produces deadlock. Furthermore, certain other filesystem operations, such as llseek, also take i_mutex. More recently some filesystems have replaced their filesystem specific lock with the global i_rwsem to read a file. As a result, when IMA attempts to calculate the file hash, reading the file attempts to take the i_rwsem again. To resolve O_DIRECT related deadlock problem, this patch re-introduces iint->mutex. But to eliminate the original chmod() related deadlock problem, this patch eliminates the requirement for chmod hooks to take the iint->mutex by introducing additional atomic iint->attr_flags to indicate calling of the hooks. The allowed locking order is to take the iint->mutex first and then the i_rwsem. Original flags were cleared in chmod(), setxattr() or removwxattr() hooks and tested when file was closed or opened again. New atomic flags are set or cleared in those hooks and tested to clear iint->flags on close or on open. Atomic flags are following: * IMA_CHANGE_ATTR - indicates that chATTR() was called (chmod, chown, chgrp) and file attributes have changed. On file open, it causes IMA to clear iint->flags to re-evaluate policy and perform IMA functions again. * IMA_CHANGE_XATTR - indicates that setxattr or removexattr was called and extended attributes have changed. On file open, it causes IMA to clear iint->flags IMA_DONE_MASK to re-appraise. * IMA_UPDATE_XATTR - indicates that security.ima needs to be updated. It is cleared if file policy changes and no update is needed. * IMA_DIGSIG - indicates that file security.ima has signature and file security.ima must not update to file has on file close. * IMA_MUST_MEASURE - indicates the file is in the measurement policy. Fixes: Commit 6552321831dc ("xfs: remove i_iolock and use i_rwsem in the VFS inode instead") Signed-off-by: Dmitry Kasatkin <dmitry.kasatkin@huawei.com> Signed-off-by: Mimi Zohar <zohar@linux.vnet.ibm.com>
Diffstat (limited to 'security/integrity/integrity.h')
-rw-r--r--security/integrity/integrity.h18
1 files changed, 13 insertions, 5 deletions
diff --git a/security/integrity/integrity.h b/security/integrity/integrity.h
index e324bf9..c64ea8f 100644
--- a/security/integrity/integrity.h
+++ b/security/integrity/integrity.h
@@ -29,11 +29,10 @@
/* iint cache flags */
#define IMA_ACTION_FLAGS 0xff000000
#define IMA_ACTION_RULE_FLAGS 0x06000000
-#define IMA_DIGSIG 0x01000000
-#define IMA_DIGSIG_REQUIRED 0x02000000
-#define IMA_PERMIT_DIRECTIO 0x04000000
-#define IMA_NEW_FILE 0x08000000
-#define EVM_IMMUTABLE_DIGSIG 0x10000000
+#define IMA_DIGSIG_REQUIRED 0x01000000
+#define IMA_PERMIT_DIRECTIO 0x02000000
+#define IMA_NEW_FILE 0x04000000
+#define EVM_IMMUTABLE_DIGSIG 0x08000000
#define IMA_DO_MASK (IMA_MEASURE | IMA_APPRAISE | IMA_AUDIT | \
IMA_APPRAISE_SUBMASK)
@@ -54,6 +53,13 @@
#define IMA_APPRAISED_SUBMASK (IMA_FILE_APPRAISED | IMA_MMAP_APPRAISED | \
IMA_BPRM_APPRAISED | IMA_READ_APPRAISED)
+/* iint cache atomic_flags */
+#define IMA_CHANGE_XATTR 0
+#define IMA_UPDATE_XATTR 1
+#define IMA_CHANGE_ATTR 2
+#define IMA_DIGSIG 3
+#define IMA_MUST_MEASURE 4
+
enum evm_ima_xattr_type {
IMA_XATTR_DIGEST = 0x01,
EVM_XATTR_HMAC,
@@ -102,10 +108,12 @@ struct signature_v2_hdr {
/* integrity data associated with an inode */
struct integrity_iint_cache {
struct rb_node rb_node; /* rooted in integrity_iint_tree */
+ struct mutex mutex; /* protects: version, flags, digest */
struct inode *inode; /* back pointer to inode in question */
u64 version; /* track inode changes */
unsigned long flags;
unsigned long measured_pcrs;
+ unsigned long atomic_flags;
enum integrity_status ima_file_status:4;
enum integrity_status ima_mmap_status:4;
enum integrity_status ima_bprm_status:4;
OpenPOWER on IntegriCloud