Linux-Security-Module Archive on lore.kernel.org
 help / color / Atom feed
From: Yonghong Song <yhs@fb.com>
To: KP Singh <kpsingh@chromium.org>
Cc: "linux-kernel@vger.kernel.org" <linux-kernel@vger.kernel.org>,
	"bpf@vger.kernel.org" <bpf@vger.kernel.org>,
	"linux-security-module@vger.kernel.org"
	<linux-security-module@vger.kernel.org>,
	"Alexei Starovoitov" <ast@kernel.org>,
	"Daniel Borkmann" <daniel@iogearbox.net>,
	"James Morris" <jmorris@namei.org>,
	"Kees Cook" <keescook@chromium.org>,
	"Thomas Garnier" <thgarnie@chromium.org>,
	"Michael Halcrow" <mhalcrow@google.com>,
	"Paul Turner" <pjt@google.com>,
	"Brendan Gregg" <brendan.d.gregg@gmail.com>,
	"Jann Horn" <jannh@google.com>,
	"Matthew Garrett" <mjg59@google.com>,
	"Christian Brauner" <christian@brauner.io>,
	"Mickaël Salaün" <mic@digikod.net>,
	"Florent Revest" <revest@chromium.org>,
	"Martin Lau" <kafai@fb.com>, "Song Liu" <songliubraving@fb.com>,
	"Serge E. Hallyn" <serge@hallyn.com>,
	"Mauro Carvalho Chehab" <mchehab+samsung@kernel.org>,
	"David S. Miller" <davem@davemloft.net>,
	"Greg Kroah-Hartman" <gregkh@linuxfoundation.org>,
	"Nicolas Ferre" <nicolas.ferre@microchip.com>,
	"Stanislav Fomichev" <sdf@google.com>,
	"Quentin Monnet" <quentin.monnet@netronome.com>,
	"Andrey Ignatov" <rdna@fb.com>, "Joe Stringer" <joe@wand.net.nz>
Subject: Re: [RFC v1 12/14] krsi: Add an eBPF helper function to get the value of an env variable
Date: Tue, 17 Sep 2019 16:58:25 +0000
Message-ID: <66d5a0b2-8ea1-cdb1-87b6-71021d875296@fb.com> (raw)
In-Reply-To: <20190916130043.GA64010@google.com>



On 9/16/19 6:00 AM, KP Singh wrote:
> Thanks for reviewing!
> 
> On 15-Sep 00:16, Yonghong Song wrote:
>>
>>
>> On 9/10/19 12:55 PM, KP Singh wrote:
>>> From: KP Singh <kpsingh@google.com>
>>
>> This patch cannot apply cleanly.
>>
>> -bash-4.4$ git apply ~/p12.txt
>> error: patch failed: include/uapi/linux/bpf.h:2715
>> error: include/uapi/linux/bpf.h: patch does not apply
>> error: patch failed: tools/include/uapi/linux/bpf.h:2715
>> error: tools/include/uapi/linux/bpf.h: patch does not apply
>> -bash-4.4$
> 
> I am not sure why this is happening, I tried:
> 
> git clone \
>    https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git && \
>    cd linux-next && \
>    git checkout -b review v5.3-rc6 && \
>    wget -P /tmp https://lore.kernel.org/patchwork/series/410101/mbox && \
>    git am /tmp/mbox
> 
> and it worked.
> 
> This seems to work too:
> 
>    patch -p1 < <file>.patch
> 
> Can you try with "git am" please?

Will try next time when reviewing the tree.

> 
>>
>>>
>>> The helper returns the value of the environment variable in the buffer
>>> that is passed to it. If the var is set multiple times, the helper
>>> returns all the values as null separated strings.
>>>
>>> If the buffer is too short for these values, the helper tries to fill it
>>> the best it can and guarantees that the value returned in the buffer
>>> is always null terminated. After the buffer is filled, the helper keeps
>>> counting the number of times the environment variable is set in the
>>> envp.
>>>
>>> The return value of the helper is an u64 value which carries two pieces
>>> of information.
>>>
>>>     * The upper 32 bits are a u32 value signifying the number of times
>>>       the environment variable is set in the envp.
>>
>> Not sure how useful this 'upper 32' bit value is. What user expected to do?
>>
>> Another option is to have upper 32 bits encode the required buffer size
>> to hold all values. This may cause some kind of user space action, e.g.,
>> to replace the program with new program with larger per cpu map value size?
>>
> 
> The upper 32-bit value is actually an important part of the LSM's MAC
> policy. It allows the user to:
> 
> - Return an -EPERM when if the environment variable is set more than
>    once.
> - Log a warning (this is what we are doing in the example) so
>    this is flagged as a potential malicious actor.

So the intention is to catch cases where the env variable
to set by more than once, not exactly to capture all the values
of the env variable.

Then may be there is no need to record the values once the number of 
values is more than one? Do you have use case for what user to react if
there are more than one setting?

> 
>>>     * The lower 32 bits are a s32 value signifying the number of bytes
>>>       written to the buffer or an error code. >
>>> Since the value of the environment variable can be very long and exceed
>>> what can be allocated on the BPF stack, a per-cpu array can be used
>>> instead:
>>>
>>> struct bpf_map_def SEC("maps") env_map = {
>>>           .type = BPF_MAP_TYPE_PERCPU_ARRAY,
>>>           .key_size = sizeof(u32),
>>>           .value_size = 4096,
>>>           .max_entries = 1,
>>> };
>>
>> Could you use use map definition with SEC(".maps")?
> 
> Sure, I added this example program in the commit message. Will update
> it to be more canonical. Thanks!
> 
>>
>>>
>>> SEC("prgrm")
>>> int bpf_prog1(void *ctx)
>>> {
>>>           u32 map_id = 0;
>>>           u64 times_ret;
>>>           s32 ret;
>>>           char name[48] = "LD_PRELOAD";
>>
>> Reverse Christmas tree coding style, here and other places?
> 
> Will happily fix it.
> 
> However, I did not find it mentioned in the style guide:
> 
>    https://www.kernel.org/doc/html/v4.10/process/coding-style.html
>    https://urldefense.proofpoint.com/v2/url?u=https-3A__elixir.bootlin.com_linux_v4.6_source_Documentation_CodingStyle&d=DwIBAg&c=5VD0RTtNlTh3ycd41b3MUw&r=DA8e1B5r073vIqRrFz7MRA&m=G_3dpLivr0lLqQlQqAVEw9EZB3GonzJjILyCBqbmMIo&s=krLmTogyg9eSdco0j4tv2etr4PmNEPZGXMMoOkWdVG4&e=
> 
> Is there one specific to BPF?

I forgot where is the documentation. We follow this for bpf/net.

> 
> 
>>
>>>
>>>           char *map_value = bpf_map_lookup_elem(&env_map, &map_id);
>>>           if (!map_value)
>>>                   return 0;
>>>
>>>           // Read the lower 32 bits for the return value
>>>           times_ret = krsi_get_env_var(ctx, name, 48, map_value, 4096);
>>>           ret = times_ret & 0xffffffff;
>>>           if (ret < 0)
>>>                   return ret;
>>>           return 0;
>>> }
>>>
>>> Signed-off-by: KP Singh <kpsingh@google.com>
>>> ---
>>>    include/uapi/linux/bpf.h                  |  42 ++++++-
>>>    security/krsi/ops.c                       | 129 ++++++++++++++++++++++
>>>    tools/include/uapi/linux/bpf.h            |  42 ++++++-
>>>    tools/testing/selftests/bpf/bpf_helpers.h |   3 +
>>>    4 files changed, 214 insertions(+), 2 deletions(-)
>>>
>>> diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h
>>> index 32ab38f1a2fe..a4ef07956e07 100644
>>> --- a/include/uapi/linux/bpf.h
>>> +++ b/include/uapi/linux/bpf.h
>>> @@ -2715,6 +2715,45 @@ union bpf_attr {
>>>     *		**-EPERM** if no permission to send the *sig*.
>>>     *
>>>     *		**-EAGAIN** if bpf program can try again.
>>> + *
>>> + * u64 krsi_get_env_var(void *ctx, char *name, char *buf,
>>> + *			size_t name_len, size_t buf_len)
>>
>> This signature is not the same as the later
>> krsi_get_env_var(...) helper definition.
>> BPF_CALL_5(krsi_get_env_var, struct krsi_ctx *, ctx, char *, name, u32,
>> n_size,
>> 	  char *, dest, u32, size)
>>
> 
> I did this because the krsi_ctx is not exposed to the userspace and
> allows KRSI to modify the context without worrying about breaking
> userspace.
> 
> That said, I could mark it as a (void *) here and cast it internally.
> I guess that would be better/cleaner?

"void *" is okay, I am complaining the argument ordering is different
from real definition.

> 
>>> + *	Description
>>> + *		This helper can be used as a part of the
>>> + *		process_execution hook of the KRSI LSM in
>>> + *		programs of type BPF_PROG_TYPE_KRSI.
>>> + *
>>> + *		The helper returns the value of the environment
>>> + *		variable with the provided "name" for process that's
>>> + *		going to be executed in the passed buffer, "buf". If the var
>>> + *		is set multiple times, the helper returns all
>>> + *		the values as null separated strings.
>>> + *
>>> + *		If the buffer is too short for these values, the helper
>>> + *		tries to fill it the best it can and guarantees that the value
>>> + *		returned in the buffer  is always null terminated.
>>> + *		After the buffer is filled, the helper keeps counting the number
>>> + *		of times the environment variable is set in the envp.
>>> + *
>>> + *	Return:
>>> + *
>>> + *		The return value of the helper is an u64 value
>>> + *		which carries two pieces of information:
>>> + *
>>> + *		   The upper 32 bits are a u32 value signifying
>>> + *		   the number of times the environment variable
>>> + *		   is set in the envp.
>>> + *		   The lower 32 bits are an s32 value signifying
>>> + *		   the number of bytes written to the buffer or an error code:
>>> + *
>>> + *		**-ENOMEM** if the kernel is unable to allocate memory
>>> + *			    for pinning the argv and envv.
>>> + *
>>> + *		**-E2BIG** if the value is larger than the size of the
>>> + *			   destination buffer. The higher bits will still
>>> + *			   the number of times the variable was set in the envp.
>>
>> The -E2BIG is returned because buffer sizee is not big enough.
>> Another possible error code is -ENOSPC, which typically indicates
>> buffer size not big enough.
> 
> Sure, I am fine with using either.
> 
>>
>>> + *
>>> + *		**-EINVAL** if name is not a NULL terminated string.
>>>     */
>>>    #define __BPF_FUNC_MAPPER(FN)		\
>>>    	FN(unspec),			\
>>> @@ -2826,7 +2865,8 @@ union bpf_attr {
>>>    	FN(strtoul),			\
>>>    	FN(sk_storage_get),		\
>>>    	FN(sk_storage_delete),		\
>>> -	FN(send_signal),
>>> +	FN(send_signal),		\
>>> +	FN(krsi_get_env_var),
>>>    
>>>    /* integer value in 'imm' field of BPF_CALL instruction selects which helper
>>>     * function eBPF program intends to call
>>> diff --git a/security/krsi/ops.c b/security/krsi/ops.c
>>> index 1f4df920139c..1db94dfaac15 100644
>>> --- a/security/krsi/ops.c
>>> +++ b/security/krsi/ops.c
>>> @@ -6,6 +6,8 @@
>>>    #include <linux/bpf.h>
>>>    #include <linux/security.h>
>>>    #include <linux/krsi.h>
>>> +#include <linux/binfmts.h>
>>> +#include <linux/highmem.h>
>>>    
>>>    #include "krsi_init.h"
>>>    #include "krsi_fs.h"
>>> @@ -162,6 +164,131 @@ static bool krsi_prog_is_valid_access(int off, int size,
>>>    	return false;
>>>    }
>>>    
>>> +static char *array_next_entry(char *array, unsigned long *offset,
>>> +			      unsigned long end)
>>> +{
>>> +	char *entry;
>>> +	unsigned long current_offset = *offset;
>>> +
>>> +	if (current_offset >= end)
>>> +		return NULL;
>>> +
>>> +	/*
>>> +	 * iterate on the array till the null byte is encountered
>>> +	 * and check for any overflows.
>>> +	 */
>>> +	entry = array + current_offset;
>>> +	while (array[current_offset]) {
>>> +		if (unlikely(++current_offset >= end))
>>> +			return NULL;
>>> +	}
>>> +
>>> +	/*
>>> +	 * Point the offset to the next element in the array.
>>> +	 */
>>> +	*offset = current_offset + 1;
>>> +
>>> +	return entry;
>>> +}
>>> +
>>> +static u64 get_env_var(struct krsi_ctx *ctx, char *name, char *dest,
>>> +		u32 n_size, u32 size)
>>> +{
>>> +	s32 ret = 0;
>>> +	u32 num_vars = 0;
>>> +	int i, name_len;
>>> +	struct linux_binprm *bprm = ctx->bprm_ctx.bprm;
>>> +	int argc = bprm->argc;
>>> +	int envc = bprm->envc;
>>> +	unsigned long end = ctx->bprm_ctx.max_arg_offset;
>>> +	unsigned long offset = bprm->p % PAGE_SIZE;
>>
>> why we need bprm->p % PAGE_SIZE instead of bprm->p?
> 
> bprm->p points to the top of the memory and it's not an offset.
> 
> The pinned buffer contains the pages for the (argv+env) and the
> brpm->p % PAGE_SIZE is the offset into the first page where the
> (argv+envv) starts.

Thanks for the explanation.

> 
>>
>>> +	char *buf = ctx->bprm_ctx.arg_pages;
>>> +	char *curr_dest = dest;
>>> +	char *entry;
>>> +
>>> +	if (unlikely(!buf))
>>> +		return -ENOMEM;
>>> +
>>> +	for (i = 0; i < argc; i++) {
>>> +		entry = array_next_entry(buf, &offset, end);
>>> +		if (!entry)
>>> +			return 0;
>>> +	}
>>> +
>>> +	name_len = strlen(name);
>>> +	for (i = 0; i < envc; i++) {
>>> +		entry = array_next_entry(buf, &offset, end);
>>> +		if (!entry)
>>> +			return 0;
>>
>> If the buf is "LD_PRELOAD=a.so\0LD_PRELOAD=b.so" and argc=0,
>> we may skip the first entry?
> 
> I think I need to rename the "array_next_entry" function / document it
> better.
> 
> The function updates the offset to the next location and the
> returns the entry at the current offset.
> 
> So, in the first instance:
> 
>     // offset is the offset into the first page.
>     entry = buf + offset;
>     offset = <updated value to the next entry>.

Yes, some documentation will help.

> 
>>
>>
>>> +
>>> +		if (!strncmp(entry, name, name_len)) {
>>> +			num_vars++;
>>
>> There helper permits n_size = 0 (ARG_CONST_SIZE_OR_ZERO).
>> in this case, name_len = 0, strncmp(entry, name, name_len) will be always 0.
> 
> Thanks, you are right, It does not make sense to have name_len = 0. I
> will change it to ARG_CONST_SIZE.
> 
>>
>>> +
>>> +			/*
>>> +			 * There is no need to do further copying
>>> +			 * if the buffer is already full. Just count how many
>>> +			 * times the environment variable is set.
>>> +			 */
>>> +			if (ret == -E2BIG)
>>> +				continue;
>>> +
>>> +			if (entry[name_len] != '=')
>>> +				continue;
>>> +
>>> +			/*
>>> +			 * Move the buf pointer by name_len + 1
>>> +			 * (for the "=" sign)
>>> +			 */
>>> +			entry += name_len + 1;
>>> +			ret = strlcpy(curr_dest, entry, size);
>>> +
>>> +			if (ret >= size) {
>>> +				ret = -E2BIG;
>>
>> Here, we have a partial copy. Should you instead nullify (memset) it as
>> it is not really invalid one?
> 
> The function does specify that the it will return a null terminated
> value even if an -E2BIG is returned so that user does get a truncated
> value. It's better to give the user some data. (I mentioned this in
> the documentation for the helper).

Do you know what user could do with this partial data?
Again, I am not a security expert, maybe partial data can still
be used in meaningful.

> 
>>
>>> +				continue;
>>> +			}
>>> +
>>> +			/*
>>> +			 * strlcpy just returns the length of the string copied.
>>> +			 * The remaining space needs to account for the added
>>> +			 * null character.
>>> +			 */
>>> +			curr_dest += ret + 1;
>>> +			size -= ret + 1;
>>> +			/*
>>> +			 * Update ret to be the current number of bytes written
>>> +			 * to the destination
>>> +			 */
>>> +			ret = curr_dest - dest;
>>> +		}
>>> +	}
>>> +
>>> +	return (u64) num_vars << 32 | (u32) ret;
>>> +}
>>> +
>>> +BPF_CALL_5(krsi_get_env_var, struct krsi_ctx *, ctx, char *, name, u32, n_size,
>>> +	  char *, dest, u32, size)
>>> +{
>>> +	char *name_end;
>>> +
>>> +	name_end = memchr(name, '\0', n_size);
>>> +	if (!name_end)
>>> +		return -EINVAL;
>>> +
>>> +	memset(dest, 0, size);
> 
> This memset ensures the buffer is zeroed out (incase the buffer is
> fully / partially empty).
> 
>>> +	return get_env_var(ctx, name, dest, n_size, size);
>>> +}
>>> +
>>> +static const struct bpf_func_proto krsi_get_env_var_proto = {
>>> +	.func = krsi_get_env_var,
>>> +	.gpl_only = true,
>>> +	.ret_type = RET_INTEGER,
>>> +	.arg1_type = ARG_PTR_TO_CTX,
>>> +	.arg2_type = ARG_PTR_TO_MEM,
>>> +	.arg3_type = ARG_CONST_SIZE_OR_ZERO,
>>> +	.arg4_type = ARG_PTR_TO_UNINIT_MEM,
>>> +	.arg5_type = ARG_CONST_SIZE_OR_ZERO,
>>> +};
>>> +
>>>    BPF_CALL_5(krsi_event_output, void *, log,
>>>    	   struct bpf_map *, map, u64, flags, void *, data, u64, size)
>>>    {
>>> @@ -192,6 +319,8 @@ static const struct bpf_func_proto *krsi_prog_func_proto(enum bpf_func_id
>>>    		return &bpf_map_lookup_elem_proto;
>>>    	case BPF_FUNC_get_current_pid_tgid:
>>>    		return &bpf_get_current_pid_tgid_proto;
>>> +	case BPF_FUNC_krsi_get_env_var:
>>> +		return &krsi_get_env_var_proto;
>>>    	case BPF_FUNC_perf_event_output:
>>>    		return &krsi_event_output_proto;
>>>    	default:
>>> diff --git a/tools/include/uapi/linux/bpf.h b/tools/include/uapi/linux/bpf.h
>>> index 32ab38f1a2fe..a4ef07956e07 100644
>>> --- a/tools/include/uapi/linux/bpf.h
>>> +++ b/tools/include/uapi/linux/bpf.h
>>> @@ -2715,6 +2715,45 @@ union bpf_attr {
>>>     *		**-EPERM** if no permission to send the *sig*.
>>>     *
>>>     *		**-EAGAIN** if bpf program can try again.
>>> + *
>>> + * u64 krsi_get_env_var(void *ctx, char *name, char *buf,
>>> + *			size_t name_len, size_t buf_len)
>>
>> Inconsistent helper definitions.
> 
> As discussed above, I can change the BPF_CALL_5 declaration to have
> a (void *) and cast to the krsi_ctx in the helper itself.
> 
> - KP
> 
>>
>>> + *	Description
>>> + *		This helper can be used as a part of the
>>> + *		process_execution hook of the KRSI LSM in
>>> + *		programs of type BPF_PROG_TYPE_KRSI.
>>> + *
>>> + *		The helper returns the value of the environment
>>> + *		variable with the provided "name" for process that's
>>> + *		going to be executed in the passed buffer, "buf". If the var
>>> + *		is set multiple times, the helper returns all
>>> + *		the values as null separated strings.
>>> + *
>>> + *		If the buffer is too short for these values, the helper
>>> + *		tries to fill it the best it can and guarantees that the value
>>> + *		returned in the buffer  is always null terminated.
>>> + *		After the buffer is filled, the helper keeps counting the number
>>> + *		of times the environment variable is set in the envp.
>>> + *
>>> + *	Return:
>>> + *
>>> + *		The return value of the helper is an u64 value
>>> + *		which carries two pieces of information:
>>> + *
>>> + *		   The upper 32 bits are a u32 value signifying
>>> + *		   the number of times the environment variable
>>> + *		   is set in the envp.
>>> + *		   The lower 32 bits are an s32 value signifying
>>> + *		   the number of bytes written to the buffer or an error code:
>>> + *
>>> + *		**-ENOMEM** if the kernel is unable to allocate memory
>>> + *			    for pinning the argv and envv.
>>> + *
>>> + *		**-E2BIG** if the value is larger than the size of the
>>> + *			   destination buffer. The higher bits will still
>>> + *			   the number of times the variable was set in the envp.
>>> + *
>>> + *		**-EINVAL** if name is not a NULL terminated string.
>>>     */
>>>    #define __BPF_FUNC_MAPPER(FN)		\
>>>    	FN(unspec),			\
>>> @@ -2826,7 +2865,8 @@ union bpf_attr {
>>>    	FN(strtoul),			\
>>>    	FN(sk_storage_get),		\
>>>    	FN(sk_storage_delete),		\
>>> -	FN(send_signal),
>>> +	FN(send_signal),		\
>>> +	FN(krsi_get_env_var),
>>>    
>>>    /* integer value in 'imm' field of BPF_CALL instruction selects which helper
>>>     * function eBPF program intends to call
>>> diff --git a/tools/testing/selftests/bpf/bpf_helpers.h b/tools/testing/selftests/bpf/bpf_helpers.h
>>> index f804f210244e..ecebdb772a9d 100644
>>> --- a/tools/testing/selftests/bpf/bpf_helpers.h
>>> +++ b/tools/testing/selftests/bpf/bpf_helpers.h
>>> @@ -303,6 +303,9 @@ static int (*bpf_get_numa_node_id)(void) =
>>>    static int (*bpf_probe_read_str)(void *ctx, __u32 size,
>>>    				 const void *unsafe_ptr) =
>>>    	(void *) BPF_FUNC_probe_read_str;
>>> +static unsigned long long (*krsi_get_env_var)(void *ctx,
>>> +	void *name, __u32 n_size, void *buf, __u32 size) =
>>> +	(void *) BPF_FUNC_krsi_get_env_var;
>>>    static unsigned int (*bpf_get_socket_uid)(void *ctx) =
>>>    	(void *) BPF_FUNC_get_socket_uid;
>>>    static unsigned int (*bpf_set_hash)(void *ctx, __u32 hash) =
>>>

  reply index

Thread overview: 28+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-09-10 11:55 [RFC v1 00/14] Kernel Runtime Security Instrumentation KP Singh
2019-09-10 11:55 ` [RFC v1 01/14] krsi: Add a skeleton and config options for the KRSI LSM KP Singh
2019-09-10 11:55 ` [RFC v1 02/14] krsi: Introduce types for KRSI eBPF KP Singh
2019-09-10 11:55 ` [RFC v1 03/14] bpf: krsi: sync BPF UAPI header with tools KP Singh
2019-09-10 11:55 ` [RFC v1 04/14] krsi: Add support in libbpf for BPF_PROG_TYPE_KRSI KP Singh
2019-09-14 16:09   ` Yonghong Song
2019-09-10 11:55 ` [RFC v1 05/14] krsi: Initialize KRSI hooks and create files in securityfs KP Singh
2019-09-14 16:26   ` Yonghong Song
2019-09-10 11:55 ` [RFC v1 06/14] krsi: Implement eBPF operations, attachment and execution KP Singh
2019-09-14 16:56   ` Yonghong Song
2019-09-15  0:37     ` Yonghong Song
2019-09-10 11:55 ` [RFC v1 07/14] krsi: Check for premissions on eBPF attachment KP Singh
2019-09-10 11:55 ` [RFC v1 08/14] krsi: Show attached program names in hook read handler KP Singh
2019-09-10 11:55 ` [RFC v1 09/14] krsi: Add a helper function for bpf_perf_event_output KP Singh
2019-09-14 18:23   ` Yonghong Song
2019-09-10 11:55 ` [RFC v1 10/14] krsi: Handle attachment of the same program KP Singh
2019-09-10 11:55 ` [RFC v1 11/14] krsi: Pin argument pages in bprm_check_security hook KP Singh
2019-09-10 11:55 ` [RFC v1 12/14] krsi: Add an eBPF helper function to get the value of an env variable KP Singh
2019-09-15  0:16   ` Yonghong Song
2019-09-16 13:00     ` KP Singh
2019-09-17 16:58       ` Yonghong Song [this message]
2019-09-17 19:36         ` KP Singh
2019-09-10 11:55 ` [RFC v1 13/14] krsi: Provide an example to read and log environment variables KP Singh
2019-09-15  0:24   ` Yonghong Song
2019-09-10 11:55 ` [RFC v1 14/14] krsi: Pin arg pages only when needed KP Singh
2019-09-15  0:33   ` Yonghong Song
2019-09-15  1:40     ` KP Singh
2019-09-15 19:45       ` Yonghong Song

Reply instructions:

You may reply publically to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=66d5a0b2-8ea1-cdb1-87b6-71021d875296@fb.com \
    --to=yhs@fb.com \
    --cc=ast@kernel.org \
    --cc=bpf@vger.kernel.org \
    --cc=brendan.d.gregg@gmail.com \
    --cc=christian@brauner.io \
    --cc=daniel@iogearbox.net \
    --cc=davem@davemloft.net \
    --cc=gregkh@linuxfoundation.org \
    --cc=jannh@google.com \
    --cc=jmorris@namei.org \
    --cc=joe@wand.net.nz \
    --cc=kafai@fb.com \
    --cc=keescook@chromium.org \
    --cc=kpsingh@chromium.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-security-module@vger.kernel.org \
    --cc=mchehab+samsung@kernel.org \
    --cc=mhalcrow@google.com \
    --cc=mic@digikod.net \
    --cc=mjg59@google.com \
    --cc=nicolas.ferre@microchip.com \
    --cc=pjt@google.com \
    --cc=quentin.monnet@netronome.com \
    --cc=rdna@fb.com \
    --cc=revest@chromium.org \
    --cc=sdf@google.com \
    --cc=serge@hallyn.com \
    --cc=songliubraving@fb.com \
    --cc=thgarnie@chromium.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link

Linux-Security-Module Archive on lore.kernel.org

Archives are clonable:
	git clone --mirror https://lore.kernel.org/linux-security-module/0 linux-security-module/git/0.git

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V2 linux-security-module linux-security-module/ https://lore.kernel.org/linux-security-module \
		linux-security-module@vger.kernel.org
	public-inbox-index linux-security-module

Example config snippet for mirrors

Newsgroup available over NNTP:
	nntp://nntp.lore.kernel.org/org.kernel.vger.linux-security-module


AGPL code for this site: git clone https://public-inbox.org/public-inbox.git