@@ -962,6 +962,24 @@ static int smack_inode_alloc_security(struct inode *inode)
962962 return 0 ;
963963}
964964
965+ /**
966+ * smk_rule_transmutes - does access rule for (subject,object) contain 't'?
967+ * @subject: a pointer to the subject's Smack label entry
968+ * @object: a pointer to the object's Smack label entry
969+ */
970+ static bool
971+ smk_rule_transmutes (struct smack_known * subject ,
972+ const struct smack_known * object )
973+ {
974+ int may ;
975+
976+ rcu_read_lock ();
977+ may = smk_access_entry (subject -> smk_known , object -> smk_known ,
978+ & subject -> smk_rules );
979+ rcu_read_unlock ();
980+ return (may > 0 ) && (may & MAY_TRANSMUTE );
981+ }
982+
965983/**
966984 * smack_inode_init_security - copy out the smack from an inode
967985 * @inode: the newly created inode
@@ -977,33 +995,27 @@ static int smack_inode_init_security(struct inode *inode, struct inode *dir,
977995 struct xattr * xattrs , int * xattr_count )
978996{
979997 struct task_smack * tsp = smack_cred (current_cred ());
980- struct inode_smack * issp = smack_inode (inode );
981- struct smack_known * skp = smk_of_task (tsp );
982- struct smack_known * isp = smk_of_inode (inode );
998+ struct inode_smack * const issp = smack_inode (inode );
983999 struct smack_known * dsp = smk_of_inode (dir );
9841000 struct xattr * xattr = lsm_get_xattr_slot (xattrs , xattr_count );
985- int may ;
1001+ bool trans_cred ;
1002+ bool trans_rule ;
9861003
9871004 /*
9881005 * If equal, transmuting already occurred in
9891006 * smack_dentry_create_files_as(). No need to check again.
9901007 */
991- if (tsp -> smk_task != tsp -> smk_transmuted ) {
992- rcu_read_lock ();
993- may = smk_access_entry (skp -> smk_known , dsp -> smk_known ,
994- & skp -> smk_rules );
995- rcu_read_unlock ();
996- }
1008+ trans_cred = (tsp -> smk_task == tsp -> smk_transmuted );
1009+ if (!trans_cred )
1010+ trans_rule = smk_rule_transmutes (smk_of_task (tsp ), dsp );
9971011
9981012 /*
9991013 * In addition to having smk_task equal to smk_transmuted,
10001014 * if the access rule allows transmutation and the directory
10011015 * requests transmutation then by all means transmute.
10021016 * Mark the inode as changed.
10031017 */
1004- if ((tsp -> smk_task == tsp -> smk_transmuted ) ||
1005- (may > 0 && ((may & MAY_TRANSMUTE ) != 0 ) &&
1006- smk_inode_transmutable (dir ))) {
1018+ if (trans_cred || (trans_rule && smk_inode_transmutable (dir ))) {
10071019 struct xattr * xattr_transmute ;
10081020
10091021 /*
@@ -1012,8 +1024,8 @@ static int smack_inode_init_security(struct inode *inode, struct inode *dir,
10121024 * inode label was already set correctly in
10131025 * smack_inode_alloc_security().
10141026 */
1015- if (tsp -> smk_task != tsp -> smk_transmuted )
1016- isp = issp -> smk_inode = dsp ;
1027+ if (! trans_cred )
1028+ issp -> smk_inode = dsp ;
10171029
10181030 issp -> smk_flags |= SMK_INODE_TRANSMUTE ;
10191031 xattr_transmute = lsm_get_xattr_slot (xattrs ,
@@ -1033,11 +1045,13 @@ static int smack_inode_init_security(struct inode *inode, struct inode *dir,
10331045 issp -> smk_flags |= SMK_INODE_INSTANT ;
10341046
10351047 if (xattr ) {
1036- xattr -> value = kstrdup (isp -> smk_known , GFP_NOFS );
1048+ const char * inode_label = issp -> smk_inode -> smk_known ;
1049+
1050+ xattr -> value = kstrdup (inode_label , GFP_NOFS );
10371051 if (!xattr -> value )
10381052 return - ENOMEM ;
10391053
1040- xattr -> value_len = strlen (isp -> smk_known );
1054+ xattr -> value_len = strlen (inode_label );
10411055 xattr -> name = XATTR_SMACK_SUFFIX ;
10421056 }
10431057
@@ -4915,7 +4929,6 @@ static int smack_dentry_create_files_as(struct dentry *dentry, int mode,
49154929 struct task_smack * otsp = smack_cred (old );
49164930 struct task_smack * ntsp = smack_cred (new );
49174931 struct inode_smack * isp ;
4918- int may ;
49194932
49204933 /*
49214934 * Use the process credential unless all of
@@ -4929,18 +4942,12 @@ static int smack_dentry_create_files_as(struct dentry *dentry, int mode,
49294942 isp = smack_inode (d_inode (dentry -> d_parent ));
49304943
49314944 if (isp -> smk_flags & SMK_INODE_TRANSMUTE ) {
4932- rcu_read_lock ();
4933- may = smk_access_entry (otsp -> smk_task -> smk_known ,
4934- isp -> smk_inode -> smk_known ,
4935- & otsp -> smk_task -> smk_rules );
4936- rcu_read_unlock ();
4937-
49384945 /*
49394946 * If the directory is transmuting and the rule
49404947 * providing access is transmuting use the containing
49414948 * directory label instead of the process label.
49424949 */
4943- if (may > 0 && ( may & MAY_TRANSMUTE )) {
4950+ if (smk_rule_transmutes ( otsp -> smk_task , isp -> smk_inode )) {
49444951 ntsp -> smk_task = isp -> smk_inode ;
49454952 ntsp -> smk_transmuted = ntsp -> smk_task ;
49464953 }
0 commit comments