lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date:   Wed, 12 Oct 2022 23:19:35 +0200
From:   Mickaël Salaün <mic@...ikod.net>
To:     Casey Schaufler <casey@...aufler-ca.com>,
        casey.schaufler@...el.com, paul@...l-moore.com,
        linux-security-module@...r.kernel.org
Cc:     linux-audit@...hat.com, jmorris@...ei.org, selinux@...r.kernel.org,
        keescook@...omium.org, john.johansen@...onical.com,
        penguin-kernel@...ove.sakura.ne.jp, stephen.smalley.work@...il.com,
        linux-kernel@...r.kernel.org
Subject: Re: [PATCH v38 20/39] LSM: Specify which LSM to display


On 27/09/2022 21:54, Casey Schaufler wrote:
> Create two new prctl() options PR_LSM_ATTR_SET and PR_LSM_ATTR_GET
> which change and report the Interface LSM respectively.
> 
> The LSM ID number of an active LSM that supplies hooks for
> human readable data may be passed in the arg2 value with the
> PR_LSM_ATTR_SET option. The PR_LSM_ATT_GET option returns the
> LSM ID currently in use. At this point there can only be one LSM
> capable of display active. A helper function lsm_task_ilsm() is
> provided to get the interface lsm slot for a task_struct.
> 
> Security modules that wish to restrict this action may provide
> a task_prctl hook to do so. Each such security module is
> responsible for defining its policy.
> 
> AppArmor hook initially provided by John Johansen
> <john.johansen@...onical.com>. SELinux hook initially provided by
> Stephen Smalley <stephen.smalley.work@...il.com>
> 
> Signed-off-by: Casey Schaufler <casey@...aufler-ca.com>
> ---

[...]

> diff --git a/security/security.c b/security/security.c
> index 80133d6e982c..43d2431dbda0 100644
> --- a/security/security.c
> +++ b/security/security.c
> @@ -28,6 +28,7 @@
>   #include <linux/backing-dev.h>
>   #include <linux/string.h>
>   #include <linux/msg.h>
> +#include <linux/prctl.h>
>   #include <uapi/linux/lsm.h>
>   #include <net/flow.h>
>   #include <net/sock.h>
> @@ -81,7 +82,16 @@ static struct kmem_cache *lsm_file_cache;
>   static struct kmem_cache *lsm_inode_cache;
>   
>   char *lsm_names;
> -static struct lsm_blob_sizes blob_sizes __lsm_ro_after_init;
> +
> +/*
> + * The task blob includes the "interface_lsm" slot used for
> + * chosing which module presents contexts.
> + * Using a long to avoid potential alignment issues with
> + * module assigned task blobs.
> + */
> +static struct lsm_blob_sizes blob_sizes __lsm_ro_after_init = {
> +	.lbs_task = sizeof(long),
> +};
>   
>   /* Boot-time LSM user choice */
>   static __initdata const char *chosen_lsm_order;
> @@ -691,6 +701,8 @@ int lsm_inode_alloc(struct inode *inode)
>    */
>   static int lsm_task_alloc(struct task_struct *task)
>   {
> +	int *ilsm;
> +
>   	if (blob_sizes.lbs_task == 0) {
>   		task->security = NULL;
>   		return 0;
> @@ -699,6 +711,15 @@ static int lsm_task_alloc(struct task_struct *task)
>   	task->security = kzalloc(blob_sizes.lbs_task, GFP_KERNEL);
>   	if (task->security == NULL)
>   		return -ENOMEM;
> +
> +	/*
> +	 * The start of the task blob contains the "interface" LSM slot number.
> +	 * Start with it set to the invalid slot number, indicating that the
> +	 * default first registered LSM be displayed.
> +	 */
> +	ilsm = task->security;
> +	*ilsm = LSMBLOB_INVALID;
> +
>   	return 0;
>   }
>   
> @@ -1765,14 +1786,26 @@ int security_file_open(struct file *file)
>   
>   int security_task_alloc(struct task_struct *task, unsigned long clone_flags)
>   {
> +	int *oilsm = current->security;
> +	int *nilsm;
>   	int rc = lsm_task_alloc(task);
>   
> -	if (rc)
> +	if (unlikely(rc))
>   		return rc;
> +
>   	rc = call_int_hook(task_alloc, 0, task, clone_flags);
> -	if (unlikely(rc))
> +	if (unlikely(rc)) {
>   		security_task_free(task);
> -	return rc;
> +		return rc;
> +	}
> +
> +	if (oilsm) {
> +		nilsm = task->security;
> +		if (nilsm)
> +			*nilsm = *oilsm;
> +	}
> +
> +	return 0;
>   }
>   
>   void security_task_free(struct task_struct *task)
> @@ -2031,10 +2064,15 @@ int security_task_kill(struct task_struct *p, struct kernel_siginfo *info,
>   int security_task_prctl(int option, unsigned long arg2, unsigned long arg3,
>   			 unsigned long arg4, unsigned long arg5)
>   {
> +	int *ilsm = current->security;
>   	int thisrc;
> +	int slot;
>   	int rc = LSM_RET_DEFAULT(task_prctl);
>   	struct security_hook_list *hp;
>   
> +	if (lsm_slot == 0)
> +		return -EINVAL;
> +
>   	hlist_for_each_entry(hp, &security_hook_heads.task_prctl, list) {
>   		thisrc = hp->hook.task_prctl(option, arg2, arg3, arg4, arg5);
>   		if (thisrc != LSM_RET_DEFAULT(task_prctl)) {
> @@ -2043,6 +2081,25 @@ int security_task_prctl(int option, unsigned long arg2, unsigned long arg3,
>   				break;
>   		}
>   	}
> +
> +	switch (option) {
> +	case PR_LSM_ATTR_SET:
> +		if (rc && rc != LSM_RET_DEFAULT(task_prctl))
> +			return rc;
> +		for (slot = 0; slot < lsm_slot; slot++)
> +			if (lsm_slotlist[slot]->id == arg2) {

This doesn't build if LSMBLOB_ENTRIES == 0


> +				*ilsm = lsm_slotlist[slot]->slot;
> +				return 0;
> +			}
> +		return -EINVAL;
> +	case PR_LSM_ATTR_GET:
> +		if (rc && rc != LSM_RET_DEFAULT(task_prctl))
> +			return rc;
> +		if (*ilsm != LSMBLOB_INVALID)
> +			return lsm_slotlist[*ilsm]->id;
> +		return lsm_slotlist[0]->id;
> +	}
> +
>   	return rc;
>   }
>   

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ