Skip to content

Commit f1c921f

Browse files
committed
Merge tag 'selinux-pr-20210426' of git://git.kernel.org/pub/scm/linux/kernel/git/pcmoore/selinux
Pull selinux updates from Paul Moore: - Add support for measuring the SELinux state and policy capabilities using IMA. - A handful of SELinux/NFS patches to compare the SELinux state of one mount with a set of mount options. Olga goes into more detail in the patch descriptions, but this is important as it allows more flexibility when using NFS and SELinux context mounts. - Properly differentiate between the subjective and objective LSM credentials; including support for the SELinux and Smack. My clumsy attempt at a proper fix for AppArmor didn't quite pass muster so John is working on a proper AppArmor patch, in the meantime this set of patches shouldn't change the behavior of AppArmor in any way. This change explains the bulk of the diffstat beyond security/. - Fix a problem where we were not properly terminating the permission list for two SELinux object classes. * tag 'selinux-pr-20210426' of git://git.kernel.org/pub/scm/linux/kernel/git/pcmoore/selinux: selinux: add proper NULL termination to the secclass_map permissions smack: differentiate between subjective and objective task credentials selinux: clarify task subjective and objective credentials lsm: separate security_task_getsecid() into subjective and objective variants nfs: account for selinux security context when deciding to share superblock nfs: remove unneeded null check in nfs_fill_super() lsm,selinux: add new hook to compare new mount to an existing mount selinux: fix misspellings using codespell tool selinux: fix misspellings using codespell tool selinux: measure state and policy capabilities selinux: Allow context mounts for unpriviliged overlayfs
2 parents fafe1e3 + e4c82ea commit f1c921f

File tree

29 files changed

+372
-92
lines changed

29 files changed

+372
-92
lines changed

drivers/android/binder.c

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2713,7 +2713,16 @@ static void binder_transaction(struct binder_proc *proc,
27132713
u32 secid;
27142714
size_t added_size;
27152715

2716-
security_task_getsecid(proc->tsk, &secid);
2716+
/*
2717+
* Arguably this should be the task's subjective LSM secid but
2718+
* we can't reliably access the subjective creds of a task
2719+
* other than our own so we must use the objective creds, which
2720+
* are safe to access. The downside is that if a task is
2721+
* temporarily overriding it's creds it will not be reflected
2722+
* here; however, it isn't clear that binder would handle that
2723+
* case well anyway.
2724+
*/
2725+
security_task_getsecid_obj(proc->tsk, &secid);
27172726
ret = security_secid_to_secctx(secid, &secctx, &secctx_sz);
27182727
if (ret) {
27192728
return_error = BR_FAILED_REPLY;

fs/nfs/fs_context.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -463,6 +463,9 @@ static int nfs_fs_context_parse_param(struct fs_context *fc,
463463
if (opt < 0)
464464
return ctx->sloppy ? 1 : opt;
465465

466+
if (fc->security)
467+
ctx->has_sec_mnt_opts = 1;
468+
466469
switch (opt) {
467470
case Opt_source:
468471
if (fc->source)

fs/nfs/internal.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,7 @@ struct nfs_fs_context {
9696
char *fscache_uniq;
9797
unsigned short protofamily;
9898
unsigned short mountfamily;
99+
bool has_sec_mnt_opts;
99100

100101
struct {
101102
union {

fs/nfs/super.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1045,7 +1045,7 @@ static void nfs_fill_super(struct super_block *sb, struct nfs_fs_context *ctx)
10451045
sb->s_blocksize = 0;
10461046
sb->s_xattr = server->nfs_client->cl_nfs_mod->xattr;
10471047
sb->s_op = server->nfs_client->cl_nfs_mod->sops;
1048-
if (ctx && ctx->bsize)
1048+
if (ctx->bsize)
10491049
sb->s_blocksize = nfs_block_size(ctx->bsize, &sb->s_blocksize_bits);
10501050

10511051
if (server->nfs_client->rpc_ops->version != 2) {
@@ -1077,6 +1077,7 @@ static void nfs_fill_super(struct super_block *sb, struct nfs_fs_context *ctx)
10771077
&sb->s_blocksize_bits);
10781078

10791079
nfs_super_set_maxbytes(sb, server->maxfilesize);
1080+
server->has_sec_mnt_opts = ctx->has_sec_mnt_opts;
10801081
}
10811082

10821083
static int nfs_compare_mount_options(const struct super_block *s, const struct nfs_server *b,
@@ -1193,6 +1194,9 @@ static int nfs_compare_super(struct super_block *sb, struct fs_context *fc)
11931194
return 0;
11941195
if (!nfs_compare_userns(old, server))
11951196
return 0;
1197+
if ((old->has_sec_mnt_opts || fc->security) &&
1198+
security_sb_mnt_opts_compat(sb, fc->security))
1199+
return 0;
11961200
return nfs_compare_mount_options(sb, server, fc);
11971201
}
11981202

include/linux/cred.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,7 @@ struct cred {
140140
struct key *request_key_auth; /* assumed request_key authority */
141141
#endif
142142
#ifdef CONFIG_SECURITY
143-
void *security; /* subjective LSM security */
143+
void *security; /* LSM security */
144144
#endif
145145
struct user_struct *user; /* real user ID subscription */
146146
struct user_namespace *user_ns; /* user_ns the caps and keyrings are relative to. */

include/linux/lsm_hook_defs.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ LSM_HOOK(int, 0, sb_alloc_security, struct super_block *sb)
6262
LSM_HOOK(void, LSM_RET_VOID, sb_free_security, struct super_block *sb)
6363
LSM_HOOK(void, LSM_RET_VOID, sb_free_mnt_opts, void *mnt_opts)
6464
LSM_HOOK(int, 0, sb_eat_lsm_opts, char *orig, void **mnt_opts)
65+
LSM_HOOK(int, 0, sb_mnt_opts_compat, struct super_block *sb, void *mnt_opts)
6566
LSM_HOOK(int, 0, sb_remount, struct super_block *sb, void *mnt_opts)
6667
LSM_HOOK(int, 0, sb_kern_mount, struct super_block *sb)
6768
LSM_HOOK(int, 0, sb_show_options, struct seq_file *m, struct super_block *sb)
@@ -203,7 +204,10 @@ LSM_HOOK(int, 0, task_fix_setgid, struct cred *new, const struct cred * old,
203204
LSM_HOOK(int, 0, task_setpgid, struct task_struct *p, pid_t pgid)
204205
LSM_HOOK(int, 0, task_getpgid, struct task_struct *p)
205206
LSM_HOOK(int, 0, task_getsid, struct task_struct *p)
206-
LSM_HOOK(void, LSM_RET_VOID, task_getsecid, struct task_struct *p, u32 *secid)
207+
LSM_HOOK(void, LSM_RET_VOID, task_getsecid_subj,
208+
struct task_struct *p, u32 *secid)
209+
LSM_HOOK(void, LSM_RET_VOID, task_getsecid_obj,
210+
struct task_struct *p, u32 *secid)
207211
LSM_HOOK(int, 0, task_setnice, struct task_struct *p, int nice)
208212
LSM_HOOK(int, 0, task_setioprio, struct task_struct *p, int ioprio)
209213
LSM_HOOK(int, 0, task_getioprio, struct task_struct *p)

include/linux/lsm_hooks.h

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,12 @@
142142
* @orig the original mount data copied from userspace.
143143
* @copy copied data which will be passed to the security module.
144144
* Returns 0 if the copy was successful.
145+
* @sb_mnt_opts_compat:
146+
* Determine if the new mount options in @mnt_opts are allowed given
147+
* the existing mounted filesystem at @sb.
148+
* @sb superblock being compared
149+
* @mnt_opts new mount options
150+
* Return 0 if options are compatible.
145151
* @sb_remount:
146152
* Extracts security system specific mount options and verifies no changes
147153
* are being made to those options.
@@ -707,9 +713,15 @@
707713
* @p.
708714
* @p contains the task_struct for the process.
709715
* Return 0 if permission is granted.
710-
* @task_getsecid:
711-
* Retrieve the security identifier of the process @p.
712-
* @p contains the task_struct for the process and place is into @secid.
716+
* @task_getsecid_subj:
717+
* Retrieve the subjective security identifier of the task_struct in @p
718+
* and return it in @secid. Special care must be taken to ensure that @p
719+
* is the either the "current" task, or the caller has exclusive access
720+
* to @p.
721+
* In case of failure, @secid will be set to zero.
722+
* @task_getsecid_obj:
723+
* Retrieve the objective security identifier of the task_struct in @p
724+
* and return it in @secid.
713725
* In case of failure, @secid will be set to zero.
714726
*
715727
* @task_setnice:

include/linux/nfs_fs_sb.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -256,6 +256,7 @@ struct nfs_server {
256256

257257
/* User namespace info */
258258
const struct cred *cred;
259+
bool has_sec_mnt_opts;
259260
};
260261

261262
/* Server capabilities */

include/linux/security.h

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -294,6 +294,7 @@ int security_sb_alloc(struct super_block *sb);
294294
void security_sb_free(struct super_block *sb);
295295
void security_free_mnt_opts(void **mnt_opts);
296296
int security_sb_eat_lsm_opts(char *options, void **mnt_opts);
297+
int security_sb_mnt_opts_compat(struct super_block *sb, void *mnt_opts);
297298
int security_sb_remount(struct super_block *sb, void *mnt_opts);
298299
int security_sb_kern_mount(struct super_block *sb);
299300
int security_sb_show_options(struct seq_file *m, struct super_block *sb);
@@ -414,7 +415,8 @@ int security_task_fix_setgid(struct cred *new, const struct cred *old,
414415
int security_task_setpgid(struct task_struct *p, pid_t pgid);
415416
int security_task_getpgid(struct task_struct *p);
416417
int security_task_getsid(struct task_struct *p);
417-
void security_task_getsecid(struct task_struct *p, u32 *secid);
418+
void security_task_getsecid_subj(struct task_struct *p, u32 *secid);
419+
void security_task_getsecid_obj(struct task_struct *p, u32 *secid);
418420
int security_task_setnice(struct task_struct *p, int nice);
419421
int security_task_setioprio(struct task_struct *p, int ioprio);
420422
int security_task_getioprio(struct task_struct *p);
@@ -646,6 +648,13 @@ static inline int security_sb_remount(struct super_block *sb,
646648
return 0;
647649
}
648650

651+
static inline int security_sb_mnt_opts_compat(struct super_block *sb,
652+
void *mnt_opts)
653+
{
654+
return 0;
655+
}
656+
657+
649658
static inline int security_sb_kern_mount(struct super_block *sb)
650659
{
651660
return 0;
@@ -1098,7 +1107,12 @@ static inline int security_task_getsid(struct task_struct *p)
10981107
return 0;
10991108
}
11001109

1101-
static inline void security_task_getsecid(struct task_struct *p, u32 *secid)
1110+
static inline void security_task_getsecid_subj(struct task_struct *p, u32 *secid)
1111+
{
1112+
*secid = 0;
1113+
}
1114+
1115+
static inline void security_task_getsecid_obj(struct task_struct *p, u32 *secid)
11021116
{
11031117
*secid = 0;
11041118
}

kernel/audit.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2132,7 +2132,7 @@ int audit_log_task_context(struct audit_buffer *ab)
21322132
int error;
21332133
u32 sid;
21342134

2135-
security_task_getsecid(current, &sid);
2135+
security_task_getsecid_subj(current, &sid);
21362136
if (!sid)
21372137
return 0;
21382138

@@ -2353,7 +2353,7 @@ int audit_signal_info(int sig, struct task_struct *t)
23532353
audit_sig_uid = auid;
23542354
else
23552355
audit_sig_uid = uid;
2356-
security_task_getsecid(current, &audit_sig_sid);
2356+
security_task_getsecid_subj(current, &audit_sig_sid);
23572357
}
23582358

23592359
return audit_signal_info_syscall(t);

0 commit comments

Comments
 (0)