Skip to content

Commit 29e48ce

Browse files
committed
task_struct: Allow randomized layout
This marks most of the layout of task_struct as randomizable, but leaves thread_info and scheduler state untouched at the start, and thread_struct untouched at the end. Other parts of the kernel use unnamed structures, but the 0-day builder using gcc-4.4 blows up on static initializers. Officially, it's documented as only working on gcc 4.6 and later, which further confuses me: https://gcc.gnu.org/wiki/C11Status The structure layout randomization already requires gcc 4.7, but instead of depending on the plugin being enabled, just check the gcc versions for wider build testing. At Linus's suggestion, the marking is hidden in a macro to reduce how ugly it looks. Additionally, indenting is left unchanged since it would make things harder to read. Randomization of task_struct is modified from Brad Spengler/PaX Team's code in the last public patch of grsecurity/PaX based on my understanding of the code. Changes or omissions from the original code are mine and don't reflect the original grsecurity/PaX code. Cc: Linus Torvalds <[email protected]> Signed-off-by: Kees Cook <[email protected]>
1 parent 3859a27 commit 29e48ce

File tree

3 files changed

+31
-1
lines changed

3 files changed

+31
-1
lines changed

include/linux/compiler-gcc.h

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -231,14 +231,25 @@
231231
#endif /* GCC_VERSION >= 40500 */
232232

233233
#if GCC_VERSION >= 40600
234+
234235
/*
235236
* When used with Link Time Optimization, gcc can optimize away C functions or
236237
* variables which are referenced only from assembly code. __visible tells the
237238
* optimizer that something else uses this function or variable, thus preventing
238239
* this.
239240
*/
240241
#define __visible __attribute__((externally_visible))
241-
#endif
242+
243+
/*
244+
* RANDSTRUCT_PLUGIN wants to use an anonymous struct, but it is only
245+
* possible since GCC 4.6. To provide as much build testing coverage
246+
* as possible, this is used for all GCC 4.6+ builds, and not just on
247+
* RANDSTRUCT_PLUGIN builds.
248+
*/
249+
#define randomized_struct_fields_start struct {
250+
#define randomized_struct_fields_end } __randomize_layout;
251+
252+
#endif /* GCC_VERSION >= 40600 */
242253

243254

244255
#if GCC_VERSION >= 40900 && !defined(__CHECKER__)

include/linux/compiler.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -456,6 +456,11 @@ static __always_inline void __write_once_size(volatile void *p, void *res, int s
456456
# define __no_randomize_layout
457457
#endif
458458

459+
#ifndef randomized_struct_fields_start
460+
# define randomized_struct_fields_start
461+
# define randomized_struct_fields_end
462+
#endif
463+
459464
/*
460465
* Tell gcc if a function is cold. The compiler will assume any path
461466
* directly leading to the call is unlikely.

include/linux/sched.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -490,6 +490,13 @@ struct task_struct {
490490
#endif
491491
/* -1 unrunnable, 0 runnable, >0 stopped: */
492492
volatile long state;
493+
494+
/*
495+
* This begins the randomizable portion of task_struct. Only
496+
* scheduling-critical items should be added above here.
497+
*/
498+
randomized_struct_fields_start
499+
493500
void *stack;
494501
atomic_t usage;
495502
/* Per task flags (PF_*), defined further below: */
@@ -1051,6 +1058,13 @@ struct task_struct {
10511058
/* Used by LSM modules for access restriction: */
10521059
void *security;
10531060
#endif
1061+
1062+
/*
1063+
* New fields for task_struct should be added above here, so that
1064+
* they are included in the randomized portion of task_struct.
1065+
*/
1066+
randomized_struct_fields_end
1067+
10541068
/* CPU-specific state of this task: */
10551069
struct thread_struct thread;
10561070

0 commit comments

Comments
 (0)