string.h: Introduce memset_after() for wiping trailing members/padding
A common idiom in kernel code is to wipe the contents of a structure after a given member. This is especially useful in places where there is trailing padding. These open-coded cases are usually difficult to read and very sensitive to struct layout changes. Introduce a new helper, memset_after() that takes the target struct instance, the byte to write, and the member name after which the zeroing should start. Cc: Steffen Klassert <steffen.klassert@secunet.com> Cc: Herbert Xu <herbert@gondor.apana.org.au> Cc: "David S. Miller" <davem@davemloft.net> Cc: Jakub Kicinski <kuba@kernel.org> Cc: Andrew Morton <akpm@linux-foundation.org> Cc: Francis Laniel <laniel_francis@privacyrequired.com> Cc: Vincenzo Frascino <vincenzo.frascino@arm.com> Cc: Daniel Axtens <dja@axtens.net> Cc: netdev@vger.kernel.org Signed-off-by: Kees Cook <keescook@chromium.org>
This commit is contained in:
parent
bb95ebbe89
commit
4797632f4f
|
@ -271,6 +271,23 @@ static inline void memcpy_and_pad(void *dest, size_t dest_len,
|
|||
memcpy(dest, src, dest_len);
|
||||
}
|
||||
|
||||
/**
|
||||
* memset_after - Set a value after a struct member to the end of a struct
|
||||
*
|
||||
* @obj: Address of target struct instance
|
||||
* @v: Byte value to repeatedly write
|
||||
* @member: after which struct member to start writing bytes
|
||||
*
|
||||
* This is good for clearing padding following the given member.
|
||||
*/
|
||||
#define memset_after(obj, v, member) \
|
||||
({ \
|
||||
u8 *__ptr = (u8 *)(obj); \
|
||||
typeof(v) __val = (v); \
|
||||
memset(__ptr + offsetofend(typeof(*(obj)), member), __val, \
|
||||
sizeof(*(obj)) - offsetofend(typeof(*(obj)), member)); \
|
||||
})
|
||||
|
||||
/**
|
||||
* str_has_prefix - Test if a string has a given prefix
|
||||
* @str: The string to test
|
||||
|
|
|
@ -215,6 +215,13 @@ static void memset_test(struct kunit *test)
|
|||
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
|
||||
},
|
||||
};
|
||||
struct some_bytes after = {
|
||||
.data = { 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x72,
|
||||
0x72, 0x72, 0x72, 0x72, 0x72, 0x72, 0x72, 0x72,
|
||||
0x72, 0x72, 0x72, 0x72, 0x72, 0x72, 0x72, 0x72,
|
||||
0x72, 0x72, 0x72, 0x72, 0x72, 0x72, 0x72, 0x72,
|
||||
},
|
||||
};
|
||||
struct some_bytes dest = { };
|
||||
int count, value;
|
||||
u8 *ptr;
|
||||
|
@ -245,6 +252,12 @@ static void memset_test(struct kunit *test)
|
|||
ptr += 8;
|
||||
memset(ptr++, value++, count++);
|
||||
compare("argument side-effects", dest, three);
|
||||
|
||||
/* Verify memset_after() */
|
||||
dest = control;
|
||||
memset_after(&dest, 0x72, three);
|
||||
compare("memset_after()", dest, after);
|
||||
|
||||
#undef TEST_OP
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue