@@ -341,6 +341,10 @@ static void inode_free_security(struct inode *inode)
341341
342342struct selinux_mnt_opts {
343343 const char * fscontext , * context , * rootcontext , * defcontext ;
344+ u32 fscontext_sid ;
345+ u32 context_sid ;
346+ u32 rootcontext_sid ;
347+ u32 defcontext_sid ;
344348};
345349
346350static void selinux_free_mnt_opts (void * mnt_opts )
@@ -597,15 +601,14 @@ static int bad_option(struct superblock_security_struct *sbsec, char flag,
597601 return 0 ;
598602}
599603
600- static int parse_sid (struct super_block * sb , const char * s , u32 * sid ,
601- gfp_t gfp )
604+ static int parse_sid (struct super_block * sb , const char * s , u32 * sid )
602605{
603606 int rc = security_context_str_to_sid (& selinux_state , s ,
604- sid , gfp );
607+ sid , GFP_KERNEL );
605608 if (rc )
606609 pr_warn ("SELinux: security_context_str_to_sid"
607610 "(%s) failed for (dev %s, type %s) errno=%d\n" ,
608- s , sb -> s_id , sb -> s_type -> name , rc );
611+ s , sb ? sb -> s_id : "?" , sb ? sb -> s_type -> name : "?" , rc );
609612 return rc ;
610613}
611614
@@ -672,8 +675,7 @@ static int selinux_set_mnt_opts(struct super_block *sb,
672675 */
673676 if (opts ) {
674677 if (opts -> fscontext ) {
675- rc = parse_sid (sb , opts -> fscontext , & fscontext_sid ,
676- GFP_KERNEL );
678+ rc = parse_sid (sb , opts -> fscontext , & fscontext_sid );
677679 if (rc )
678680 goto out ;
679681 if (bad_option (sbsec , FSCONTEXT_MNT , sbsec -> sid ,
@@ -682,8 +684,7 @@ static int selinux_set_mnt_opts(struct super_block *sb,
682684 sbsec -> flags |= FSCONTEXT_MNT ;
683685 }
684686 if (opts -> context ) {
685- rc = parse_sid (sb , opts -> context , & context_sid ,
686- GFP_KERNEL );
687+ rc = parse_sid (sb , opts -> context , & context_sid );
687688 if (rc )
688689 goto out ;
689690 if (bad_option (sbsec , CONTEXT_MNT , sbsec -> mntpoint_sid ,
@@ -692,8 +693,7 @@ static int selinux_set_mnt_opts(struct super_block *sb,
692693 sbsec -> flags |= CONTEXT_MNT ;
693694 }
694695 if (opts -> rootcontext ) {
695- rc = parse_sid (sb , opts -> rootcontext , & rootcontext_sid ,
696- GFP_KERNEL );
696+ rc = parse_sid (sb , opts -> rootcontext , & rootcontext_sid );
697697 if (rc )
698698 goto out ;
699699 if (bad_option (sbsec , ROOTCONTEXT_MNT , root_isec -> sid ,
@@ -702,8 +702,7 @@ static int selinux_set_mnt_opts(struct super_block *sb,
702702 sbsec -> flags |= ROOTCONTEXT_MNT ;
703703 }
704704 if (opts -> defcontext ) {
705- rc = parse_sid (sb , opts -> defcontext , & defcontext_sid ,
706- GFP_KERNEL );
705+ rc = parse_sid (sb , opts -> defcontext , & defcontext_sid );
707706 if (rc )
708707 goto out ;
709708 if (bad_option (sbsec , DEFCONTEXT_MNT , sbsec -> def_sid ,
@@ -995,21 +994,29 @@ static int selinux_add_opt(int token, const char *s, void **mnt_opts)
995994 if (opts -> context || opts -> defcontext )
996995 goto err ;
997996 opts -> context = s ;
997+ if (selinux_initialized (& selinux_state ))
998+ parse_sid (NULL , s , & opts -> context_sid );
998999 break ;
9991000 case Opt_fscontext :
10001001 if (opts -> fscontext )
10011002 goto err ;
10021003 opts -> fscontext = s ;
1004+ if (selinux_initialized (& selinux_state ))
1005+ parse_sid (NULL , s , & opts -> fscontext_sid );
10031006 break ;
10041007 case Opt_rootcontext :
10051008 if (opts -> rootcontext )
10061009 goto err ;
10071010 opts -> rootcontext = s ;
1011+ if (selinux_initialized (& selinux_state ))
1012+ parse_sid (NULL , s , & opts -> rootcontext_sid );
10081013 break ;
10091014 case Opt_defcontext :
10101015 if (opts -> context || opts -> defcontext )
10111016 goto err ;
10121017 opts -> defcontext = s ;
1018+ if (selinux_initialized (& selinux_state ))
1019+ parse_sid (NULL , s , & opts -> defcontext_sid );
10131020 break ;
10141021 }
10151022
@@ -2647,8 +2654,6 @@ static int selinux_sb_mnt_opts_compat(struct super_block *sb, void *mnt_opts)
26472654{
26482655 struct selinux_mnt_opts * opts = mnt_opts ;
26492656 struct superblock_security_struct * sbsec = selinux_superblock (sb );
2650- u32 sid ;
2651- int rc ;
26522657
26532658 /*
26542659 * Superblock not initialized (i.e. no options) - reject if any
@@ -2665,34 +2670,36 @@ static int selinux_sb_mnt_opts_compat(struct super_block *sb, void *mnt_opts)
26652670 return (sbsec -> flags & SE_MNTMASK ) ? 1 : 0 ;
26662671
26672672 if (opts -> fscontext ) {
2668- rc = parse_sid (sb , opts -> fscontext , & sid , GFP_NOWAIT );
2669- if (rc )
2673+ if (opts -> fscontext_sid == SECSID_NULL )
26702674 return 1 ;
2671- if (bad_option (sbsec , FSCONTEXT_MNT , sbsec -> sid , sid ))
2675+ else if (bad_option (sbsec , FSCONTEXT_MNT , sbsec -> sid ,
2676+ opts -> fscontext_sid ))
26722677 return 1 ;
26732678 }
26742679 if (opts -> context ) {
2675- rc = parse_sid (sb , opts -> context , & sid , GFP_NOWAIT );
2676- if (rc )
2680+ if (opts -> context_sid == SECSID_NULL )
26772681 return 1 ;
2678- if (bad_option (sbsec , CONTEXT_MNT , sbsec -> mntpoint_sid , sid ))
2682+ else if (bad_option (sbsec , CONTEXT_MNT , sbsec -> mntpoint_sid ,
2683+ opts -> context_sid ))
26792684 return 1 ;
26802685 }
26812686 if (opts -> rootcontext ) {
2682- struct inode_security_struct * root_isec ;
2683-
2684- root_isec = backing_inode_security (sb -> s_root );
2685- rc = parse_sid (sb , opts -> rootcontext , & sid , GFP_NOWAIT );
2686- if (rc )
2687- return 1 ;
2688- if (bad_option (sbsec , ROOTCONTEXT_MNT , root_isec -> sid , sid ))
2687+ if (opts -> rootcontext_sid == SECSID_NULL )
26892688 return 1 ;
2689+ else {
2690+ struct inode_security_struct * root_isec ;
2691+
2692+ root_isec = backing_inode_security (sb -> s_root );
2693+ if (bad_option (sbsec , ROOTCONTEXT_MNT , root_isec -> sid ,
2694+ opts -> rootcontext_sid ))
2695+ return 1 ;
2696+ }
26902697 }
26912698 if (opts -> defcontext ) {
2692- rc = parse_sid (sb , opts -> defcontext , & sid , GFP_NOWAIT );
2693- if (rc )
2699+ if (opts -> defcontext_sid == SECSID_NULL )
26942700 return 1 ;
2695- if (bad_option (sbsec , DEFCONTEXT_MNT , sbsec -> def_sid , sid ))
2701+ else if (bad_option (sbsec , DEFCONTEXT_MNT , sbsec -> def_sid ,
2702+ opts -> defcontext_sid ))
26962703 return 1 ;
26972704 }
26982705 return 0 ;
@@ -2712,14 +2719,14 @@ static int selinux_sb_remount(struct super_block *sb, void *mnt_opts)
27122719 return 0 ;
27132720
27142721 if (opts -> fscontext ) {
2715- rc = parse_sid (sb , opts -> fscontext , & sid , GFP_KERNEL );
2722+ rc = parse_sid (sb , opts -> fscontext , & sid );
27162723 if (rc )
27172724 return rc ;
27182725 if (bad_option (sbsec , FSCONTEXT_MNT , sbsec -> sid , sid ))
27192726 goto out_bad_option ;
27202727 }
27212728 if (opts -> context ) {
2722- rc = parse_sid (sb , opts -> context , & sid , GFP_KERNEL );
2729+ rc = parse_sid (sb , opts -> context , & sid );
27232730 if (rc )
27242731 return rc ;
27252732 if (bad_option (sbsec , CONTEXT_MNT , sbsec -> mntpoint_sid , sid ))
@@ -2728,14 +2735,14 @@ static int selinux_sb_remount(struct super_block *sb, void *mnt_opts)
27282735 if (opts -> rootcontext ) {
27292736 struct inode_security_struct * root_isec ;
27302737 root_isec = backing_inode_security (sb -> s_root );
2731- rc = parse_sid (sb , opts -> rootcontext , & sid , GFP_KERNEL );
2738+ rc = parse_sid (sb , opts -> rootcontext , & sid );
27322739 if (rc )
27332740 return rc ;
27342741 if (bad_option (sbsec , ROOTCONTEXT_MNT , root_isec -> sid , sid ))
27352742 goto out_bad_option ;
27362743 }
27372744 if (opts -> defcontext ) {
2738- rc = parse_sid (sb , opts -> defcontext , & sid , GFP_KERNEL );
2745+ rc = parse_sid (sb , opts -> defcontext , & sid );
27392746 if (rc )
27402747 return rc ;
27412748 if (bad_option (sbsec , DEFCONTEXT_MNT , sbsec -> def_sid , sid ))
0 commit comments