Skip to content

Commit e5a8b64

Browse files
MaxKellermannbrauner
authored andcommitted
cachefiles: Parse the "secctx" immediately
Instead of storing an opaque string, call security_secctx_to_secid() right in the "secctx" command handler and store only the numeric "secid". This eliminates an unnecessary string allocation and allows the daemon to receive errors when writing the "secctx" command instead of postponing the error to the "bind" command handler. For example, if the kernel was built without `CONFIG_SECURITY`, "bind" will return `EOPNOTSUPP`, but the daemon doesn't know why. With this patch, the "secctx" will instead return `EOPNOTSUPP` which is the right context for this error. This patch adds a boolean flag `have_secid` because I'm not sure if we can safely assume that zero is the special secid value for "not set". This appears to be true for SELinux, Smack and AppArmor, but since this attribute is not documented, I'm unable to derive a stable guarantee for that. Signed-off-by: Max Kellermann <max.kellermann@ionos.com> Signed-off-by: David Howells <dhowells@redhat.com> Link: https://lore.kernel.org/r/20241209141554.638708-1-max.kellermann@ionos.com/ Link: https://lore.kernel.org/r/20241213135013.2964079-6-dhowells@redhat.com Signed-off-by: Christian Brauner <brauner@kernel.org>
1 parent 86ad1a5 commit e5a8b64

File tree

3 files changed

+12
-11
lines changed

3 files changed

+12
-11
lines changed

fs/cachefiles/daemon.c

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#include <linux/namei.h>
1616
#include <linux/poll.h>
1717
#include <linux/mount.h>
18+
#include <linux/security.h>
1819
#include <linux/statfs.h>
1920
#include <linux/ctype.h>
2021
#include <linux/string.h>
@@ -576,7 +577,7 @@ static int cachefiles_daemon_dir(struct cachefiles_cache *cache, char *args)
576577
*/
577578
static int cachefiles_daemon_secctx(struct cachefiles_cache *cache, char *args)
578579
{
579-
char *secctx;
580+
int err;
580581

581582
_enter(",%s", args);
582583

@@ -585,16 +586,16 @@ static int cachefiles_daemon_secctx(struct cachefiles_cache *cache, char *args)
585586
return -EINVAL;
586587
}
587588

588-
if (cache->secctx) {
589+
if (cache->have_secid) {
589590
pr_err("Second security context specified\n");
590591
return -EINVAL;
591592
}
592593

593-
secctx = kstrdup(args, GFP_KERNEL);
594-
if (!secctx)
595-
return -ENOMEM;
594+
err = security_secctx_to_secid(args, strlen(args), &cache->secid);
595+
if (err)
596+
return err;
596597

597-
cache->secctx = secctx;
598+
cache->have_secid = true;
598599
return 0;
599600
}
600601

@@ -820,7 +821,6 @@ static void cachefiles_daemon_unbind(struct cachefiles_cache *cache)
820821
put_cred(cache->cache_cred);
821822

822823
kfree(cache->rootdirname);
823-
kfree(cache->secctx);
824824
kfree(cache->tag);
825825

826826
_leave("");

fs/cachefiles/internal.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -122,14 +122,15 @@ struct cachefiles_cache {
122122
#define CACHEFILES_STATE_CHANGED 3 /* T if state changed (poll trigger) */
123123
#define CACHEFILES_ONDEMAND_MODE 4 /* T if in on-demand read mode */
124124
char *rootdirname; /* name of cache root directory */
125-
char *secctx; /* LSM security context */
126125
char *tag; /* cache binding tag */
127126
refcount_t unbind_pincount;/* refcount to do daemon unbind */
128127
struct xarray reqs; /* xarray of pending on-demand requests */
129128
unsigned long req_id_next;
130129
struct xarray ondemand_ids; /* xarray for ondemand_id allocation */
131130
u32 ondemand_id_next;
132131
u32 msg_id_next;
132+
u32 secid; /* LSM security id */
133+
bool have_secid; /* whether "secid" was set */
133134
};
134135

135136
static inline bool cachefiles_in_ondemand_mode(struct cachefiles_cache *cache)

fs/cachefiles/security.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,16 +18,16 @@ int cachefiles_get_security_ID(struct cachefiles_cache *cache)
1818
struct cred *new;
1919
int ret;
2020

21-
_enter("{%s}", cache->secctx);
21+
_enter("{%u}", cache->have_secid ? cache->secid : 0);
2222

2323
new = prepare_kernel_cred(current);
2424
if (!new) {
2525
ret = -ENOMEM;
2626
goto error;
2727
}
2828

29-
if (cache->secctx) {
30-
ret = set_security_override_from_ctx(new, cache->secctx);
29+
if (cache->have_secid) {
30+
ret = set_security_override(new, cache->secid);
3131
if (ret < 0) {
3232
put_cred(new);
3333
pr_err("Security denies permission to nominate security context: error %d\n",

0 commit comments

Comments
 (0)