Commit 98be618a authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'Smack-for-6.5' of https://github.com/cschaufler/smack-next

Pull smack updates from Casey Schaufler:
 "There are two patches, both of which change how Smack initializes the
  SMACK64TRANSMUTE extended attribute.

  The first corrects the behavior of overlayfs, which creates inodes
  differently from other filesystems. The second ensures that transmute
  attributes specified by mount options are correctly assigned"

* tag 'Smack-for-6.5' of https://github.com/cschaufler/smack-next:
  smack: Record transmuting in smk_transmuted
  smack: Retrieve transmuting information in smack_inode_getsecurity()
parents b4c7f2e6 2c085f3a
...@@ -120,6 +120,7 @@ struct inode_smack { ...@@ -120,6 +120,7 @@ struct inode_smack {
struct task_smack { struct task_smack {
struct smack_known *smk_task; /* label for access control */ struct smack_known *smk_task; /* label for access control */
struct smack_known *smk_forked; /* label when forked */ struct smack_known *smk_forked; /* label when forked */
struct smack_known *smk_transmuted;/* label when transmuted */
struct list_head smk_rules; /* per task access rules */ struct list_head smk_rules; /* per task access rules */
struct mutex smk_rules_lock; /* lock for the rules */ struct mutex smk_rules_lock; /* lock for the rules */
struct list_head smk_relabel; /* transit allowed labels */ struct list_head smk_relabel; /* transit allowed labels */
......
...@@ -933,8 +933,9 @@ static int smack_inode_init_security(struct inode *inode, struct inode *dir, ...@@ -933,8 +933,9 @@ static int smack_inode_init_security(struct inode *inode, struct inode *dir,
const struct qstr *qstr, const char **name, const struct qstr *qstr, const char **name,
void **value, size_t *len) void **value, size_t *len)
{ {
struct task_smack *tsp = smack_cred(current_cred());
struct inode_smack *issp = smack_inode(inode); struct inode_smack *issp = smack_inode(inode);
struct smack_known *skp = smk_of_current(); struct smack_known *skp = smk_of_task(tsp);
struct smack_known *isp = smk_of_inode(inode); struct smack_known *isp = smk_of_inode(inode);
struct smack_known *dsp = smk_of_inode(dir); struct smack_known *dsp = smk_of_inode(dir);
int may; int may;
...@@ -943,19 +944,33 @@ static int smack_inode_init_security(struct inode *inode, struct inode *dir, ...@@ -943,19 +944,33 @@ static int smack_inode_init_security(struct inode *inode, struct inode *dir,
*name = XATTR_SMACK_SUFFIX; *name = XATTR_SMACK_SUFFIX;
if (value && len) { if (value && len) {
/*
* If equal, transmuting already occurred in
* smack_dentry_create_files_as(). No need to check again.
*/
if (tsp->smk_task != tsp->smk_transmuted) {
rcu_read_lock(); rcu_read_lock();
may = smk_access_entry(skp->smk_known, dsp->smk_known, may = smk_access_entry(skp->smk_known, dsp->smk_known,
&skp->smk_rules); &skp->smk_rules);
rcu_read_unlock(); rcu_read_unlock();
}
/* /*
* If the access rule allows transmutation and * In addition to having smk_task equal to smk_transmuted,
* the directory requests transmutation then * if the access rule allows transmutation and the directory
* by all means transmute. * requests transmutation then by all means transmute.
* Mark the inode as changed. * Mark the inode as changed.
*/ */
if (may > 0 && ((may & MAY_TRANSMUTE) != 0) && if ((tsp->smk_task == tsp->smk_transmuted) ||
smk_inode_transmutable(dir)) { (may > 0 && ((may & MAY_TRANSMUTE) != 0) &&
smk_inode_transmutable(dir))) {
/*
* The caller of smack_dentry_create_files_as()
* should have overridden the current cred, so the
* inode label was already set correctly in
* smack_inode_alloc_security().
*/
if (tsp->smk_task != tsp->smk_transmuted)
isp = dsp; isp = dsp;
issp->smk_flags |= SMK_INODE_CHANGED; issp->smk_flags |= SMK_INODE_CHANGED;
} }
...@@ -1463,10 +1478,19 @@ static int smack_inode_getsecurity(struct mnt_idmap *idmap, ...@@ -1463,10 +1478,19 @@ static int smack_inode_getsecurity(struct mnt_idmap *idmap,
struct super_block *sbp; struct super_block *sbp;
struct inode *ip = inode; struct inode *ip = inode;
struct smack_known *isp; struct smack_known *isp;
struct inode_smack *ispp;
size_t label_len;
char *label = NULL;
if (strcmp(name, XATTR_SMACK_SUFFIX) == 0) if (strcmp(name, XATTR_SMACK_SUFFIX) == 0) {
isp = smk_of_inode(inode); isp = smk_of_inode(inode);
else { } else if (strcmp(name, XATTR_SMACK_TRANSMUTE) == 0) {
ispp = smack_inode(inode);
if (ispp->smk_flags & SMK_INODE_TRANSMUTE)
label = TRANS_TRUE;
else
label = "";
} else {
/* /*
* The rest of the Smack xattrs are only on sockets. * The rest of the Smack xattrs are only on sockets.
*/ */
...@@ -1488,13 +1512,18 @@ static int smack_inode_getsecurity(struct mnt_idmap *idmap, ...@@ -1488,13 +1512,18 @@ static int smack_inode_getsecurity(struct mnt_idmap *idmap,
return -EOPNOTSUPP; return -EOPNOTSUPP;
} }
if (!label)
label = isp->smk_known;
label_len = strlen(label);
if (alloc) { if (alloc) {
*buffer = kstrdup(isp->smk_known, GFP_KERNEL); *buffer = kstrdup(label, GFP_KERNEL);
if (*buffer == NULL) if (*buffer == NULL)
return -ENOMEM; return -ENOMEM;
} }
return strlen(isp->smk_known); return label_len;
} }
...@@ -4753,8 +4782,10 @@ static int smack_dentry_create_files_as(struct dentry *dentry, int mode, ...@@ -4753,8 +4782,10 @@ static int smack_dentry_create_files_as(struct dentry *dentry, int mode,
* providing access is transmuting use the containing * providing access is transmuting use the containing
* directory label instead of the process label. * directory label instead of the process label.
*/ */
if (may > 0 && (may & MAY_TRANSMUTE)) if (may > 0 && (may & MAY_TRANSMUTE)) {
ntsp->smk_task = isp->smk_inode; ntsp->smk_task = isp->smk_inode;
ntsp->smk_transmuted = ntsp->smk_task;
}
} }
return 0; return 0;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment