@@ -259,7 +259,7 @@ static int __inode_security_revalidate(struct inode *inode,
259
259
260
260
might_sleep_if (may_sleep );
261
261
262
- if (isec -> initialized == LABEL_INVALID ) {
262
+ if (ss_initialized && isec -> initialized != LABEL_INITIALIZED ) {
263
263
if (!may_sleep )
264
264
return - ECHILD ;
265
265
@@ -297,6 +297,13 @@ static struct inode_security_struct *inode_security(struct inode *inode)
297
297
return inode -> i_security ;
298
298
}
299
299
300
+ static struct inode_security_struct * backing_inode_security_novalidate (struct dentry * dentry )
301
+ {
302
+ struct inode * inode = d_backing_inode (dentry );
303
+
304
+ return inode -> i_security ;
305
+ }
306
+
300
307
/*
301
308
* Get the security label of a dentry's backing inode.
302
309
*/
@@ -686,7 +693,7 @@ static int selinux_set_mnt_opts(struct super_block *sb,
686
693
struct superblock_security_struct * sbsec = sb -> s_security ;
687
694
const char * name = sb -> s_type -> name ;
688
695
struct dentry * root = sbsec -> sb -> s_root ;
689
- struct inode_security_struct * root_isec = backing_inode_security ( root ) ;
696
+ struct inode_security_struct * root_isec ;
690
697
u32 fscontext_sid = 0 , context_sid = 0 , rootcontext_sid = 0 ;
691
698
u32 defcontext_sid = 0 ;
692
699
char * * mount_options = opts -> mnt_opts ;
@@ -729,6 +736,8 @@ static int selinux_set_mnt_opts(struct super_block *sb,
729
736
&& (num_opts == 0 ))
730
737
goto out ;
731
738
739
+ root_isec = backing_inode_security_novalidate (root );
740
+
732
741
/*
733
742
* parse the mount options, check if they are valid sids.
734
743
* also check if someone is trying to mount the same sb more
@@ -1622,7 +1631,7 @@ static int current_has_perm(const struct task_struct *tsk,
1622
1631
1623
1632
/* Check whether a task is allowed to use a capability. */
1624
1633
static int cred_has_capability (const struct cred * cred ,
1625
- int cap , int audit )
1634
+ int cap , int audit , bool initns )
1626
1635
{
1627
1636
struct common_audit_data ad ;
1628
1637
struct av_decision avd ;
@@ -1636,10 +1645,10 @@ static int cred_has_capability(const struct cred *cred,
1636
1645
1637
1646
switch (CAP_TO_INDEX (cap )) {
1638
1647
case 0 :
1639
- sclass = SECCLASS_CAPABILITY ;
1648
+ sclass = initns ? SECCLASS_CAPABILITY : SECCLASS_CAP_USERNS ;
1640
1649
break ;
1641
1650
case 1 :
1642
- sclass = SECCLASS_CAPABILITY2 ;
1651
+ sclass = initns ? SECCLASS_CAPABILITY2 : SECCLASS_CAP2_USERNS ;
1643
1652
break ;
1644
1653
default :
1645
1654
printk (KERN_ERR
@@ -1781,7 +1790,6 @@ static int selinux_determine_inode_label(struct inode *dir,
1781
1790
u32 * _new_isid )
1782
1791
{
1783
1792
const struct superblock_security_struct * sbsec = dir -> i_sb -> s_security ;
1784
- const struct inode_security_struct * dsec = inode_security (dir );
1785
1793
const struct task_security_struct * tsec = current_security ();
1786
1794
1787
1795
if ((sbsec -> flags & SE_SBINITIALIZED ) &&
@@ -1791,6 +1799,7 @@ static int selinux_determine_inode_label(struct inode *dir,
1791
1799
tsec -> create_sid ) {
1792
1800
* _new_isid = tsec -> create_sid ;
1793
1801
} else {
1802
+ const struct inode_security_struct * dsec = inode_security (dir );
1794
1803
return security_transition_sid (tsec -> sid , dsec -> sid , tclass ,
1795
1804
name , _new_isid );
1796
1805
}
@@ -2075,7 +2084,7 @@ static int selinux_binder_transfer_file(struct task_struct *from,
2075
2084
u32 sid = task_sid (to );
2076
2085
struct file_security_struct * fsec = file -> f_security ;
2077
2086
struct dentry * dentry = file -> f_path .dentry ;
2078
- struct inode_security_struct * isec = backing_inode_security ( dentry ) ;
2087
+ struct inode_security_struct * isec ;
2079
2088
struct common_audit_data ad ;
2080
2089
int rc ;
2081
2090
@@ -2094,6 +2103,7 @@ static int selinux_binder_transfer_file(struct task_struct *from,
2094
2103
if (unlikely (IS_PRIVATE (d_backing_inode (dentry ))))
2095
2104
return 0 ;
2096
2105
2106
+ isec = backing_inode_security (dentry );
2097
2107
return avc_has_perm (sid , isec -> sid , isec -> sclass , file_to_av (file ),
2098
2108
& ad );
2099
2109
}
@@ -2142,7 +2152,7 @@ static int selinux_capset(struct cred *new, const struct cred *old,
2142
2152
static int selinux_capable (const struct cred * cred , struct user_namespace * ns ,
2143
2153
int cap , int audit )
2144
2154
{
2145
- return cred_has_capability (cred , cap , audit );
2155
+ return cred_has_capability (cred , cap , audit , ns == & init_user_ns );
2146
2156
}
2147
2157
2148
2158
static int selinux_quotactl (int cmds , int type , int id , struct super_block * sb )
@@ -2220,7 +2230,7 @@ static int selinux_vm_enough_memory(struct mm_struct *mm, long pages)
2220
2230
int rc , cap_sys_admin = 0 ;
2221
2231
2222
2232
rc = cred_has_capability (current_cred (), CAP_SYS_ADMIN ,
2223
- SECURITY_CAP_NOAUDIT );
2233
+ SECURITY_CAP_NOAUDIT , true );
2224
2234
if (rc == 0 )
2225
2235
cap_sys_admin = 1 ;
2226
2236
@@ -2229,6 +2239,20 @@ static int selinux_vm_enough_memory(struct mm_struct *mm, long pages)
2229
2239
2230
2240
/* binprm security operations */
2231
2241
2242
+ static u32 ptrace_parent_sid (struct task_struct * task )
2243
+ {
2244
+ u32 sid = 0 ;
2245
+ struct task_struct * tracer ;
2246
+
2247
+ rcu_read_lock ();
2248
+ tracer = ptrace_parent (task );
2249
+ if (tracer )
2250
+ sid = task_sid (tracer );
2251
+ rcu_read_unlock ();
2252
+
2253
+ return sid ;
2254
+ }
2255
+
2232
2256
static int check_nnp_nosuid (const struct linux_binprm * bprm ,
2233
2257
const struct task_security_struct * old_tsec ,
2234
2258
const struct task_security_struct * new_tsec )
@@ -2350,18 +2374,7 @@ static int selinux_bprm_set_creds(struct linux_binprm *bprm)
2350
2374
* changes its SID has the appropriate permit */
2351
2375
if (bprm -> unsafe &
2352
2376
(LSM_UNSAFE_PTRACE | LSM_UNSAFE_PTRACE_CAP )) {
2353
- struct task_struct * tracer ;
2354
- struct task_security_struct * sec ;
2355
- u32 ptsid = 0 ;
2356
-
2357
- rcu_read_lock ();
2358
- tracer = ptrace_parent (current );
2359
- if (likely (tracer != NULL )) {
2360
- sec = __task_cred (tracer )-> security ;
2361
- ptsid = sec -> sid ;
2362
- }
2363
- rcu_read_unlock ();
2364
-
2377
+ u32 ptsid = ptrace_parent_sid (current );
2365
2378
if (ptsid != 0 ) {
2366
2379
rc = avc_has_perm (ptsid , new_tsec -> sid ,
2367
2380
SECCLASS_PROCESS ,
@@ -3045,7 +3058,7 @@ static int selinux_inode_setxattr(struct dentry *dentry, const char *name,
3045
3058
const void * value , size_t size , int flags )
3046
3059
{
3047
3060
struct inode * inode = d_backing_inode (dentry );
3048
- struct inode_security_struct * isec = backing_inode_security ( dentry ) ;
3061
+ struct inode_security_struct * isec ;
3049
3062
struct superblock_security_struct * sbsec ;
3050
3063
struct common_audit_data ad ;
3051
3064
u32 newsid , sid = current_sid ();
@@ -3064,6 +3077,7 @@ static int selinux_inode_setxattr(struct dentry *dentry, const char *name,
3064
3077
ad .type = LSM_AUDIT_DATA_DENTRY ;
3065
3078
ad .u .dentry = dentry ;
3066
3079
3080
+ isec = backing_inode_security (dentry );
3067
3081
rc = avc_has_perm (sid , isec -> sid , isec -> sclass ,
3068
3082
FILE__RELABELFROM , & ad );
3069
3083
if (rc )
@@ -3122,7 +3136,7 @@ static void selinux_inode_post_setxattr(struct dentry *dentry, const char *name,
3122
3136
int flags )
3123
3137
{
3124
3138
struct inode * inode = d_backing_inode (dentry );
3125
- struct inode_security_struct * isec = backing_inode_security ( dentry ) ;
3139
+ struct inode_security_struct * isec ;
3126
3140
u32 newsid ;
3127
3141
int rc ;
3128
3142
@@ -3139,6 +3153,7 @@ static void selinux_inode_post_setxattr(struct dentry *dentry, const char *name,
3139
3153
return ;
3140
3154
}
3141
3155
3156
+ isec = backing_inode_security (dentry );
3142
3157
isec -> sclass = inode_mode_to_security_class (inode -> i_mode );
3143
3158
isec -> sid = newsid ;
3144
3159
isec -> initialized = LABEL_INITIALIZED ;
@@ -3180,7 +3195,7 @@ static int selinux_inode_getsecurity(struct inode *inode, const char *name, void
3180
3195
u32 size ;
3181
3196
int error ;
3182
3197
char * context = NULL ;
3183
- struct inode_security_struct * isec = inode_security ( inode ) ;
3198
+ struct inode_security_struct * isec ;
3184
3199
3185
3200
if (strcmp (name , XATTR_SELINUX_SUFFIX ))
3186
3201
return - EOPNOTSUPP ;
@@ -3198,7 +3213,8 @@ static int selinux_inode_getsecurity(struct inode *inode, const char *name, void
3198
3213
SECURITY_CAP_NOAUDIT );
3199
3214
if (!error )
3200
3215
error = cred_has_capability (current_cred (), CAP_MAC_ADMIN ,
3201
- SECURITY_CAP_NOAUDIT );
3216
+ SECURITY_CAP_NOAUDIT , true);
3217
+ isec = inode_security (inode );
3202
3218
if (!error )
3203
3219
error = security_sid_to_context_force (isec -> sid , & context ,
3204
3220
& size );
@@ -3219,7 +3235,7 @@ static int selinux_inode_getsecurity(struct inode *inode, const char *name, void
3219
3235
static int selinux_inode_setsecurity (struct inode * inode , const char * name ,
3220
3236
const void * value , size_t size , int flags )
3221
3237
{
3222
- struct inode_security_struct * isec = inode_security (inode );
3238
+ struct inode_security_struct * isec = inode_security_novalidate (inode );
3223
3239
u32 newsid ;
3224
3240
int rc ;
3225
3241
@@ -3308,7 +3324,7 @@ static int ioctl_has_perm(const struct cred *cred, struct file *file,
3308
3324
struct common_audit_data ad ;
3309
3325
struct file_security_struct * fsec = file -> f_security ;
3310
3326
struct inode * inode = file_inode (file );
3311
- struct inode_security_struct * isec = inode_security ( inode ) ;
3327
+ struct inode_security_struct * isec ;
3312
3328
struct lsm_ioctlop_audit ioctl ;
3313
3329
u32 ssid = cred_sid (cred );
3314
3330
int rc ;
@@ -3332,6 +3348,7 @@ static int ioctl_has_perm(const struct cred *cred, struct file *file,
3332
3348
if (unlikely (IS_PRIVATE (inode )))
3333
3349
return 0 ;
3334
3350
3351
+ isec = inode_security (inode );
3335
3352
rc = avc_has_extended_perms (ssid , isec -> sid , isec -> sclass ,
3336
3353
requested , driver , xperm , & ad );
3337
3354
out :
@@ -3373,7 +3390,7 @@ static int selinux_file_ioctl(struct file *file, unsigned int cmd,
3373
3390
case KDSKBENT :
3374
3391
case KDSKBSENT :
3375
3392
error = cred_has_capability (cred , CAP_SYS_TTY_CONFIG ,
3376
- SECURITY_CAP_AUDIT );
3393
+ SECURITY_CAP_AUDIT , true );
3377
3394
break ;
3378
3395
3379
3396
/* default case assumes that the command will go
@@ -3462,8 +3479,9 @@ static int selinux_file_mprotect(struct vm_area_struct *vma,
3462
3479
vma -> vm_end <= vma -> vm_mm -> brk ) {
3463
3480
rc = cred_has_perm (cred , cred , PROCESS__EXECHEAP );
3464
3481
} else if (!vma -> vm_file &&
3465
- vma -> vm_start <= vma -> vm_mm -> start_stack &&
3466
- vma -> vm_end >= vma -> vm_mm -> start_stack ) {
3482
+ ((vma -> vm_start <= vma -> vm_mm -> start_stack &&
3483
+ vma -> vm_end >= vma -> vm_mm -> start_stack ) ||
3484
+ vma_is_stack_for_task (vma , current ))) {
3467
3485
rc = current_has_perm (current , PROCESS__EXECSTACK );
3468
3486
} else if (vma -> vm_file && vma -> anon_vma ) {
3469
3487
/*
@@ -3719,6 +3737,52 @@ static int selinux_kernel_module_request(char *kmod_name)
3719
3737
SYSTEM__MODULE_REQUEST , & ad );
3720
3738
}
3721
3739
3740
+ static int selinux_kernel_module_from_file (struct file * file )
3741
+ {
3742
+ struct common_audit_data ad ;
3743
+ struct inode_security_struct * isec ;
3744
+ struct file_security_struct * fsec ;
3745
+ u32 sid = current_sid ();
3746
+ int rc ;
3747
+
3748
+ /* init_module */
3749
+ if (file == NULL )
3750
+ return avc_has_perm (sid , sid , SECCLASS_SYSTEM ,
3751
+ SYSTEM__MODULE_LOAD , NULL );
3752
+
3753
+ /* finit_module */
3754
+
3755
+ ad .type = LSM_AUDIT_DATA_PATH ;
3756
+ ad .u .path = file -> f_path ;
3757
+
3758
+ fsec = file -> f_security ;
3759
+ if (sid != fsec -> sid ) {
3760
+ rc = avc_has_perm (sid , fsec -> sid , SECCLASS_FD , FD__USE , & ad );
3761
+ if (rc )
3762
+ return rc ;
3763
+ }
3764
+
3765
+ isec = inode_security (file_inode (file ));
3766
+ return avc_has_perm (sid , isec -> sid , SECCLASS_SYSTEM ,
3767
+ SYSTEM__MODULE_LOAD , & ad );
3768
+ }
3769
+
3770
+ static int selinux_kernel_read_file (struct file * file ,
3771
+ enum kernel_read_file_id id )
3772
+ {
3773
+ int rc = 0 ;
3774
+
3775
+ switch (id ) {
3776
+ case READING_MODULE :
3777
+ rc = selinux_kernel_module_from_file (file );
3778
+ break ;
3779
+ default :
3780
+ break ;
3781
+ }
3782
+
3783
+ return rc ;
3784
+ }
3785
+
3722
3786
static int selinux_task_setpgid (struct task_struct * p , pid_t pgid )
3723
3787
{
3724
3788
return current_has_perm (p , PROCESS__SETPGID );
@@ -4598,6 +4662,7 @@ static int selinux_socket_getpeersec_dgram(struct socket *sock, struct sk_buff *
4598
4662
{
4599
4663
u32 peer_secid = SECSID_NULL ;
4600
4664
u16 family ;
4665
+ struct inode_security_struct * isec ;
4601
4666
4602
4667
if (skb && skb -> protocol == htons (ETH_P_IP ))
4603
4668
family = PF_INET ;
@@ -4608,9 +4673,10 @@ static int selinux_socket_getpeersec_dgram(struct socket *sock, struct sk_buff *
4608
4673
else
4609
4674
goto out ;
4610
4675
4611
- if (sock && family == PF_UNIX )
4612
- selinux_inode_getsecid (SOCK_INODE (sock ), & peer_secid );
4613
- else if (skb )
4676
+ if (sock && family == PF_UNIX ) {
4677
+ isec = inode_security_novalidate (SOCK_INODE (sock ));
4678
+ peer_secid = isec -> sid ;
4679
+ } else if (skb )
4614
4680
selinux_skb_peerlbl_sid (skb , family , & peer_secid );
4615
4681
4616
4682
out :
@@ -5675,7 +5741,6 @@ static int selinux_setprocattr(struct task_struct *p,
5675
5741
char * name , void * value , size_t size )
5676
5742
{
5677
5743
struct task_security_struct * tsec ;
5678
- struct task_struct * tracer ;
5679
5744
struct cred * new ;
5680
5745
u32 sid = 0 , ptsid ;
5681
5746
int error ;
@@ -5782,14 +5847,8 @@ static int selinux_setprocattr(struct task_struct *p,
5782
5847
5783
5848
/* Check for ptracing, and update the task SID if ok.
5784
5849
Otherwise, leave SID unchanged and fail. */
5785
- ptsid = 0 ;
5786
- rcu_read_lock ();
5787
- tracer = ptrace_parent (p );
5788
- if (tracer )
5789
- ptsid = task_sid (tracer );
5790
- rcu_read_unlock ();
5791
-
5792
- if (tracer ) {
5850
+ ptsid = ptrace_parent_sid (p );
5851
+ if (ptsid != 0 ) {
5793
5852
error = avc_has_perm (ptsid , sid , SECCLASS_PROCESS ,
5794
5853
PROCESS__PTRACE , NULL );
5795
5854
if (error )
@@ -6020,6 +6079,7 @@ static struct security_hook_list selinux_hooks[] = {
6020
6079
LSM_HOOK_INIT (kernel_act_as , selinux_kernel_act_as ),
6021
6080
LSM_HOOK_INIT (kernel_create_files_as , selinux_kernel_create_files_as ),
6022
6081
LSM_HOOK_INIT (kernel_module_request , selinux_kernel_module_request ),
6082
+ LSM_HOOK_INIT (kernel_read_file , selinux_kernel_read_file ),
6023
6083
LSM_HOOK_INIT (task_setpgid , selinux_task_setpgid ),
6024
6084
LSM_HOOK_INIT (task_getpgid , selinux_task_getpgid ),
6025
6085
LSM_HOOK_INIT (task_getsid , selinux_task_getsid ),
0 commit comments