selinux/stable-5.13 PR 20210426
-----BEGIN PGP SIGNATURE----- iQJIBAABCAAyFiEES0KozwfymdVUl37v6iDy2pc3iXMFAmCHM2sUHHBhdWxAcGF1 bC1tb29yZS5jb20ACgkQ6iDy2pc3iXNfCg/9GmoCyCh+ZRj5RGQ6M+yJas1+yyJQ uEfTNde54yfATUTaaWYnZG59yqzM3I2uaV11U7tqg8ajiFPxJKqbs5R9jl3lnSjH 0Dg22nXPSCOTKcU0x/DeLoKRr+M9jO1K/nQ8NEZvYX4nC/OgtCvJqb/oEQZIKAk5 2a7OEmNNQyFGd274p9dELaDHxN9UIaJ2PzQFXtq7ROHgBXQO4ONb2ajOf6mDSFQb vP/CDHwaH+pcE28w44oRy0/YBkO1SrdqoFQchg5yFagM5tQRLGkXK4OFSs5KHi5Q YMtmaOzMPIv1e5eaC1HuuMJYA4pPb30T9hFHP7tmBVZfmZaFaDeUs+BhMm98WTiS o0iTP7tfs36/poOR1Q0/sB06uvF9hUAAX1ZuE95YySifbXU9hsUc9b0uQSwCdg9P /J9rcdHLTpWqjw9n02mezWmAvo5U8ZvbDs+0xPIwI+3RTUP5t6mp+Hd5Tc7bPTq1 0rpWXx+FQoSytFap5qiUSiwBp+HF6HQnNIXB0Muf6wctChoTjvo7TwoxH//z4kEm +SddhOCNkB7VC/X7hOxhl0F/rdHuXvb1AFIWjpTLJH2CR1PvMtF+sGey+uPT6hKZ /gvhmQGjFdph99eGlfVbCNvx1pM61O25IscaYD1T2wGImw+z7dX4WkG3WoOdDSkR bRjrBkcHh0gLhWk= =HTEy -----END PGP SIGNATURE----- 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
This commit is contained in:
commit
f1c921fb70
@ -2713,7 +2713,16 @@ static void binder_transaction(struct binder_proc *proc,
|
||||
u32 secid;
|
||||
size_t added_size;
|
||||
|
||||
security_task_getsecid(proc->tsk, &secid);
|
||||
/*
|
||||
* Arguably this should be the task's subjective LSM secid but
|
||||
* we can't reliably access the subjective creds of a task
|
||||
* other than our own so we must use the objective creds, which
|
||||
* are safe to access. The downside is that if a task is
|
||||
* temporarily overriding it's creds it will not be reflected
|
||||
* here; however, it isn't clear that binder would handle that
|
||||
* case well anyway.
|
||||
*/
|
||||
security_task_getsecid_obj(proc->tsk, &secid);
|
||||
ret = security_secid_to_secctx(secid, &secctx, &secctx_sz);
|
||||
if (ret) {
|
||||
return_error = BR_FAILED_REPLY;
|
||||
|
@ -463,6 +463,9 @@ static int nfs_fs_context_parse_param(struct fs_context *fc,
|
||||
if (opt < 0)
|
||||
return ctx->sloppy ? 1 : opt;
|
||||
|
||||
if (fc->security)
|
||||
ctx->has_sec_mnt_opts = 1;
|
||||
|
||||
switch (opt) {
|
||||
case Opt_source:
|
||||
if (fc->source)
|
||||
|
@ -96,6 +96,7 @@ struct nfs_fs_context {
|
||||
char *fscache_uniq;
|
||||
unsigned short protofamily;
|
||||
unsigned short mountfamily;
|
||||
bool has_sec_mnt_opts;
|
||||
|
||||
struct {
|
||||
union {
|
||||
|
@ -1045,7 +1045,7 @@ static void nfs_fill_super(struct super_block *sb, struct nfs_fs_context *ctx)
|
||||
sb->s_blocksize = 0;
|
||||
sb->s_xattr = server->nfs_client->cl_nfs_mod->xattr;
|
||||
sb->s_op = server->nfs_client->cl_nfs_mod->sops;
|
||||
if (ctx && ctx->bsize)
|
||||
if (ctx->bsize)
|
||||
sb->s_blocksize = nfs_block_size(ctx->bsize, &sb->s_blocksize_bits);
|
||||
|
||||
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)
|
||||
&sb->s_blocksize_bits);
|
||||
|
||||
nfs_super_set_maxbytes(sb, server->maxfilesize);
|
||||
server->has_sec_mnt_opts = ctx->has_sec_mnt_opts;
|
||||
}
|
||||
|
||||
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)
|
||||
return 0;
|
||||
if (!nfs_compare_userns(old, server))
|
||||
return 0;
|
||||
if ((old->has_sec_mnt_opts || fc->security) &&
|
||||
security_sb_mnt_opts_compat(sb, fc->security))
|
||||
return 0;
|
||||
return nfs_compare_mount_options(sb, server, fc);
|
||||
}
|
||||
|
||||
|
@ -140,7 +140,7 @@ struct cred {
|
||||
struct key *request_key_auth; /* assumed request_key authority */
|
||||
#endif
|
||||
#ifdef CONFIG_SECURITY
|
||||
void *security; /* subjective LSM security */
|
||||
void *security; /* LSM security */
|
||||
#endif
|
||||
struct user_struct *user; /* real user ID subscription */
|
||||
struct user_namespace *user_ns; /* user_ns the caps and keyrings are relative to. */
|
||||
|
@ -62,6 +62,7 @@ LSM_HOOK(int, 0, sb_alloc_security, struct super_block *sb)
|
||||
LSM_HOOK(void, LSM_RET_VOID, sb_free_security, struct super_block *sb)
|
||||
LSM_HOOK(void, LSM_RET_VOID, sb_free_mnt_opts, void *mnt_opts)
|
||||
LSM_HOOK(int, 0, sb_eat_lsm_opts, char *orig, void **mnt_opts)
|
||||
LSM_HOOK(int, 0, sb_mnt_opts_compat, struct super_block *sb, void *mnt_opts)
|
||||
LSM_HOOK(int, 0, sb_remount, struct super_block *sb, void *mnt_opts)
|
||||
LSM_HOOK(int, 0, sb_kern_mount, struct super_block *sb)
|
||||
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,
|
||||
LSM_HOOK(int, 0, task_setpgid, struct task_struct *p, pid_t pgid)
|
||||
LSM_HOOK(int, 0, task_getpgid, struct task_struct *p)
|
||||
LSM_HOOK(int, 0, task_getsid, struct task_struct *p)
|
||||
LSM_HOOK(void, LSM_RET_VOID, task_getsecid, struct task_struct *p, u32 *secid)
|
||||
LSM_HOOK(void, LSM_RET_VOID, task_getsecid_subj,
|
||||
struct task_struct *p, u32 *secid)
|
||||
LSM_HOOK(void, LSM_RET_VOID, task_getsecid_obj,
|
||||
struct task_struct *p, u32 *secid)
|
||||
LSM_HOOK(int, 0, task_setnice, struct task_struct *p, int nice)
|
||||
LSM_HOOK(int, 0, task_setioprio, struct task_struct *p, int ioprio)
|
||||
LSM_HOOK(int, 0, task_getioprio, struct task_struct *p)
|
||||
|
@ -142,6 +142,12 @@
|
||||
* @orig the original mount data copied from userspace.
|
||||
* @copy copied data which will be passed to the security module.
|
||||
* Returns 0 if the copy was successful.
|
||||
* @sb_mnt_opts_compat:
|
||||
* Determine if the new mount options in @mnt_opts are allowed given
|
||||
* the existing mounted filesystem at @sb.
|
||||
* @sb superblock being compared
|
||||
* @mnt_opts new mount options
|
||||
* Return 0 if options are compatible.
|
||||
* @sb_remount:
|
||||
* Extracts security system specific mount options and verifies no changes
|
||||
* are being made to those options.
|
||||
@ -707,9 +713,15 @@
|
||||
* @p.
|
||||
* @p contains the task_struct for the process.
|
||||
* Return 0 if permission is granted.
|
||||
* @task_getsecid:
|
||||
* Retrieve the security identifier of the process @p.
|
||||
* @p contains the task_struct for the process and place is into @secid.
|
||||
* @task_getsecid_subj:
|
||||
* Retrieve the subjective security identifier of the task_struct in @p
|
||||
* and return it in @secid. Special care must be taken to ensure that @p
|
||||
* is the either the "current" task, or the caller has exclusive access
|
||||
* to @p.
|
||||
* In case of failure, @secid will be set to zero.
|
||||
* @task_getsecid_obj:
|
||||
* Retrieve the objective security identifier of the task_struct in @p
|
||||
* and return it in @secid.
|
||||
* In case of failure, @secid will be set to zero.
|
||||
*
|
||||
* @task_setnice:
|
||||
|
@ -256,6 +256,7 @@ struct nfs_server {
|
||||
|
||||
/* User namespace info */
|
||||
const struct cred *cred;
|
||||
bool has_sec_mnt_opts;
|
||||
};
|
||||
|
||||
/* Server capabilities */
|
||||
|
@ -294,6 +294,7 @@ int security_sb_alloc(struct super_block *sb);
|
||||
void security_sb_free(struct super_block *sb);
|
||||
void security_free_mnt_opts(void **mnt_opts);
|
||||
int security_sb_eat_lsm_opts(char *options, void **mnt_opts);
|
||||
int security_sb_mnt_opts_compat(struct super_block *sb, void *mnt_opts);
|
||||
int security_sb_remount(struct super_block *sb, void *mnt_opts);
|
||||
int security_sb_kern_mount(struct super_block *sb);
|
||||
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,
|
||||
int security_task_setpgid(struct task_struct *p, pid_t pgid);
|
||||
int security_task_getpgid(struct task_struct *p);
|
||||
int security_task_getsid(struct task_struct *p);
|
||||
void security_task_getsecid(struct task_struct *p, u32 *secid);
|
||||
void security_task_getsecid_subj(struct task_struct *p, u32 *secid);
|
||||
void security_task_getsecid_obj(struct task_struct *p, u32 *secid);
|
||||
int security_task_setnice(struct task_struct *p, int nice);
|
||||
int security_task_setioprio(struct task_struct *p, int ioprio);
|
||||
int security_task_getioprio(struct task_struct *p);
|
||||
@ -646,6 +648,13 @@ static inline int security_sb_remount(struct super_block *sb,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int security_sb_mnt_opts_compat(struct super_block *sb,
|
||||
void *mnt_opts)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static inline int security_sb_kern_mount(struct super_block *sb)
|
||||
{
|
||||
return 0;
|
||||
@ -1098,7 +1107,12 @@ static inline int security_task_getsid(struct task_struct *p)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline void security_task_getsecid(struct task_struct *p, u32 *secid)
|
||||
static inline void security_task_getsecid_subj(struct task_struct *p, u32 *secid)
|
||||
{
|
||||
*secid = 0;
|
||||
}
|
||||
|
||||
static inline void security_task_getsecid_obj(struct task_struct *p, u32 *secid)
|
||||
{
|
||||
*secid = 0;
|
||||
}
|
||||
|
@ -2132,7 +2132,7 @@ int audit_log_task_context(struct audit_buffer *ab)
|
||||
int error;
|
||||
u32 sid;
|
||||
|
||||
security_task_getsecid(current, &sid);
|
||||
security_task_getsecid_subj(current, &sid);
|
||||
if (!sid)
|
||||
return 0;
|
||||
|
||||
@ -2353,7 +2353,7 @@ int audit_signal_info(int sig, struct task_struct *t)
|
||||
audit_sig_uid = auid;
|
||||
else
|
||||
audit_sig_uid = uid;
|
||||
security_task_getsecid(current, &audit_sig_sid);
|
||||
security_task_getsecid_subj(current, &audit_sig_sid);
|
||||
}
|
||||
|
||||
return audit_signal_info_syscall(t);
|
||||
|
@ -1359,7 +1359,8 @@ int audit_filter(int msgtype, unsigned int listtype)
|
||||
case AUDIT_SUBJ_SEN:
|
||||
case AUDIT_SUBJ_CLR:
|
||||
if (f->lsm_rule) {
|
||||
security_task_getsecid(current, &sid);
|
||||
security_task_getsecid_subj(current,
|
||||
&sid);
|
||||
result = security_audit_rule_match(sid,
|
||||
f->type, f->op, f->lsm_rule);
|
||||
}
|
||||
|
@ -667,7 +667,7 @@ static int audit_filter_rules(struct task_struct *tsk,
|
||||
logged upon error */
|
||||
if (f->lsm_rule) {
|
||||
if (need_sid) {
|
||||
security_task_getsecid(tsk, &sid);
|
||||
security_task_getsecid_subj(tsk, &sid);
|
||||
need_sid = 0;
|
||||
}
|
||||
result = security_audit_rule_match(sid, f->type,
|
||||
@ -2400,7 +2400,7 @@ void __audit_ptrace(struct task_struct *t)
|
||||
context->target_auid = audit_get_loginuid(t);
|
||||
context->target_uid = task_uid(t);
|
||||
context->target_sessionid = audit_get_sessionid(t);
|
||||
security_task_getsecid(t, &context->target_sid);
|
||||
security_task_getsecid_obj(t, &context->target_sid);
|
||||
memcpy(context->target_comm, t->comm, TASK_COMM_LEN);
|
||||
}
|
||||
|
||||
@ -2427,7 +2427,7 @@ int audit_signal_info_syscall(struct task_struct *t)
|
||||
ctx->target_auid = audit_get_loginuid(t);
|
||||
ctx->target_uid = t_uid;
|
||||
ctx->target_sessionid = audit_get_sessionid(t);
|
||||
security_task_getsecid(t, &ctx->target_sid);
|
||||
security_task_getsecid_obj(t, &ctx->target_sid);
|
||||
memcpy(ctx->target_comm, t->comm, TASK_COMM_LEN);
|
||||
return 0;
|
||||
}
|
||||
@ -2448,7 +2448,7 @@ int audit_signal_info_syscall(struct task_struct *t)
|
||||
axp->target_auid[axp->pid_count] = audit_get_loginuid(t);
|
||||
axp->target_uid[axp->pid_count] = t_uid;
|
||||
axp->target_sessionid[axp->pid_count] = audit_get_sessionid(t);
|
||||
security_task_getsecid(t, &axp->target_sid[axp->pid_count]);
|
||||
security_task_getsecid_obj(t, &axp->target_sid[axp->pid_count]);
|
||||
memcpy(axp->target_comm[axp->pid_count], t->comm, TASK_COMM_LEN);
|
||||
axp->pid_count++;
|
||||
|
||||
|
@ -209,7 +209,8 @@ BTF_ID(func, bpf_lsm_socket_socketpair)
|
||||
|
||||
BTF_ID(func, bpf_lsm_syslog)
|
||||
BTF_ID(func, bpf_lsm_task_alloc)
|
||||
BTF_ID(func, bpf_lsm_task_getsecid)
|
||||
BTF_ID(func, bpf_lsm_task_getsecid_subj)
|
||||
BTF_ID(func, bpf_lsm_task_getsecid_obj)
|
||||
BTF_ID(func, bpf_lsm_task_prctl)
|
||||
BTF_ID(func, bpf_lsm_task_setscheduler)
|
||||
BTF_ID(func, bpf_lsm_task_to_inode)
|
||||
|
@ -1539,7 +1539,7 @@ int __init netlbl_unlabel_defconf(void)
|
||||
/* Only the kernel is allowed to call this function and the only time
|
||||
* it is called is at bootup before the audit subsystem is reporting
|
||||
* messages so don't worry to much about these values. */
|
||||
security_task_getsecid(current, &audit_info.secid);
|
||||
security_task_getsecid_subj(current, &audit_info.secid);
|
||||
audit_info.loginuid = GLOBAL_ROOT_UID;
|
||||
audit_info.sessionid = 0;
|
||||
|
||||
|
@ -34,7 +34,7 @@
|
||||
static inline void netlbl_netlink_auditinfo(struct sk_buff *skb,
|
||||
struct netlbl_audit *audit_info)
|
||||
{
|
||||
security_task_getsecid(current, &audit_info->secid);
|
||||
security_task_getsecid_subj(current, &audit_info->secid);
|
||||
audit_info->loginuid = audit_get_loginuid(current);
|
||||
audit_info->sessionid = audit_get_sessionid(current);
|
||||
}
|
||||
|
@ -1252,7 +1252,8 @@ static struct security_hook_list apparmor_hooks[] __lsm_ro_after_init = {
|
||||
|
||||
LSM_HOOK_INIT(task_free, apparmor_task_free),
|
||||
LSM_HOOK_INIT(task_alloc, apparmor_task_alloc),
|
||||
LSM_HOOK_INIT(task_getsecid, apparmor_task_getsecid),
|
||||
LSM_HOOK_INIT(task_getsecid_subj, apparmor_task_getsecid),
|
||||
LSM_HOOK_INIT(task_getsecid_obj, apparmor_task_getsecid),
|
||||
LSM_HOOK_INIT(task_setrlimit, apparmor_task_setrlimit),
|
||||
LSM_HOOK_INIT(task_kill, apparmor_task_kill),
|
||||
|
||||
|
@ -76,7 +76,7 @@ int ima_must_appraise(struct user_namespace *mnt_userns, struct inode *inode,
|
||||
if (!ima_appraise)
|
||||
return 0;
|
||||
|
||||
security_task_getsecid(current, &secid);
|
||||
security_task_getsecid_subj(current, &secid);
|
||||
return ima_match_policy(mnt_userns, inode, current_cred(), secid, func,
|
||||
mask, IMA_APPRAISE | IMA_HASH, NULL, NULL, NULL);
|
||||
}
|
||||
|
@ -391,7 +391,7 @@ int ima_file_mmap(struct file *file, unsigned long prot)
|
||||
u32 secid;
|
||||
|
||||
if (file && (prot & PROT_EXEC)) {
|
||||
security_task_getsecid(current, &secid);
|
||||
security_task_getsecid_subj(current, &secid);
|
||||
return process_measurement(file, current_cred(), secid, NULL,
|
||||
0, MAY_EXEC, MMAP_CHECK);
|
||||
}
|
||||
@ -429,7 +429,7 @@ int ima_file_mprotect(struct vm_area_struct *vma, unsigned long prot)
|
||||
!(prot & PROT_EXEC) || (vma->vm_flags & VM_EXEC))
|
||||
return 0;
|
||||
|
||||
security_task_getsecid(current, &secid);
|
||||
security_task_getsecid_subj(current, &secid);
|
||||
inode = file_inode(vma->vm_file);
|
||||
action = ima_get_action(file_mnt_user_ns(vma->vm_file), inode,
|
||||
current_cred(), secid, MAY_EXEC, MMAP_CHECK,
|
||||
@ -470,7 +470,7 @@ int ima_bprm_check(struct linux_binprm *bprm)
|
||||
int ret;
|
||||
u32 secid;
|
||||
|
||||
security_task_getsecid(current, &secid);
|
||||
security_task_getsecid_subj(current, &secid);
|
||||
ret = process_measurement(bprm->file, current_cred(), secid, NULL, 0,
|
||||
MAY_EXEC, BPRM_CHECK);
|
||||
if (ret)
|
||||
@ -495,7 +495,7 @@ int ima_file_check(struct file *file, int mask)
|
||||
{
|
||||
u32 secid;
|
||||
|
||||
security_task_getsecid(current, &secid);
|
||||
security_task_getsecid_subj(current, &secid);
|
||||
return process_measurement(file, current_cred(), secid, NULL, 0,
|
||||
mask & (MAY_READ | MAY_WRITE | MAY_EXEC |
|
||||
MAY_APPEND), FILE_CHECK);
|
||||
@ -686,7 +686,7 @@ int ima_read_file(struct file *file, enum kernel_read_file_id read_id,
|
||||
|
||||
/* Read entire file for all partial reads. */
|
||||
func = read_idmap[read_id] ?: FILE_CHECK;
|
||||
security_task_getsecid(current, &secid);
|
||||
security_task_getsecid_subj(current, &secid);
|
||||
return process_measurement(file, current_cred(), secid, NULL,
|
||||
0, MAY_READ, func);
|
||||
}
|
||||
@ -729,7 +729,7 @@ int ima_post_read_file(struct file *file, void *buf, loff_t size,
|
||||
}
|
||||
|
||||
func = read_idmap[read_id] ?: FILE_CHECK;
|
||||
security_task_getsecid(current, &secid);
|
||||
security_task_getsecid_subj(current, &secid);
|
||||
return process_measurement(file, current_cred(), secid, buf, size,
|
||||
MAY_READ, func);
|
||||
}
|
||||
@ -872,7 +872,7 @@ void process_buffer_measurement(struct user_namespace *mnt_userns,
|
||||
* buffer measurements.
|
||||
*/
|
||||
if (func) {
|
||||
security_task_getsecid(current, &secid);
|
||||
security_task_getsecid_subj(current, &secid);
|
||||
action = ima_get_action(mnt_userns, inode, current_cred(),
|
||||
secid, 0, func, &pcr, &template,
|
||||
func_data);
|
||||
|
@ -890,6 +890,13 @@ int security_sb_eat_lsm_opts(char *options, void **mnt_opts)
|
||||
}
|
||||
EXPORT_SYMBOL(security_sb_eat_lsm_opts);
|
||||
|
||||
int security_sb_mnt_opts_compat(struct super_block *sb,
|
||||
void *mnt_opts)
|
||||
{
|
||||
return call_int_hook(sb_mnt_opts_compat, 0, sb, mnt_opts);
|
||||
}
|
||||
EXPORT_SYMBOL(security_sb_mnt_opts_compat);
|
||||
|
||||
int security_sb_remount(struct super_block *sb,
|
||||
void *mnt_opts)
|
||||
{
|
||||
@ -1762,12 +1769,19 @@ int security_task_getsid(struct task_struct *p)
|
||||
return call_int_hook(task_getsid, 0, p);
|
||||
}
|
||||
|
||||
void security_task_getsecid(struct task_struct *p, u32 *secid)
|
||||
void security_task_getsecid_subj(struct task_struct *p, u32 *secid)
|
||||
{
|
||||
*secid = 0;
|
||||
call_void_hook(task_getsecid, p, secid);
|
||||
call_void_hook(task_getsecid_subj, p, secid);
|
||||
}
|
||||
EXPORT_SYMBOL(security_task_getsecid);
|
||||
EXPORT_SYMBOL(security_task_getsecid_subj);
|
||||
|
||||
void security_task_getsecid_obj(struct task_struct *p, u32 *secid)
|
||||
{
|
||||
*secid = 0;
|
||||
call_void_hook(task_getsecid_obj, p, secid);
|
||||
}
|
||||
EXPORT_SYMBOL(security_task_getsecid_obj);
|
||||
|
||||
int security_task_setnice(struct task_struct *p, int nice)
|
||||
{
|
||||
|
@ -229,10 +229,23 @@ static inline u32 cred_sid(const struct cred *cred)
|
||||
return tsec->sid;
|
||||
}
|
||||
|
||||
/*
|
||||
* get the subjective security ID of a task
|
||||
*/
|
||||
static inline u32 task_sid_subj(const struct task_struct *task)
|
||||
{
|
||||
u32 sid;
|
||||
|
||||
rcu_read_lock();
|
||||
sid = cred_sid(rcu_dereference(task->cred));
|
||||
rcu_read_unlock();
|
||||
return sid;
|
||||
}
|
||||
|
||||
/*
|
||||
* get the objective security ID of a task
|
||||
*/
|
||||
static inline u32 task_sid(const struct task_struct *task)
|
||||
static inline u32 task_sid_obj(const struct task_struct *task)
|
||||
{
|
||||
u32 sid;
|
||||
|
||||
@ -242,6 +255,29 @@ static inline u32 task_sid(const struct task_struct *task)
|
||||
return sid;
|
||||
}
|
||||
|
||||
/*
|
||||
* get the security ID of a task for use with binder
|
||||
*/
|
||||
static inline u32 task_sid_binder(const struct task_struct *task)
|
||||
{
|
||||
/*
|
||||
* In many case where this function is used we should be using the
|
||||
* task's subjective SID, but we can't reliably access the subjective
|
||||
* creds of a task other than our own so we must use the objective
|
||||
* creds/SID, which are safe to access. The downside is that if a task
|
||||
* is temporarily overriding it's creds it will not be reflected here;
|
||||
* however, it isn't clear that binder would handle that case well
|
||||
* anyway.
|
||||
*
|
||||
* If this ever changes and we can safely reference the subjective
|
||||
* creds/SID of another task, this function will make it easier to
|
||||
* identify the various places where we make use of the task SIDs in
|
||||
* the binder code. It is also likely that we will need to adjust
|
||||
* the main drivers/android binder code as well.
|
||||
*/
|
||||
return task_sid_obj(task);
|
||||
}
|
||||
|
||||
static int inode_doinit_with_dentry(struct inode *inode, struct dentry *opt_dentry);
|
||||
|
||||
/*
|
||||
@ -760,7 +796,8 @@ static int selinux_set_mnt_opts(struct super_block *sb,
|
||||
if (sb->s_user_ns != &init_user_ns &&
|
||||
strcmp(sb->s_type->name, "tmpfs") &&
|
||||
strcmp(sb->s_type->name, "ramfs") &&
|
||||
strcmp(sb->s_type->name, "devpts")) {
|
||||
strcmp(sb->s_type->name, "devpts") &&
|
||||
strcmp(sb->s_type->name, "overlay")) {
|
||||
if (context_sid || fscontext_sid || rootcontext_sid ||
|
||||
defcontext_sid) {
|
||||
rc = -EACCES;
|
||||
@ -2034,11 +2071,8 @@ static inline u32 open_file_to_av(struct file *file)
|
||||
|
||||
static int selinux_binder_set_context_mgr(struct task_struct *mgr)
|
||||
{
|
||||
u32 mysid = current_sid();
|
||||
u32 mgrsid = task_sid(mgr);
|
||||
|
||||
return avc_has_perm(&selinux_state,
|
||||
mysid, mgrsid, SECCLASS_BINDER,
|
||||
current_sid(), task_sid_binder(mgr), SECCLASS_BINDER,
|
||||
BINDER__SET_CONTEXT_MGR, NULL);
|
||||
}
|
||||
|
||||
@ -2046,8 +2080,7 @@ static int selinux_binder_transaction(struct task_struct *from,
|
||||
struct task_struct *to)
|
||||
{
|
||||
u32 mysid = current_sid();
|
||||
u32 fromsid = task_sid(from);
|
||||
u32 tosid = task_sid(to);
|
||||
u32 fromsid = task_sid_binder(from);
|
||||
int rc;
|
||||
|
||||
if (mysid != fromsid) {
|
||||
@ -2058,19 +2091,16 @@ static int selinux_binder_transaction(struct task_struct *from,
|
||||
return rc;
|
||||
}
|
||||
|
||||
return avc_has_perm(&selinux_state,
|
||||
fromsid, tosid, SECCLASS_BINDER, BINDER__CALL,
|
||||
NULL);
|
||||
return avc_has_perm(&selinux_state, fromsid, task_sid_binder(to),
|
||||
SECCLASS_BINDER, BINDER__CALL, NULL);
|
||||
}
|
||||
|
||||
static int selinux_binder_transfer_binder(struct task_struct *from,
|
||||
struct task_struct *to)
|
||||
{
|
||||
u32 fromsid = task_sid(from);
|
||||
u32 tosid = task_sid(to);
|
||||
|
||||
return avc_has_perm(&selinux_state,
|
||||
fromsid, tosid, SECCLASS_BINDER, BINDER__TRANSFER,
|
||||
task_sid_binder(from), task_sid_binder(to),
|
||||
SECCLASS_BINDER, BINDER__TRANSFER,
|
||||
NULL);
|
||||
}
|
||||
|
||||
@ -2078,7 +2108,7 @@ static int selinux_binder_transfer_file(struct task_struct *from,
|
||||
struct task_struct *to,
|
||||
struct file *file)
|
||||
{
|
||||
u32 sid = task_sid(to);
|
||||
u32 sid = task_sid_binder(to);
|
||||
struct file_security_struct *fsec = selinux_file(file);
|
||||
struct dentry *dentry = file->f_path.dentry;
|
||||
struct inode_security_struct *isec;
|
||||
@ -2114,10 +2144,10 @@ static int selinux_binder_transfer_file(struct task_struct *from,
|
||||
}
|
||||
|
||||
static int selinux_ptrace_access_check(struct task_struct *child,
|
||||
unsigned int mode)
|
||||
unsigned int mode)
|
||||
{
|
||||
u32 sid = current_sid();
|
||||
u32 csid = task_sid(child);
|
||||
u32 csid = task_sid_obj(child);
|
||||
|
||||
if (mode & PTRACE_MODE_READ)
|
||||
return avc_has_perm(&selinux_state,
|
||||
@ -2130,15 +2160,15 @@ static int selinux_ptrace_access_check(struct task_struct *child,
|
||||
static int selinux_ptrace_traceme(struct task_struct *parent)
|
||||
{
|
||||
return avc_has_perm(&selinux_state,
|
||||
task_sid(parent), current_sid(), SECCLASS_PROCESS,
|
||||
PROCESS__PTRACE, NULL);
|
||||
task_sid_subj(parent), task_sid_obj(current),
|
||||
SECCLASS_PROCESS, PROCESS__PTRACE, NULL);
|
||||
}
|
||||
|
||||
static int selinux_capget(struct task_struct *target, kernel_cap_t *effective,
|
||||
kernel_cap_t *inheritable, kernel_cap_t *permitted)
|
||||
{
|
||||
return avc_has_perm(&selinux_state,
|
||||
current_sid(), task_sid(target), SECCLASS_PROCESS,
|
||||
current_sid(), task_sid_obj(target), SECCLASS_PROCESS,
|
||||
PROCESS__GETCAP, NULL);
|
||||
}
|
||||
|
||||
@ -2263,7 +2293,7 @@ static u32 ptrace_parent_sid(void)
|
||||
rcu_read_lock();
|
||||
tracer = ptrace_parent(current);
|
||||
if (tracer)
|
||||
sid = task_sid(tracer);
|
||||
sid = task_sid_obj(tracer);
|
||||
rcu_read_unlock();
|
||||
|
||||
return sid;
|
||||
@ -2684,6 +2714,61 @@ free_opt:
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int selinux_sb_mnt_opts_compat(struct super_block *sb, void *mnt_opts)
|
||||
{
|
||||
struct selinux_mnt_opts *opts = mnt_opts;
|
||||
struct superblock_security_struct *sbsec = sb->s_security;
|
||||
u32 sid;
|
||||
int rc;
|
||||
|
||||
/*
|
||||
* Superblock not initialized (i.e. no options) - reject if any
|
||||
* options specified, otherwise accept.
|
||||
*/
|
||||
if (!(sbsec->flags & SE_SBINITIALIZED))
|
||||
return opts ? 1 : 0;
|
||||
|
||||
/*
|
||||
* Superblock initialized and no options specified - reject if
|
||||
* superblock has any options set, otherwise accept.
|
||||
*/
|
||||
if (!opts)
|
||||
return (sbsec->flags & SE_MNTMASK) ? 1 : 0;
|
||||
|
||||
if (opts->fscontext) {
|
||||
rc = parse_sid(sb, opts->fscontext, &sid);
|
||||
if (rc)
|
||||
return 1;
|
||||
if (bad_option(sbsec, FSCONTEXT_MNT, sbsec->sid, sid))
|
||||
return 1;
|
||||
}
|
||||
if (opts->context) {
|
||||
rc = parse_sid(sb, opts->context, &sid);
|
||||
if (rc)
|
||||
return 1;
|
||||
if (bad_option(sbsec, CONTEXT_MNT, sbsec->mntpoint_sid, sid))
|
||||
return 1;
|
||||
}
|
||||
if (opts->rootcontext) {
|
||||
struct inode_security_struct *root_isec;
|
||||
|
||||
root_isec = backing_inode_security(sb->s_root);
|
||||
rc = parse_sid(sb, opts->rootcontext, &sid);
|
||||
if (rc)
|
||||
return 1;
|
||||
if (bad_option(sbsec, ROOTCONTEXT_MNT, root_isec->sid, sid))
|
||||
return 1;
|
||||
}
|
||||
if (opts->defcontext) {
|
||||
rc = parse_sid(sb, opts->defcontext, &sid);
|
||||
if (rc)
|
||||
return 1;
|
||||
if (bad_option(sbsec, DEFCONTEXT_MNT, sbsec->def_sid, sid))
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int selinux_sb_remount(struct super_block *sb, void *mnt_opts)
|
||||
{
|
||||
struct selinux_mnt_opts *opts = mnt_opts;
|
||||
@ -3920,7 +4005,7 @@ static int selinux_file_send_sigiotask(struct task_struct *tsk,
|
||||
struct fown_struct *fown, int signum)
|
||||
{
|
||||
struct file *file;
|
||||
u32 sid = task_sid(tsk);
|
||||
u32 sid = task_sid_obj(tsk);
|
||||
u32 perm;
|
||||
struct file_security_struct *fsec;
|
||||
|
||||
@ -4139,47 +4224,52 @@ static int selinux_kernel_load_data(enum kernel_load_data_id id, bool contents)
|
||||
static int selinux_task_setpgid(struct task_struct *p, pid_t pgid)
|
||||
{
|
||||
return avc_has_perm(&selinux_state,
|
||||
current_sid(), task_sid(p), SECCLASS_PROCESS,
|
||||
current_sid(), task_sid_obj(p), SECCLASS_PROCESS,
|
||||
PROCESS__SETPGID, NULL);
|
||||
}
|
||||
|
||||
static int selinux_task_getpgid(struct task_struct *p)
|
||||
{
|
||||
return avc_has_perm(&selinux_state,
|
||||
current_sid(), task_sid(p), SECCLASS_PROCESS,
|
||||
current_sid(), task_sid_obj(p), SECCLASS_PROCESS,
|
||||
PROCESS__GETPGID, NULL);
|
||||
}
|
||||
|
||||
static int selinux_task_getsid(struct task_struct *p)
|
||||
{
|
||||
return avc_has_perm(&selinux_state,
|
||||
current_sid(), task_sid(p), SECCLASS_PROCESS,
|
||||
current_sid(), task_sid_obj(p), SECCLASS_PROCESS,
|
||||
PROCESS__GETSESSION, NULL);
|
||||
}
|
||||
|
||||
static void selinux_task_getsecid(struct task_struct *p, u32 *secid)
|
||||
static void selinux_task_getsecid_subj(struct task_struct *p, u32 *secid)
|
||||
{
|
||||
*secid = task_sid(p);
|
||||
*secid = task_sid_subj(p);
|
||||
}
|
||||
|
||||
static void selinux_task_getsecid_obj(struct task_struct *p, u32 *secid)
|
||||
{
|
||||
*secid = task_sid_obj(p);
|
||||
}
|
||||
|
||||
static int selinux_task_setnice(struct task_struct *p, int nice)
|
||||
{
|
||||
return avc_has_perm(&selinux_state,
|
||||
current_sid(), task_sid(p), SECCLASS_PROCESS,
|
||||
current_sid(), task_sid_obj(p), SECCLASS_PROCESS,
|
||||
PROCESS__SETSCHED, NULL);
|
||||
}
|
||||
|
||||
static int selinux_task_setioprio(struct task_struct *p, int ioprio)
|
||||
{
|
||||
return avc_has_perm(&selinux_state,
|
||||
current_sid(), task_sid(p), SECCLASS_PROCESS,
|
||||
current_sid(), task_sid_obj(p), SECCLASS_PROCESS,
|
||||
PROCESS__SETSCHED, NULL);
|
||||
}
|
||||
|
||||
static int selinux_task_getioprio(struct task_struct *p)
|
||||
{
|
||||
return avc_has_perm(&selinux_state,
|
||||
current_sid(), task_sid(p), SECCLASS_PROCESS,
|
||||
current_sid(), task_sid_obj(p), SECCLASS_PROCESS,
|
||||
PROCESS__GETSCHED, NULL);
|
||||
}
|
||||
|
||||
@ -4210,7 +4300,7 @@ static int selinux_task_setrlimit(struct task_struct *p, unsigned int resource,
|
||||
upon context transitions. See selinux_bprm_committing_creds. */
|
||||
if (old_rlim->rlim_max != new_rlim->rlim_max)
|
||||
return avc_has_perm(&selinux_state,
|
||||
current_sid(), task_sid(p),
|
||||
current_sid(), task_sid_obj(p),
|
||||
SECCLASS_PROCESS, PROCESS__SETRLIMIT, NULL);
|
||||
|
||||
return 0;
|
||||
@ -4219,21 +4309,21 @@ static int selinux_task_setrlimit(struct task_struct *p, unsigned int resource,
|
||||
static int selinux_task_setscheduler(struct task_struct *p)
|
||||
{
|
||||
return avc_has_perm(&selinux_state,
|
||||
current_sid(), task_sid(p), SECCLASS_PROCESS,
|
||||
current_sid(), task_sid_obj(p), SECCLASS_PROCESS,
|
||||
PROCESS__SETSCHED, NULL);
|
||||
}
|
||||
|
||||
static int selinux_task_getscheduler(struct task_struct *p)
|
||||
{
|
||||
return avc_has_perm(&selinux_state,
|
||||
current_sid(), task_sid(p), SECCLASS_PROCESS,
|
||||
current_sid(), task_sid_obj(p), SECCLASS_PROCESS,
|
||||
PROCESS__GETSCHED, NULL);
|
||||
}
|
||||
|
||||
static int selinux_task_movememory(struct task_struct *p)
|
||||
{
|
||||
return avc_has_perm(&selinux_state,
|
||||
current_sid(), task_sid(p), SECCLASS_PROCESS,
|
||||
current_sid(), task_sid_obj(p), SECCLASS_PROCESS,
|
||||
PROCESS__SETSCHED, NULL);
|
||||
}
|
||||
|
||||
@ -4252,14 +4342,14 @@ static int selinux_task_kill(struct task_struct *p, struct kernel_siginfo *info,
|
||||
else
|
||||
secid = cred_sid(cred);
|
||||
return avc_has_perm(&selinux_state,
|
||||
secid, task_sid(p), SECCLASS_PROCESS, perm, NULL);
|
||||
secid, task_sid_obj(p), SECCLASS_PROCESS, perm, NULL);
|
||||
}
|
||||
|
||||
static void selinux_task_to_inode(struct task_struct *p,
|
||||
struct inode *inode)
|
||||
{
|
||||
struct inode_security_struct *isec = selinux_inode(inode);
|
||||
u32 sid = task_sid(p);
|
||||
u32 sid = task_sid_obj(p);
|
||||
|
||||
spin_lock(&isec->lock);
|
||||
isec->sclass = inode_mode_to_security_class(inode->i_mode);
|
||||
@ -6152,7 +6242,7 @@ static int selinux_msg_queue_msgrcv(struct kern_ipc_perm *msq, struct msg_msg *m
|
||||
struct ipc_security_struct *isec;
|
||||
struct msg_security_struct *msec;
|
||||
struct common_audit_data ad;
|
||||
u32 sid = task_sid(target);
|
||||
u32 sid = task_sid_subj(target);
|
||||
int rc;
|
||||
|
||||
isec = selinux_ipc(msq);
|
||||
@ -7077,6 +7167,7 @@ static struct security_hook_list selinux_hooks[] __lsm_ro_after_init = {
|
||||
|
||||
LSM_HOOK_INIT(sb_free_security, selinux_sb_free_security),
|
||||
LSM_HOOK_INIT(sb_free_mnt_opts, selinux_free_mnt_opts),
|
||||
LSM_HOOK_INIT(sb_mnt_opts_compat, selinux_sb_mnt_opts_compat),
|
||||
LSM_HOOK_INIT(sb_remount, selinux_sb_remount),
|
||||
LSM_HOOK_INIT(sb_kern_mount, selinux_sb_kern_mount),
|
||||
LSM_HOOK_INIT(sb_show_options, selinux_sb_show_options),
|
||||
@ -7148,7 +7239,8 @@ static struct security_hook_list selinux_hooks[] __lsm_ro_after_init = {
|
||||
LSM_HOOK_INIT(task_setpgid, selinux_task_setpgid),
|
||||
LSM_HOOK_INIT(task_getpgid, selinux_task_getpgid),
|
||||
LSM_HOOK_INIT(task_getsid, selinux_task_getsid),
|
||||
LSM_HOOK_INIT(task_getsecid, selinux_task_getsecid),
|
||||
LSM_HOOK_INIT(task_getsecid_subj, selinux_task_getsecid_subj),
|
||||
LSM_HOOK_INIT(task_getsecid_obj, selinux_task_getsecid_obj),
|
||||
LSM_HOOK_INIT(task_setnice, selinux_task_setnice),
|
||||
LSM_HOOK_INIT(task_setioprio, selinux_task_setioprio),
|
||||
LSM_HOOK_INIT(task_getioprio, selinux_task_getioprio),
|
||||
|
@ -13,18 +13,83 @@
|
||||
#include "ima.h"
|
||||
|
||||
/*
|
||||
* selinux_ima_measure_state - Measure hash of the SELinux policy
|
||||
* selinux_ima_collect_state - Read selinux configuration settings
|
||||
*
|
||||
* @state: selinux_state
|
||||
*
|
||||
* On success returns the configuration settings string.
|
||||
* On error, returns NULL.
|
||||
*/
|
||||
static char *selinux_ima_collect_state(struct selinux_state *state)
|
||||
{
|
||||
const char *on = "=1;", *off = "=0;";
|
||||
char *buf;
|
||||
int buf_len, len, i, rc;
|
||||
|
||||
buf_len = strlen("initialized=0;enforcing=0;checkreqprot=0;") + 1;
|
||||
|
||||
len = strlen(on);
|
||||
for (i = 0; i < __POLICYDB_CAPABILITY_MAX; i++)
|
||||
buf_len += strlen(selinux_policycap_names[i]) + len;
|
||||
|
||||
buf = kzalloc(buf_len, GFP_KERNEL);
|
||||
if (!buf)
|
||||
return NULL;
|
||||
|
||||
rc = strscpy(buf, "initialized", buf_len);
|
||||
WARN_ON(rc < 0);
|
||||
|
||||
rc = strlcat(buf, selinux_initialized(state) ? on : off, buf_len);
|
||||
WARN_ON(rc >= buf_len);
|
||||
|
||||
rc = strlcat(buf, "enforcing", buf_len);
|
||||
WARN_ON(rc >= buf_len);
|
||||
|
||||
rc = strlcat(buf, enforcing_enabled(state) ? on : off, buf_len);
|
||||
WARN_ON(rc >= buf_len);
|
||||
|
||||
rc = strlcat(buf, "checkreqprot", buf_len);
|
||||
WARN_ON(rc >= buf_len);
|
||||
|
||||
rc = strlcat(buf, checkreqprot_get(state) ? on : off, buf_len);
|
||||
WARN_ON(rc >= buf_len);
|
||||
|
||||
for (i = 0; i < __POLICYDB_CAPABILITY_MAX; i++) {
|
||||
rc = strlcat(buf, selinux_policycap_names[i], buf_len);
|
||||
WARN_ON(rc >= buf_len);
|
||||
|
||||
rc = strlcat(buf, state->policycap[i] ? on : off, buf_len);
|
||||
WARN_ON(rc >= buf_len);
|
||||
}
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
/*
|
||||
* selinux_ima_measure_state_locked - Measure SELinux state and hash of policy
|
||||
*
|
||||
* @state: selinux state struct
|
||||
*
|
||||
* NOTE: This function must be called with policy_mutex held.
|
||||
*/
|
||||
void selinux_ima_measure_state(struct selinux_state *state)
|
||||
void selinux_ima_measure_state_locked(struct selinux_state *state)
|
||||
{
|
||||
char *state_str = NULL;
|
||||
void *policy = NULL;
|
||||
size_t policy_len;
|
||||
int rc = 0;
|
||||
|
||||
WARN_ON(!mutex_is_locked(&state->policy_mutex));
|
||||
|
||||
state_str = selinux_ima_collect_state(state);
|
||||
if (!state_str) {
|
||||
pr_err("SELinux: %s: failed to read state.\n", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
ima_measure_critical_data("selinux", "selinux-state",
|
||||
state_str, strlen(state_str), false);
|
||||
|
||||
kfree(state_str);
|
||||
|
||||
/*
|
||||
* Measure SELinux policy only after initialization is completed.
|
||||
*/
|
||||
@ -42,3 +107,17 @@ void selinux_ima_measure_state(struct selinux_state *state)
|
||||
|
||||
vfree(policy);
|
||||
}
|
||||
|
||||
/*
|
||||
* selinux_ima_measure_state - Measure SELinux state and hash of policy
|
||||
*
|
||||
* @state: selinux state struct
|
||||
*/
|
||||
void selinux_ima_measure_state(struct selinux_state *state)
|
||||
{
|
||||
WARN_ON(mutex_is_locked(&state->policy_mutex));
|
||||
|
||||
mutex_lock(&state->policy_mutex);
|
||||
selinux_ima_measure_state_locked(state);
|
||||
mutex_unlock(&state->policy_mutex);
|
||||
}
|
||||
|
@ -242,11 +242,12 @@ struct security_class_mapping secclass_map[] = {
|
||||
{ "infiniband_endport",
|
||||
{ "manage_subnet", NULL } },
|
||||
{ "bpf",
|
||||
{"map_create", "map_read", "map_write", "prog_load", "prog_run"} },
|
||||
{ "map_create", "map_read", "map_write", "prog_load", "prog_run",
|
||||
NULL } },
|
||||
{ "xdp_socket",
|
||||
{ COMMON_SOCK_PERMS, NULL } },
|
||||
{ "perf_event",
|
||||
{"open", "cpu", "kernel", "tracepoint", "read", "write"} },
|
||||
{ "open", "cpu", "kernel", "tracepoint", "read", "write", NULL } },
|
||||
{ "lockdown",
|
||||
{ "integrity", "confidentiality", NULL } },
|
||||
{ "anon_inode",
|
||||
|
@ -15,10 +15,16 @@
|
||||
|
||||
#ifdef CONFIG_IMA
|
||||
extern void selinux_ima_measure_state(struct selinux_state *selinux_state);
|
||||
extern void selinux_ima_measure_state_locked(
|
||||
struct selinux_state *selinux_state);
|
||||
#else
|
||||
static inline void selinux_ima_measure_state(struct selinux_state *selinux_state)
|
||||
{
|
||||
}
|
||||
static inline void selinux_ima_measure_state_locked(
|
||||
struct selinux_state *selinux_state)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _SELINUX_IMA_H_ */
|
||||
|
@ -426,7 +426,7 @@ extern struct page *selinux_kernel_status_page(struct selinux_state *state);
|
||||
|
||||
#define SELINUX_KERNEL_STATUS_VERSION 1
|
||||
struct selinux_kernel_status {
|
||||
u32 version; /* version number of thie structure */
|
||||
u32 version; /* version number of the structure */
|
||||
u32 sequence; /* sequence number of seqlock logic */
|
||||
u32 enforcing; /* current setting of enforcing mode */
|
||||
u32 policyload; /* times of policy reloaded */
|
||||
|
@ -41,6 +41,7 @@
|
||||
#include "security.h"
|
||||
#include "objsec.h"
|
||||
#include "conditional.h"
|
||||
#include "ima.h"
|
||||
|
||||
enum sel_inos {
|
||||
SEL_ROOT_INO = 2,
|
||||
@ -182,6 +183,8 @@ static ssize_t sel_write_enforce(struct file *file, const char __user *buf,
|
||||
selinux_status_update_setenforce(state, new_value);
|
||||
if (!new_value)
|
||||
call_blocking_lsm_notifier(LSM_POLICY_CHANGE, NULL);
|
||||
|
||||
selinux_ima_measure_state(state);
|
||||
}
|
||||
length = count;
|
||||
out:
|
||||
@ -758,6 +761,9 @@ static ssize_t sel_write_checkreqprot(struct file *file, const char __user *buf,
|
||||
|
||||
checkreqprot_set(fsi->state, (new_value ? 1 : 0));
|
||||
length = count;
|
||||
|
||||
selinux_ima_measure_state(fsi->state);
|
||||
|
||||
out:
|
||||
kfree(page);
|
||||
return length;
|
||||
|
@ -13,7 +13,7 @@ static struct kmem_cache *hashtab_node_cachep __ro_after_init;
|
||||
|
||||
/*
|
||||
* Here we simply round the number of elements up to the nearest power of two.
|
||||
* I tried also other options like rouding down or rounding to the closest
|
||||
* I tried also other options like rounding down or rounding to the closest
|
||||
* power of two (up or down based on which is closer), but I was unable to
|
||||
* find any significant difference in lookup/insert performance that would
|
||||
* justify switching to a different (less intuitive) formula. It could be that
|
||||
|
@ -2202,7 +2202,7 @@ static void selinux_notify_policy_change(struct selinux_state *state,
|
||||
selinux_status_update_policyload(state, seqno);
|
||||
selinux_netlbl_cache_invalidate();
|
||||
selinux_xfrm_notify_policyload();
|
||||
selinux_ima_measure_state(state);
|
||||
selinux_ima_measure_state_locked(state);
|
||||
}
|
||||
|
||||
void selinux_policy_commit(struct selinux_state *state,
|
||||
|
@ -383,7 +383,23 @@ static inline struct smack_known *smk_of_task(const struct task_smack *tsp)
|
||||
return tsp->smk_task;
|
||||
}
|
||||
|
||||
static inline struct smack_known *smk_of_task_struct(
|
||||
static inline struct smack_known *smk_of_task_struct_subj(
|
||||
const struct task_struct *t)
|
||||
{
|
||||
struct smack_known *skp;
|
||||
const struct cred *cred;
|
||||
|
||||
rcu_read_lock();
|
||||
|
||||
cred = rcu_dereference(t->cred);
|
||||
skp = smk_of_task(smack_cred(cred));
|
||||
|
||||
rcu_read_unlock();
|
||||
|
||||
return skp;
|
||||
}
|
||||
|
||||
static inline struct smack_known *smk_of_task_struct_obj(
|
||||
const struct task_struct *t)
|
||||
{
|
||||
struct smack_known *skp;
|
||||
|
@ -159,7 +159,7 @@ static int smk_bu_current(char *note, struct smack_known *oskp,
|
||||
static int smk_bu_task(struct task_struct *otp, int mode, int rc)
|
||||
{
|
||||
struct task_smack *tsp = smack_cred(current_cred());
|
||||
struct smack_known *smk_task = smk_of_task_struct(otp);
|
||||
struct smack_known *smk_task = smk_of_task_struct_obj(otp);
|
||||
char acc[SMK_NUM_ACCESS_TYPE + 1];
|
||||
|
||||
if (rc <= 0)
|
||||
@ -479,7 +479,7 @@ static int smack_ptrace_access_check(struct task_struct *ctp, unsigned int mode)
|
||||
{
|
||||
struct smack_known *skp;
|
||||
|
||||
skp = smk_of_task_struct(ctp);
|
||||
skp = smk_of_task_struct_obj(ctp);
|
||||
|
||||
return smk_ptrace_rule_check(current, skp, mode, __func__);
|
||||
}
|
||||
@ -2033,7 +2033,7 @@ static int smk_curacc_on_task(struct task_struct *p, int access,
|
||||
const char *caller)
|
||||
{
|
||||
struct smk_audit_info ad;
|
||||
struct smack_known *skp = smk_of_task_struct(p);
|
||||
struct smack_known *skp = smk_of_task_struct_subj(p);
|
||||
int rc;
|
||||
|
||||
smk_ad_init(&ad, caller, LSM_AUDIT_DATA_TASK);
|
||||
@ -2078,15 +2078,29 @@ static int smack_task_getsid(struct task_struct *p)
|
||||
}
|
||||
|
||||
/**
|
||||
* smack_task_getsecid - get the secid of the task
|
||||
* @p: the object task
|
||||
* smack_task_getsecid_subj - get the subjective secid of the task
|
||||
* @p: the task
|
||||
* @secid: where to put the result
|
||||
*
|
||||
* Sets the secid to contain a u32 version of the smack label.
|
||||
* Sets the secid to contain a u32 version of the task's subjective smack label.
|
||||
*/
|
||||
static void smack_task_getsecid(struct task_struct *p, u32 *secid)
|
||||
static void smack_task_getsecid_subj(struct task_struct *p, u32 *secid)
|
||||
{
|
||||
struct smack_known *skp = smk_of_task_struct(p);
|
||||
struct smack_known *skp = smk_of_task_struct_subj(p);
|
||||
|
||||
*secid = skp->smk_secid;
|
||||
}
|
||||
|
||||
/**
|
||||
* smack_task_getsecid_obj - get the objective secid of the task
|
||||
* @p: the task
|
||||
* @secid: where to put the result
|
||||
*
|
||||
* Sets the secid to contain a u32 version of the task's objective smack label.
|
||||
*/
|
||||
static void smack_task_getsecid_obj(struct task_struct *p, u32 *secid)
|
||||
{
|
||||
struct smack_known *skp = smk_of_task_struct_obj(p);
|
||||
|
||||
*secid = skp->smk_secid;
|
||||
}
|
||||
@ -2174,7 +2188,7 @@ static int smack_task_kill(struct task_struct *p, struct kernel_siginfo *info,
|
||||
{
|
||||
struct smk_audit_info ad;
|
||||
struct smack_known *skp;
|
||||
struct smack_known *tkp = smk_of_task_struct(p);
|
||||
struct smack_known *tkp = smk_of_task_struct_obj(p);
|
||||
int rc;
|
||||
|
||||
if (!sig)
|
||||
@ -2212,7 +2226,7 @@ static int smack_task_kill(struct task_struct *p, struct kernel_siginfo *info,
|
||||
static void smack_task_to_inode(struct task_struct *p, struct inode *inode)
|
||||
{
|
||||
struct inode_smack *isp = smack_inode(inode);
|
||||
struct smack_known *skp = smk_of_task_struct(p);
|
||||
struct smack_known *skp = smk_of_task_struct_obj(p);
|
||||
|
||||
isp->smk_inode = skp;
|
||||
isp->smk_flags |= SMK_INODE_INSTANT;
|
||||
@ -3483,7 +3497,7 @@ static void smack_d_instantiate(struct dentry *opt_dentry, struct inode *inode)
|
||||
*/
|
||||
static int smack_getprocattr(struct task_struct *p, char *name, char **value)
|
||||
{
|
||||
struct smack_known *skp = smk_of_task_struct(p);
|
||||
struct smack_known *skp = smk_of_task_struct_subj(p);
|
||||
char *cp;
|
||||
int slen;
|
||||
|
||||
@ -4759,7 +4773,8 @@ static struct security_hook_list smack_hooks[] __lsm_ro_after_init = {
|
||||
LSM_HOOK_INIT(task_setpgid, smack_task_setpgid),
|
||||
LSM_HOOK_INIT(task_getpgid, smack_task_getpgid),
|
||||
LSM_HOOK_INIT(task_getsid, smack_task_getsid),
|
||||
LSM_HOOK_INIT(task_getsecid, smack_task_getsecid),
|
||||
LSM_HOOK_INIT(task_getsecid_subj, smack_task_getsecid_subj),
|
||||
LSM_HOOK_INIT(task_getsecid_obj, smack_task_getsecid_obj),
|
||||
LSM_HOOK_INIT(task_setnice, smack_task_setnice),
|
||||
LSM_HOOK_INIT(task_setioprio, smack_task_setioprio),
|
||||
LSM_HOOK_INIT(task_getioprio, smack_task_getioprio),
|
||||
|
Loading…
Reference in New Issue
Block a user