summaryrefslogtreecommitdiffstats
path: root/security/smack
diff options
context:
space:
mode:
Diffstat (limited to 'security/smack')
-rw-r--r--security/smack/smack_lsm.c98
1 files changed, 51 insertions, 47 deletions
diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c
index 6f9a80783a..c6df5c00c7 100644
--- a/security/smack/smack_lsm.c
+++ b/security/smack/smack_lsm.c
@@ -994,57 +994,62 @@ static int smack_inode_init_security(struct inode *inode, struct inode *dir,
struct xattr *xattrs, int *xattr_count)
{
struct task_smack *tsp = smack_cred(current_cred());
+ struct inode_smack *issp = smack_inode(inode);
struct smack_known *skp = smk_of_task(tsp);
struct smack_known *isp = smk_of_inode(inode);
struct smack_known *dsp = smk_of_inode(dir);
struct xattr *xattr = lsm_get_xattr_slot(xattrs, xattr_count);
int may;
- if (xattr) {
- /*
- * 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();
- may = smk_access_entry(skp->smk_known, dsp->smk_known,
- &skp->smk_rules);
- rcu_read_unlock();
- }
+ /*
+ * 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();
+ may = smk_access_entry(skp->smk_known, dsp->smk_known,
+ &skp->smk_rules);
+ rcu_read_unlock();
+ }
+
+ /*
+ * In addition to having smk_task equal to smk_transmuted,
+ * if the access rule allows transmutation and the directory
+ * requests transmutation then by all means transmute.
+ * Mark the inode as changed.
+ */
+ if ((tsp->smk_task == tsp->smk_transmuted) ||
+ (may > 0 && ((may & MAY_TRANSMUTE) != 0) &&
+ smk_inode_transmutable(dir))) {
+ struct xattr *xattr_transmute;
/*
- * In addition to having smk_task equal to smk_transmuted,
- * if the access rule allows transmutation and the directory
- * requests transmutation then by all means transmute.
- * Mark the inode as changed.
+ * 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) ||
- (may > 0 && ((may & MAY_TRANSMUTE) != 0) &&
- smk_inode_transmutable(dir))) {
- struct xattr *xattr_transmute;
+ if (tsp->smk_task != tsp->smk_transmuted)
+ isp = issp->smk_inode = dsp;
+
+ issp->smk_flags |= SMK_INODE_TRANSMUTE;
+ xattr_transmute = lsm_get_xattr_slot(xattrs,
+ xattr_count);
+ if (xattr_transmute) {
+ xattr_transmute->value = kmemdup(TRANS_TRUE,
+ TRANS_TRUE_SIZE,
+ GFP_NOFS);
+ if (!xattr_transmute->value)
+ return -ENOMEM;
- /*
- * 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;
- xattr_transmute = lsm_get_xattr_slot(xattrs,
- xattr_count);
- if (xattr_transmute) {
- xattr_transmute->value = kmemdup(TRANS_TRUE,
- TRANS_TRUE_SIZE,
- GFP_NOFS);
- if (!xattr_transmute->value)
- return -ENOMEM;
-
- xattr_transmute->value_len = TRANS_TRUE_SIZE;
- xattr_transmute->name = XATTR_SMACK_TRANSMUTE;
- }
+ xattr_transmute->value_len = TRANS_TRUE_SIZE;
+ xattr_transmute->name = XATTR_SMACK_TRANSMUTE;
}
+ }
+ issp->smk_flags |= SMK_INODE_INSTANT;
+
+ if (xattr) {
xattr->value = kstrdup(isp->smk_known, GFP_NOFS);
if (!xattr->value)
return -ENOMEM;
@@ -1233,12 +1238,14 @@ static int smack_inode_permission(struct inode *inode, int mask)
/**
* smack_inode_setattr - Smack check for setting attributes
+ * @idmap: idmap of the mount
* @dentry: the object
* @iattr: for the force flag
*
* Returns 0 if access is permitted, an error code otherwise
*/
-static int smack_inode_setattr(struct dentry *dentry, struct iattr *iattr)
+static int smack_inode_setattr(struct mnt_idmap *idmap, struct dentry *dentry,
+ struct iattr *iattr)
{
struct smk_audit_info ad;
int rc;
@@ -2096,12 +2103,7 @@ static void smack_cred_transfer(struct cred *new, const struct cred *old)
struct task_smack *old_tsp = smack_cred(old);
struct task_smack *new_tsp = smack_cred(new);
- new_tsp->smk_task = old_tsp->smk_task;
- new_tsp->smk_forked = old_tsp->smk_task;
- mutex_init(&new_tsp->smk_rules_lock);
- INIT_LIST_HEAD(&new_tsp->smk_rules);
-
- /* cbs copy rule list */
+ init_task_smack(new_tsp, old_tsp->smk_task, old_tsp->smk_task);
}
/**
@@ -4690,11 +4692,13 @@ static int smack_post_notification(const struct cred *w_cred,
* @op: required testing operator (=, !=, >, <, ...)
* @rulestr: smack label to be audited
* @vrule: pointer to save our own audit rule representation
+ * @gfp: type of the memory for the allocation
*
* Prepare to audit cases where (@field @op @rulestr) is true.
* The label to be audited is created if necessay.
*/
-static int smack_audit_rule_init(u32 field, u32 op, char *rulestr, void **vrule)
+static int smack_audit_rule_init(u32 field, u32 op, char *rulestr, void **vrule,
+ gfp_t gfp)
{
struct smack_known *skp;
char **rule = (char **)vrule;