From: Stephen Smalley This patch adds new permission checks to the SELinux mmap and mprotect hooks to enable control over the ability to make executable a mapping that can contain data not covered by the existing file-based permission checks. The task->self execmem permission controls the ability to create an executable anonymous mapping or a writable executable private file mapping. The task->file execmod permission controls the ability to make executable a previously written private file mapping, e.g. for text relocations. Thanks to Roland McGrath for input and feedback on earlier versions of this patch. Signed-off-by: Stephen Smalley Signed-off-by: James Morris Signed-off-by: Andrew Morton --- 25-akpm/security/selinux/hooks.c | 23 +++++++++++++++++++ 25-akpm/security/selinux/include/av_perm_to_string.h | 2 + 25-akpm/security/selinux/include/av_permissions.h | 2 + 3 files changed, 27 insertions(+) diff -puN security/selinux/hooks.c~selinux-enhance-selinux-control-of-executable-mappings security/selinux/hooks.c --- 25/security/selinux/hooks.c~selinux-enhance-selinux-control-of-executable-mappings Thu Dec 2 12:56:50 2004 +++ 25-akpm/security/selinux/hooks.c Thu Dec 2 12:56:50 2004 @@ -2443,6 +2443,17 @@ static int selinux_file_ioctl(struct fil static int file_map_prot_check(struct file *file, unsigned long prot, int shared) { + if ((prot & PROT_EXEC) && (!file || (!shared && (prot & PROT_WRITE)))) { + /* + * We are making executable an anonymous mapping or a + * private file mapping that will also be writable. + * This has an additional check. + */ + int rc = task_has_perm(current, current, PROCESS__EXECMEM); + if (rc) + return rc; + } + if (file) { /* read access is always possible with a mapping */ u32 av = FILE__READ; @@ -2480,6 +2491,18 @@ static int selinux_file_mprotect(struct if (rc) return rc; + if (vma->vm_file != NULL && vma->anon_vma != NULL && (prot & PROT_EXEC)) { + /* + * We are making executable a file mapping that has + * had some COW done. Since pages might have been written, + * check ability to execute the possibly modified content. + * This typically should only occur for text relocations. + */ + int rc = file_has_perm(current, vma->vm_file, FILE__EXECMOD); + if (rc) + return rc; + } + return file_map_prot_check(vma->vm_file, prot, vma->vm_flags&VM_SHARED); } diff -puN security/selinux/include/av_permissions.h~selinux-enhance-selinux-control-of-executable-mappings security/selinux/include/av_permissions.h --- 25/security/selinux/include/av_permissions.h~selinux-enhance-selinux-control-of-executable-mappings Thu Dec 2 12:56:50 2004 +++ 25-akpm/security/selinux/include/av_permissions.h Thu Dec 2 12:56:50 2004 @@ -105,6 +105,7 @@ #define FILE__EXECUTE_NO_TRANS 0x00020000UL #define FILE__ENTRYPOINT 0x00040000UL +#define FILE__EXECMOD 0x00080000UL #define LNK_FILE__IOCTL 0x00000001UL #define LNK_FILE__READ 0x00000002UL @@ -458,6 +459,7 @@ #define PROCESS__RLIMITINH 0x00400000UL #define PROCESS__DYNTRANSITION 0x00800000UL #define PROCESS__SETCURRENT 0x01000000UL +#define PROCESS__EXECMEM 0x02000000UL #define IPC__CREATE 0x00000001UL #define IPC__DESTROY 0x00000002UL diff -puN security/selinux/include/av_perm_to_string.h~selinux-enhance-selinux-control-of-executable-mappings security/selinux/include/av_perm_to_string.h --- 25/security/selinux/include/av_perm_to_string.h~selinux-enhance-selinux-control-of-executable-mappings Thu Dec 2 12:56:50 2004 +++ 25-akpm/security/selinux/include/av_perm_to_string.h Thu Dec 2 12:56:50 2004 @@ -16,6 +16,7 @@ S_(SECCLASS_DIR, DIR__RMDIR, "rmdir") S_(SECCLASS_FILE, FILE__EXECUTE_NO_TRANS, "execute_no_trans") S_(SECCLASS_FILE, FILE__ENTRYPOINT, "entrypoint") + S_(SECCLASS_FILE, FILE__EXECMOD, "execmod") S_(SECCLASS_FD, FD__USE, "use") S_(SECCLASS_TCP_SOCKET, TCP_SOCKET__CONNECTTO, "connectto") S_(SECCLASS_TCP_SOCKET, TCP_SOCKET__NEWCONN, "newconn") @@ -64,6 +65,7 @@ S_(SECCLASS_PROCESS, PROCESS__RLIMITINH, "rlimitinh") S_(SECCLASS_PROCESS, PROCESS__DYNTRANSITION, "dyntransition") S_(SECCLASS_PROCESS, PROCESS__SETCURRENT, "setcurrent") + S_(SECCLASS_PROCESS, PROCESS__EXECMEM, "execmem") S_(SECCLASS_MSGQ, MSGQ__ENQUEUE, "enqueue") S_(SECCLASS_MSG, MSG__SEND, "send") S_(SECCLASS_MSG, MSG__RECEIVE, "receive") _