Commit 681ba318 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

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

Pull smack updates from Casey Schaufler:

 - Improvements to the initialization of in-memory inodes

 - A fix in ramfs to propery ensure the initialization of in-memory
   inodes

 - Removal of duplicated code in smack_cred_transfer()

* tag 'Smack-for-6.9' of https://github.com/cschaufler/smack-next:
  Smack: use init_task_smack() in smack_cred_transfer()
  ramfs: Initialize security of in-memory inodes
  smack: Initialize the in-memory inode in smack_inode_init_security()
  smack: Always determine inode labels in smack_inode_init_security()
  smack: Handle SMACK64TRANSMUTE in smack_inode_setsecurity()
  smack: Set SMACK64TRANSMUTE only for dirs in smack_inode_setxattr()
parents 7f1a2774 69b6d710
Loading
Loading
Loading
Loading
+31 −1
Original line number Diff line number Diff line
@@ -102,11 +102,20 @@ ramfs_mknod(struct mnt_idmap *idmap, struct inode *dir,
	int error = -ENOSPC;

	if (inode) {
		error = security_inode_init_security(inode, dir,
						     &dentry->d_name, NULL,
						     NULL);
		if (error) {
			iput(inode);
			goto out;
		}

		d_instantiate(dentry, inode);
		dget(dentry);	/* Extra count - pin the dentry in core */
		error = 0;
		inode_set_mtime_to_ts(dir, inode_set_ctime_current(dir));
	}
out:
	return error;
}

@@ -134,6 +143,15 @@ static int ramfs_symlink(struct mnt_idmap *idmap, struct inode *dir,
	inode = ramfs_get_inode(dir->i_sb, dir, S_IFLNK|S_IRWXUGO, 0);
	if (inode) {
		int l = strlen(symname)+1;

		error = security_inode_init_security(inode, dir,
						     &dentry->d_name, NULL,
						     NULL);
		if (error) {
			iput(inode);
			goto out;
		}

		error = page_symlink(inode, symname, l);
		if (!error) {
			d_instantiate(dentry, inode);
@@ -143,6 +161,7 @@ static int ramfs_symlink(struct mnt_idmap *idmap, struct inode *dir,
		} else
			iput(inode);
	}
out:
	return error;
}

@@ -150,12 +169,23 @@ static int ramfs_tmpfile(struct mnt_idmap *idmap,
			 struct inode *dir, struct file *file, umode_t mode)
{
	struct inode *inode;
	int error;

	inode = ramfs_get_inode(dir->i_sb, dir, mode, 0);
	if (!inode)
		return -ENOSPC;

	error = security_inode_init_security(inode, dir,
					     &file_dentry(file)->d_name, NULL,
					     NULL);
	if (error) {
		iput(inode);
		goto out;
	}

	d_tmpfile(file, inode);
	return finish_open_simple(file, 0);
out:
	return finish_open_simple(file, error);
}

static const struct inode_operations ramfs_dir_inode_operations = {
+56 −46
Original line number Diff line number Diff line
@@ -994,13 +994,13 @@ 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.
@@ -1030,7 +1030,9 @@ static int smack_inode_init_security(struct inode *inode, struct inode *dir,
		 * smack_inode_alloc_security().
		 */
		if (tsp->smk_task != tsp->smk_transmuted)
				isp = dsp;
			isp = issp->smk_inode = dsp;

		issp->smk_flags |= SMK_INODE_TRANSMUTE;
		xattr_transmute = lsm_get_xattr_slot(xattrs,
						     xattr_count);
		if (xattr_transmute) {
@@ -1045,6 +1047,9 @@ static int smack_inode_init_security(struct inode *inode, struct inode *dir,
		}
	}

	issp->smk_flags |= SMK_INODE_INSTANT;

	if (xattr) {
		xattr->value = kstrdup(isp->smk_known, GFP_NOFS);
		if (!xattr->value)
			return -ENOMEM;
@@ -1314,7 +1319,8 @@ static int smack_inode_setxattr(struct mnt_idmap *idmap,
		check_star = 1;
	} else if (strcmp(name, XATTR_NAME_SMACKTRANSMUTE) == 0) {
		check_priv = 1;
		if (size != TRANS_TRUE_SIZE ||
		if (!S_ISDIR(d_backing_inode(dentry)->i_mode) ||
		    size != TRANS_TRUE_SIZE ||
		    strncmp(value, TRANS_TRUE, TRANS_TRUE_SIZE) != 0)
			rc = -EINVAL;
	} else
@@ -2095,12 +2101,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);
}

/**
@@ -2855,6 +2856,15 @@ static int smack_inode_setsecurity(struct inode *inode, const char *name,
	if (value == NULL || size > SMK_LONGLABEL || size == 0)
		return -EINVAL;

	if (strcmp(name, XATTR_SMACK_TRANSMUTE) == 0) {
		if (!S_ISDIR(inode->i_mode) || size != TRANS_TRUE_SIZE ||
		    strncmp(value, TRANS_TRUE, TRANS_TRUE_SIZE) != 0)
			return -EINVAL;

		nsp->smk_flags |= SMK_INODE_TRANSMUTE;
		return 0;
	}

	skp = smk_import_entry(value, size);
	if (IS_ERR(skp))
		return PTR_ERR(skp);