@@ -1745,49 +1745,72 @@ static inline int file_path_has_perm(const struct cred *cred,
17451745static int bpf_fd_pass (const struct file * file , u32 sid );
17461746#endif
17471747
1748- /* Check whether a task can use an open file descriptor to
1749- access an inode in a given way. Check access to the
1750- descriptor itself, and then use dentry_has_perm to
1751- check a particular permission to the file.
1752- Access to the descriptor is implicitly granted if it
1753- has the same SID as the process. If av is zero, then
1754- access to the file is not checked, e.g. for cases
1755- where only the descriptor is affected like seek. */
1756- static int file_has_perm (const struct cred * cred ,
1757- struct file * file ,
1758- u32 av )
1748+ static int __file_has_perm (const struct cred * cred , const struct file * file ,
1749+ u32 av , bool bf_user_file )
1750+
17591751{
1760- struct file_security_struct * fsec = selinux_file (file );
1761- struct inode * inode = file_inode (file );
17621752 struct common_audit_data ad ;
1763- u32 sid = cred_sid (cred );
1753+ struct inode * inode ;
1754+ u32 ssid = cred_sid (cred );
1755+ u32 tsid_fd ;
17641756 int rc ;
17651757
1766- ad .type = LSM_AUDIT_DATA_FILE ;
1767- ad .u .file = file ;
1758+ if (bf_user_file ) {
1759+ struct backing_file_security_struct * bfsec ;
1760+ const struct path * path ;
17681761
1769- if (sid != fsec -> sid ) {
1770- rc = avc_has_perm (sid , fsec -> sid ,
1771- SECCLASS_FD ,
1772- FD__USE ,
1773- & ad );
1762+ if (WARN_ON (!(file -> f_mode & FMODE_BACKING )))
1763+ return - EIO ;
1764+
1765+ bfsec = selinux_backing_file (file );
1766+ path = backing_file_user_path (file );
1767+ tsid_fd = bfsec -> uf_sid ;
1768+ inode = d_inode (path -> dentry );
1769+
1770+ ad .type = LSM_AUDIT_DATA_PATH ;
1771+ ad .u .path = * path ;
1772+ } else {
1773+ struct file_security_struct * fsec = selinux_file (file );
1774+
1775+ tsid_fd = fsec -> sid ;
1776+ inode = file_inode (file );
1777+
1778+ ad .type = LSM_AUDIT_DATA_FILE ;
1779+ ad .u .file = file ;
1780+ }
1781+
1782+ if (ssid != tsid_fd ) {
1783+ rc = avc_has_perm (ssid , tsid_fd , SECCLASS_FD , FD__USE , & ad );
17741784 if (rc )
1775- goto out ;
1785+ return rc ;
17761786 }
17771787
17781788#ifdef CONFIG_BPF_SYSCALL
1779- rc = bpf_fd_pass (file , cred_sid (cred ));
1789+ /* regardless of backing vs user file, use the underlying file here */
1790+ rc = bpf_fd_pass (file , ssid );
17801791 if (rc )
17811792 return rc ;
17821793#endif
17831794
17841795 /* av is zero if only checking access to the descriptor. */
1785- rc = 0 ;
17861796 if (av )
1787- rc = inode_has_perm (cred , inode , av , & ad );
1797+ return inode_has_perm (cred , inode , av , & ad );
17881798
1789- out :
1790- return rc ;
1799+ return 0 ;
1800+ }
1801+
1802+ /* Check whether a task can use an open file descriptor to
1803+ access an inode in a given way. Check access to the
1804+ descriptor itself, and then use dentry_has_perm to
1805+ check a particular permission to the file.
1806+ Access to the descriptor is implicitly granted if it
1807+ has the same SID as the process. If av is zero, then
1808+ access to the file is not checked, e.g. for cases
1809+ where only the descriptor is affected like seek. */
1810+ static inline int file_has_perm (const struct cred * cred ,
1811+ const struct file * file , u32 av )
1812+ {
1813+ return __file_has_perm (cred , file , av , false);
17911814}
17921815
17931816/*
@@ -3825,6 +3848,17 @@ static int selinux_file_alloc_security(struct file *file)
38253848 return 0 ;
38263849}
38273850
3851+ static int selinux_backing_file_alloc (struct file * backing_file ,
3852+ const struct file * user_file )
3853+ {
3854+ struct backing_file_security_struct * bfsec ;
3855+
3856+ bfsec = selinux_backing_file (backing_file );
3857+ bfsec -> uf_sid = selinux_file (user_file )-> sid ;
3858+
3859+ return 0 ;
3860+ }
3861+
38283862/*
38293863 * Check whether a task has the ioctl permission and cmd
38303864 * operation to an inode.
@@ -3942,42 +3976,55 @@ static int selinux_file_ioctl_compat(struct file *file, unsigned int cmd,
39423976
39433977static int default_noexec __ro_after_init ;
39443978
3945- static int file_map_prot_check (struct file * file , unsigned long prot , int shared )
3979+ static int __file_map_prot_check (const struct cred * cred ,
3980+ const struct file * file , unsigned long prot ,
3981+ bool shared , bool bf_user_file )
39463982{
3947- const struct cred * cred = current_cred ();
3948- u32 sid = cred_sid (cred );
3949- int rc = 0 ;
3983+ struct inode * inode = NULL ;
3984+ bool prot_exec = prot & PROT_EXEC ;
3985+ bool prot_write = prot & PROT_WRITE ;
3986+
3987+ if (file ) {
3988+ if (bf_user_file )
3989+ inode = d_inode (backing_file_user_path (file )-> dentry );
3990+ else
3991+ inode = file_inode (file );
3992+ }
3993+
3994+ if (default_noexec && prot_exec &&
3995+ (!file || IS_PRIVATE (inode ) || (!shared && prot_write ))) {
3996+ int rc ;
3997+ u32 sid = cred_sid (cred );
39503998
3951- if (default_noexec &&
3952- (prot & PROT_EXEC ) && (!file || IS_PRIVATE (file_inode (file )) ||
3953- (!shared && (prot & PROT_WRITE )))) {
39543999 /*
3955- * We are making executable an anonymous mapping or a
3956- * private file mapping that will also be writable.
3957- * This has an additional check.
4000+ * We are making executable an anonymous mapping or a private
4001+ * file mapping that will also be writable.
39584002 */
3959- rc = avc_has_perm (sid , sid , SECCLASS_PROCESS ,
3960- PROCESS__EXECMEM , NULL );
4003+ rc = avc_has_perm (sid , sid , SECCLASS_PROCESS , PROCESS__EXECMEM ,
4004+ NULL );
39614005 if (rc )
3962- goto error ;
4006+ return rc ;
39634007 }
39644008
39654009 if (file ) {
3966- /* read access is always possible with a mapping */
4010+ /* " read" always possible, "write" only if shared */
39674011 u32 av = FILE__READ ;
3968-
3969- /* write access only matters if the mapping is shared */
3970- if (shared && (prot & PROT_WRITE ))
4012+ if (shared && prot_write )
39714013 av |= FILE__WRITE ;
3972-
3973- if (prot & PROT_EXEC )
4014+ if (prot_exec )
39744015 av |= FILE__EXECUTE ;
39754016
3976- return file_has_perm (cred , file , av );
4017+ return __file_has_perm (cred , file , av , bf_user_file );
39774018 }
39784019
3979- error :
3980- return rc ;
4020+ return 0 ;
4021+ }
4022+
4023+ static inline int file_map_prot_check (const struct cred * cred ,
4024+ const struct file * file ,
4025+ unsigned long prot , bool shared )
4026+ {
4027+ return __file_map_prot_check (cred , file , prot , shared , false);
39814028}
39824029
39834030static int selinux_mmap_addr (unsigned long addr )
@@ -3993,36 +4040,80 @@ static int selinux_mmap_addr(unsigned long addr)
39934040 return rc ;
39944041}
39954042
3996- static int selinux_mmap_file (struct file * file ,
3997- unsigned long reqprot __always_unused ,
3998- unsigned long prot , unsigned long flags )
4043+ static int selinux_mmap_file_common (const struct cred * cred , struct file * file ,
4044+ unsigned long prot , bool shared )
39994045{
4000- struct common_audit_data ad ;
4001- int rc ;
4002-
40034046 if (file ) {
4047+ int rc ;
4048+ struct common_audit_data ad ;
4049+
40044050 ad .type = LSM_AUDIT_DATA_FILE ;
40054051 ad .u .file = file ;
4006- rc = inode_has_perm (current_cred (), file_inode (file ),
4007- FILE__MAP , & ad );
4052+ rc = inode_has_perm (cred , file_inode (file ), FILE__MAP , & ad );
40084053 if (rc )
40094054 return rc ;
40104055 }
40114056
4012- return file_map_prot_check (file , prot ,
4013- (flags & MAP_TYPE ) == MAP_SHARED );
4057+ return file_map_prot_check (cred , file , prot , shared );
4058+ }
4059+
4060+ static int selinux_mmap_file (struct file * file ,
4061+ unsigned long reqprot __always_unused ,
4062+ unsigned long prot , unsigned long flags )
4063+ {
4064+ return selinux_mmap_file_common (current_cred (), file , prot ,
4065+ (flags & MAP_TYPE ) == MAP_SHARED );
4066+ }
4067+
4068+ /**
4069+ * selinux_mmap_backing_file - Check mmap permissions on a backing file
4070+ * @vma: memory region
4071+ * @backing_file: stacked filesystem backing file
4072+ * @user_file: user visible file
4073+ *
4074+ * This is called after selinux_mmap_file() on stacked filesystems, and it
4075+ * is this function's responsibility to verify access to @backing_file and
4076+ * setup the SELinux state for possible later use in the mprotect() code path.
4077+ *
4078+ * By the time this function is called, mmap() access to @user_file has already
4079+ * been authorized and @vma->vm_file has been set to point to @backing_file.
4080+ *
4081+ * Return zero on success, negative values otherwise.
4082+ */
4083+ static int selinux_mmap_backing_file (struct vm_area_struct * vma ,
4084+ struct file * backing_file ,
4085+ struct file * user_file __always_unused )
4086+ {
4087+ unsigned long prot = 0 ;
4088+
4089+ /* translate vma->vm_flags perms into PROT perms */
4090+ if (vma -> vm_flags & VM_READ )
4091+ prot |= PROT_READ ;
4092+ if (vma -> vm_flags & VM_WRITE )
4093+ prot |= PROT_WRITE ;
4094+ if (vma -> vm_flags & VM_EXEC )
4095+ prot |= PROT_EXEC ;
4096+
4097+ return selinux_mmap_file_common (backing_file -> f_cred , backing_file ,
4098+ prot , vma -> vm_flags & VM_SHARED );
40144099}
40154100
40164101static int selinux_file_mprotect (struct vm_area_struct * vma ,
40174102 unsigned long reqprot __always_unused ,
40184103 unsigned long prot )
40194104{
4105+ int rc ;
40204106 const struct cred * cred = current_cred ();
40214107 u32 sid = cred_sid (cred );
4108+ const struct file * file = vma -> vm_file ;
4109+ bool backing_file ;
4110+ bool shared = vma -> vm_flags & VM_SHARED ;
4111+
4112+ /* check if we need to trigger the "backing files are awful" mode */
4113+ backing_file = file && (file -> f_mode & FMODE_BACKING );
40224114
40234115 if (default_noexec &&
40244116 (prot & PROT_EXEC ) && !(vma -> vm_flags & VM_EXEC )) {
4025- int rc = 0 ;
40264117 /*
40274118 * We don't use the vma_is_initial_heap() helper as it has
40284119 * a history of problems and is currently broken on systems
@@ -4036,25 +4127,45 @@ static int selinux_file_mprotect(struct vm_area_struct *vma,
40364127 vma -> vm_end <= vma -> vm_mm -> brk ) {
40374128 rc = avc_has_perm (sid , sid , SECCLASS_PROCESS ,
40384129 PROCESS__EXECHEAP , NULL );
4039- } else if (!vma -> vm_file && (vma_is_initial_stack (vma ) ||
4130+ if (rc )
4131+ return rc ;
4132+ } else if (!file && (vma_is_initial_stack (vma ) ||
40404133 vma_is_stack_for_current (vma ))) {
40414134 rc = avc_has_perm (sid , sid , SECCLASS_PROCESS ,
40424135 PROCESS__EXECSTACK , NULL );
4043- } else if (vma -> vm_file && vma -> anon_vma ) {
4136+ if (rc )
4137+ return rc ;
4138+ } else if (file && vma -> anon_vma ) {
40444139 /*
40454140 * We are making executable a file mapping that has
40464141 * had some COW done. Since pages might have been
40474142 * written, check ability to execute the possibly
40484143 * modified content. This typically should only
40494144 * occur for text relocations.
40504145 */
4051- rc = file_has_perm (cred , vma -> vm_file , FILE__EXECMOD );
4146+ rc = __file_has_perm (cred , file , FILE__EXECMOD ,
4147+ backing_file );
4148+ if (rc )
4149+ return rc ;
4150+ if (backing_file ) {
4151+ rc = file_has_perm (file -> f_cred , file ,
4152+ FILE__EXECMOD );
4153+ if (rc )
4154+ return rc ;
4155+ }
40524156 }
4157+ }
4158+
4159+ rc = __file_map_prot_check (cred , file , prot , shared , backing_file );
4160+ if (rc )
4161+ return rc ;
4162+ if (backing_file ) {
4163+ rc = file_map_prot_check (file -> f_cred , file , prot , shared );
40534164 if (rc )
40544165 return rc ;
40554166 }
40564167
4057- return file_map_prot_check ( vma -> vm_file , prot , vma -> vm_flags & VM_SHARED ) ;
4168+ return 0 ;
40584169}
40594170
40604171static int selinux_file_lock (struct file * file , unsigned int cmd )
@@ -7393,6 +7504,7 @@ struct lsm_blob_sizes selinux_blob_sizes __ro_after_init = {
73937504 .lbs_cred = sizeof (struct cred_security_struct ),
73947505 .lbs_task = sizeof (struct task_security_struct ),
73957506 .lbs_file = sizeof (struct file_security_struct ),
7507+ .lbs_backing_file = sizeof (struct backing_file_security_struct ),
73967508 .lbs_inode = sizeof (struct inode_security_struct ),
73977509 .lbs_ipc = sizeof (struct ipc_security_struct ),
73987510 .lbs_key = sizeof (struct key_security_struct ),
@@ -7498,9 +7610,11 @@ static struct security_hook_list selinux_hooks[] __ro_after_init = {
74987610
74997611 LSM_HOOK_INIT (file_permission , selinux_file_permission ),
75007612 LSM_HOOK_INIT (file_alloc_security , selinux_file_alloc_security ),
7613+ LSM_HOOK_INIT (backing_file_alloc , selinux_backing_file_alloc ),
75017614 LSM_HOOK_INIT (file_ioctl , selinux_file_ioctl ),
75027615 LSM_HOOK_INIT (file_ioctl_compat , selinux_file_ioctl_compat ),
75037616 LSM_HOOK_INIT (mmap_file , selinux_mmap_file ),
7617+ LSM_HOOK_INIT (mmap_backing_file , selinux_mmap_backing_file ),
75047618 LSM_HOOK_INIT (mmap_addr , selinux_mmap_addr ),
75057619 LSM_HOOK_INIT (file_mprotect , selinux_file_mprotect ),
75067620 LSM_HOOK_INIT (file_lock , selinux_file_lock ),
0 commit comments