lkml.org 
[lkml]   [2022]   [Oct]   [19]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    Subject[tip: x86/misc] x86/signal: Merge get_sigframe()
    The following commit has been merged into the x86/misc branch of tip:

    Commit-ID: 9c36e592b3f899c90b9d0d46ae29fcc065051b96
    Gitweb: https://git.kernel.org/tip/9c36e592b3f899c90b9d0d46ae29fcc065051b96
    Author: Brian Gerst <brgerst@gmail.com>
    AuthorDate: Mon, 06 Jun 2022 16:37:59 -04:00
    Committer: Borislav Petkov <bp@suse.de>
    CommitterDate: Wed, 19 Oct 2022 09:58:49 +02:00

    x86/signal: Merge get_sigframe()

    Adapt the native get_sigframe() function so that the compat signal code
    can use it.

    Signed-off-by: Brian Gerst <brgerst@gmail.com>
    Signed-off-by: Borislav Petkov <bp@suse.de>
    Acked-by: "Eric W. Biederman" <ebiederm@xmission.com>
    Link: https://lore.kernel.org/r/20220606203802.158958-6-brgerst@gmail.com
    Signed-off-by: Borislav Petkov <bp@suse.de>
    ---
    arch/x86/ia32/ia32_signal.c | 34 +------------
    arch/x86/include/asm/sighandling.h | 4 +-
    arch/x86/kernel/signal.c | 80 +++++++++++++----------------
    3 files changed, 42 insertions(+), 76 deletions(-)

    diff --git a/arch/x86/ia32/ia32_signal.c b/arch/x86/ia32/ia32_signal.c
    index a78885e..e28421f 100644
    --- a/arch/x86/ia32/ia32_signal.c
    +++ b/arch/x86/ia32/ia32_signal.c
    @@ -196,40 +196,6 @@ do { \
    goto label; \
    } while(0)

    -/*
    - * Determine which stack to use..
    - */
    -static void __user *get_sigframe(struct ksignal *ksig, struct pt_regs *regs,
    - size_t frame_size,
    - void __user **fpstate)
    -{
    - unsigned long sp, fx_aligned, math_size;
    -
    - /* Default to using normal stack */
    - sp = regs->sp;
    -
    - /* This is the X/Open sanctioned signal stack switching. */
    - if (ksig->ka.sa.sa_flags & SA_ONSTACK)
    - sp = sigsp(sp, ksig);
    - /* This is the legacy signal stack switching. */
    - else if (regs->ss != __USER_DS &&
    - !(ksig->ka.sa.sa_flags & SA_RESTORER) &&
    - ksig->ka.sa.sa_restorer)
    - sp = (unsigned long) ksig->ka.sa.sa_restorer;
    -
    - sp = fpu__alloc_mathframe(sp, 1, &fx_aligned, &math_size);
    - *fpstate = (struct _fpstate_32 __user *) sp;
    - if (!copy_fpstate_to_sigframe(*fpstate, (void __user *)fx_aligned,
    - math_size))
    - return (void __user *) -1L;
    -
    - sp -= frame_size;
    - /* Align the stack pointer according to the i386 ABI,
    - * i.e. so that on function entry ((sp + 4) & 15) == 0. */
    - sp = ((sp + 4) & -16ul) - 4;
    - return (void __user *) sp;
    -}
    -
    int ia32_setup_frame(struct ksignal *ksig, struct pt_regs *regs)
    {
    compat_sigset_t *set = (compat_sigset_t *) sigmask_to_save();
    diff --git a/arch/x86/include/asm/sighandling.h b/arch/x86/include/asm/sighandling.h
    index 65e6672..c9e9784 100644
    --- a/arch/x86/include/asm/sighandling.h
    +++ b/arch/x86/include/asm/sighandling.h
    @@ -15,4 +15,8 @@

    void signal_fault(struct pt_regs *regs, void __user *frame, char *where);

    +void __user *
    +get_sigframe(struct ksignal *ksig, struct pt_regs *regs, size_t frame_size,
    + void __user **fpstate);
    +
    #endif /* _ASM_X86_SIGHANDLING_H */
    diff --git a/arch/x86/kernel/signal.c b/arch/x86/kernel/signal.c
    index 489a085..890ca05 100644
    --- a/arch/x86/kernel/signal.c
    +++ b/arch/x86/kernel/signal.c
    @@ -48,6 +48,23 @@
    #include <asm/sigframe.h>
    #include <asm/signal.h>

    +static inline int is_ia32_compat_frame(struct ksignal *ksig)
    +{
    + return IS_ENABLED(CONFIG_IA32_EMULATION) &&
    + ksig->ka.sa.sa_flags & SA_IA32_ABI;
    +}
    +
    +static inline int is_ia32_frame(struct ksignal *ksig)
    +{
    + return IS_ENABLED(CONFIG_X86_32) || is_ia32_compat_frame(ksig);
    +}
    +
    +static inline int is_x32_frame(struct ksignal *ksig)
    +{
    + return IS_ENABLED(CONFIG_X86_X32_ABI) &&
    + ksig->ka.sa.sa_flags & SA_X32_ABI;
    +}
    +
    #ifdef CONFIG_X86_64
    /*
    * If regs->ss will cause an IRET fault, change it. Otherwise leave it
    @@ -223,24 +240,12 @@ do { \
    /*
    * Determine which stack to use..
    */
    -static unsigned long align_sigframe(unsigned long sp)
    -{
    -#ifdef CONFIG_X86_32
    - /*
    - * Align the stack pointer according to the i386 ABI,
    - * i.e. so that on function entry ((sp + 4) & 15) == 0.
    - */
    - sp = ((sp + 4) & -FRAME_ALIGNMENT) - 4;
    -#else /* !CONFIG_X86_32 */
    - sp = round_down(sp, FRAME_ALIGNMENT) - 8;
    -#endif
    - return sp;
    -}
    -
    -static void __user *
    -get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, size_t frame_size,
    +void __user *
    +get_sigframe(struct ksignal *ksig, struct pt_regs *regs, size_t frame_size,
    void __user **fpstate)
    {
    + struct k_sigaction *ka = &ksig->ka;
    + int ia32_frame = is_ia32_frame(ksig);
    /* Default to using normal stack */
    bool nested_altstack = on_sig_stack(regs->sp);
    bool entering_altstack = false;
    @@ -249,7 +254,7 @@ get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, size_t frame_size,
    unsigned long buf_fx = 0;

    /* redzone */
    - if (IS_ENABLED(CONFIG_X86_64))
    + if (!ia32_frame)
    sp -= 128;

    /* This is the X/Open sanctioned signal stack switching. */
    @@ -263,7 +268,7 @@ get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, size_t frame_size,
    sp = current->sas_ss_sp + current->sas_ss_size;
    entering_altstack = true;
    }
    - } else if (IS_ENABLED(CONFIG_X86_32) &&
    + } else if (ia32_frame &&
    !nested_altstack &&
    regs->ss != __USER_DS &&
    !(ka->sa.sa_flags & SA_RESTORER) &&
    @@ -273,11 +278,19 @@ get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, size_t frame_size,
    entering_altstack = true;
    }

    - sp = fpu__alloc_mathframe(sp, IS_ENABLED(CONFIG_X86_32),
    - &buf_fx, &math_size);
    + sp = fpu__alloc_mathframe(sp, ia32_frame, &buf_fx, &math_size);
    *fpstate = (void __user *)sp;

    - sp = align_sigframe(sp - frame_size);
    + sp -= frame_size;
    +
    + if (ia32_frame)
    + /*
    + * Align the stack pointer according to the i386 ABI,
    + * i.e. so that on function entry ((sp + 4) & 15) == 0.
    + */
    + sp = ((sp + 4) & -FRAME_ALIGNMENT) - 4;
    + else
    + sp = round_down(sp, FRAME_ALIGNMENT) - 8;

    /*
    * If we are on the alternate signal stack and would overflow it, don't.
    @@ -331,7 +344,7 @@ __setup_frame(struct ksignal *ksig, struct pt_regs *regs)
    void __user *restorer;
    void __user *fp = NULL;

    - frame = get_sigframe(&ksig->ka, regs, sizeof(*frame), &fp);
    + frame = get_sigframe(ksig, regs, sizeof(*frame), &fp);

    if (!user_access_begin(frame, sizeof(*frame)))
    return -EFAULT;
    @@ -386,7 +399,7 @@ static int __setup_rt_frame(struct ksignal *ksig, struct pt_regs *regs)
    void __user *restorer;
    void __user *fp = NULL;

    - frame = get_sigframe(&ksig->ka, regs, sizeof(*frame), &fp);
    + frame = get_sigframe(ksig, regs, sizeof(*frame), &fp);

    if (!user_access_begin(frame, sizeof(*frame)))
    return -EFAULT;
    @@ -469,7 +482,7 @@ static int __setup_rt_frame(struct ksignal *ksig, struct pt_regs *regs)
    if (!(ksig->ka.sa.sa_flags & SA_RESTORER))
    return -EFAULT;

    - frame = get_sigframe(&ksig->ka, regs, sizeof(struct rt_sigframe), &fp);
    + frame = get_sigframe(ksig, regs, sizeof(struct rt_sigframe), &fp);
    uc_flags = frame_uc_flags(regs);

    if (!user_access_begin(frame, sizeof(*frame)))
    @@ -572,7 +585,7 @@ static int x32_setup_rt_frame(struct ksignal *ksig, struct pt_regs *regs)
    if (!(ksig->ka.sa.sa_flags & SA_RESTORER))
    return -EFAULT;

    - frame = get_sigframe(&ksig->ka, regs, sizeof(*frame), &fp);
    + frame = get_sigframe(ksig, regs, sizeof(*frame), &fp);

    uc_flags = frame_uc_flags(regs);

    @@ -742,23 +755,6 @@ unsigned long get_sigframe_size(void)
    return max_frame_size;
    }

    -static inline int is_ia32_compat_frame(struct ksignal *ksig)
    -{
    - return IS_ENABLED(CONFIG_IA32_EMULATION) &&
    - ksig->ka.sa.sa_flags & SA_IA32_ABI;
    -}
    -
    -static inline int is_ia32_frame(struct ksignal *ksig)
    -{
    - return IS_ENABLED(CONFIG_X86_32) || is_ia32_compat_frame(ksig);
    -}
    -
    -static inline int is_x32_frame(struct ksignal *ksig)
    -{
    - return IS_ENABLED(CONFIG_X86_X32_ABI) &&
    - ksig->ka.sa.sa_flags & SA_X32_ABI;
    -}
    -
    static int
    setup_rt_frame(struct ksignal *ksig, struct pt_regs *regs)
    {
    \
     
     \ /
      Last update: 2022-10-19 14:17    [W:4.053 / U:0.060 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site