diff options
author | Mimi Zohar <zohar@linux.vnet.ibm.com> | 2011-03-10 18:54:15 -0500 |
---|---|---|
committer | Mimi Zohar <zohar@linux.vnet.ibm.com> | 2012-09-07 14:57:47 -0400 |
commit | 42c63330f2b05aa6077c1bfc2798c04afe54f6b2 (patch) | |
tree | bbd7d212ba9c686b2b649718b8b919bdd2eecea4 /security/integrity | |
parent | 9957a5043e7b0b7361cdf48eea22b2900293e63a (diff) |
ima: add ima_inode_setxattr/removexattr function and calls
Based on xattr_permission comments, the restriction to modify 'security'
xattr is left up to the underlying fs or lsm. Ensure that not just anyone
can modify or remove 'security.ima'.
Changelog v1:
- Unless IMA-APPRAISE is configured, use stub ima_inode_removexattr()/setxattr()
functions. (Moved ima_inode_removexattr()/setxattr() to ima_appraise.c)
Changelog:
- take i_mutex to fix locking (Dmitry Kasatkin)
- ima_reset_appraise_flags should only be called when modifying or
removing the 'security.ima' xattr. Requires CAP_SYS_ADMIN privilege.
(Incorporated fix from Roberto Sassu)
- Even if allowed to update security.ima, reset the appraisal flags,
forcing re-appraisal.
- Replace CAP_MAC_ADMIN with CAP_SYS_ADMIN
- static inline ima_inode_setxattr()/ima_inode_removexattr() stubs
- ima_protect_xattr should be static
Signed-off-by: Mimi Zohar <zohar@us.ibm.com>
Signed-off-by: Dmitry Kasatkin <dmitry.kasatkin@intel.com>
Diffstat (limited to 'security/integrity')
-rw-r--r-- | security/integrity/ima/ima_appraise.c | 57 |
1 files changed, 57 insertions, 0 deletions
diff --git a/security/integrity/ima/ima_appraise.c b/security/integrity/ima/ima_appraise.c index 681cb6e72257..becc7e09116d 100644 --- a/security/integrity/ima/ima_appraise.c +++ b/security/integrity/ima/ima_appraise.c | |||
@@ -169,3 +169,60 @@ void ima_inode_post_setattr(struct dentry *dentry) | |||
169 | rc = inode->i_op->removexattr(dentry, XATTR_NAME_IMA); | 169 | rc = inode->i_op->removexattr(dentry, XATTR_NAME_IMA); |
170 | return; | 170 | return; |
171 | } | 171 | } |
172 | |||
173 | /* | ||
174 | * ima_protect_xattr - protect 'security.ima' | ||
175 | * | ||
176 | * Ensure that not just anyone can modify or remove 'security.ima'. | ||
177 | */ | ||
178 | static int ima_protect_xattr(struct dentry *dentry, const char *xattr_name, | ||
179 | const void *xattr_value, size_t xattr_value_len) | ||
180 | { | ||
181 | if (strcmp(xattr_name, XATTR_NAME_IMA) == 0) { | ||
182 | if (!capable(CAP_SYS_ADMIN)) | ||
183 | return -EPERM; | ||
184 | return 1; | ||
185 | } | ||
186 | return 0; | ||
187 | } | ||
188 | |||
189 | static void ima_reset_appraise_flags(struct inode *inode) | ||
190 | { | ||
191 | struct integrity_iint_cache *iint; | ||
192 | |||
193 | if (!ima_initialized || !ima_appraise || !S_ISREG(inode->i_mode)) | ||
194 | return; | ||
195 | |||
196 | iint = integrity_iint_find(inode); | ||
197 | if (!iint) | ||
198 | return; | ||
199 | |||
200 | iint->flags &= ~(IMA_COLLECTED | IMA_APPRAISED | IMA_MEASURED); | ||
201 | return; | ||
202 | } | ||
203 | |||
204 | int ima_inode_setxattr(struct dentry *dentry, const char *xattr_name, | ||
205 | const void *xattr_value, size_t xattr_value_len) | ||
206 | { | ||
207 | int result; | ||
208 | |||
209 | result = ima_protect_xattr(dentry, xattr_name, xattr_value, | ||
210 | xattr_value_len); | ||
211 | if (result == 1) { | ||
212 | ima_reset_appraise_flags(dentry->d_inode); | ||
213 | result = 0; | ||
214 | } | ||
215 | return result; | ||
216 | } | ||
217 | |||
218 | int ima_inode_removexattr(struct dentry *dentry, const char *xattr_name) | ||
219 | { | ||
220 | int result; | ||
221 | |||
222 | result = ima_protect_xattr(dentry, xattr_name, NULL, 0); | ||
223 | if (result == 1) { | ||
224 | ima_reset_appraise_flags(dentry->d_inode); | ||
225 | result = 0; | ||
226 | } | ||
227 | return result; | ||
228 | } | ||