|
Message-ID: <CAGXu5jLerFuW=-uxpegBinAjJN0shPJkYAVaz9K7VWzVRmnOEQ@mail.gmail.com> Date: Wed, 18 Apr 2018 09:07:31 -0700 From: Kees Cook <keescook@...omium.org> To: Ingo Molnar <mingo@...nel.org> Cc: Joao Moreira <jmoreira@...e.de>, Kernel Hardening <kernel-hardening@...ts.openwall.com>, LKML <linux-kernel@...r.kernel.org>, X86 ML <x86@...nel.org>, Herbert Xu <herbert@...dor.apana.org.au>, "David S. Miller" <davem@...emloft.net>, Thomas Gleixner <tglx@...utronix.de>, Ingo Molnar <mingo@...hat.com>, "H. Peter Anvin" <hpa@...or.com>, Greg KH <gregkh@...uxfoundation.org> Subject: Re: [PATCH 1/4] x86/crypto: camellia: Fix function prototypes On Sun, Apr 15, 2018 at 11:10 PM, Ingo Molnar <mingo@...nel.org> wrote: > > * Joao Moreira <jmoreira@...e.de> wrote: > >> Convert the use of 'struct camellia_ctx *' to 'void *' in prototypes of >> functions which are referenced through 'struct common_glue_func_entry', >> making their prototypes match those of this struct and, consequently, >> turning them compatible with CFI requirements. >> >> Whenever needed, cast 'void *' to 'struct camellia_ctx *'. > >> +static inline void camellia_enc_blk(void *ctx, u8 *dst, const u8 *src) >> { >> - __camellia_enc_blk(ctx, dst, src, false); >> + __camellia_enc_blk((struct camellia_ctx *) ctx, dst, src, false); >> } > > I don't see how this is an improvement: instead of having a proper type there's > now an opaque type and an ugly (and dangerous) type cast. I agree with your instinct, as the existing best-practice in the kernel is to always use correct types and avoid casts to let the compiler check things, avoid nasty surprises, etc, but for callbacks with context pointers, we're already just hiding the casts in various places. For example, even without this patch: typedef void (*common_glue_func_t)(void *ctx, u8 *dst, const u8 *src); #define GLUE_FUNC_CAST(fn) ((common_glue_func_t)(fn)) static const struct common_glue_ctx camellia_enc = { ... .funcs = { { ... .num_blocks = 1, .fn_u = { .ecb = GLUE_FUNC_CAST(camellia_enc_blk) } } } }; While it is nicely wrapped up in macros, this is actually casting away the _entire_ function prototype, not just the first argument. The "camellia_enc_blk" function could point to anything (even "void (*func)(void)") and the compiler wouldn't complain. And this was done just to mask the ctx argument. > What does "compatible with CFI requirements" mean? As Joao mentioned, he wrote this up pretty well in his 0/n patch: https://lkml.kernel.org/r/20180415041542.5364-1-jmoreira@suse.de To further clarify, fine-grained function-prototype-checking CFI makes sure that indirect function call sites only call functions with a matching expected prototype (to protect against having function pointers rewritten during an attack, etc). In this case, callers of .fn_u.ecb() expect the target function to have the prototype "void (*func)(void *ctx, u8 *dst, const u8 *src)" (as defined by struct common_glue_ctx), however, camellia_enc_blk() is "void (*func)(struct camellia_ctx *ctx, u8 *dst, const u8 *src)" and will trip the CFI check. If we rearrange our macro magic to defining the callbacks rather than defining the function pointers, I think we'll gain several things: - we will cast only the ctx argument instead of the entire function prototype - we'll retain (and improve) source-code robustness against generally miscasting - CFI will be happy So, instead of the original series, how about something like this: Switch function pointers to not use the function cast, and define a new GLUE_FUNC macro that kinda looks like the tricks used for syscalls: static const struct common_glue_ctx camellia_enc = { ... .funcs = { { ... .num_blocks = 1, .fn_u = { .ecb = camellia_enc_blk } } } }; #define GLUE_FUNC(func, context) \ static inline void func(void *ctx, u8 *dst, const u8 *src) \ { __##func((context)ctx, dst, src); } \ __##func(context ctx, u8 *dst, const u8 *src) GLUE_FUNC(camellia_enc_blk, struct camellia_ctx *) { ...original function... } -Kees -- Kees Cook Pixel Security
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.