Skip to content

Commit 2b93c2c

Browse files
committed
Merge tag 'lsm-pr-20231030' of git://git.kernel.org/pub/scm/linux/kernel/git/pcmoore/lsm
Pull LSM updates from Paul Moore: - Add new credential functions, get_cred_many() and put_cred_many() to save some atomic_t operations for a few operations. While not strictly LSM related, this patchset had been rotting on the mailing lists for some time and since the LSMs do care a lot about credentials I thought it reasonable to give this patch a home. - Five patches to constify different LSM hook parameters. - Fix a spelling mistake. * tag 'lsm-pr-20231030' of git://git.kernel.org/pub/scm/linux/kernel/git/pcmoore/lsm: lsm: fix a spelling mistake cred: add get_cred_many and put_cred_many lsm: constify 'sb' parameter in security_sb_kern_mount() lsm: constify 'bprm' parameter in security_bprm_committed_creds() lsm: constify 'bprm' parameter in security_bprm_committing_creds() lsm: constify 'file' parameter in security_bprm_creds_from_file() lsm: constify 'sb' parameter in security_quotactl()
2 parents f5fc9e4 + e508560 commit 2b93c2c

File tree

10 files changed

+97
-52
lines changed

10 files changed

+97
-52
lines changed

include/linux/cred.h

Lines changed: 50 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -219,6 +219,20 @@ static inline bool cap_ambient_invariant_ok(const struct cred *cred)
219219
cred->cap_inheritable));
220220
}
221221

222+
/**
223+
* get_new_cred_many - Get references on a new set of credentials
224+
* @cred: The new credentials to reference
225+
* @nr: Number of references to acquire
226+
*
227+
* Get references on the specified set of new credentials. The caller must
228+
* release all acquired references.
229+
*/
230+
static inline struct cred *get_new_cred_many(struct cred *cred, int nr)
231+
{
232+
atomic_add(nr, &cred->usage);
233+
return cred;
234+
}
235+
222236
/**
223237
* get_new_cred - Get a reference on a new set of credentials
224238
* @cred: The new credentials to reference
@@ -228,31 +242,45 @@ static inline bool cap_ambient_invariant_ok(const struct cred *cred)
228242
*/
229243
static inline struct cred *get_new_cred(struct cred *cred)
230244
{
231-
atomic_inc(&cred->usage);
232-
return cred;
245+
return get_new_cred_many(cred, 1);
233246
}
234247

235248
/**
236-
* get_cred - Get a reference on a set of credentials
249+
* get_cred_many - Get references on a set of credentials
237250
* @cred: The credentials to reference
251+
* @nr: Number of references to acquire
238252
*
239-
* Get a reference on the specified set of credentials. The caller must
240-
* release the reference. If %NULL is passed, it is returned with no action.
253+
* Get references on the specified set of credentials. The caller must release
254+
* all acquired reference. If %NULL is passed, it is returned with no action.
241255
*
242256
* This is used to deal with a committed set of credentials. Although the
243257
* pointer is const, this will temporarily discard the const and increment the
244258
* usage count. The purpose of this is to attempt to catch at compile time the
245259
* accidental alteration of a set of credentials that should be considered
246260
* immutable.
247261
*/
248-
static inline const struct cred *get_cred(const struct cred *cred)
262+
static inline const struct cred *get_cred_many(const struct cred *cred, int nr)
249263
{
250264
struct cred *nonconst_cred = (struct cred *) cred;
251265
if (!cred)
252266
return cred;
253267
validate_creds(cred);
254268
nonconst_cred->non_rcu = 0;
255-
return get_new_cred(nonconst_cred);
269+
return get_new_cred_many(nonconst_cred, nr);
270+
}
271+
272+
/*
273+
* get_cred - Get a reference on a set of credentials
274+
* @cred: The credentials to reference
275+
*
276+
* Get a reference on the specified set of credentials. The caller must
277+
* release the reference. If %NULL is passed, it is returned with no action.
278+
*
279+
* This is used to deal with a committed set of credentials.
280+
*/
281+
static inline const struct cred *get_cred(const struct cred *cred)
282+
{
283+
return get_cred_many(cred, 1);
256284
}
257285

258286
static inline const struct cred *get_cred_rcu(const struct cred *cred)
@@ -270,6 +298,7 @@ static inline const struct cred *get_cred_rcu(const struct cred *cred)
270298
/**
271299
* put_cred - Release a reference to a set of credentials
272300
* @cred: The credentials to release
301+
* @nr: Number of references to release
273302
*
274303
* Release a reference to a set of credentials, deleting them when the last ref
275304
* is released. If %NULL is passed, nothing is done.
@@ -278,17 +307,29 @@ static inline const struct cred *get_cred_rcu(const struct cred *cred)
278307
* on task_struct are attached by const pointers to prevent accidental
279308
* alteration of otherwise immutable credential sets.
280309
*/
281-
static inline void put_cred(const struct cred *_cred)
310+
static inline void put_cred_many(const struct cred *_cred, int nr)
282311
{
283312
struct cred *cred = (struct cred *) _cred;
284313

285314
if (cred) {
286315
validate_creds(cred);
287-
if (atomic_dec_and_test(&(cred)->usage))
316+
if (atomic_sub_and_test(nr, &cred->usage))
288317
__put_cred(cred);
289318
}
290319
}
291320

321+
/*
322+
* put_cred - Release a reference to a set of credentials
323+
* @cred: The credentials to release
324+
*
325+
* Release a reference to a set of credentials, deleting them when the last ref
326+
* is released. If %NULL is passed, nothing is done.
327+
*/
328+
static inline void put_cred(const struct cred *cred)
329+
{
330+
put_cred_many(cred, 1);
331+
}
332+
292333
/**
293334
* current_cred - Access the current task's subjective credentials
294335
*

include/linux/fs.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2478,7 +2478,7 @@ struct filename {
24782478
};
24792479
static_assert(offsetof(struct filename, iname) % sizeof(long) == 0);
24802480

2481-
static inline struct mnt_idmap *file_mnt_idmap(struct file *file)
2481+
static inline struct mnt_idmap *file_mnt_idmap(const struct file *file)
24822482
{
24832483
return mnt_idmap(file->f_path.mnt);
24842484
}

include/linux/lsm_hook_defs.h

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -43,17 +43,17 @@ LSM_HOOK(int, 0, capset, struct cred *new, const struct cred *old,
4343
const kernel_cap_t *permitted)
4444
LSM_HOOK(int, 0, capable, const struct cred *cred, struct user_namespace *ns,
4545
int cap, unsigned int opts)
46-
LSM_HOOK(int, 0, quotactl, int cmds, int type, int id, struct super_block *sb)
46+
LSM_HOOK(int, 0, quotactl, int cmds, int type, int id, const struct super_block *sb)
4747
LSM_HOOK(int, 0, quota_on, struct dentry *dentry)
4848
LSM_HOOK(int, 0, syslog, int type)
4949
LSM_HOOK(int, 0, settime, const struct timespec64 *ts,
5050
const struct timezone *tz)
5151
LSM_HOOK(int, 0, vm_enough_memory, struct mm_struct *mm, long pages)
5252
LSM_HOOK(int, 0, bprm_creds_for_exec, struct linux_binprm *bprm)
53-
LSM_HOOK(int, 0, bprm_creds_from_file, struct linux_binprm *bprm, struct file *file)
53+
LSM_HOOK(int, 0, bprm_creds_from_file, struct linux_binprm *bprm, const struct file *file)
5454
LSM_HOOK(int, 0, bprm_check_security, struct linux_binprm *bprm)
55-
LSM_HOOK(void, LSM_RET_VOID, bprm_committing_creds, struct linux_binprm *bprm)
56-
LSM_HOOK(void, LSM_RET_VOID, bprm_committed_creds, struct linux_binprm *bprm)
55+
LSM_HOOK(void, LSM_RET_VOID, bprm_committing_creds, const struct linux_binprm *bprm)
56+
LSM_HOOK(void, LSM_RET_VOID, bprm_committed_creds, const struct linux_binprm *bprm)
5757
LSM_HOOK(int, 0, fs_context_submount, struct fs_context *fc, struct super_block *reference)
5858
LSM_HOOK(int, 0, fs_context_dup, struct fs_context *fc,
5959
struct fs_context *src_sc)
@@ -66,7 +66,7 @@ LSM_HOOK(void, LSM_RET_VOID, sb_free_mnt_opts, void *mnt_opts)
6666
LSM_HOOK(int, 0, sb_eat_lsm_opts, char *orig, void **mnt_opts)
6767
LSM_HOOK(int, 0, sb_mnt_opts_compat, struct super_block *sb, void *mnt_opts)
6868
LSM_HOOK(int, 0, sb_remount, struct super_block *sb, void *mnt_opts)
69-
LSM_HOOK(int, 0, sb_kern_mount, struct super_block *sb)
69+
LSM_HOOK(int, 0, sb_kern_mount, const struct super_block *sb)
7070
LSM_HOOK(int, 0, sb_show_options, struct seq_file *m, struct super_block *sb)
7171
LSM_HOOK(int, 0, sb_statfs, struct dentry *dentry)
7272
LSM_HOOK(int, 0, sb_mount, const char *dev_name, const struct path *path,

include/linux/security.h

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,7 @@ extern int cap_capset(struct cred *new, const struct cred *old,
151151
const kernel_cap_t *effective,
152152
const kernel_cap_t *inheritable,
153153
const kernel_cap_t *permitted);
154-
extern int cap_bprm_creds_from_file(struct linux_binprm *bprm, struct file *file);
154+
extern int cap_bprm_creds_from_file(struct linux_binprm *bprm, const struct file *file);
155155
int cap_inode_setxattr(struct dentry *dentry, const char *name,
156156
const void *value, size_t size, int flags);
157157
int cap_inode_removexattr(struct mnt_idmap *idmap,
@@ -284,16 +284,16 @@ int security_capable(const struct cred *cred,
284284
struct user_namespace *ns,
285285
int cap,
286286
unsigned int opts);
287-
int security_quotactl(int cmds, int type, int id, struct super_block *sb);
287+
int security_quotactl(int cmds, int type, int id, const struct super_block *sb);
288288
int security_quota_on(struct dentry *dentry);
289289
int security_syslog(int type);
290290
int security_settime64(const struct timespec64 *ts, const struct timezone *tz);
291291
int security_vm_enough_memory_mm(struct mm_struct *mm, long pages);
292292
int security_bprm_creds_for_exec(struct linux_binprm *bprm);
293-
int security_bprm_creds_from_file(struct linux_binprm *bprm, struct file *file);
293+
int security_bprm_creds_from_file(struct linux_binprm *bprm, const struct file *file);
294294
int security_bprm_check(struct linux_binprm *bprm);
295-
void security_bprm_committing_creds(struct linux_binprm *bprm);
296-
void security_bprm_committed_creds(struct linux_binprm *bprm);
295+
void security_bprm_committing_creds(const struct linux_binprm *bprm);
296+
void security_bprm_committed_creds(const struct linux_binprm *bprm);
297297
int security_fs_context_submount(struct fs_context *fc, struct super_block *reference);
298298
int security_fs_context_dup(struct fs_context *fc, struct fs_context *src_fc);
299299
int security_fs_context_parse_param(struct fs_context *fc, struct fs_parameter *param);
@@ -304,7 +304,7 @@ void security_free_mnt_opts(void **mnt_opts);
304304
int security_sb_eat_lsm_opts(char *options, void **mnt_opts);
305305
int security_sb_mnt_opts_compat(struct super_block *sb, void *mnt_opts);
306306
int security_sb_remount(struct super_block *sb, void *mnt_opts);
307-
int security_sb_kern_mount(struct super_block *sb);
307+
int security_sb_kern_mount(const struct super_block *sb);
308308
int security_sb_show_options(struct seq_file *m, struct super_block *sb);
309309
int security_sb_statfs(struct dentry *dentry);
310310
int security_sb_mount(const char *dev_name, const struct path *path,
@@ -581,7 +581,7 @@ static inline int security_capable(const struct cred *cred,
581581
}
582582

583583
static inline int security_quotactl(int cmds, int type, int id,
584-
struct super_block *sb)
584+
const struct super_block *sb)
585585
{
586586
return 0;
587587
}
@@ -613,7 +613,7 @@ static inline int security_bprm_creds_for_exec(struct linux_binprm *bprm)
613613
}
614614

615615
static inline int security_bprm_creds_from_file(struct linux_binprm *bprm,
616-
struct file *file)
616+
const struct file *file)
617617
{
618618
return cap_bprm_creds_from_file(bprm, file);
619619
}
@@ -623,11 +623,11 @@ static inline int security_bprm_check(struct linux_binprm *bprm)
623623
return 0;
624624
}
625625

626-
static inline void security_bprm_committing_creds(struct linux_binprm *bprm)
626+
static inline void security_bprm_committing_creds(const struct linux_binprm *bprm)
627627
{
628628
}
629629

630-
static inline void security_bprm_committed_creds(struct linux_binprm *bprm)
630+
static inline void security_bprm_committed_creds(const struct linux_binprm *bprm)
631631
{
632632
}
633633

kernel/cred.c

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -162,23 +162,29 @@ EXPORT_SYMBOL(__put_cred);
162162
*/
163163
void exit_creds(struct task_struct *tsk)
164164
{
165-
struct cred *cred;
165+
struct cred *real_cred, *cred;
166166

167167
kdebug("exit_creds(%u,%p,%p,{%d,%d})", tsk->pid, tsk->real_cred, tsk->cred,
168168
atomic_read(&tsk->cred->usage),
169169
read_cred_subscribers(tsk->cred));
170170

171-
cred = (struct cred *) tsk->real_cred;
171+
real_cred = (struct cred *) tsk->real_cred;
172172
tsk->real_cred = NULL;
173-
validate_creds(cred);
174-
alter_cred_subscribers(cred, -1);
175-
put_cred(cred);
176173

177174
cred = (struct cred *) tsk->cred;
178175
tsk->cred = NULL;
176+
179177
validate_creds(cred);
180-
alter_cred_subscribers(cred, -1);
181-
put_cred(cred);
178+
if (real_cred == cred) {
179+
alter_cred_subscribers(cred, -2);
180+
put_cred_many(cred, 2);
181+
} else {
182+
validate_creds(real_cred);
183+
alter_cred_subscribers(real_cred, -1);
184+
put_cred(real_cred);
185+
alter_cred_subscribers(cred, -1);
186+
put_cred(cred);
187+
}
182188

183189
#ifdef CONFIG_KEYS_REQUEST_CACHE
184190
key_put(tsk->cached_requested_key);
@@ -355,8 +361,7 @@ int copy_creds(struct task_struct *p, unsigned long clone_flags)
355361
#endif
356362
clone_flags & CLONE_THREAD
357363
) {
358-
p->real_cred = get_cred(p->cred);
359-
get_cred(p->cred);
364+
p->real_cred = get_cred_many(p->cred, 2);
360365
alter_cred_subscribers(p->cred, 2);
361366
kdebug("share_creds(%p{%d,%d})",
362367
p->cred, atomic_read(&p->cred->usage),
@@ -520,8 +525,7 @@ int commit_creds(struct cred *new)
520525
proc_id_connector(task, PROC_EVENT_GID);
521526

522527
/* release the old obj and subj refs both */
523-
put_cred(old);
524-
put_cred(old);
528+
put_cred_many(old, 2);
525529
return 0;
526530
}
527531
EXPORT_SYMBOL(commit_creds);

security/apparmor/lsm.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -734,7 +734,7 @@ static int apparmor_setprocattr(const char *name, void *value,
734734
* apparmor_bprm_committing_creds - do task cleanup on committing new creds
735735
* @bprm: binprm for the exec (NOT NULL)
736736
*/
737-
static void apparmor_bprm_committing_creds(struct linux_binprm *bprm)
737+
static void apparmor_bprm_committing_creds(const struct linux_binprm *bprm)
738738
{
739739
struct aa_label *label = aa_current_raw_label();
740740
struct aa_label *new_label = cred_label(bprm->cred);
@@ -756,7 +756,7 @@ static void apparmor_bprm_committing_creds(struct linux_binprm *bprm)
756756
* apparmor_bprm_committed_creds() - do cleanup after new creds committed
757757
* @bprm: binprm for the exec (NOT NULL)
758758
*/
759-
static void apparmor_bprm_committed_creds(struct linux_binprm *bprm)
759+
static void apparmor_bprm_committed_creds(const struct linux_binprm *bprm)
760760
{
761761
/* clear out temporary/transitional state from the context */
762762
aa_clear_task_ctx_trans(task_ctx(current));

security/commoncap.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -720,7 +720,7 @@ int get_vfs_caps_from_disk(struct mnt_idmap *idmap,
720720
* its xattrs and, if present, apply them to the proposed credentials being
721721
* constructed by execve().
722722
*/
723-
static int get_file_caps(struct linux_binprm *bprm, struct file *file,
723+
static int get_file_caps(struct linux_binprm *bprm, const struct file *file,
724724
bool *effective, bool *has_fcap)
725725
{
726726
int rc = 0;
@@ -882,7 +882,7 @@ static inline bool nonroot_raised_pE(struct cred *new, const struct cred *old,
882882
*
883883
* Return: 0 if successful, -ve on error.
884884
*/
885-
int cap_bprm_creds_from_file(struct linux_binprm *bprm, struct file *file)
885+
int cap_bprm_creds_from_file(struct linux_binprm *bprm, const struct file *file)
886886
{
887887
/* Process setpcap binaries and capabilities for uid 0 */
888888
const struct cred *old = current_cred();

security/security.c

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -957,7 +957,7 @@ int security_capable(const struct cred *cred,
957957
*
958958
* Return: Returns 0 if permission is granted.
959959
*/
960-
int security_quotactl(int cmds, int type, int id, struct super_block *sb)
960+
int security_quotactl(int cmds, int type, int id, const struct super_block *sb)
961961
{
962962
return call_int_hook(quotactl, 0, cmds, type, id, sb);
963963
}
@@ -1079,7 +1079,7 @@ int security_bprm_creds_for_exec(struct linux_binprm *bprm)
10791079
*
10801080
* Return: Returns 0 if the hook is successful and permission is granted.
10811081
*/
1082-
int security_bprm_creds_from_file(struct linux_binprm *bprm, struct file *file)
1082+
int security_bprm_creds_from_file(struct linux_binprm *bprm, const struct file *file)
10831083
{
10841084
return call_int_hook(bprm_creds_from_file, 0, bprm, file);
10851085
}
@@ -1118,7 +1118,7 @@ int security_bprm_check(struct linux_binprm *bprm)
11181118
* open file descriptors to which access will no longer be granted when the
11191119
* attributes are changed. This is called immediately before commit_creds().
11201120
*/
1121-
void security_bprm_committing_creds(struct linux_binprm *bprm)
1121+
void security_bprm_committing_creds(const struct linux_binprm *bprm)
11221122
{
11231123
call_void_hook(bprm_committing_creds, bprm);
11241124
}
@@ -1134,7 +1134,7 @@ void security_bprm_committing_creds(struct linux_binprm *bprm)
11341134
* process such as clearing out non-inheritable signal state. This is called
11351135
* immediately after commit_creds().
11361136
*/
1137-
void security_bprm_committed_creds(struct linux_binprm *bprm)
1137+
void security_bprm_committed_creds(const struct linux_binprm *bprm)
11381138
{
11391139
call_void_hook(bprm_committed_creds, bprm);
11401140
}
@@ -1319,7 +1319,7 @@ EXPORT_SYMBOL(security_sb_remount);
13191319
*
13201320
* Return: Returns 0 if permission is granted.
13211321
*/
1322-
int security_sb_kern_mount(struct super_block *sb)
1322+
int security_sb_kern_mount(const struct super_block *sb)
13231323
{
13241324
return call_int_hook(sb_kern_mount, 0, sb);
13251325
}
@@ -3957,7 +3957,7 @@ void security_inode_invalidate_secctx(struct inode *inode)
39573957
EXPORT_SYMBOL(security_inode_invalidate_secctx);
39583958

39593959
/**
3960-
* security_inode_notifysecctx() - Nofify the LSM of an inode's security label
3960+
* security_inode_notifysecctx() - Notify the LSM of an inode's security label
39613961
* @inode: inode
39623962
* @ctx: secctx
39633963
* @ctxlen: length of secctx

0 commit comments

Comments
 (0)