Skip to content

Commit 681ba31

Browse files
committed
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()
2 parents 7f1a277 + 69b6d71 commit 681ba31

File tree

2 files changed

+87
-47
lines changed

2 files changed

+87
-47
lines changed

fs/ramfs/inode.c

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,11 +102,20 @@ ramfs_mknod(struct mnt_idmap *idmap, struct inode *dir,
102102
int error = -ENOSPC;
103103

104104
if (inode) {
105+
error = security_inode_init_security(inode, dir,
106+
&dentry->d_name, NULL,
107+
NULL);
108+
if (error) {
109+
iput(inode);
110+
goto out;
111+
}
112+
105113
d_instantiate(dentry, inode);
106114
dget(dentry); /* Extra count - pin the dentry in core */
107115
error = 0;
108116
inode_set_mtime_to_ts(dir, inode_set_ctime_current(dir));
109117
}
118+
out:
110119
return error;
111120
}
112121

@@ -134,6 +143,15 @@ static int ramfs_symlink(struct mnt_idmap *idmap, struct inode *dir,
134143
inode = ramfs_get_inode(dir->i_sb, dir, S_IFLNK|S_IRWXUGO, 0);
135144
if (inode) {
136145
int l = strlen(symname)+1;
146+
147+
error = security_inode_init_security(inode, dir,
148+
&dentry->d_name, NULL,
149+
NULL);
150+
if (error) {
151+
iput(inode);
152+
goto out;
153+
}
154+
137155
error = page_symlink(inode, symname, l);
138156
if (!error) {
139157
d_instantiate(dentry, inode);
@@ -143,19 +161,31 @@ static int ramfs_symlink(struct mnt_idmap *idmap, struct inode *dir,
143161
} else
144162
iput(inode);
145163
}
164+
out:
146165
return error;
147166
}
148167

149168
static int ramfs_tmpfile(struct mnt_idmap *idmap,
150169
struct inode *dir, struct file *file, umode_t mode)
151170
{
152171
struct inode *inode;
172+
int error;
153173

154174
inode = ramfs_get_inode(dir->i_sb, dir, mode, 0);
155175
if (!inode)
156176
return -ENOSPC;
177+
178+
error = security_inode_init_security(inode, dir,
179+
&file_dentry(file)->d_name, NULL,
180+
NULL);
181+
if (error) {
182+
iput(inode);
183+
goto out;
184+
}
185+
157186
d_tmpfile(file, inode);
158-
return finish_open_simple(file, 0);
187+
out:
188+
return finish_open_simple(file, error);
159189
}
160190

161191
static const struct inode_operations ramfs_dir_inode_operations = {

security/smack/smack_lsm.c

Lines changed: 56 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -994,57 +994,62 @@ static int smack_inode_init_security(struct inode *inode, struct inode *dir,
994994
struct xattr *xattrs, int *xattr_count)
995995
{
996996
struct task_smack *tsp = smack_cred(current_cred());
997+
struct inode_smack *issp = smack_inode(inode);
997998
struct smack_known *skp = smk_of_task(tsp);
998999
struct smack_known *isp = smk_of_inode(inode);
9991000
struct smack_known *dsp = smk_of_inode(dir);
10001001
struct xattr *xattr = lsm_get_xattr_slot(xattrs, xattr_count);
10011002
int may;
10021003

1003-
if (xattr) {
1004-
/*
1005-
* If equal, transmuting already occurred in
1006-
* smack_dentry_create_files_as(). No need to check again.
1007-
*/
1008-
if (tsp->smk_task != tsp->smk_transmuted) {
1009-
rcu_read_lock();
1010-
may = smk_access_entry(skp->smk_known, dsp->smk_known,
1011-
&skp->smk_rules);
1012-
rcu_read_unlock();
1013-
}
1004+
/*
1005+
* If equal, transmuting already occurred in
1006+
* smack_dentry_create_files_as(). No need to check again.
1007+
*/
1008+
if (tsp->smk_task != tsp->smk_transmuted) {
1009+
rcu_read_lock();
1010+
may = smk_access_entry(skp->smk_known, dsp->smk_known,
1011+
&skp->smk_rules);
1012+
rcu_read_unlock();
1013+
}
1014+
1015+
/*
1016+
* In addition to having smk_task equal to smk_transmuted,
1017+
* if the access rule allows transmutation and the directory
1018+
* requests transmutation then by all means transmute.
1019+
* Mark the inode as changed.
1020+
*/
1021+
if ((tsp->smk_task == tsp->smk_transmuted) ||
1022+
(may > 0 && ((may & MAY_TRANSMUTE) != 0) &&
1023+
smk_inode_transmutable(dir))) {
1024+
struct xattr *xattr_transmute;
10141025

10151026
/*
1016-
* In addition to having smk_task equal to smk_transmuted,
1017-
* if the access rule allows transmutation and the directory
1018-
* requests transmutation then by all means transmute.
1019-
* Mark the inode as changed.
1027+
* The caller of smack_dentry_create_files_as()
1028+
* should have overridden the current cred, so the
1029+
* inode label was already set correctly in
1030+
* smack_inode_alloc_security().
10201031
*/
1021-
if ((tsp->smk_task == tsp->smk_transmuted) ||
1022-
(may > 0 && ((may & MAY_TRANSMUTE) != 0) &&
1023-
smk_inode_transmutable(dir))) {
1024-
struct xattr *xattr_transmute;
1032+
if (tsp->smk_task != tsp->smk_transmuted)
1033+
isp = issp->smk_inode = dsp;
1034+
1035+
issp->smk_flags |= SMK_INODE_TRANSMUTE;
1036+
xattr_transmute = lsm_get_xattr_slot(xattrs,
1037+
xattr_count);
1038+
if (xattr_transmute) {
1039+
xattr_transmute->value = kmemdup(TRANS_TRUE,
1040+
TRANS_TRUE_SIZE,
1041+
GFP_NOFS);
1042+
if (!xattr_transmute->value)
1043+
return -ENOMEM;
10251044

1026-
/*
1027-
* The caller of smack_dentry_create_files_as()
1028-
* should have overridden the current cred, so the
1029-
* inode label was already set correctly in
1030-
* smack_inode_alloc_security().
1031-
*/
1032-
if (tsp->smk_task != tsp->smk_transmuted)
1033-
isp = dsp;
1034-
xattr_transmute = lsm_get_xattr_slot(xattrs,
1035-
xattr_count);
1036-
if (xattr_transmute) {
1037-
xattr_transmute->value = kmemdup(TRANS_TRUE,
1038-
TRANS_TRUE_SIZE,
1039-
GFP_NOFS);
1040-
if (!xattr_transmute->value)
1041-
return -ENOMEM;
1042-
1043-
xattr_transmute->value_len = TRANS_TRUE_SIZE;
1044-
xattr_transmute->name = XATTR_SMACK_TRANSMUTE;
1045-
}
1045+
xattr_transmute->value_len = TRANS_TRUE_SIZE;
1046+
xattr_transmute->name = XATTR_SMACK_TRANSMUTE;
10461047
}
1048+
}
10471049

1050+
issp->smk_flags |= SMK_INODE_INSTANT;
1051+
1052+
if (xattr) {
10481053
xattr->value = kstrdup(isp->smk_known, GFP_NOFS);
10491054
if (!xattr->value)
10501055
return -ENOMEM;
@@ -1314,7 +1319,8 @@ static int smack_inode_setxattr(struct mnt_idmap *idmap,
13141319
check_star = 1;
13151320
} else if (strcmp(name, XATTR_NAME_SMACKTRANSMUTE) == 0) {
13161321
check_priv = 1;
1317-
if (size != TRANS_TRUE_SIZE ||
1322+
if (!S_ISDIR(d_backing_inode(dentry)->i_mode) ||
1323+
size != TRANS_TRUE_SIZE ||
13181324
strncmp(value, TRANS_TRUE, TRANS_TRUE_SIZE) != 0)
13191325
rc = -EINVAL;
13201326
} else
@@ -2095,12 +2101,7 @@ static void smack_cred_transfer(struct cred *new, const struct cred *old)
20952101
struct task_smack *old_tsp = smack_cred(old);
20962102
struct task_smack *new_tsp = smack_cred(new);
20972103

2098-
new_tsp->smk_task = old_tsp->smk_task;
2099-
new_tsp->smk_forked = old_tsp->smk_task;
2100-
mutex_init(&new_tsp->smk_rules_lock);
2101-
INIT_LIST_HEAD(&new_tsp->smk_rules);
2102-
2103-
/* cbs copy rule list */
2104+
init_task_smack(new_tsp, old_tsp->smk_task, old_tsp->smk_task);
21042105
}
21052106

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

2859+
if (strcmp(name, XATTR_SMACK_TRANSMUTE) == 0) {
2860+
if (!S_ISDIR(inode->i_mode) || size != TRANS_TRUE_SIZE ||
2861+
strncmp(value, TRANS_TRUE, TRANS_TRUE_SIZE) != 0)
2862+
return -EINVAL;
2863+
2864+
nsp->smk_flags |= SMK_INODE_TRANSMUTE;
2865+
return 0;
2866+
}
2867+
28582868
skp = smk_import_entry(value, size);
28592869
if (IS_ERR(skp))
28602870
return PTR_ERR(skp);

0 commit comments

Comments
 (0)