Skip to content

Commit f96a974

Browse files
committed
Merge tag 'lsm-pr-20250121' of git://git.kernel.org/pub/scm/linux/kernel/git/pcmoore/lsm
Pull lsm updates from Paul Moore: - Improved handling of LSM "secctx" strings through lsm_context struct The LSM secctx string interface is from an older time when only one LSM was supported, migrate over to the lsm_context struct to better support the different LSMs we now have and make it easier to support new LSMs in the future. These changes explain the Rust, VFS, and networking changes in the diffstat. - Only build lsm_audit.c if CONFIG_SECURITY and CONFIG_AUDIT are enabled Small tweak to be a bit smarter about when we build the LSM's common audit helpers. - Check for absurdly large policies from userspace in SafeSetID SafeSetID policies rules are fairly small, basically just "UID:UID", it easy to impose a limit of KMALLOC_MAX_SIZE on policy writes which helps quiet a number of syzbot related issues. While work is being done to address the syzbot issues through other mechanisms, this is a trivial and relatively safe fix that we can do now. - Various minor improvements and cleanups A collection of improvements to the kernel selftests, constification of some function parameters, removing redundant assignments, and local variable renames to improve readability. * tag 'lsm-pr-20250121' of git://git.kernel.org/pub/scm/linux/kernel/git/pcmoore/lsm: lockdown: initialize local array before use to quiet static analysis safesetid: check size of policy writes net: corrections for security_secid_to_secctx returns lsm: rename variable to avoid shadowing lsm: constify function parameters security: remove redundant assignment to return variable lsm: Only build lsm_audit.c if CONFIG_SECURITY and CONFIG_AUDIT are set selftests: refactor the lsm `flags_overset_lsm_set_self_attr` test binder: initialize lsm_context structure rust: replace lsm context+len with lsm_context lsm: secctx provider check on release lsm: lsm_context in security_dentry_init_security lsm: use lsm_context in security_inode_getsecctx lsm: replace context+len with lsm_context lsm: ensure the correct LSM context releaser
2 parents 678ca9f + 714d87c commit f96a974

File tree

31 files changed

+351
-309
lines changed

31 files changed

+351
-309
lines changed

drivers/android/binder.c

Lines changed: 12 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3017,8 +3017,7 @@ static void binder_transaction(struct binder_proc *proc,
30173017
struct binder_context *context = proc->context;
30183018
int t_debug_id = atomic_inc_return(&binder_last_id);
30193019
ktime_t t_start_time = ktime_get();
3020-
char *secctx = NULL;
3021-
u32 secctx_sz = 0;
3020+
struct lsm_context lsmctx = { };
30223021
struct list_head sgc_head;
30233022
struct list_head pf_head;
30243023
const void __user *user_buffer = (const void __user *)
@@ -3297,16 +3296,16 @@ static void binder_transaction(struct binder_proc *proc,
32973296
size_t added_size;
32983297

32993298
security_cred_getsecid(proc->cred, &secid);
3300-
ret = security_secid_to_secctx(secid, &secctx, &secctx_sz);
3301-
if (ret) {
3299+
ret = security_secid_to_secctx(secid, &lsmctx);
3300+
if (ret < 0) {
33023301
binder_txn_error("%d:%d failed to get security context\n",
33033302
thread->pid, proc->pid);
33043303
return_error = BR_FAILED_REPLY;
33053304
return_error_param = ret;
33063305
return_error_line = __LINE__;
33073306
goto err_get_secctx_failed;
33083307
}
3309-
added_size = ALIGN(secctx_sz, sizeof(u64));
3308+
added_size = ALIGN(lsmctx.len, sizeof(u64));
33103309
extra_buffers_size += added_size;
33113310
if (extra_buffers_size < added_size) {
33123311
binder_txn_error("%d:%d integer overflow of extra_buffers_size\n",
@@ -3340,23 +3339,23 @@ static void binder_transaction(struct binder_proc *proc,
33403339
t->buffer = NULL;
33413340
goto err_binder_alloc_buf_failed;
33423341
}
3343-
if (secctx) {
3342+
if (lsmctx.context) {
33443343
int err;
33453344
size_t buf_offset = ALIGN(tr->data_size, sizeof(void *)) +
33463345
ALIGN(tr->offsets_size, sizeof(void *)) +
33473346
ALIGN(extra_buffers_size, sizeof(void *)) -
3348-
ALIGN(secctx_sz, sizeof(u64));
3347+
ALIGN(lsmctx.len, sizeof(u64));
33493348

33503349
t->security_ctx = t->buffer->user_data + buf_offset;
33513350
err = binder_alloc_copy_to_buffer(&target_proc->alloc,
33523351
t->buffer, buf_offset,
3353-
secctx, secctx_sz);
3352+
lsmctx.context, lsmctx.len);
33543353
if (err) {
33553354
t->security_ctx = 0;
33563355
WARN_ON(1);
33573356
}
3358-
security_release_secctx(secctx, secctx_sz);
3359-
secctx = NULL;
3357+
security_release_secctx(&lsmctx);
3358+
lsmctx.context = NULL;
33603359
}
33613360
t->buffer->debug_id = t->debug_id;
33623361
t->buffer->transaction = t;
@@ -3400,7 +3399,7 @@ static void binder_transaction(struct binder_proc *proc,
34003399
off_end_offset = off_start_offset + tr->offsets_size;
34013400
sg_buf_offset = ALIGN(off_end_offset, sizeof(void *));
34023401
sg_buf_end_offset = sg_buf_offset + extra_buffers_size -
3403-
ALIGN(secctx_sz, sizeof(u64));
3402+
ALIGN(lsmctx.len, sizeof(u64));
34043403
off_min = 0;
34053404
for (buffer_offset = off_start_offset; buffer_offset < off_end_offset;
34063405
buffer_offset += sizeof(binder_size_t)) {
@@ -3779,8 +3778,8 @@ static void binder_transaction(struct binder_proc *proc,
37793778
binder_alloc_free_buf(&target_proc->alloc, t->buffer);
37803779
err_binder_alloc_buf_failed:
37813780
err_bad_extra_size:
3782-
if (secctx)
3783-
security_release_secctx(secctx, secctx_sz);
3781+
if (lsmctx.context)
3782+
security_release_secctx(&lsmctx);
37843783
err_get_secctx_failed:
37853784
kfree(tcomplete);
37863785
binder_stats_deleted(BINDER_STAT_TRANSACTION_COMPLETE);

fs/ceph/super.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1132,8 +1132,7 @@ struct ceph_acl_sec_ctx {
11321132
void *acl;
11331133
#endif
11341134
#ifdef CONFIG_CEPH_FS_SECURITY_LABEL
1135-
void *sec_ctx;
1136-
u32 sec_ctxlen;
1135+
struct lsm_context lsmctx;
11371136
#endif
11381137
#ifdef CONFIG_FS_ENCRYPTION
11391138
struct ceph_fscrypt_auth *fscrypt_auth;

fs/ceph/xattr.c

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1383,8 +1383,7 @@ int ceph_security_init_secctx(struct dentry *dentry, umode_t mode,
13831383
int err;
13841384

13851385
err = security_dentry_init_security(dentry, mode, &dentry->d_name,
1386-
&name, &as_ctx->sec_ctx,
1387-
&as_ctx->sec_ctxlen);
1386+
&name, &as_ctx->lsmctx);
13881387
if (err < 0) {
13891388
WARN_ON_ONCE(err != -EOPNOTSUPP);
13901389
err = 0; /* do nothing */
@@ -1409,7 +1408,7 @@ int ceph_security_init_secctx(struct dentry *dentry, umode_t mode,
14091408
*/
14101409
name_len = strlen(name);
14111410
err = ceph_pagelist_reserve(pagelist,
1412-
4 * 2 + name_len + as_ctx->sec_ctxlen);
1411+
4 * 2 + name_len + as_ctx->lsmctx.len);
14131412
if (err)
14141413
goto out;
14151414

@@ -1432,8 +1431,9 @@ int ceph_security_init_secctx(struct dentry *dentry, umode_t mode,
14321431
ceph_pagelist_encode_32(pagelist, name_len);
14331432
ceph_pagelist_append(pagelist, name, name_len);
14341433

1435-
ceph_pagelist_encode_32(pagelist, as_ctx->sec_ctxlen);
1436-
ceph_pagelist_append(pagelist, as_ctx->sec_ctx, as_ctx->sec_ctxlen);
1434+
ceph_pagelist_encode_32(pagelist, as_ctx->lsmctx.len);
1435+
ceph_pagelist_append(pagelist, as_ctx->lsmctx.context,
1436+
as_ctx->lsmctx.len);
14371437

14381438
err = 0;
14391439
out:
@@ -1451,7 +1451,7 @@ void ceph_release_acl_sec_ctx(struct ceph_acl_sec_ctx *as_ctx)
14511451
posix_acl_release(as_ctx->default_acl);
14521452
#endif
14531453
#ifdef CONFIG_CEPH_FS_SECURITY_LABEL
1454-
security_release_secctx(as_ctx->sec_ctx, as_ctx->sec_ctxlen);
1454+
security_release_secctx(&as_ctx->lsmctx);
14551455
#endif
14561456
#ifdef CONFIG_FS_ENCRYPTION
14571457
kfree(as_ctx->fscrypt_auth);

fs/fuse/dir.c

Lines changed: 18 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -467,29 +467,29 @@ static int get_security_context(struct dentry *entry, umode_t mode,
467467
{
468468
struct fuse_secctx *fctx;
469469
struct fuse_secctx_header *header;
470-
void *ctx = NULL, *ptr;
471-
u32 ctxlen, total_len = sizeof(*header);
470+
struct lsm_context lsmctx = { };
471+
void *ptr;
472+
u32 total_len = sizeof(*header);
472473
int err, nr_ctx = 0;
473-
const char *name;
474+
const char *name = NULL;
474475
size_t namelen;
475476

476477
err = security_dentry_init_security(entry, mode, &entry->d_name,
477-
&name, &ctx, &ctxlen);
478-
if (err) {
479-
if (err != -EOPNOTSUPP)
480-
goto out_err;
481-
/* No LSM is supporting this security hook. Ignore error */
482-
ctxlen = 0;
483-
ctx = NULL;
484-
}
478+
&name, &lsmctx);
479+
480+
/* If no LSM is supporting this security hook ignore error */
481+
if (err && err != -EOPNOTSUPP)
482+
goto out_err;
485483

486-
if (ctxlen) {
484+
if (lsmctx.len) {
487485
nr_ctx = 1;
488486
namelen = strlen(name) + 1;
489487
err = -EIO;
490-
if (WARN_ON(namelen > XATTR_NAME_MAX + 1 || ctxlen > S32_MAX))
488+
if (WARN_ON(namelen > XATTR_NAME_MAX + 1 ||
489+
lsmctx.len > S32_MAX))
491490
goto out_err;
492-
total_len += FUSE_REC_ALIGN(sizeof(*fctx) + namelen + ctxlen);
491+
total_len += FUSE_REC_ALIGN(sizeof(*fctx) + namelen +
492+
lsmctx.len);
493493
}
494494

495495
err = -ENOMEM;
@@ -502,19 +502,20 @@ static int get_security_context(struct dentry *entry, umode_t mode,
502502
ptr += sizeof(*header);
503503
if (nr_ctx) {
504504
fctx = ptr;
505-
fctx->size = ctxlen;
505+
fctx->size = lsmctx.len;
506506
ptr += sizeof(*fctx);
507507

508508
strcpy(ptr, name);
509509
ptr += namelen;
510510

511-
memcpy(ptr, ctx, ctxlen);
511+
memcpy(ptr, lsmctx.context, lsmctx.len);
512512
}
513513
ext->size = total_len;
514514
ext->value = header;
515515
err = 0;
516516
out_err:
517-
kfree(ctx);
517+
if (nr_ctx)
518+
security_release_secctx(&lsmctx);
518519
return err;
519520
}
520521

fs/nfs/nfs4proc.c

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,7 @@ static inline struct nfs4_label *
114114
nfs4_label_init_security(struct inode *dir, struct dentry *dentry,
115115
struct iattr *sattr, struct nfs4_label *label)
116116
{
117+
struct lsm_context shim;
117118
int err;
118119

119120
if (label == NULL)
@@ -128,18 +129,25 @@ nfs4_label_init_security(struct inode *dir, struct dentry *dentry,
128129
label->label = NULL;
129130

130131
err = security_dentry_init_security(dentry, sattr->ia_mode,
131-
&dentry->d_name, NULL,
132-
(void **)&label->label, &label->len);
133-
if (err == 0)
134-
return label;
132+
&dentry->d_name, NULL, &shim);
133+
if (err)
134+
return NULL;
135135

136-
return NULL;
136+
label->label = shim.context;
137+
label->len = shim.len;
138+
return label;
137139
}
138140
static inline void
139141
nfs4_label_release_security(struct nfs4_label *label)
140142
{
141-
if (label)
142-
security_release_secctx(label->label, label->len);
143+
struct lsm_context shim;
144+
145+
if (label) {
146+
shim.context = label->label;
147+
shim.len = label->len;
148+
shim.id = LSM_ID_UNDEF;
149+
security_release_secctx(&shim);
150+
}
143151
}
144152
static inline u32 *nfs4_bitmask(struct nfs_server *server, struct nfs4_label *label)
145153
{

fs/nfsd/nfs4xdr.c

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2818,11 +2818,11 @@ static __be32 nfsd4_encode_nfsace4(struct xdr_stream *xdr, struct svc_rqst *rqst
28182818
#ifdef CONFIG_NFSD_V4_SECURITY_LABEL
28192819
static inline __be32
28202820
nfsd4_encode_security_label(struct xdr_stream *xdr, struct svc_rqst *rqstp,
2821-
void *context, int len)
2821+
const struct lsm_context *context)
28222822
{
28232823
__be32 *p;
28242824

2825-
p = xdr_reserve_space(xdr, len + 4 + 4 + 4);
2825+
p = xdr_reserve_space(xdr, context->len + 4 + 4 + 4);
28262826
if (!p)
28272827
return nfserr_resource;
28282828

@@ -2832,13 +2832,13 @@ nfsd4_encode_security_label(struct xdr_stream *xdr, struct svc_rqst *rqstp,
28322832
*/
28332833
*p++ = cpu_to_be32(0); /* lfs */
28342834
*p++ = cpu_to_be32(0); /* pi */
2835-
p = xdr_encode_opaque(p, context, len);
2835+
p = xdr_encode_opaque(p, context->context, context->len);
28362836
return 0;
28372837
}
28382838
#else
28392839
static inline __be32
28402840
nfsd4_encode_security_label(struct xdr_stream *xdr, struct svc_rqst *rqstp,
2841-
void *context, int len)
2841+
struct lsm_context *context)
28422842
{ return 0; }
28432843
#endif
28442844

@@ -2920,8 +2920,7 @@ struct nfsd4_fattr_args {
29202920
struct kstatfs statfs;
29212921
struct nfs4_acl *acl;
29222922
#ifdef CONFIG_NFSD_V4_SECURITY_LABEL
2923-
void *context;
2924-
int contextlen;
2923+
struct lsm_context context;
29252924
#endif
29262925
u32 rdattr_err;
29272926
bool contextsupport;
@@ -3376,8 +3375,7 @@ static __be32 nfsd4_encode_fattr4_suppattr_exclcreat(struct xdr_stream *xdr,
33763375
static __be32 nfsd4_encode_fattr4_sec_label(struct xdr_stream *xdr,
33773376
const struct nfsd4_fattr_args *args)
33783377
{
3379-
return nfsd4_encode_security_label(xdr, args->rqstp,
3380-
args->context, args->contextlen);
3378+
return nfsd4_encode_security_label(xdr, args->rqstp, &args->context);
33813379
}
33823380
#endif
33833381

@@ -3527,7 +3525,7 @@ nfsd4_encode_fattr4(struct svc_rqst *rqstp, struct xdr_stream *xdr,
35273525
args.ignore_crossmnt = (ignore_crossmnt != 0);
35283526
args.acl = NULL;
35293527
#ifdef CONFIG_NFSD_V4_SECURITY_LABEL
3530-
args.context = NULL;
3528+
args.context.context = NULL;
35313529
#endif
35323530

35333531
/*
@@ -3607,7 +3605,7 @@ nfsd4_encode_fattr4(struct svc_rqst *rqstp, struct xdr_stream *xdr,
36073605
attrmask[0] & FATTR4_WORD0_SUPPORTED_ATTRS) {
36083606
if (exp->ex_flags & NFSEXP_SECURITY_LABEL)
36093607
err = security_inode_getsecctx(d_inode(dentry),
3610-
&args.context, &args.contextlen);
3608+
&args.context);
36113609
else
36123610
err = -EOPNOTSUPP;
36133611
args.contextsupport = (err == 0);
@@ -3644,8 +3642,8 @@ nfsd4_encode_fattr4(struct svc_rqst *rqstp, struct xdr_stream *xdr,
36443642

36453643
out:
36463644
#ifdef CONFIG_NFSD_V4_SECURITY_LABEL
3647-
if (args.context)
3648-
security_release_secctx(args.context, args.contextlen);
3645+
if (args.context.context)
3646+
security_release_secctx(&args.context);
36493647
#endif /* CONFIG_NFSD_V4_SECURITY_LABEL */
36503648
kfree(args.acl);
36513649
if (tempfh) {

include/linux/lsm_audit.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,14 +116,28 @@ struct common_audit_data {
116116
#define v4info fam.v4
117117
#define v6info fam.v6
118118

119+
#ifdef CONFIG_AUDIT
120+
119121
int ipv4_skb_to_auditdata(struct sk_buff *skb,
120122
struct common_audit_data *ad, u8 *proto);
121123

124+
#if IS_ENABLED(CONFIG_IPV6)
122125
int ipv6_skb_to_auditdata(struct sk_buff *skb,
123126
struct common_audit_data *ad, u8 *proto);
127+
#endif /* IS_ENABLED(CONFIG_IPV6) */
124128

125129
void common_lsm_audit(struct common_audit_data *a,
126130
void (*pre_audit)(struct audit_buffer *, void *),
127131
void (*post_audit)(struct audit_buffer *, void *));
128132

133+
#else /* CONFIG_AUDIT */
134+
135+
static inline void common_lsm_audit(struct common_audit_data *a,
136+
void (*pre_audit)(struct audit_buffer *, void *),
137+
void (*post_audit)(struct audit_buffer *, void *))
138+
{
139+
}
140+
141+
#endif /* CONFIG_AUDIT */
142+
129143
#endif

include/linux/lsm_hook_defs.h

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ LSM_HOOK(int, 0, move_mount, const struct path *from_path,
8383
const struct path *to_path)
8484
LSM_HOOK(int, -EOPNOTSUPP, dentry_init_security, struct dentry *dentry,
8585
int mode, const struct qstr *name, const char **xattr_name,
86-
void **ctx, u32 *ctxlen)
86+
struct lsm_context *cp)
8787
LSM_HOOK(int, 0, dentry_create_files_as, struct dentry *dentry, int mode,
8888
struct qstr *name, const struct cred *old, struct cred *new)
8989

@@ -295,17 +295,16 @@ LSM_HOOK(int, -EINVAL, getprocattr, struct task_struct *p, const char *name,
295295
char **value)
296296
LSM_HOOK(int, -EINVAL, setprocattr, const char *name, void *value, size_t size)
297297
LSM_HOOK(int, 0, ismaclabel, const char *name)
298-
LSM_HOOK(int, -EOPNOTSUPP, secid_to_secctx, u32 secid, char **secdata,
299-
u32 *seclen)
298+
LSM_HOOK(int, -EOPNOTSUPP, secid_to_secctx, u32 secid, struct lsm_context *cp)
300299
LSM_HOOK(int, -EOPNOTSUPP, lsmprop_to_secctx, struct lsm_prop *prop,
301-
char **secdata, u32 *seclen)
300+
struct lsm_context *cp)
302301
LSM_HOOK(int, 0, secctx_to_secid, const char *secdata, u32 seclen, u32 *secid)
303-
LSM_HOOK(void, LSM_RET_VOID, release_secctx, char *secdata, u32 seclen)
302+
LSM_HOOK(void, LSM_RET_VOID, release_secctx, struct lsm_context *cp)
304303
LSM_HOOK(void, LSM_RET_VOID, inode_invalidate_secctx, struct inode *inode)
305304
LSM_HOOK(int, 0, inode_notifysecctx, struct inode *inode, void *ctx, u32 ctxlen)
306305
LSM_HOOK(int, 0, inode_setsecctx, struct dentry *dentry, void *ctx, u32 ctxlen)
307-
LSM_HOOK(int, -EOPNOTSUPP, inode_getsecctx, struct inode *inode, void **ctx,
308-
u32 *ctxlen)
306+
LSM_HOOK(int, -EOPNOTSUPP, inode_getsecctx, struct inode *inode,
307+
struct lsm_context *cp)
309308

310309
#if defined(CONFIG_SECURITY) && defined(CONFIG_WATCH_QUEUE)
311310
LSM_HOOK(int, 0, post_notification, const struct cred *w_cred,

0 commit comments

Comments
 (0)