@@ -933,8 +933,9 @@ static int smack_inode_init_security(struct inode *inode, struct inode *dir,
933
933
const struct qstr * qstr , const char * * name ,
934
934
void * * value , size_t * len )
935
935
{
936
+ struct task_smack * tsp = smack_cred (current_cred ());
936
937
struct inode_smack * issp = smack_inode (inode );
937
- struct smack_known * skp = smk_of_current ( );
938
+ struct smack_known * skp = smk_of_task ( tsp );
938
939
struct smack_known * isp = smk_of_inode (inode );
939
940
struct smack_known * dsp = smk_of_inode (dir );
940
941
int may ;
@@ -943,20 +944,34 @@ static int smack_inode_init_security(struct inode *inode, struct inode *dir,
943
944
* name = XATTR_SMACK_SUFFIX ;
944
945
945
946
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
+ }
950
957
951
958
/*
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.
955
962
* Mark the inode as changed.
956
963
*/
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 ;
960
975
issp -> smk_flags |= SMK_INODE_CHANGED ;
961
976
}
962
977
@@ -1463,10 +1478,19 @@ static int smack_inode_getsecurity(struct mnt_idmap *idmap,
1463
1478
struct super_block * sbp ;
1464
1479
struct inode * ip = inode ;
1465
1480
struct smack_known * isp ;
1481
+ struct inode_smack * ispp ;
1482
+ size_t label_len ;
1483
+ char * label = NULL ;
1466
1484
1467
- if (strcmp (name , XATTR_SMACK_SUFFIX ) == 0 )
1485
+ if (strcmp (name , XATTR_SMACK_SUFFIX ) == 0 ) {
1468
1486
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 {
1470
1494
/*
1471
1495
* The rest of the Smack xattrs are only on sockets.
1472
1496
*/
@@ -1488,13 +1512,18 @@ static int smack_inode_getsecurity(struct mnt_idmap *idmap,
1488
1512
return - EOPNOTSUPP ;
1489
1513
}
1490
1514
1515
+ if (!label )
1516
+ label = isp -> smk_known ;
1517
+
1518
+ label_len = strlen (label );
1519
+
1491
1520
if (alloc ) {
1492
- * buffer = kstrdup (isp -> smk_known , GFP_KERNEL );
1521
+ * buffer = kstrdup (label , GFP_KERNEL );
1493
1522
if (* buffer == NULL )
1494
1523
return - ENOMEM ;
1495
1524
}
1496
1525
1497
- return strlen ( isp -> smk_known ) ;
1526
+ return label_len ;
1498
1527
}
1499
1528
1500
1529
@@ -4753,8 +4782,10 @@ static int smack_dentry_create_files_as(struct dentry *dentry, int mode,
4753
4782
* providing access is transmuting use the containing
4754
4783
* directory label instead of the process label.
4755
4784
*/
4756
- if (may > 0 && (may & MAY_TRANSMUTE ))
4785
+ if (may > 0 && (may & MAY_TRANSMUTE )) {
4757
4786
ntsp -> smk_task = isp -> smk_inode ;
4787
+ ntsp -> smk_transmuted = ntsp -> smk_task ;
4788
+ }
4758
4789
}
4759
4790
return 0 ;
4760
4791
}
0 commit comments