@@ -933,8 +933,9 @@ static int smack_inode_init_security(struct inode *inode, struct inode *dir,
933933 const struct qstr * qstr , const char * * name ,
934934 void * * value , size_t * len )
935935{
936+ struct task_smack * tsp = smack_cred (current_cred ());
936937 struct inode_smack * issp = smack_inode (inode );
937- struct smack_known * skp = smk_of_current ( );
938+ struct smack_known * skp = smk_of_task ( tsp );
938939 struct smack_known * isp = smk_of_inode (inode );
939940 struct smack_known * dsp = smk_of_inode (dir );
940941 int may ;
@@ -943,20 +944,34 @@ static int smack_inode_init_security(struct inode *inode, struct inode *dir,
943944 * name = XATTR_SMACK_SUFFIX ;
944945
945946 if (value && len ) {
946- rcu_read_lock ();
947- may = smk_access_entry (skp -> smk_known , dsp -> smk_known ,
948- & skp -> smk_rules );
949- rcu_read_unlock ();
947+ /*
948+ * If equal, transmuting already occurred in
949+ * smack_dentry_create_files_as(). No need to check again.
950+ */
951+ if (tsp -> smk_task != tsp -> smk_transmuted ) {
952+ rcu_read_lock ();
953+ may = smk_access_entry (skp -> smk_known , dsp -> smk_known ,
954+ & skp -> smk_rules );
955+ rcu_read_unlock ();
956+ }
950957
951958 /*
952- * If the access rule allows transmutation and
953- * the directory requests transmutation then
954- * by all means transmute.
959+ * In addition to having smk_task equal to smk_transmuted,
960+ * if the access rule allows transmutation and the directory
961+ * requests transmutation then by all means transmute.
955962 * Mark the inode as changed.
956963 */
957- if (may > 0 && ((may & MAY_TRANSMUTE ) != 0 ) &&
958- smk_inode_transmutable (dir )) {
959- isp = dsp ;
964+ if ((tsp -> smk_task == tsp -> smk_transmuted ) ||
965+ (may > 0 && ((may & MAY_TRANSMUTE ) != 0 ) &&
966+ smk_inode_transmutable (dir ))) {
967+ /*
968+ * The caller of smack_dentry_create_files_as()
969+ * should have overridden the current cred, so the
970+ * inode label was already set correctly in
971+ * smack_inode_alloc_security().
972+ */
973+ if (tsp -> smk_task != tsp -> smk_transmuted )
974+ isp = dsp ;
960975 issp -> smk_flags |= SMK_INODE_CHANGED ;
961976 }
962977
@@ -1463,10 +1478,19 @@ static int smack_inode_getsecurity(struct mnt_idmap *idmap,
14631478 struct super_block * sbp ;
14641479 struct inode * ip = inode ;
14651480 struct smack_known * isp ;
1481+ struct inode_smack * ispp ;
1482+ size_t label_len ;
1483+ char * label = NULL ;
14661484
1467- if (strcmp (name , XATTR_SMACK_SUFFIX ) == 0 )
1485+ if (strcmp (name , XATTR_SMACK_SUFFIX ) == 0 ) {
14681486 isp = smk_of_inode (inode );
1469- else {
1487+ } else if (strcmp (name , XATTR_SMACK_TRANSMUTE ) == 0 ) {
1488+ ispp = smack_inode (inode );
1489+ if (ispp -> smk_flags & SMK_INODE_TRANSMUTE )
1490+ label = TRANS_TRUE ;
1491+ else
1492+ label = "" ;
1493+ } else {
14701494 /*
14711495 * The rest of the Smack xattrs are only on sockets.
14721496 */
@@ -1488,13 +1512,18 @@ static int smack_inode_getsecurity(struct mnt_idmap *idmap,
14881512 return - EOPNOTSUPP ;
14891513 }
14901514
1515+ if (!label )
1516+ label = isp -> smk_known ;
1517+
1518+ label_len = strlen (label );
1519+
14911520 if (alloc ) {
1492- * buffer = kstrdup (isp -> smk_known , GFP_KERNEL );
1521+ * buffer = kstrdup (label , GFP_KERNEL );
14931522 if (* buffer == NULL )
14941523 return - ENOMEM ;
14951524 }
14961525
1497- return strlen ( isp -> smk_known ) ;
1526+ return label_len ;
14981527}
14991528
15001529
@@ -4753,8 +4782,10 @@ static int smack_dentry_create_files_as(struct dentry *dentry, int mode,
47534782 * providing access is transmuting use the containing
47544783 * directory label instead of the process label.
47554784 */
4756- if (may > 0 && (may & MAY_TRANSMUTE ))
4785+ if (may > 0 && (may & MAY_TRANSMUTE )) {
47574786 ntsp -> smk_task = isp -> smk_inode ;
4787+ ntsp -> smk_transmuted = ntsp -> smk_task ;
4788+ }
47584789 }
47594790 return 0 ;
47604791}
0 commit comments