• Athira Rajeev's avatar
    powerpc/perf: Fix handling of privilege level checks in perf interrupt context · 5ae5fbd2
    Athira Rajeev authored
    Running "perf mem record" in powerpc platforms with selinux enabled
    resulted in soft lockup's. Below call-trace was seen in the logs:
    
      CPU: 58 PID: 3751 Comm: sssd_nss Not tainted 5.11.0-rc7+ #2
      NIP:  c000000000dff3d4 LR: c000000000dff3d0 CTR: 0000000000000000
      REGS: c000007fffab7d60 TRAP: 0100   Not tainted  (5.11.0-rc7+)
      ...
      NIP _raw_spin_lock_irqsave+0x94/0x120
      LR  _raw_spin_lock_irqsave+0x90/0x120
      Call Trace:
        0xc00000000fd47260 (unreliable)
        skb_queue_tail+0x3c/0x90
        audit_log_end+0x6c/0x180
        common_lsm_audit+0xb0/0xe0
        slow_avc_audit+0xa4/0x110
        avc_has_perm+0x1c4/0x260
        selinux_perf_event_open+0x74/0xd0
        security_perf_event_open+0x68/0xc0
        record_and_restart+0x6e8/0x7f0
        perf_event_interrupt+0x22c/0x560
        performance_monitor_exception0x4c/0x60
        performance_monitor_common_virt+0x1c8/0x1d0
      interrupt: f00 at _raw_spin_lock_irqsave+0x38/0x120
      NIP:  c000000000dff378 LR: c000000000b5fbbc CTR: c0000000007d47f0
      REGS: c00000000fd47860 TRAP: 0f00   Not tainted  (5.11.0-rc7+)
      ...
      NIP _raw_spin_lock_irqsave+0x38/0x120
      LR  skb_queue_tail+0x3c/0x90
      interrupt: f00
        0x38 (unreliable)
        0xc00000000aae6200
        audit_log_end+0x6c/0x180
        audit_log_exit+0x344/0xf80
        __audit_syscall_exit+0x2c0/0x320
        do_syscall_trace_leave+0x148/0x200
        syscall_exit_prepare+0x324/0x390
        system_call_common+0xfc/0x27c
    
    The above trace shows that while the CPU was handling a performance
    monitor exception, there was a call to security_perf_event_open()
    function. In powerpc core-book3s, this function is called from
    perf_allow_kernel() check during recording of data address in the
    sample via perf_get_data_addr().
    
    Commit da97e184 ("perf_event: Add support for LSM and SELinux
    checks") introduced security enhancements to perf. As part of this
    commit, the new security hook for perf_event_open() was added in all
    places where perf paranoid check was previously used. In powerpc
    core-book3s code, originally had paranoid checks in
    perf_get_data_addr() and power_pmu_bhrb_read(). So
    perf_paranoid_kernel() checks were replaced with perf_allow_kernel()
    in these PMU helper functions as well.
    
    The intention of paranoid checks in core-book3s was to verify
    privilege access before capturing some of the sample data. Along with
    paranoid checks, perf_allow_kernel() also does a
    security_perf_event_open(). Since these functions are accessed while
    recording a sample, we end up calling selinux_perf_event_open() in PMI
    context. Some of the security functions use spinlock like
    sidtab_sid2str_put(). If a perf interrupt hits under a spin lock and
    if we end up in calling selinux hook functions in PMI handler, this
    could cause a dead lock.
    
    Since the purpose of this security hook is to control access to
    perf_event_open(), it is not right to call this in interrupt context.
    
    The paranoid checks in powerpc core-book3s were done at interrupt time
    which is also not correct.
    
    Reference commits:
      Commit cd1231d7 ("powerpc/perf: Prevent kernel address leak via perf_get_data_addr()")
      Commit bb19af81 ("powerpc/perf: Prevent kernel address leak to userspace via BHRB buffer")
    
    We only allow creation of events that have already passed the
    privilege checks in perf_event_open(). So these paranoid checks are
    not needed at event time. As a fix, patch uses
    'event->attr.exclude_kernel' check to prevent exposing kernel address
    for userspace only sampling.
    
    Fixes: cd1231d7 ("powerpc/perf: Prevent kernel address leak via perf_get_data_addr()")
    Cc: stable@vger.kernel.org # v4.17+
    Suggested-by: default avatarMichael Ellerman <mpe@ellerman.id.au>
    Signed-off-by: default avatarAthira Rajeev <atrajeev@linux.vnet.ibm.com>
    Acked-by: default avatarPeter Zijlstra (Intel) <peterz@infradead.org>
    Signed-off-by: default avatarMichael Ellerman <mpe@ellerman.id.au>
    Link: https://lore.kernel.org/r/1614247839-1428-1-git-send-email-atrajeev@linux.vnet.ibm.com
    5ae5fbd2
core-book3s.c 61.2 KB