@@ -994,57 +994,62 @@ static int smack_inode_init_security(struct inode *inode, struct inode *dir,
994994 struct xattr * xattrs , int * xattr_count )
995995{
996996 struct task_smack * tsp = smack_cred (current_cred ());
997+ struct inode_smack * issp = smack_inode (inode );
997998 struct smack_known * skp = smk_of_task (tsp );
998999 struct smack_known * isp = smk_of_inode (inode );
9991000 struct smack_known * dsp = smk_of_inode (dir );
10001001 struct xattr * xattr = lsm_get_xattr_slot (xattrs , xattr_count );
10011002 int may ;
10021003
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 ;
10141025
10151026 /*
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() .
10201031 */
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 ;
10251044
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 ;
10461047 }
1048+ }
10471049
1050+ issp -> smk_flags |= SMK_INODE_INSTANT ;
1051+
1052+ if (xattr ) {
10481053 xattr -> value = kstrdup (isp -> smk_known , GFP_NOFS );
10491054 if (!xattr -> value )
10501055 return - ENOMEM ;
@@ -1314,7 +1319,8 @@ static int smack_inode_setxattr(struct mnt_idmap *idmap,
13141319 check_star = 1 ;
13151320 } else if (strcmp (name , XATTR_NAME_SMACKTRANSMUTE ) == 0 ) {
13161321 check_priv = 1 ;
1317- if (size != TRANS_TRUE_SIZE ||
1322+ if (!S_ISDIR (d_backing_inode (dentry )-> i_mode ) ||
1323+ size != TRANS_TRUE_SIZE ||
13181324 strncmp (value , TRANS_TRUE , TRANS_TRUE_SIZE ) != 0 )
13191325 rc = - EINVAL ;
13201326 } else
@@ -2095,12 +2101,7 @@ static void smack_cred_transfer(struct cred *new, const struct cred *old)
20952101 struct task_smack * old_tsp = smack_cred (old );
20962102 struct task_smack * new_tsp = smack_cred (new );
20972103
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 );
21042105}
21052106
21062107/**
@@ -2855,6 +2856,15 @@ static int smack_inode_setsecurity(struct inode *inode, const char *name,
28552856 if (value == NULL || size > SMK_LONGLABEL || size == 0 )
28562857 return - EINVAL ;
28572858
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+
28582868 skp = smk_import_entry (value , size );
28592869 if (IS_ERR (skp ))
28602870 return PTR_ERR (skp );
0 commit comments