On Tue, 17 Nov 2020 13:33:42 -0800
Kees Cook <[email protected]> wrote:

> As I think got discussed in the thread, what you had here wouldn't work
> in a CFI build if the function prototype of the call site and the
> function don't match. (Though I can't tell if .func() is ever called?)
> 
> i.e. .func's prototype must match tp_stub_func()'s.
> 


Hmm, I wonder how you handle tracepoints? This is called here:

include/linux/tracepoint.h:


#define DEFINE_TRACE_FN(_name, _reg, _unreg, proto, args)               \
        static const char __tpstrtab_##_name[]                          \
        __section("__tracepoints_strings") = #_name;                    \
        extern struct static_call_key STATIC_CALL_KEY(tp_func_##_name); \
        int __traceiter_##_name(void *__data, proto);                   \
        struct tracepoint __tracepoint_##_name  __used                  \
        __section("__tracepoints") = {                                  \
                .name = __tpstrtab_##_name,                             \
                .key = STATIC_KEY_INIT_FALSE,                           \
                .static_call_key = &STATIC_CALL_KEY(tp_func_##_name),   \
                .static_call_tramp = STATIC_CALL_TRAMP_ADDR(tp_func_##_name), \
                .iterator = &__traceiter_##_name,                       \
                .regfunc = _reg,                                        \
                .unregfunc = _unreg,                                    \
                .funcs = NULL };                                        \
        __TRACEPOINT_ENTRY(_name);                                      \
        int __traceiter_##_name(void *__data, proto)                    \
        {                                                               \
                struct tracepoint_func *it_func_ptr;                    \
                void *it_func;                                          \
                                                                        \
                it_func_ptr =                                           \
                        rcu_dereference_raw((&__tracepoint_##_name)->funcs); \
                do {                                                    \
                        it_func = (it_func_ptr)->func;                  \
                        __data = (it_func_ptr)->data;                   \

                        ((void(*)(void *, proto))(it_func))(__data, args); \

                        ^^^^ called above ^^^^

Where args is unique for every tracepoint, but func is simply a void
pointer.

-- Steve


                } while ((++it_func_ptr)->func);                        \
                return 0;                                               \
        }                                                               \

Reply via email to