lkml.org 
[lkml]   [2024]   [Feb]   [3]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    /
    From
    Subject[PATCH RFT v5 0/7] fork: Support shadow stacks in clone3()
    Date
    The kernel has recently added support for shadow stacks, currently
    x86 only using their CET feature but both arm64 and RISC-V have
    equivalent features (GCS and Zicfiss respectively), I am actively
    working on GCS[1]. With shadow stacks the hardware maintains an
    additional stack containing only the return addresses for branch
    instructions which is not generally writeable by userspace and ensures
    that any returns are to the recorded addresses. This provides some
    protection against ROP attacks and making it easier to collect call
    stacks. These shadow stacks are allocated in the address space of the
    userspace process.

    Our API for shadow stacks does not currently offer userspace any
    flexiblity for managing the allocation of shadow stacks for newly
    created threads, instead the kernel allocates a new shadow stack with
    the same size as the normal stack whenever a thread is created with the
    feature enabled. The stacks allocated in this way are freed by the
    kernel when the thread exits or shadow stacks are disabled for the
    thread. This lack of flexibility and control isn't ideal, in the vast
    majority of cases the shadow stack will be over allocated and the
    implicit allocation and deallocation is not consistent with other
    interfaces. As far as I can tell the interface is done in this manner
    mainly because the shadow stack patches were in development since before
    clone3() was implemented.

    Since clone3() is readily extensible let's add support for specifying a
    shadow stack when creating a new thread or process in a similar manner
    to how the normal stack is specified, keeping the current implicit
    allocation behaviour if one is not specified either with clone3() or
    through the use of clone(). The user must provide a shadow stack
    address and size, this must point to memory mapped for use as a shadow
    stackby map_shadow_stack() with a shadow stack token at the top of the
    stack.

    Please note that the x86 portions of this code are build tested only, I
    don't appear to have a system that can run CET avaible to me, I have
    done testing with an integration into my pending work for GCS. There is
    some possibility that the arm64 implementation may require the use of
    clone3() and explicit userspace allocation of shadow stacks, this is
    still under discussion.

    Please further note that the token consumption done by clone3() is not
    currently implemented in an atomic fashion, Rick indicated that he would
    look into fixing this if people are OK with the implementation.

    A new architecture feature Kconfig option for shadow stacks is added as
    here, this was suggested as part of the review comments for the arm64
    GCS series and since we need to detect if shadow stacks are supported it
    seemed sensible to roll it in here.

    [1] https://lore.kernel.org/r/20231009-arm64-gcs-v6-0-78e55deaa4dd@kernel.org/

    Signed-off-by: Mark Brown <broonie@kernel.org>
    ---
    Changes in v5:
    - Rebase onto v6.8-rc2.
    - Rework ABI to have the user allocate the shadow stack memory with
    map_shadow_stack() and a token.
    - Force inlining of the x86 shadow stack enablement.
    - Move shadow stack enablement out into a shared header for reuse by
    other tests.
    - Link to v4: https://lore.kernel.org/r/20231128-clone3-shadow-stack-v4-0-8b28ffe4f676@kernel.org

    Changes in v4:
    - Formatting changes.
    - Use a define for minimum shadow stack size and move some basic
    validation to fork.c.
    - Link to v3: https://lore.kernel.org/r/20231120-clone3-shadow-stack-v3-0-a7b8ed3e2acc@kernel.org

    Changes in v3:
    - Rebase onto v6.7-rc2.
    - Remove stale shadow_stack in internal kargs.
    - If a shadow stack is specified unconditionally use it regardless of
    CLONE_ parameters.
    - Force enable shadow stacks in the selftest.
    - Update changelogs for RISC-V feature rename.
    - Link to v2: https://lore.kernel.org/r/20231114-clone3-shadow-stack-v2-0-b613f8681155@kernel.org

    Changes in v2:
    - Rebase onto v6.7-rc1.
    - Remove ability to provide preallocated shadow stack, just specify the
    desired size.
    - Link to v1: https://lore.kernel.org/r/20231023-clone3-shadow-stack-v1-0-d867d0b5d4d0@kernel.org

    ---
    Mark Brown (7):
    Documentation: userspace-api: Add shadow stack API documentation
    selftests: Provide helper header for shadow stack testing
    mm: Introduce ARCH_HAS_USER_SHADOW_STACK
    fork: Add shadow stack support to clone3()
    selftests/clone3: Factor more of main loop into test_clone3()
    selftests/clone3: Allow tests to flag if -E2BIG is a valid error code
    selftests/clone3: Test shadow stack support

    Documentation/userspace-api/index.rst | 1 +
    Documentation/userspace-api/shadow_stack.rst | 41 +++++
    arch/x86/Kconfig | 1 +
    arch/x86/include/asm/shstk.h | 11 +-
    arch/x86/kernel/process.c | 2 +-
    arch/x86/kernel/shstk.c | 91 +++++++---
    fs/proc/task_mmu.c | 2 +-
    include/linux/mm.h | 2 +-
    include/linux/sched/task.h | 2 +
    include/uapi/linux/sched.h | 13 +-
    kernel/fork.c | 61 +++++--
    mm/Kconfig | 6 +
    tools/testing/selftests/clone3/clone3.c | 211 ++++++++++++++++++----
    tools/testing/selftests/clone3/clone3_selftests.h | 8 +
    tools/testing/selftests/ksft_shstk.h | 63 +++++++
    15 files changed, 430 insertions(+), 85 deletions(-)
    ---
    base-commit: 41bccc98fb7931d63d03f326a746ac4d429c1dd3
    change-id: 20231019-clone3-shadow-stack-15d40d2bf536

    Best regards,
    --
    Mark Brown <broonie@kernel.org>


    \
     
     \ /
      Last update: 2024-05-27 14:46    [W:6.527 / U:0.004 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site