|
Message-Id: <20190929163028.9665-2-romain.perier@gmail.com> Date: Sun, 29 Sep 2019 18:30:13 +0200 From: Romain Perier <romain.perier@...il.com> To: kernel-hardening@...ts.openwall.com Cc: Kees Cook <keescook@...omium.org>, Romain Perier <romain.perier@...il.com> Subject: [PRE-REVIEW PATCH 01/16] tasklet: Prepare to change tasklet callback argument type Nowadays, modern kernel subsystems that use callbacks pass the data structure associated with a given callback as argument to the callback. The tasklet subsystem remains the one to pass callback argument as an arbitrary unsigned long argument. This has several problems: - This keeps an extra field for storing the argument in each tasklet data structure, it bloats the tasklet_struct structure with a redundant .data field - No type checking cannot be performed on this argument. Instead of using container_of() like other callback subsystems, it forces callbacks to do explicit type cast of the unsigned long argument into the required object type. - Buffer overflows can overwrite the .function and the .data field, so an attacker can easily overwrite the function and its first argument to whatever it wants. This adds a new tasklet initialization API which will gradually replace the existing one. This work is greatly inspired from the timer_struct conversion series, see commit e99e88a9d ("treewide: setup_timer() -> timer_setup()") Signed-off-by: Romain Perier <romain.perier@...il.com> --- include/linux/interrupt.h | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/include/linux/interrupt.h b/include/linux/interrupt.h index 89fc59dab57d..f5332ae2dbeb 100644 --- a/include/linux/interrupt.h +++ b/include/linux/interrupt.h @@ -673,6 +673,18 @@ extern void tasklet_kill_immediate(struct tasklet_struct *t, unsigned int cpu); extern void tasklet_init(struct tasklet_struct *t, void (*func)(unsigned long), unsigned long data); +#define TASKLET_DATA_TYPE unsigned long +#define TASKLET_FUNC_TYPE void (*)(TASKLET_DATA_TYPE) + +#define from_tasklet(var, callback_tasklet, tasklet_fieldname) \ + container_of(callback_tasklet, typeof(*var), tasklet_fieldname) + +static inline void tasklet_setup(struct tasklet_struct *t, + void (*callback)(struct tasklet_struct *)) +{ + tasklet_init(t, (TASKLET_FUNC_TYPE)callback, (TASKLET_DATA_TYPE)t); +} + /* * Autoprobing for irqs: * -- 2.23.0
Powered by blists - more mailing lists
Confused about mailing lists and their use? Read about mailing lists on Wikipedia and check out these guidelines on proper formatting of your messages.