Skip to content

Commit de6f87b

Browse files
cschauflerAndrea Righi
authored andcommitted
UBUNTU: SAUCE: apparmor4.0.0 [28/76]: Stacking v38: LSM: Ensure the correct LSM context releaser
BugLink: https://bugs.launchpad.net/bugs/2028253 Add a new lsmcontext data structure to hold all the information about a "security context", including the string, its size and which LSM allocated the string. The allocation information is necessary because LSMs have different policies regarding the lifecycle of these strings. SELinux allocates and destroys them on each use, whereas Smack provides a pointer to an entry in a list that never goes away. Reviewed-by: Kees Cook <[email protected]> Reviewed-by: John Johansen <[email protected]> Acked-by: Paul Moore <[email protected]> Acked-by: Stephen Smalley <[email protected]> Acked-by: Chuck Lever <[email protected]> Signed-off-by: Casey Schaufler <[email protected]> Cc: [email protected] Cc: [email protected] Cc: [email protected] Cc: [email protected] To: Pablo Neira Ayuso <[email protected]> Cc: [email protected] Signed-off-by: John Johansen <[email protected]> (cherry picked from https://gitlab.com/jjohansen/apparmor-kernel) Signed-off-by: Andrea Righi <[email protected]>
1 parent 648a07a commit de6f87b

File tree

15 files changed

+122
-37
lines changed

15 files changed

+122
-37
lines changed

drivers/android/binder.c

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2922,6 +2922,7 @@ static void binder_transaction(struct binder_proc *proc,
29222922
ktime_t t_start_time = ktime_get();
29232923
char *secctx = NULL;
29242924
u32 secctx_sz = 0;
2925+
struct lsmcontext scaff; /* scaffolding */
29252926
struct list_head sgc_head;
29262927
struct list_head pf_head;
29272928
const void __user *user_buffer = (const void __user *)
@@ -3258,7 +3259,8 @@ static void binder_transaction(struct binder_proc *proc,
32583259
t->security_ctx = 0;
32593260
WARN_ON(1);
32603261
}
3261-
security_release_secctx(secctx, secctx_sz);
3262+
lsmcontext_init(&scaff, secctx, secctx_sz, 0);
3263+
security_release_secctx(&scaff);
32623264
secctx = NULL;
32633265
}
32643266
t->buffer->debug_id = t->debug_id;
@@ -3682,8 +3684,10 @@ static void binder_transaction(struct binder_proc *proc,
36823684
binder_alloc_free_buf(&target_proc->alloc, t->buffer);
36833685
err_binder_alloc_buf_failed:
36843686
err_bad_extra_size:
3685-
if (secctx)
3686-
security_release_secctx(secctx, secctx_sz);
3687+
if (secctx) {
3688+
lsmcontext_init(&scaff, secctx, secctx_sz, 0);
3689+
security_release_secctx(&scaff);
3690+
}
36873691
err_get_secctx_failed:
36883692
kfree(tcomplete);
36893693
binder_stats_deleted(BINDER_STAT_TRANSACTION_COMPLETE);

fs/ceph/xattr.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1446,12 +1446,16 @@ int ceph_security_init_secctx(struct dentry *dentry, umode_t mode,
14461446

14471447
void ceph_release_acl_sec_ctx(struct ceph_acl_sec_ctx *as_ctx)
14481448
{
1449+
#ifdef CONFIG_CEPH_FS_SECURITY_LABEL
1450+
struct lsmcontext scaff; /* scaffolding */
1451+
#endif
14491452
#ifdef CONFIG_CEPH_FS_POSIX_ACL
14501453
posix_acl_release(as_ctx->acl);
14511454
posix_acl_release(as_ctx->default_acl);
14521455
#endif
14531456
#ifdef CONFIG_CEPH_FS_SECURITY_LABEL
1454-
security_release_secctx(as_ctx->sec_ctx, as_ctx->sec_ctxlen);
1457+
lsmcontext_init(&scaff, as_ctx->sec_ctx, as_ctx->sec_ctxlen, 0);
1458+
security_release_secctx(&scaff);
14551459
#endif
14561460
#ifdef CONFIG_FS_ENCRYPTION
14571461
kfree(as_ctx->fscrypt_auth);

fs/nfs/nfs4proc.c

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -138,8 +138,12 @@ nfs4_label_init_security(struct inode *dir, struct dentry *dentry,
138138
static inline void
139139
nfs4_label_release_security(struct nfs4_label *label)
140140
{
141-
if (label)
142-
security_release_secctx(label->label, label->len);
141+
struct lsmcontext scaff; /* scaffolding */
142+
143+
if (label) {
144+
lsmcontext_init(&scaff, label->label, label->len, 0);
145+
security_release_secctx(&scaff);
146+
}
143147
}
144148
static inline u32 *nfs4_bitmask(struct nfs_server *server, struct nfs4_label *label)
145149
{

fs/nfsd/nfs4xdr.c

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2964,6 +2964,7 @@ nfsd4_encode_fattr(struct xdr_stream *xdr, struct svc_fh *fhp,
29642964
int err;
29652965
struct nfs4_acl *acl = NULL;
29662966
#ifdef CONFIG_NFSD_V4_SECURITY_LABEL
2967+
struct lsmcontext scaff; /* scaffolding */
29672968
void *context = NULL;
29682969
int contextlen;
29692970
#endif
@@ -3465,8 +3466,10 @@ nfsd4_encode_fattr(struct xdr_stream *xdr, struct svc_fh *fhp,
34653466

34663467
out:
34673468
#ifdef CONFIG_NFSD_V4_SECURITY_LABEL
3468-
if (context)
3469-
security_release_secctx(context, contextlen);
3469+
if (context) {
3470+
lsmcontext_init(&scaff, context, contextlen, 0); /*scaffolding*/
3471+
security_release_secctx(&scaff);
3472+
}
34703473
#endif /* CONFIG_NFSD_V4_SECURITY_LABEL */
34713474
kfree(acl);
34723475
if (tempfh) {

include/linux/security.h

Lines changed: 33 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,37 @@ extern const char *const lockdown_reasons[LOCKDOWN_CONFIDENTIALITY_MAX+1];
157157
extern int lsm_id;
158158
extern struct lsm_id *lsm_idlist[];
159159

160+
/*
161+
* A "security context" is the text representation of
162+
* the information used by LSMs.
163+
* This structure contains the string, its length, and which LSM
164+
* it is useful for.
165+
*/
166+
struct lsmcontext {
167+
char *context; /* Provided by the module */
168+
u32 len;
169+
int slot; /* Identifies the module */
170+
};
171+
172+
/**
173+
* lsmcontext_init - initialize an lsmcontext structure.
174+
* @cp: Pointer to the context to initialize
175+
* @context: Initial context, or NULL
176+
* @size: Size of context, or 0
177+
* @slot: Which LSM provided the context
178+
*
179+
* Fill in the lsmcontext from the provided information.
180+
* This is a scaffolding function that will be removed when
181+
* lsmcontext integration is complete.
182+
*/
183+
static inline void lsmcontext_init(struct lsmcontext *cp, char *context,
184+
u32 size, int slot)
185+
{
186+
cp->slot = slot;
187+
cp->context = context;
188+
cp->len = size;
189+
}
190+
160191
/*
161192
* Data exported by the security modules
162193
*
@@ -614,7 +645,7 @@ int security_ismaclabel(const char *name);
614645
int security_secid_to_secctx(struct lsmblob *blob, char **secdata, u32 *seclen);
615646
int security_secctx_to_secid(const char *secdata, u32 seclen,
616647
struct lsmblob *blob);
617-
void security_release_secctx(char *secdata, u32 seclen);
648+
void security_release_secctx(struct lsmcontext *cp);
618649
void security_inode_invalidate_secctx(struct inode *inode);
619650
int security_inode_notifysecctx(struct inode *inode, void *ctx, u32 ctxlen);
620651
int security_inode_setsecctx(struct dentry *dentry, void *ctx, u32 ctxlen);
@@ -1509,7 +1540,7 @@ static inline int security_secctx_to_secid(const char *secdata,
15091540
return -EOPNOTSUPP;
15101541
}
15111542

1512-
static inline void security_release_secctx(char *secdata, u32 seclen)
1543+
static inline void security_release_secctx(struct lsmcontext *cp)
15131544
{
15141545
}
15151546

include/net/scm.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,7 @@ static __inline__ int scm_send(struct socket *sock, struct msghdr *msg,
9292
#ifdef CONFIG_SECURITY_NETWORK
9393
static inline void scm_passec(struct socket *sock, struct msghdr *msg, struct scm_cookie *scm)
9494
{
95+
struct lsmcontext context;
9596
struct lsmblob lb;
9697
char *secdata;
9798
u32 seclen;
@@ -106,7 +107,9 @@ static inline void scm_passec(struct socket *sock, struct msghdr *msg, struct sc
106107

107108
if (!err) {
108109
put_cmsg(msg, SOL_SOCKET, SCM_SECURITY, seclen, secdata);
109-
security_release_secctx(secdata, seclen);
110+
/*scaffolding*/
111+
lsmcontext_init(&context, secdata, seclen, 0);
112+
security_release_secctx(&context);
110113
}
111114
}
112115
}

kernel/audit.c

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1212,6 +1212,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
12121212
struct audit_sig_info *sig_data;
12131213
char *ctx = NULL;
12141214
u32 len;
1215+
struct lsmcontext scaff; /* scaffolding */
12151216

12161217
err = audit_netlink_ok(skb, msg_type);
12171218
if (err)
@@ -1469,15 +1470,18 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
14691470
}
14701471
sig_data = kmalloc(struct_size(sig_data, ctx, len), GFP_KERNEL);
14711472
if (!sig_data) {
1472-
if (lsmblob_is_set(&audit_sig_lsm))
1473-
security_release_secctx(ctx, len);
1473+
if (lsmblob_is_set(&audit_sig_lsm)) {
1474+
lsmcontext_init(&scaff, ctx, len, 0);
1475+
security_release_secctx(&scaff);
1476+
}
14741477
return -ENOMEM;
14751478
}
14761479
sig_data->uid = from_kuid(&init_user_ns, audit_sig_uid);
14771480
sig_data->pid = audit_sig_pid;
14781481
if (lsmblob_is_set(&audit_sig_lsm)) {
14791482
memcpy(sig_data->ctx, ctx, len);
1480-
security_release_secctx(ctx, len);
1483+
lsmcontext_init(&scaff, ctx, len, 0);
1484+
security_release_secctx(&scaff);
14811485
}
14821486
audit_send_reply(skb, seq, AUDIT_SIGNAL_INFO, 0, 0,
14831487
sig_data, struct_size(sig_data, ctx, len));
@@ -2169,6 +2173,7 @@ int audit_log_task_context(struct audit_buffer *ab)
21692173
unsigned len;
21702174
int error;
21712175
struct lsmblob blob;
2176+
struct lsmcontext scaff; /* scaffolding */
21722177

21732178
security_current_getsecid_subj(&blob);
21742179
if (!lsmblob_is_set(&blob))
@@ -2183,7 +2188,8 @@ int audit_log_task_context(struct audit_buffer *ab)
21832188
}
21842189

21852190
audit_log_format(ab, " subj=%s", ctx);
2186-
security_release_secctx(ctx, len);
2191+
lsmcontext_init(&scaff, ctx, len, 0);
2192+
security_release_secctx(&scaff);
21872193
return 0;
21882194

21892195
error_path:

kernel/auditsc.c

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1100,6 +1100,7 @@ static int audit_log_pid_context(struct audit_context *context, pid_t pid,
11001100
struct lsmblob *blob, char *comm)
11011101
{
11021102
struct audit_buffer *ab;
1103+
struct lsmcontext lsmcxt;
11031104
char *ctx = NULL;
11041105
u32 len;
11051106
int rc = 0;
@@ -1117,7 +1118,8 @@ static int audit_log_pid_context(struct audit_context *context, pid_t pid,
11171118
rc = 1;
11181119
} else {
11191120
audit_log_format(ab, " obj=%s", ctx);
1120-
security_release_secctx(ctx, len);
1121+
lsmcontext_init(&lsmcxt, ctx, len, 0); /*scaffolding*/
1122+
security_release_secctx(&lsmcxt);
11211123
}
11221124
}
11231125
audit_log_format(ab, " ocomm=");
@@ -1373,6 +1375,7 @@ static void audit_log_time(struct audit_context *context, struct audit_buffer **
13731375

13741376
static void show_special(struct audit_context *context, int *call_panic)
13751377
{
1378+
struct lsmcontext lsmcxt;
13761379
struct audit_buffer *ab;
13771380
int i;
13781381

@@ -1407,7 +1410,8 @@ static void show_special(struct audit_context *context, int *call_panic)
14071410
*call_panic = 1;
14081411
} else {
14091412
audit_log_format(ab, " obj=%s", ctx);
1410-
security_release_secctx(ctx, len);
1413+
lsmcontext_init(&lsmcxt, ctx, len, 0);
1414+
security_release_secctx(&lsmcxt);
14111415
}
14121416
}
14131417
if (context->ipc.has_perm) {
@@ -1569,6 +1573,7 @@ static void audit_log_name(struct audit_context *context, struct audit_names *n,
15691573
char *ctx = NULL;
15701574
u32 len;
15711575
struct lsmblob blob;
1576+
struct lsmcontext lsmcxt;
15721577

15731578
lsmblob_init(&blob, n->osid);
15741579
if (security_secid_to_secctx(&blob, &ctx, &len)) {
@@ -1577,7 +1582,8 @@ static void audit_log_name(struct audit_context *context, struct audit_names *n,
15771582
*call_panic = 2;
15781583
} else {
15791584
audit_log_format(ab, " obj=%s", ctx);
1580-
security_release_secctx(ctx, len);
1585+
lsmcontext_init(&lsmcxt, ctx, len, 0); /* scaffolding */
1586+
security_release_secctx(&lsmcxt);
15811587
}
15821588
}
15831589

net/ipv4/ip_sockglue.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,7 @@ static void ip_cmsg_recv_checksum(struct msghdr *msg, struct sk_buff *skb,
130130

131131
static void ip_cmsg_recv_security(struct msghdr *msg, struct sk_buff *skb)
132132
{
133+
struct lsmcontext context;
133134
struct lsmblob lb;
134135
char *secdata;
135136
u32 seclen, secid;
@@ -145,7 +146,8 @@ static void ip_cmsg_recv_security(struct msghdr *msg, struct sk_buff *skb)
145146
return;
146147

147148
put_cmsg(msg, SOL_IP, SCM_SECURITY, seclen, secdata);
148-
security_release_secctx(secdata, seclen);
149+
lsmcontext_init(&context, secdata, seclen, 0); /* scaffolding */
150+
security_release_secctx(&context);
149151
}
150152

151153
static void ip_cmsg_recv_dstaddr(struct msghdr *msg, struct sk_buff *skb)

net/netfilter/nf_conntrack_netlink.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -359,6 +359,7 @@ static int ctnetlink_dump_secctx(struct sk_buff *skb, const struct nf_conn *ct)
359359
int len, ret;
360360
char *secctx;
361361
struct lsmblob blob;
362+
struct lsmcontext context;
362363

363364
/* lsmblob_init() puts ct->secmark into all of the secids in blob.
364365
* security_secid_to_secctx() will know which security module
@@ -379,7 +380,8 @@ static int ctnetlink_dump_secctx(struct sk_buff *skb, const struct nf_conn *ct)
379380

380381
ret = 0;
381382
nla_put_failure:
382-
security_release_secctx(secctx, len);
383+
lsmcontext_init(&context, secctx, len, 0); /* scaffolding */
384+
security_release_secctx(&context);
383385
return ret;
384386
}
385387
#else

net/netfilter/nf_conntrack_standalone.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,7 @@ static void ct_show_secctx(struct seq_file *s, const struct nf_conn *ct)
179179
u32 len;
180180
char *secctx;
181181
struct lsmblob blob;
182+
struct lsmcontext context;
182183

183184
lsmblob_init(&blob, ct->secmark);
184185
ret = security_secid_to_secctx(&blob, &secctx, &len);
@@ -187,7 +188,8 @@ static void ct_show_secctx(struct seq_file *s, const struct nf_conn *ct)
187188

188189
seq_printf(s, "secctx=%s ", secctx);
189190

190-
security_release_secctx(secctx, len);
191+
lsmcontext_init(&context, secctx, len, 0); /* scaffolding */
192+
security_release_secctx(&context);
191193
}
192194
#else
193195
static inline void ct_show_secctx(struct seq_file *s, const struct nf_conn *ct)

net/netfilter/nfnetlink_queue.c

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -412,6 +412,7 @@ nfqnl_build_packet_message(struct net *net, struct nfqnl_instance *queue,
412412
enum ip_conntrack_info ctinfo = 0;
413413
const struct nfnl_ct_hook *nfnl_ct;
414414
bool csum_verify;
415+
struct lsmcontext scaff; /* scaffolding */
415416
char *secdata = NULL;
416417
u32 seclen = 0;
417418
ktime_t tstamp;
@@ -655,17 +656,21 @@ nfqnl_build_packet_message(struct net *net, struct nfqnl_instance *queue,
655656
}
656657

657658
nlh->nlmsg_len = skb->len;
658-
if (seclen)
659-
security_release_secctx(secdata, seclen);
659+
if (seclen) {
660+
lsmcontext_init(&scaff, secdata, seclen, 0);
661+
security_release_secctx(&scaff);
662+
}
660663
return skb;
661664

662665
nla_put_failure:
663666
skb_tx_error(entskb);
664667
kfree_skb(skb);
665668
net_err_ratelimited("nf_queue: error creating packet message\n");
666669
nlmsg_failure:
667-
if (seclen)
668-
security_release_secctx(secdata, seclen);
670+
if (seclen) {
671+
lsmcontext_init(&scaff, secdata, seclen, 0);
672+
security_release_secctx(&scaff);
673+
}
669674
return NULL;
670675
}
671676

0 commit comments

Comments
 (0)