@@ -994,57 +994,62 @@ static int smack_inode_init_security(struct inode *inode, struct inode *dir,
994
994
struct xattr * xattrs , int * xattr_count )
995
995
{
996
996
struct task_smack * tsp = smack_cred (current_cred ());
997
+ struct inode_smack * issp = smack_inode (inode );
997
998
struct smack_known * skp = smk_of_task (tsp );
998
999
struct smack_known * isp = smk_of_inode (inode );
999
1000
struct smack_known * dsp = smk_of_inode (dir );
1000
1001
struct xattr * xattr = lsm_get_xattr_slot (xattrs , xattr_count );
1001
1002
int may ;
1002
1003
1003
- if (xattr ) {
1004
- /*
1005
- * If equal, transmuting already occurred in
1006
- * smack_dentry_create_files_as(). No need to check again.
1007
- */
1008
- if (tsp -> smk_task != tsp -> smk_transmuted ) {
1009
- rcu_read_lock ();
1010
- may = smk_access_entry (skp -> smk_known , dsp -> smk_known ,
1011
- & skp -> smk_rules );
1012
- rcu_read_unlock ();
1013
- }
1004
+ /*
1005
+ * If equal, transmuting already occurred in
1006
+ * smack_dentry_create_files_as(). No need to check again.
1007
+ */
1008
+ if (tsp -> smk_task != tsp -> smk_transmuted ) {
1009
+ rcu_read_lock ();
1010
+ may = smk_access_entry (skp -> smk_known , dsp -> smk_known ,
1011
+ & skp -> smk_rules );
1012
+ rcu_read_unlock ();
1013
+ }
1014
+
1015
+ /*
1016
+ * In addition to having smk_task equal to smk_transmuted,
1017
+ * if the access rule allows transmutation and the directory
1018
+ * requests transmutation then by all means transmute.
1019
+ * Mark the inode as changed.
1020
+ */
1021
+ if ((tsp -> smk_task == tsp -> smk_transmuted ) ||
1022
+ (may > 0 && ((may & MAY_TRANSMUTE ) != 0 ) &&
1023
+ smk_inode_transmutable (dir ))) {
1024
+ struct xattr * xattr_transmute ;
1014
1025
1015
1026
/*
1016
- * In addition to having smk_task equal to smk_transmuted,
1017
- * if the access rule allows transmutation and the directory
1018
- * requests transmutation then by all means transmute.
1019
- * Mark the inode as changed .
1027
+ * The caller of smack_dentry_create_files_as()
1028
+ * should have overridden the current cred, so the
1029
+ * inode label was already set correctly in
1030
+ * smack_inode_alloc_security() .
1020
1031
*/
1021
- if ((tsp -> smk_task == tsp -> smk_transmuted ) ||
1022
- (may > 0 && ((may & MAY_TRANSMUTE ) != 0 ) &&
1023
- smk_inode_transmutable (dir ))) {
1024
- struct xattr * xattr_transmute ;
1032
+ if (tsp -> smk_task != tsp -> smk_transmuted )
1033
+ isp = issp -> smk_inode = dsp ;
1034
+
1035
+ issp -> smk_flags |= SMK_INODE_TRANSMUTE ;
1036
+ xattr_transmute = lsm_get_xattr_slot (xattrs ,
1037
+ xattr_count );
1038
+ if (xattr_transmute ) {
1039
+ xattr_transmute -> value = kmemdup (TRANS_TRUE ,
1040
+ TRANS_TRUE_SIZE ,
1041
+ GFP_NOFS );
1042
+ if (!xattr_transmute -> value )
1043
+ return - ENOMEM ;
1025
1044
1026
- /*
1027
- * The caller of smack_dentry_create_files_as()
1028
- * should have overridden the current cred, so the
1029
- * inode label was already set correctly in
1030
- * smack_inode_alloc_security().
1031
- */
1032
- if (tsp -> smk_task != tsp -> smk_transmuted )
1033
- isp = dsp ;
1034
- xattr_transmute = lsm_get_xattr_slot (xattrs ,
1035
- xattr_count );
1036
- if (xattr_transmute ) {
1037
- xattr_transmute -> value = kmemdup (TRANS_TRUE ,
1038
- TRANS_TRUE_SIZE ,
1039
- GFP_NOFS );
1040
- if (!xattr_transmute -> value )
1041
- return - ENOMEM ;
1042
-
1043
- xattr_transmute -> value_len = TRANS_TRUE_SIZE ;
1044
- xattr_transmute -> name = XATTR_SMACK_TRANSMUTE ;
1045
- }
1045
+ xattr_transmute -> value_len = TRANS_TRUE_SIZE ;
1046
+ xattr_transmute -> name = XATTR_SMACK_TRANSMUTE ;
1046
1047
}
1048
+ }
1047
1049
1050
+ issp -> smk_flags |= SMK_INODE_INSTANT ;
1051
+
1052
+ if (xattr ) {
1048
1053
xattr -> value = kstrdup (isp -> smk_known , GFP_NOFS );
1049
1054
if (!xattr -> value )
1050
1055
return - ENOMEM ;
@@ -1314,7 +1319,8 @@ static int smack_inode_setxattr(struct mnt_idmap *idmap,
1314
1319
check_star = 1 ;
1315
1320
} else if (strcmp (name , XATTR_NAME_SMACKTRANSMUTE ) == 0 ) {
1316
1321
check_priv = 1 ;
1317
- if (size != TRANS_TRUE_SIZE ||
1322
+ if (!S_ISDIR (d_backing_inode (dentry )-> i_mode ) ||
1323
+ size != TRANS_TRUE_SIZE ||
1318
1324
strncmp (value , TRANS_TRUE , TRANS_TRUE_SIZE ) != 0 )
1319
1325
rc = - EINVAL ;
1320
1326
} else
@@ -2095,12 +2101,7 @@ static void smack_cred_transfer(struct cred *new, const struct cred *old)
2095
2101
struct task_smack * old_tsp = smack_cred (old );
2096
2102
struct task_smack * new_tsp = smack_cred (new );
2097
2103
2098
- new_tsp -> smk_task = old_tsp -> smk_task ;
2099
- new_tsp -> smk_forked = old_tsp -> smk_task ;
2100
- mutex_init (& new_tsp -> smk_rules_lock );
2101
- INIT_LIST_HEAD (& new_tsp -> smk_rules );
2102
-
2103
- /* cbs copy rule list */
2104
+ init_task_smack (new_tsp , old_tsp -> smk_task , old_tsp -> smk_task );
2104
2105
}
2105
2106
2106
2107
/**
@@ -2855,6 +2856,15 @@ static int smack_inode_setsecurity(struct inode *inode, const char *name,
2855
2856
if (value == NULL || size > SMK_LONGLABEL || size == 0 )
2856
2857
return - EINVAL ;
2857
2858
2859
+ if (strcmp (name , XATTR_SMACK_TRANSMUTE ) == 0 ) {
2860
+ if (!S_ISDIR (inode -> i_mode ) || size != TRANS_TRUE_SIZE ||
2861
+ strncmp (value , TRANS_TRUE , TRANS_TRUE_SIZE ) != 0 )
2862
+ return - EINVAL ;
2863
+
2864
+ nsp -> smk_flags |= SMK_INODE_TRANSMUTE ;
2865
+ return 0 ;
2866
+ }
2867
+
2858
2868
skp = smk_import_entry (value , size );
2859
2869
if (IS_ERR (skp ))
2860
2870
return PTR_ERR (skp );
0 commit comments