Skip to content

Commit eb57afe

Browse files
robertosassugregkh
authored andcommitted
ima: Align ima_file_mmap() parameters with mmap_file LSM hook
commit 4971c26 upstream. Commit 98de59b ("take calculation of final prot in security_mmap_file() into a helper") moved the code to update prot, to be the actual protections applied to the kernel, to a new helper called mmap_prot(). However, while without the helper ima_file_mmap() was getting the updated prot, with the helper ima_file_mmap() gets the original prot, which contains the protections requested by the application. A possible consequence of this change is that, if an application calls mmap() with only PROT_READ, and the kernel applies PROT_EXEC in addition, that application would have access to executable memory without having this event recorded in the IMA measurement list. This situation would occur for example if the application, before mmap(), calls the personality() system call with READ_IMPLIES_EXEC as the first argument. Align ima_file_mmap() parameters with those of the mmap_file LSM hook, so that IMA can receive both the requested prot and the final prot. Since the requested protections are stored in a new variable, and the final protections are stored in the existing variable, this effectively restores the original behavior of the MMAP_CHECK hook. Cc: stable@vger.kernel.org Fixes: 98de59b ("take calculation of final prot in security_mmap_file() into a helper") Signed-off-by: Roberto Sassu <roberto.sassu@huawei.com> Reviewed-by: Stefan Berger <stefanb@linux.ibm.com> Signed-off-by: Mimi Zohar <zohar@linux.ibm.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
1 parent 51bf199 commit eb57afe

File tree

3 files changed

+13
-7
lines changed

3 files changed

+13
-7
lines changed

include/linux/ima.h

+4-2
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,8 @@ extern int ima_file_check(struct file *file, int mask);
2121
extern void ima_post_create_tmpfile(struct user_namespace *mnt_userns,
2222
struct inode *inode);
2323
extern void ima_file_free(struct file *file);
24-
extern int ima_file_mmap(struct file *file, unsigned long prot);
24+
extern int ima_file_mmap(struct file *file, unsigned long reqprot,
25+
unsigned long prot, unsigned long flags);
2526
extern int ima_file_mprotect(struct vm_area_struct *vma, unsigned long prot);
2627
extern int ima_load_data(enum kernel_load_data_id id, bool contents);
2728
extern int ima_post_load_data(char *buf, loff_t size,
@@ -76,7 +77,8 @@ static inline void ima_file_free(struct file *file)
7677
return;
7778
}
7879

79-
static inline int ima_file_mmap(struct file *file, unsigned long prot)
80+
static inline int ima_file_mmap(struct file *file, unsigned long reqprot,
81+
unsigned long prot, unsigned long flags)
8082
{
8183
return 0;
8284
}

security/integrity/ima/ima_main.c

+5-2
Original file line numberDiff line numberDiff line change
@@ -397,15 +397,18 @@ static int process_measurement(struct file *file, const struct cred *cred,
397397
/**
398398
* ima_file_mmap - based on policy, collect/store measurement.
399399
* @file: pointer to the file to be measured (May be NULL)
400-
* @prot: contains the protection that will be applied by the kernel.
400+
* @reqprot: protection requested by the application
401+
* @prot: protection that will be applied by the kernel
402+
* @flags: operational flags
401403
*
402404
* Measure files being mmapped executable based on the ima_must_measure()
403405
* policy decision.
404406
*
405407
* On success return 0. On integrity appraisal error, assuming the file
406408
* is in policy and IMA-appraisal is in enforcing mode, return -EACCES.
407409
*/
408-
int ima_file_mmap(struct file *file, unsigned long prot)
410+
int ima_file_mmap(struct file *file, unsigned long reqprot,
411+
unsigned long prot, unsigned long flags)
409412
{
410413
u32 secid;
411414

security/security.c

+4-3
Original file line numberDiff line numberDiff line change
@@ -1661,12 +1661,13 @@ static inline unsigned long mmap_prot(struct file *file, unsigned long prot)
16611661
int security_mmap_file(struct file *file, unsigned long prot,
16621662
unsigned long flags)
16631663
{
1664+
unsigned long prot_adj = mmap_prot(file, prot);
16641665
int ret;
1665-
ret = call_int_hook(mmap_file, 0, file, prot,
1666-
mmap_prot(file, prot), flags);
1666+
1667+
ret = call_int_hook(mmap_file, 0, file, prot, prot_adj, flags);
16671668
if (ret)
16681669
return ret;
1669-
return ima_file_mmap(file, prot);
1670+
return ima_file_mmap(file, prot, prot_adj, flags);
16701671
}
16711672

16721673
int security_mmap_addr(unsigned long addr)

0 commit comments

Comments
 (0)