lkml.org 
[lkml]   [2013]   [Aug]   [7]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    Subject[PATCH 3/4] x86/jump-label: Add safety checks to jump label conversions
    From: Steven Rostedt <srostedt@redhat.com>

    As with all modifying of kernel text, we need to be very paranoid.

    When converting the jump label locations to and from nops to jumps
    a check has been added to make sure what we are replacing is what we
    expect, otherwise we bug.

    Cc: H. Peter Anvin <hpa@zytor.com>
    Cc: Jason Baron <jbaron@redhat.com>
    Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
    ---
    arch/x86/kernel/jump_label.c | 32 ++++++++++++++++++++++++++++----
    1 file changed, 28 insertions(+), 4 deletions(-)

    diff --git a/arch/x86/kernel/jump_label.c b/arch/x86/kernel/jump_label.c
    index ae3d8fb..24cf2b2 100644
    --- a/arch/x86/kernel/jump_label.c
    +++ b/arch/x86/kernel/jump_label.c
    @@ -26,16 +26,40 @@ union jump_code_union {

    static void __jump_label_transform(struct jump_entry *entry,
    enum jump_label_type type,
    - void *(*poker)(void *, const void *, size_t))
    + void *(*poker)(void *, const void *, size_t),
    + int init)
    {
    union jump_code_union code;
    + const unsigned char *ideal_nop = ideal_nops[NOP_ATOMIC5];

    if (type == JUMP_LABEL_ENABLE) {
    + /*
    + * We are enabling this jump label. If it is not a nop
    + * then something must have gone wrong.
    + */
    + BUG_ON(memcmp((void *)entry->code, ideal_nop, 5) != 0);
    +
    code.jump = 0xe9;
    code.offset = entry->target -
    (entry->code + JUMP_LABEL_NOP_SIZE);
    - } else
    + } else {
    + /*
    + * We are disabling this jump label. If it is not what
    + * we think it is, then something must have gone wrong.
    + * If this is the first initialization call, then we
    + * are converting the default nop to the ideal nop.
    + */
    + if (init) {
    + const unsigned char default_nop[] = { STATIC_KEY_INIT_NOP };
    + BUG_ON(memcmp((void *)entry->code, default_nop, 5) != 0);
    + } else {
    + code.jump = 0xe9;
    + code.offset = entry->target -
    + (entry->code + JUMP_LABEL_NOP_SIZE);
    + BUG_ON(memcmp((void *)entry->code, &code, 5) != 0);
    + }
    memcpy(&code, ideal_nops[NOP_ATOMIC5], JUMP_LABEL_NOP_SIZE);
    + }

    (*poker)((void *)entry->code, &code, JUMP_LABEL_NOP_SIZE);
    }
    @@ -45,7 +69,7 @@ void arch_jump_label_transform(struct jump_entry *entry,
    {
    get_online_cpus();
    mutex_lock(&text_mutex);
    - __jump_label_transform(entry, type, text_poke_smp);
    + __jump_label_transform(entry, type, text_poke_smp, 0);
    mutex_unlock(&text_mutex);
    put_online_cpus();
    }
    @@ -76,7 +100,7 @@ __init_or_module void arch_jump_label_transform_static(struct jump_entry *entry,
    jlstate = JL_STATE_NO_UPDATE;
    }
    if (jlstate == JL_STATE_UPDATE)
    - __jump_label_transform(entry, type, text_poke_early);
    + __jump_label_transform(entry, type, text_poke_early, 1);
    }

    #endif
    --
    1.7.10.4



    \
     
     \ /
      Last update: 2013-08-07 19:01    [W:3.818 / U:0.004 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site