netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Kees Cook <keescook@chromium.org>
To: Andrew Morton <akpm@linux-foundation.org>
Cc: xiujianfeng <xiujianfeng@huawei.com>,
	laniel_francis@privacyrequired.com,
	andriy.shevchenko@linux.intel.com, adobriyan@gmail.com,
	linux@roeck-us.net, andreyknvl@gmail.com, dja@axtens.net,
	ast@kernel.org, daniel@iogearbox.net, andrii@kernel.org,
	kafai@fb.com, songliubraving@fb.com, yhs@fb.com,
	john.fastabend@gmail.com, kpsingh@kernel.org,
	linux-kernel@vger.kernel.org, netdev@vger.kernel.org,
	bpf@vger.kernel.org
Subject: Re: [PATCH -next 1/2] string.h: Introduce memset_range() for wiping members
Date: Wed, 8 Dec 2021 21:17:44 -0800	[thread overview]
Message-ID: <202112082111.14E796A23@keescook> (raw)
In-Reply-To: <20211208154437.01441d2dcf4cd812a9c58a7d@linux-foundation.org>

On Wed, Dec 08, 2021 at 03:44:37PM -0800, Andrew Morton wrote:
> On Wed, 8 Dec 2021 18:30:26 +0800 xiujianfeng <xiujianfeng@huawei.com> wrote:
> 
> > 
> > 在 2021/12/8 12:28, Andrew Morton 写道:
> > > On Wed, 8 Dec 2021 11:04:50 +0800 Xiu Jianfeng <xiujianfeng@huawei.com> wrote:
> > >
> > >> Motivated by memset_after() and memset_startat(), introduce a new helper,
> > >> memset_range() that takes the target struct instance, the byte to write,
> > >> and two member names where zeroing should start and end.
> > > Is this likely to have more than a single call site?
> > There maybe more call site for this function, but I just use bpf as an 
> > example.
> > >
> > >> ...
> > >>
> > >> --- a/include/linux/string.h
> > >> +++ b/include/linux/string.h
> > >> @@ -291,6 +291,26 @@ void memcpy_and_pad(void *dest, size_t dest_len, const void *src, size_t count,
> > >>   	       sizeof(*(obj)) - offsetof(typeof(*(obj)), member));	\
> > >>   })
> > >>   
> > >> +/**
> > >> + * memset_range - Set a value ranging from member1 to member2, boundary included.
> > > I'm not sure what "boundary included" means.
> > I mean zeroing from member1 to member2(including position indicated by 
> > member1 and member2)
> > >
> > >> + *
> > >> + * @obj: Address of target struct instance
> > >> + * @v: Byte value to repeatedly write
> > >> + * @member1: struct member to start writing at
> > >> + * @member2: struct member where writing should stop
> > > Perhaps "struct member before which writing should stop"?
> > memset_range should include position indicated by member2 as well
> 
> In that case we could say "struct member where writing should stop
> (inclusive)", to make it very clear.
> 
> > >
> > >> + *
> > >> + */
> > >> +#define memset_range(obj, v, member_1, member_2)			\
> > >> +({									\
> > >> +	u8 *__ptr = (u8 *)(obj);					\
> > >> +	typeof(v) __val = (v);						\
> > >> +	BUILD_BUG_ON(offsetof(typeof(*(obj)), member_1) >		\
> > >> +		     offsetof(typeof(*(obj)), member_2));		\
> > >> +	memset(__ptr + offsetof(typeof(*(obj)), member_1), __val,	\
> > >> +	       offsetofend(typeof(*(obj)), member_2) -			\
> > >> +	       offsetof(typeof(*(obj)), member_1));			\
> > >> +})
> > > struct a {
> > > 	int b;
> > > 	int c;
> > > 	int d;
> > > };
> > >
> > > How do I zero out `c' and `d'?
> > if you want to zero out 'c' and 'd', you can use it like 
> > memset_range(a_ptr, c, d);
> 
> But I don't think that's what the code does!
> 
> it expands to
> 
> 	memset(__ptr + offsetof(typeof(*(a)), c), __val,
> 	       offsetofend(typeof(*(a)), d) -
> 	       offsetof(typeof(*(a)), c));
> 
> which expands to
> 
> 	memset(__ptr + 4, __val,
> 	       8 -
> 	       4);
> 
> and `d' will not be written to.

Please don't add memset_range(): just use a struct_group() to capture
the range and use memset() against the new substruct. This will allow
for the range to be documented where it is defined in the struct (rather
than deep in some code), keep any changes centralized instead of spread
around in memset_range() calls, protect against accidental struct member
reordering breaking things, and lets the compiler be able to examine
the range explicitly and do all the correct bounds checking:

struct a {
	int b;
	struct_group(range,
		int c;
		int d;
	);
	int e;
};

memset(&instance->range, 0, sizeof(instance->range));

memset_from/after() were added because of the very common case of "wipe
from here to end", which stays tied to a single member, and addressed
cases where struct_group() couldn't help (e.g. trailing padding).

-- 
Kees Cook

  reply	other threads:[~2021-12-09  5:17 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-12-08  3:04 [PATCH -next 0/2] Introduce memset_range() helper for wiping members Xiu Jianfeng
2021-12-08  3:04 ` [PATCH -next 1/2] string.h: Introduce memset_range() " Xiu Jianfeng
2021-12-08  4:28   ` Andrew Morton
2021-12-08 10:30     ` xiujianfeng
2021-12-08 23:44       ` Andrew Morton
2021-12-09  5:17         ` Kees Cook [this message]
2021-12-09  6:29           ` xiujianfeng
2021-12-09  6:29         ` xiujianfeng
2021-12-08 17:12   ` Alexey Dobriyan
2021-12-08  3:04 ` [PATCH -next 2/2] bpf: use memset_range helper in __mark_reg_known Xiu Jianfeng
2021-12-08  5:27 ` [PATCH -next 0/2] Introduce memset_range() helper for wiping members Kees Cook
2021-12-08 10:30   ` xiujianfeng

Reply instructions:

You may reply publicly 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=202112082111.14E796A23@keescook \
    --to=keescook@chromium.org \
    --cc=adobriyan@gmail.com \
    --cc=akpm@linux-foundation.org \
    --cc=andreyknvl@gmail.com \
    --cc=andrii@kernel.org \
    --cc=andriy.shevchenko@linux.intel.com \
    --cc=ast@kernel.org \
    --cc=bpf@vger.kernel.org \
    --cc=daniel@iogearbox.net \
    --cc=dja@axtens.net \
    --cc=john.fastabend@gmail.com \
    --cc=kafai@fb.com \
    --cc=kpsingh@kernel.org \
    --cc=laniel_francis@privacyrequired.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux@roeck-us.net \
    --cc=netdev@vger.kernel.org \
    --cc=songliubraving@fb.com \
    --cc=xiujianfeng@huawei.com \
    --cc=yhs@fb.com \
    /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
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).