Skip to content

Commit 78fc6a9

Browse files
goongascschaufler
authored andcommitted
smack: fix bug: invalid label of unix socket file
According to [1], the label of a UNIX domain socket (UDS) file (i.e., the filesystem object representing the socket) is not supposed to participate in Smack security. To achieve this, [1] labels UDS files with "*" in smack_d_instantiate(). Before [2], smack_d_instantiate() was responsible for initializing Smack security for all inodes, except ones under /proc [2] imposed the sole responsibility for initializing inode security for newly created filesystem objects on smack_inode_init_security(). However, smack_inode_init_security() lacks some logic present in smack_d_instantiate(). In particular, it does not label UDS files with "*". This patch adds the missing labeling of UDS files with "*" to smack_inode_init_security(). Labeling UDS files with "*" in smack_d_instantiate() still works for stale UDS files that already exist on disk. Stale UDS files are useless, but I keep labeling them for consistency and maybe to make easier for user to delete them. Compared to [1], this version introduces the following improvements: * UDS file label is held inside inode only and not saved to xattrs. * relabeling UDS files (setxattr, removexattr, etc.) is blocked. [1] 2010-11-24 Casey Schaufler commit b4e0d5f ("Smack: UDS revision") [2] 2023-11-16 roberto.sassu Fixes: e63d86b ("smack: Initialize the in-memory inode in smack_inode_init_security()") Link: https://lore.kernel.org/linux-security-module/20231116090125.187209-5-roberto.sassu@huaweicloud.com/ Signed-off-by: Konstantin Andreev <andreev@swemel.ru> Signed-off-by: Casey Schaufler <casey@schaufler-ca.com>
1 parent 69204f6 commit 78fc6a9

2 files changed

Lines changed: 49 additions & 14 deletions

File tree

Documentation/admin-guide/LSM/Smack.rst

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -696,6 +696,11 @@ sockets.
696696
A privileged program may set this to match the label of another
697697
task with which it hopes to communicate.
698698

699+
UNIX domain socket (UDS) with a BSD address functions both as a file in a
700+
filesystem and as a socket. As a file, it carries the SMACK64 attribute. This
701+
attribute is not involved in Smack security enforcement and is immutably
702+
assigned the label "*".
703+
699704
Smack Netlabel Exceptions
700705
~~~~~~~~~~~~~~~~~~~~~~~~~
701706

security/smack/smack_lsm.c

Lines changed: 44 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1020,6 +1020,16 @@ static int smack_inode_init_security(struct inode *inode, struct inode *dir,
10201020
bool trans_cred;
10211021
bool trans_rule;
10221022

1023+
/*
1024+
* UNIX domain sockets use lower level socket data. Let
1025+
* UDS inode have fixed * label to keep smack_inode_permission() calm
1026+
* when called from unix_find_bsd()
1027+
*/
1028+
if (S_ISSOCK(inode->i_mode)) {
1029+
/* forced label, no need to save to xattrs */
1030+
issp->smk_inode = &smack_known_star;
1031+
goto instant_inode;
1032+
}
10231033
/*
10241034
* If equal, transmuting already occurred in
10251035
* smack_dentry_create_files_as(). No need to check again.
@@ -1056,14 +1066,16 @@ static int smack_inode_init_security(struct inode *inode, struct inode *dir,
10561066
}
10571067
}
10581068

1059-
issp->smk_flags |= (SMK_INODE_INSTANT | transflag);
1060-
if (rc)
1061-
return rc;
1062-
1063-
return xattr_dupval(xattrs, xattr_count,
1069+
if (rc == 0)
1070+
if (xattr_dupval(xattrs, xattr_count,
10641071
XATTR_SMACK_SUFFIX,
10651072
issp->smk_inode->smk_known,
1066-
strlen(issp->smk_inode->smk_known));
1073+
strlen(issp->smk_inode->smk_known)
1074+
))
1075+
rc = -ENOMEM;
1076+
instant_inode:
1077+
issp->smk_flags |= (SMK_INODE_INSTANT | transflag);
1078+
return rc;
10671079
}
10681080

10691081
/**
@@ -1337,13 +1349,23 @@ static int smack_inode_setxattr(struct mnt_idmap *idmap,
13371349
int check_import = 0;
13381350
int check_star = 0;
13391351
int rc = 0;
1352+
umode_t const i_mode = d_backing_inode(dentry)->i_mode;
13401353

13411354
/*
13421355
* Check label validity here so import won't fail in post_setxattr
13431356
*/
1344-
if (strcmp(name, XATTR_NAME_SMACK) == 0 ||
1345-
strcmp(name, XATTR_NAME_SMACKIPIN) == 0 ||
1346-
strcmp(name, XATTR_NAME_SMACKIPOUT) == 0) {
1357+
if (strcmp(name, XATTR_NAME_SMACK) == 0) {
1358+
/*
1359+
* UDS inode has fixed label
1360+
*/
1361+
if (S_ISSOCK(i_mode)) {
1362+
rc = -EINVAL;
1363+
} else {
1364+
check_priv = 1;
1365+
check_import = 1;
1366+
}
1367+
} else if (strcmp(name, XATTR_NAME_SMACKIPIN) == 0 ||
1368+
strcmp(name, XATTR_NAME_SMACKIPOUT) == 0) {
13471369
check_priv = 1;
13481370
check_import = 1;
13491371
} else if (strcmp(name, XATTR_NAME_SMACKEXEC) == 0 ||
@@ -1353,7 +1375,7 @@ static int smack_inode_setxattr(struct mnt_idmap *idmap,
13531375
check_star = 1;
13541376
} else if (strcmp(name, XATTR_NAME_SMACKTRANSMUTE) == 0) {
13551377
check_priv = 1;
1356-
if (!S_ISDIR(d_backing_inode(dentry)->i_mode) ||
1378+
if (!S_ISDIR(i_mode) ||
13571379
size != TRANS_TRUE_SIZE ||
13581380
strncmp(value, TRANS_TRUE, TRANS_TRUE_SIZE) != 0)
13591381
rc = -EINVAL;
@@ -1484,12 +1506,15 @@ static int smack_inode_removexattr(struct mnt_idmap *idmap,
14841506
* Don't do anything special for these.
14851507
* XATTR_NAME_SMACKIPIN
14861508
* XATTR_NAME_SMACKIPOUT
1509+
* XATTR_NAME_SMACK if S_ISSOCK (UDS inode has fixed label)
14871510
*/
14881511
if (strcmp(name, XATTR_NAME_SMACK) == 0) {
1489-
struct super_block *sbp = dentry->d_sb;
1490-
struct superblock_smack *sbsp = smack_superblock(sbp);
1512+
if (!S_ISSOCK(d_backing_inode(dentry)->i_mode)) {
1513+
struct super_block *sbp = dentry->d_sb;
1514+
struct superblock_smack *sbsp = smack_superblock(sbp);
14911515

1492-
isp->smk_inode = sbsp->smk_default;
1516+
isp->smk_inode = sbsp->smk_default;
1517+
}
14931518
} else if (strcmp(name, XATTR_NAME_SMACKEXEC) == 0)
14941519
isp->smk_task = NULL;
14951520
else if (strcmp(name, XATTR_NAME_SMACKMMAP) == 0)
@@ -3607,7 +3632,7 @@ static void smack_d_instantiate(struct dentry *opt_dentry, struct inode *inode)
36073632
*/
36083633

36093634
/*
3610-
* UNIX domain sockets use lower level socket data.
3635+
* UDS inode has fixed label (*)
36113636
*/
36123637
if (S_ISSOCK(inode->i_mode)) {
36133638
final = &smack_known_star;
@@ -4872,6 +4897,11 @@ static int smack_secctx_to_secid(const char *secdata, u32 seclen, u32 *secid)
48724897

48734898
static int smack_inode_notifysecctx(struct inode *inode, void *ctx, u32 ctxlen)
48744899
{
4900+
/*
4901+
* UDS inode has fixed label. Ignore nfs label.
4902+
*/
4903+
if (S_ISSOCK(inode->i_mode))
4904+
return 0;
48754905
return smack_inode_setsecurity(inode, XATTR_SMACK_SUFFIX, ctx,
48764906
ctxlen, 0);
48774907
}

0 commit comments

Comments
 (0)