1. 07 1月, 2021 1 次提交
  2. 23 12月, 2020 1 次提交
  3. 03 12月, 2020 5 次提交
    • M
      arm64: uaccess: remove redundant PAN toggling · 7cf283c7
      Mark Rutland 提交于
      Some code (e.g. futex) needs to make privileged accesses to userspace
      memory, and uses uaccess_{enable,disable}_privileged() in order to
      permit this. All other uaccess primitives use LDTR/STTR, and never need
      to toggle PAN.
      
      Remove the redundant PAN toggling.
      Signed-off-by: NMark Rutland <mark.rutland@arm.com>
      Cc: Christoph Hellwig <hch@lst.de>
      Cc: James Morse <james.morse@arm.com>
      Cc: Will Deacon <will@kernel.org>
      Link: https://lore.kernel.org/r/20201202131558.39270-12-mark.rutland@arm.comSigned-off-by: NCatalin Marinas <catalin.marinas@arm.com>
      7cf283c7
    • M
      arm64: uaccess: remove set_fs() · 3d2403fd
      Mark Rutland 提交于
      Now that the uaccess primitives dont take addr_limit into account, we
      have no need to manipulate this via set_fs() and get_fs(). Remove
      support for these, along with some infrastructure this renders
      redundant.
      
      We no longer need to flip UAO to access kernel memory under KERNEL_DS,
      and head.S unconditionally clears UAO for all kernel configurations via
      an ERET in init_kernel_el. Thus, we don't need to dynamically flip UAO,
      nor do we need to context-switch it. However, we still need to adjust
      PAN during SDEI entry.
      
      Masking of __user pointers no longer needs to use the dynamic value of
      addr_limit, and can use a constant derived from the maximum possible
      userspace task size. A new TASK_SIZE_MAX constant is introduced for
      this, which is also used by core code. In configurations supporting
      52-bit VAs, this may include a region of unusable VA space above a
      48-bit TTBR0 limit, but never includes any portion of TTBR1.
      
      Note that TASK_SIZE_MAX is an exclusive limit, while USER_DS and
      KERNEL_DS were inclusive limits, and is converted to a mask by
      subtracting one.
      
      As the SDEI entry code repurposes the otherwise unnecessary
      pt_regs::orig_addr_limit field to store the TTBR1 of the interrupted
      context, for now we rename that to pt_regs::sdei_ttbr1. In future we can
      consider factoring that out.
      Signed-off-by: NMark Rutland <mark.rutland@arm.com>
      Acked-by: NJames Morse <james.morse@arm.com>
      Cc: Christoph Hellwig <hch@lst.de>
      Cc: Will Deacon <will@kernel.org>
      Link: https://lore.kernel.org/r/20201202131558.39270-10-mark.rutland@arm.comSigned-off-by: NCatalin Marinas <catalin.marinas@arm.com>
      3d2403fd
    • M
      arm64: uaccess: split user/kernel routines · fc703d80
      Mark Rutland 提交于
      This patch separates arm64's user and kernel memory access primitives
      into distinct routines, adding new __{get,put}_kernel_nofault() helpers
      to access kernel memory, upon which core code builds larger copy
      routines.
      
      The kernel access routines (using LDR/STR) are not affected by PAN (when
      legitimately accessing kernel memory), nor are they affected by UAO.
      Switching to KERNEL_DS may set UAO, but this does not adversely affect
      the kernel access routines.
      
      The user access routines (using LDTR/STTR) are not affected by PAN (when
      legitimately accessing user memory), but are affected by UAO. As these
      are only legitimate to use under USER_DS with UAO clear, this should not
      be problematic.
      
      Routines performing atomics to user memory (futex and deprecated
      instruction emulation) still need to transiently clear PAN, and these
      are left as-is. These are never used on kernel memory.
      
      Subsequent patches will refactor the uaccess helpers to remove redundant
      code, and will also remove the redundant PAN/UAO manipulation.
      Signed-off-by: NMark Rutland <mark.rutland@arm.com>
      Cc: Christoph Hellwig <hch@lst.de>
      Cc: James Morse <james.morse@arm.com>
      Cc: Will Deacon <will@kernel.org>
      Link: https://lore.kernel.org/r/20201202131558.39270-8-mark.rutland@arm.comSigned-off-by: NCatalin Marinas <catalin.marinas@arm.com>
      fc703d80
    • M
      arm64: uaccess: refactor __{get,put}_user · f253d827
      Mark Rutland 提交于
      As a step towards implementing __{get,put}_kernel_nofault(), this patch
      splits most user-memory specific logic out of __{get,put}_user(), with
      the memory access and fault handling in new __{raw_get,put}_mem()
      helpers.
      
      For now the LDR/LDTR patching is left within the *get_mem() helpers, and
      will be removed in a subsequent patch.
      
      There should be no functional change as a result of this patch.
      Signed-off-by: NMark Rutland <mark.rutland@arm.com>
      Cc: Christoph Hellwig <hch@lst.de>
      Cc: James Morse <james.morse@arm.com>
      Cc: Will Deacon <will@kernel.org>
      Link: https://lore.kernel.org/r/20201202131558.39270-7-mark.rutland@arm.comSigned-off-by: NCatalin Marinas <catalin.marinas@arm.com>
      f253d827
    • M
      arm64: uaccess: rename privileged uaccess routines · 923e1e7d
      Mark Rutland 提交于
      We currently have many uaccess_*{enable,disable}*() variants, which
      subsequent patches will cut down as part of removing set_fs() and
      friends. Once this simplification is made, most uaccess routines will
      only need to ensure that the user page tables are mapped in TTBR0, as is
      currently dealt with by uaccess_ttbr0_{enable,disable}().
      
      The existing uaccess_{enable,disable}() routines ensure that user page
      tables are mapped in TTBR0, and also disable PAN protections, which is
      necessary to be able to use atomics on user memory, but also permit
      unrelated privileged accesses to access user memory.
      
      As preparatory step, let's rename uaccess_{enable,disable}() to
      uaccess_{enable,disable}_privileged(), highlighting this caveat and
      discouraging wider misuse. Subsequent patches can reuse the
      uaccess_{enable,disable}() naming for the common case of ensuring the
      user page tables are mapped in TTBR0.
      
      There should be no functional change as a result of this patch.
      Signed-off-by: NMark Rutland <mark.rutland@arm.com>
      Cc: Christoph Hellwig <hch@lst.de>
      Cc: James Morse <james.morse@arm.com>
      Cc: Will Deacon <will@kernel.org>
      Link: https://lore.kernel.org/r/20201202131558.39270-5-mark.rutland@arm.comSigned-off-by: NCatalin Marinas <catalin.marinas@arm.com>
      923e1e7d
  4. 11 11月, 2020 1 次提交
    • M
      arm64: consistently use reserved_pg_dir · 833be850
      Mark Rutland 提交于
      Depending on configuration options and specific code paths, we either
      use the empty_zero_page or the configuration-dependent reserved_ttbr0
      as a reserved value for TTBR{0,1}_EL1.
      
      To simplify this code, let's always allocate and use the same
      reserved_pg_dir, replacing reserved_ttbr0. Note that this is allocated
      (and hence pre-zeroed), and is also marked as read-only in the kernel
      Image mapping.
      
      Keeping this separate from the empty_zero_page potentially helps with
      robustness as the empty_zero_page is used in a number of cases where a
      failure to map it read-only could allow it to become corrupted.
      
      The (presently unused) swapper_pg_end symbol is also removed, and
      comments are added wherever we rely on the offsets between the
      pre-allocated pg_dirs to keep these cases easily identifiable.
      Signed-off-by: NMark Rutland <mark.rutland@arm.com>
      Cc: Will Deacon <will@kernel.org>
      Link: https://lore.kernel.org/r/20201103102229.8542-1-mark.rutland@arm.comSigned-off-by: NCatalin Marinas <catalin.marinas@arm.com>
      833be850
  5. 13 8月, 2020 1 次提交
  6. 21 7月, 2020 1 次提交
    • W
      arm64: Reduce the number of header files pulled into vmlinux.lds.S · 5f1f7f6c
      Will Deacon 提交于
      Although vmlinux.lds.S smells like an assembly file and is compiled
      with __ASSEMBLY__ defined, it's actually just fed to the preprocessor to
      create our linker script. This means that any assembly macros defined
      by headers that it includes will result in a helpful link error:
      
      | aarch64-linux-gnu-ld:./arch/arm64/kernel/vmlinux.lds:1: syntax error
      
      In preparation for an arm64-private asm/rwonce.h implementation, which
      will end up pulling assembly macros into linux/compiler.h, reduce the
      number of headers we include directly and transitively in vmlinux.lds.S
      Acked-by: NPeter Zijlstra (Intel) <peterz@infradead.org>
      Signed-off-by: NWill Deacon <will@kernel.org>
      5f1f7f6c
  7. 22 5月, 2020 1 次提交
  8. 06 12月, 2019 1 次提交
    • C
      arm64: Validate tagged addresses in access_ok() called from kernel threads · df325e05
      Catalin Marinas 提交于
      __range_ok(), invoked from access_ok(), clears the tag of the user
      address only if CONFIG_ARM64_TAGGED_ADDR_ABI is enabled and the thread
      opted in to the relaxed ABI. The latter sets the TIF_TAGGED_ADDR thread
      flag. In the case of asynchronous I/O (e.g. io_submit()), the
      access_ok() may be called from a kernel thread. Since kernel threads
      don't have TIF_TAGGED_ADDR set, access_ok() will fail for valid tagged
      user addresses. Example from the ffs_user_copy_worker() thread:
      
      	use_mm(io_data->mm);
      	ret = ffs_copy_to_iter(io_data->buf, ret, &io_data->data);
      	unuse_mm(io_data->mm);
      
      Relax the __range_ok() check to always untag the user address if called
      in the context of a kernel thread. The user pointers would have already
      been checked via aio_setup_rw() -> import_{single_range,iovec}() at the
      time of the asynchronous I/O request.
      
      Fixes: 63f0c603 ("arm64: Introduce prctl() options to control the tagged user addresses ABI")
      Cc: <stable@vger.kernel.org> # 5.4.x-
      Cc: Will Deacon <will@kernel.org>
      Reported-by: NEvgenii Stepanov <eugenis@google.com>
      Tested-by: NEvgenii Stepanov <eugenis@google.com>
      Signed-off-by: NCatalin Marinas <catalin.marinas@arm.com>
      df325e05
  9. 21 11月, 2019 1 次提交
  10. 07 8月, 2019 2 次提交
  11. 19 6月, 2019 1 次提交
  12. 05 3月, 2019 1 次提交
    • L
      get rid of legacy 'get_ds()' function · 736706be
      Linus Torvalds 提交于
      Every in-kernel use of this function defined it to KERNEL_DS (either as
      an actual define, or as an inline function).  It's an entirely
      historical artifact, and long long long ago used to actually read the
      segment selector valueof '%ds' on x86.
      
      Which in the kernel is always KERNEL_DS.
      
      Inspired by a patch from Jann Horn that just did this for a very small
      subset of users (the ones in fs/), along with Al who suggested a script.
      I then just took it to the logical extreme and removed all the remaining
      gunk.
      
      Roughly scripted with
      
         git grep -l '(get_ds())' -- :^tools/ | xargs sed -i 's/(get_ds())/(KERNEL_DS)/'
         git grep -lw 'get_ds' -- :^tools/ | xargs sed -i '/^#define get_ds()/d'
      
      plus manual fixups to remove a few unusual usage patterns, the couple of
      inline function cases and to fix up a comment that had become stale.
      
      The 'get_ds()' function remains in an x86 kvm selftest, since in user
      space it actually does something relevant.
      Inspired-by: NJann Horn <jannh@google.com>
      Inspired-by: NAl Viro <viro@zeniv.linux.org.uk>
      Signed-off-by: NLinus Torvalds <torvalds@linux-foundation.org>
      736706be
  13. 01 3月, 2019 1 次提交
  14. 25 1月, 2019 2 次提交
  15. 04 1月, 2019 1 次提交
    • L
      Remove 'type' argument from access_ok() function · 96d4f267
      Linus Torvalds 提交于
      Nobody has actually used the type (VERIFY_READ vs VERIFY_WRITE) argument
      of the user address range verification function since we got rid of the
      old racy i386-only code to walk page tables by hand.
      
      It existed because the original 80386 would not honor the write protect
      bit when in kernel mode, so you had to do COW by hand before doing any
      user access.  But we haven't supported that in a long time, and these
      days the 'type' argument is a purely historical artifact.
      
      A discussion about extending 'user_access_begin()' to do the range
      checking resulted this patch, because there is no way we're going to
      move the old VERIFY_xyz interface to that model.  And it's best done at
      the end of the merge window when I've done most of my merges, so let's
      just get this done once and for all.
      
      This patch was mostly done with a sed-script, with manual fix-ups for
      the cases that weren't of the trivial 'access_ok(VERIFY_xyz' form.
      
      There were a couple of notable cases:
      
       - csky still had the old "verify_area()" name as an alias.
      
       - the iter_iov code had magical hardcoded knowledge of the actual
         values of VERIFY_{READ,WRITE} (not that they mattered, since nothing
         really used it)
      
       - microblaze used the type argument for a debug printout
      
      but other than those oddities this should be a total no-op patch.
      
      I tried to fix up all architectures, did fairly extensive grepping for
      access_ok() uses, and the changes are trivial, but I may have missed
      something.  Any missed conversion should be trivially fixable, though.
      Signed-off-by: NLinus Torvalds <torvalds@linux-foundation.org>
      96d4f267
  16. 29 12月, 2018 1 次提交
  17. 07 12月, 2018 1 次提交
  18. 11 10月, 2018 1 次提交
    • J
      Revert "arm64: uaccess: implement unsafe accessors" · 3b82a6ea
      James Morse 提交于
      This reverts commit a1f33941.
      
      The unsafe accessors allow the PAN enable/disable calls to be made
      once for a group of accesses. Adding these means we can now have
      sequences that look like this:
      
      | user_access_begin();
      | unsafe_put_user(static-value, x, err);
      | unsafe_put_user(helper-that-sleeps(), x, err);
      | user_access_end();
      
      Calling schedule() without taking an exception doesn't switch the
      PSTATE or TTBRs. We can switch out of a uaccess-enabled region, and
      run other code with uaccess enabled for a different thread.
      
      We can also switch from uaccess-disabled code back into this region,
      meaning the unsafe_put_user()s will fault.
      
      For software-PAN, threads that do this will get stuck as
      handle_mm_fault() will determine the page has already been mapped in,
      but we fault again as the page tables aren't loaded.
      
      To solve this we need code in __switch_to() that save/restores the
      PAN state.
      Acked-by: NJulien Thierry <julien.thierry@arm.com>
      Acked-by: NMark Rutland <mark.rutland@arm.com>
      Signed-off-by: NJames Morse <james.morse@arm.com>
      Signed-off-by: NCatalin Marinas <catalin.marinas@arm.com>
      3b82a6ea
  19. 01 10月, 2018 1 次提交
  20. 10 9月, 2018 1 次提交
  21. 19 2月, 2018 1 次提交
    • R
      arm64: uaccess: Formalise types for access_ok() · 9085b34d
      Robin Murphy 提交于
      In converting __range_ok() into a static inline, I inadvertently made
      it more type-safe, but without considering the ordering of the relevant
      conversions. This leads to quite a lot of Sparse noise about the fact
      that we use __chk_user_ptr() after addr has already been converted from
      a user pointer to an unsigned long.
      
      Rather than just adding another cast for the sake of shutting Sparse up,
      it seems reasonable to rework the types to make logical sense (although
      the resulting codegen for __range_ok() remains identical). The only
      callers this affects directly are our compat traps where the inferred
      "user-pointer-ness" of a register value now warrants explicit casting.
      Signed-off-by: NRobin Murphy <robin.murphy@arm.com>
      Signed-off-by: NCatalin Marinas <catalin.marinas@arm.com>
      9085b34d
  22. 07 2月, 2018 5 次提交
  23. 17 1月, 2018 1 次提交
    • C
      arm64: kpti: Fix the interaction between ASID switching and software PAN · 6b88a32c
      Catalin Marinas 提交于
      With ARM64_SW_TTBR0_PAN enabled, the exception entry code checks the
      active ASID to decide whether user access was enabled (non-zero ASID)
      when the exception was taken. On return from exception, if user access
      was previously disabled, it re-instates TTBR0_EL1 from the per-thread
      saved value (updated in switch_mm() or efi_set_pgd()).
      
      Commit 7655abb9 ("arm64: mm: Move ASID from TTBR0 to TTBR1") makes a
      TTBR0_EL1 + ASID switching non-atomic. Subsequently, commit 27a921e7
      ("arm64: mm: Fix and re-enable ARM64_SW_TTBR0_PAN") changes the
      __uaccess_ttbr0_disable() function and asm macro to first write the
      reserved TTBR0_EL1 followed by the ASID=0 update in TTBR1_EL1. If an
      exception occurs between these two, the exception return code will
      re-instate a valid TTBR0_EL1. Similar scenario can happen in
      cpu_switch_mm() between setting the reserved TTBR0_EL1 and the ASID
      update in cpu_do_switch_mm().
      
      This patch reverts the entry.S check for ASID == 0 to TTBR0_EL1 and
      disables the interrupts around the TTBR0_EL1 and ASID switching code in
      __uaccess_ttbr0_disable(). It also ensures that, when returning from the
      EFI runtime services, efi_set_pgd() doesn't leave a non-zero ASID in
      TTBR1_EL1 by using uaccess_ttbr0_{enable,disable}.
      
      The accesses to current_thread_info()->ttbr0 are updated to use
      READ_ONCE/WRITE_ONCE.
      
      As a safety measure, __uaccess_ttbr0_enable() always masks out any
      existing non-zero ASID TTBR1_EL1 before writing in the new ASID.
      
      Fixes: 27a921e7 ("arm64: mm: Fix and re-enable ARM64_SW_TTBR0_PAN")
      Acked-by: NWill Deacon <will.deacon@arm.com>
      Reported-by: NArd Biesheuvel <ard.biesheuvel@linaro.org>
      Tested-by: NArd Biesheuvel <ard.biesheuvel@linaro.org>
      Reviewed-by: NJames Morse <james.morse@arm.com>
      Tested-by: NJames Morse <james.morse@arm.com>
      Co-developed-by: NMarc Zyngier <marc.zyngier@arm.com>
      Signed-off-by: NCatalin Marinas <catalin.marinas@arm.com>
      6b88a32c
  24. 15 1月, 2018 1 次提交
  25. 13 1月, 2018 1 次提交
  26. 11 12月, 2017 2 次提交
  27. 09 8月, 2017 1 次提交
  28. 20 7月, 2017 1 次提交
  29. 08 7月, 2017 1 次提交
    • T
      arm64/syscalls: Check address limit on user-mode return · cf7de27a
      Thomas Garnier 提交于
      Ensure the address limit is a user-mode segment before returning to
      user-mode. Otherwise a process can corrupt kernel-mode memory and
      elevate privileges [1].
      
      The set_fs function sets the TIF_SETFS flag to force a slow path on
      return. In the slow path, the address limit is checked to be USER_DS if
      needed.
      
      [1] https://bugs.chromium.org/p/project-zero/issues/detail?id=990Signed-off-by: NThomas Garnier <thgarnie@google.com>
      Reviewed-by: NCatalin Marinas <catalin.marinas@arm.com>
      Signed-off-by: NThomas Gleixner <tglx@linutronix.de>
      Cc: Mark Rutland <mark.rutland@arm.com>
      Cc: kernel-hardening@lists.openwall.com
      Cc: Will Deacon <will.deacon@arm.com>
      Cc: David Howells <dhowells@redhat.com>
      Cc: Dave Hansen <dave.hansen@intel.com>
      Cc: Miroslav Benes <mbenes@suse.cz>
      Cc: Chris Metcalf <cmetcalf@mellanox.com>
      Cc: Pratyush Anand <panand@redhat.com>
      Cc: Russell King <linux@armlinux.org.uk>
      Cc: Petr Mladek <pmladek@suse.com>
      Cc: Rik van Riel <riel@redhat.com>
      Cc: Kees Cook <keescook@chromium.org>
      Cc: Arnd Bergmann <arnd@arndb.de>
      Cc: Al Viro <viro@zeniv.linux.org.uk>
      Cc: Andy Lutomirski <luto@kernel.org>
      Cc: Josh Poimboeuf <jpoimboe@redhat.com>
      Cc: linux-arm-kernel@lists.infradead.org
      Cc: Will Drewry <wad@chromium.org>
      Cc: linux-api@vger.kernel.org
      Cc: Oleg Nesterov <oleg@redhat.com>
      Cc: Andy Lutomirski <luto@amacapital.net>
      Cc: Paolo Bonzini <pbonzini@redhat.com>
      Link: http://lkml.kernel.org/r/20170615011203.144108-3-thgarnie@google.com
      cf7de27a