linux_dsm_epyc7002/arch/sparc/kernel
Aleksa Sarai fddb5d430a open: introduce openat2(2) syscall
/* Background. */
For a very long time, extending openat(2) with new features has been
incredibly frustrating. This stems from the fact that openat(2) is
possibly the most famous counter-example to the mantra "don't silently
accept garbage from userspace" -- it doesn't check whether unknown flags
are present[1].

This means that (generally) the addition of new flags to openat(2) has
been fraught with backwards-compatibility issues (O_TMPFILE has to be
defined as __O_TMPFILE|O_DIRECTORY|[O_RDWR or O_WRONLY] to ensure old
kernels gave errors, since it's insecure to silently ignore the
flag[2]). All new security-related flags therefore have a tough road to
being added to openat(2).

Userspace also has a hard time figuring out whether a particular flag is
supported on a particular kernel. While it is now possible with
contemporary kernels (thanks to [3]), older kernels will expose unknown
flag bits through fcntl(F_GETFL). Giving a clear -EINVAL during
openat(2) time matches modern syscall designs and is far more
fool-proof.

In addition, the newly-added path resolution restriction LOOKUP flags
(which we would like to expose to user-space) don't feel related to the
pre-existing O_* flag set -- they affect all components of path lookup.
We'd therefore like to add a new flag argument.

Adding a new syscall allows us to finally fix the flag-ignoring problem,
and we can make it extensible enough so that we will hopefully never
need an openat3(2).

/* Syscall Prototype. */
  /*
   * open_how is an extensible structure (similar in interface to
   * clone3(2) or sched_setattr(2)). The size parameter must be set to
   * sizeof(struct open_how), to allow for future extensions. All future
   * extensions will be appended to open_how, with their zero value
   * acting as a no-op default.
   */
  struct open_how { /* ... */ };

  int openat2(int dfd, const char *pathname,
              struct open_how *how, size_t size);

/* Description. */
The initial version of 'struct open_how' contains the following fields:

  flags
    Used to specify openat(2)-style flags. However, any unknown flag
    bits or otherwise incorrect flag combinations (like O_PATH|O_RDWR)
    will result in -EINVAL. In addition, this field is 64-bits wide to
    allow for more O_ flags than currently permitted with openat(2).

  mode
    The file mode for O_CREAT or O_TMPFILE.

    Must be set to zero if flags does not contain O_CREAT or O_TMPFILE.

  resolve
    Restrict path resolution (in contrast to O_* flags they affect all
    path components). The current set of flags are as follows (at the
    moment, all of the RESOLVE_ flags are implemented as just passing
    the corresponding LOOKUP_ flag).

    RESOLVE_NO_XDEV       => LOOKUP_NO_XDEV
    RESOLVE_NO_SYMLINKS   => LOOKUP_NO_SYMLINKS
    RESOLVE_NO_MAGICLINKS => LOOKUP_NO_MAGICLINKS
    RESOLVE_BENEATH       => LOOKUP_BENEATH
    RESOLVE_IN_ROOT       => LOOKUP_IN_ROOT

open_how does not contain an embedded size field, because it is of
little benefit (userspace can figure out the kernel open_how size at
runtime fairly easily without it). It also only contains u64s (even
though ->mode arguably should be a u16) to avoid having padding fields
which are never used in the future.

Note that as a result of the new how->flags handling, O_PATH|O_TMPFILE
is no longer permitted for openat(2). As far as I can tell, this has
always been a bug and appears to not be used by userspace (and I've not
seen any problems on my machines by disallowing it). If it turns out
this breaks something, we can special-case it and only permit it for
openat(2) but not openat2(2).

After input from Florian Weimer, the new open_how and flag definitions
are inside a separate header from uapi/linux/fcntl.h, to avoid problems
that glibc has with importing that header.

/* Testing. */
In a follow-up patch there are over 200 selftests which ensure that this
syscall has the correct semantics and will correctly handle several
attack scenarios.

In addition, I've written a userspace library[4] which provides
convenient wrappers around openat2(RESOLVE_IN_ROOT) (this is necessary
because no other syscalls support RESOLVE_IN_ROOT, and thus lots of care
must be taken when using RESOLVE_IN_ROOT'd file descriptors with other
syscalls). During the development of this patch, I've run numerous
verification tests using libpathrs (showing that the API is reasonably
usable by userspace).

/* Future Work. */
Additional RESOLVE_ flags have been suggested during the review period.
These can be easily implemented separately (such as blocking auto-mount
during resolution).

Furthermore, there are some other proposed changes to the openat(2)
interface (the most obvious example is magic-link hardening[5]) which
would be a good opportunity to add a way for userspace to restrict how
O_PATH file descriptors can be re-opened.

Another possible avenue of future work would be some kind of
CHECK_FIELDS[6] flag which causes the kernel to indicate to userspace
which openat2(2) flags and fields are supported by the current kernel
(to avoid userspace having to go through several guesses to figure it
out).

[1]: https://lwn.net/Articles/588444/
[2]: https://lore.kernel.org/lkml/CA+55aFyyxJL1LyXZeBsf2ypriraj5ut1XkNDsunRBqgVjZU_6Q@mail.gmail.com
[3]: commit 629e014bb8 ("fs: completely ignore unknown open flags")
[4]: https://sourceware.org/bugzilla/show_bug.cgi?id=17523
[5]: https://lore.kernel.org/lkml/20190930183316.10190-2-cyphar@cyphar.com/
[6]: https://youtu.be/ggD-eb3yPVs

Suggested-by: Christian Brauner <christian.brauner@ubuntu.com>
Signed-off-by: Aleksa Sarai <cyphar@cyphar.com>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
2020-01-18 09:19:18 -05:00
..
syscalls open: introduce openat2(2) syscall 2020-01-18 09:19:18 -05:00
.gitignore
adi_64.c treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 482 2019-06-19 17:09:52 +02:00
apc.c License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
asm-offsets.c License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
audit.c License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
auxio_32.c License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
auxio_64.c sparc: Use of_node_name_eq for node name comparisons 2018-11-18 13:35:21 -08:00
btext.c License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
central.c sparc: Use of_node_name_eq for node name comparisons 2018-11-18 13:35:21 -08:00
cherrs.S License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
chmc.c treewide: Add SPDX license identifier for more missed files 2019-05-21 10:50:45 +02:00
compat_audit.c License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
cpu.c License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
cpumap.c sparc: use struct_size() in kzalloc() 2019-05-09 14:26:16 -07:00
cpumap.h License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
devices.c License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
ds.c treewide: Add SPDX license identifier for more missed files 2019-05-21 10:50:45 +02:00
dtlb_miss.S License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
dtlb_prot.S License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
ebus.c License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
entry.h sparc64: Add support for ADI register fields, ASIs and traps 2018-03-18 07:38:45 -07:00
entry.S sparc: get rid of asm wrapper for nis_syscall() 2018-03-20 12:05:17 -04:00
etrap_32.S License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
etrap_64.S sparc64: Add support for ADI (Application Data Integrity) 2018-03-18 07:38:48 -07:00
fpu_traps.S License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
ftrace.c sparc/function_graph: Simplify with function_graph_enter() 2018-11-27 20:31:46 -05:00
getsetcc.S License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
head_32.S License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
head_64.S sparc64: Add support for ADI register fields, ASIs and traps 2018-03-18 07:38:45 -07:00
helpers.S treewide: Add SPDX license identifier for missed files 2019-05-21 10:50:45 +02:00
hvapi.c sparc64: Oracle DAX infrastructure 2018-01-22 08:17:15 -08:00
hvcalls.S sparc64: Oracle DAX infrastructure 2018-01-22 08:17:15 -08:00
hvtramp.S License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
idprom.c License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
iommu_common.h sparc: remove the mapping_error dma_map_ops method 2018-12-06 06:56:40 -08:00
iommu-common.c iommu-common: move to arch/sparc 2018-05-09 06:54:27 +02:00
iommu.c sparc64/iommu: allow large DMA masks 2019-02-20 07:28:58 -07:00
ioport.c dma-mapping: drop the dev argument to arch_sync_dma_for_* 2019-11-20 20:31:38 +01:00
irq_32.c License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
irq_64.c sparc: Use of_node_name_eq for node name comparisons 2018-11-18 13:35:21 -08:00
irq.h License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
itlb_miss.S License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
ivec.S License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
jump_label.c jump_label: move 'asm goto' support test to Kconfig 2019-01-06 09:46:51 +09:00
kernel.h sparc64: refactor the ali DMA quirk 2019-02-20 07:28:53 -07:00
kgdb_32.c kgdb/treewide: constify struct kgdb_arch arch_kgdb_ops 2018-12-30 08:33:06 +00:00
kgdb_64.c kgdb/treewide: constify struct kgdb_arch arch_kgdb_ops 2018-12-30 08:33:06 +00:00
kprobes.c bpf/error-inject/kprobes: Clear current_kprobe and enable preempt in kprobe 2018-06-21 12:33:19 +02:00
kstack.h License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
ktlb.S License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
ldc.c iommu-common: move to arch/sparc 2018-05-09 06:54:27 +02:00
led.c treewide: Add SPDX license identifier for more missed files 2019-05-21 10:50:45 +02:00
leon_kernel.c sparc: Remove unused leon_trans_init 2018-11-18 13:35:22 -08:00
leon_pci_grpci1.c License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
leon_pci_grpci2.c License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
leon_pci.c sparc/PCI: Use dev_printk() when possible 2018-05-22 07:54:06 -05:00
leon_pmc.c License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
leon_smp.c License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
Makefile jump_label: move 'asm goto' support test to Kconfig 2019-01-06 09:46:51 +09:00
mdesc.c mdesc: fix a missing-check bug in get_vdev_port_node_info() 2019-06-02 22:15:35 -07:00
misctrap.S License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
module.c License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
nmi.c treewide: Add SPDX license identifier for missed files 2019-05-21 10:50:45 +02:00
of_device_32.c sparc: Use DT node full_name instead of name for resources 2018-11-18 13:35:22 -08:00
of_device_64.c sparc: Use DT node full_name instead of name for resources 2018-11-18 13:35:22 -08:00
of_device_common.c treewide: Add SPDX license identifier for missed files 2019-05-21 10:50:45 +02:00
of_device_common.h License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
pci_common.c sparc/PCI: Use dev_printk() when possible 2018-05-22 07:54:06 -05:00
pci_fire.c mm: replace all open encodings for NUMA_NO_NODE 2019-03-05 21:07:14 -08:00
pci_impl.h sparc/PCI: Support arbitrary host bridge address offset 2018-02-15 15:07:30 -06:00
pci_msi.c sparc/PCI: Use dev_printk() when possible 2018-05-22 07:54:06 -05:00
pci_psycho.c License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
pci_sabre.c sparc: Use of_node_name_eq for node name comparisons 2018-11-18 13:35:21 -08:00
pci_schizo.c mm: replace all open encodings for NUMA_NO_NODE 2019-03-05 21:07:14 -08:00
pci_sun4v_asm.S License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
pci_sun4v.c sparc64/pci_sun4v: fix ATU checks for large DMA masks 2019-04-10 21:42:04 +02:00
pci_sun4v.h License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
pci.c sparc64: refactor the ali DMA quirk 2019-02-20 07:28:53 -07:00
pcic.c sparc/PCI: Use dev_printk() when possible 2018-05-22 07:54:06 -05:00
pcr.c treewide: Add SPDX license identifier for missed files 2019-05-21 10:50:45 +02:00
perf_event.c sparc: perf: fix updated event period in response to PERF_EVENT_IOC_PERIOD 2019-06-02 22:16:33 -07:00
pmc.c License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
power.c sparc: Convert to using %pOFn instead of device_node.name 2018-11-18 13:35:20 -08:00
process_32.c sparc: Use device_type helpers to access the node type 2018-11-18 13:35:21 -08:00
process_64.c signal: Remove the task parameter from force_sig_fault 2019-05-29 09:31:43 -05:00
prom_32.c treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 152 2019-05-30 11:26:32 -07:00
prom_64.c treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 152 2019-05-30 11:26:32 -07:00
prom_common.c treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 152 2019-05-30 11:26:32 -07:00
prom_irqtrans.c sparc: Use device_type helpers to access the node type 2018-11-18 13:35:21 -08:00
prom.h License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
psycho_common.c mm: replace all open encodings for NUMA_NO_NODE 2019-03-05 21:07:14 -08:00
psycho_common.h License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
ptrace_32.c License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
ptrace_64.c treewide: Add SPDX license identifier for missed files 2019-05-21 10:50:45 +02:00
reboot.c sparc: Use device_type helpers to access the node type 2018-11-18 13:35:21 -08:00
rtrap_32.S License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
rtrap_64.S sparc64: Make corrupted user stacks more debuggable. 2018-10-26 15:04:41 -07:00
sbus.c mm: replace all open encodings for NUMA_NO_NODE 2019-03-05 21:07:14 -08:00
setup_32.c Merge branch 'mount.part1' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs 2019-01-05 13:25:58 -08:00
setup_64.c sparc: add checks for the return value of memblock_alloc*() 2019-03-12 10:04:02 -07:00
signal32.c signal: Remove task parameter from force_sig 2019-05-27 09:36:28 -05:00
signal_32.c signal: Remove task parameter from force_sig 2019-05-27 09:36:28 -05:00
signal_64.c signal: Remove task parameter from force_sig 2019-05-27 09:36:28 -05:00
sigutil_32.c Remove 'type' argument from access_ok() function 2019-01-03 18:57:57 -08:00
sigutil_64.c License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
sigutil.h License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
smp_32.c License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
smp_64.c sparc: Use pr_warn instead of pr_warning 2019-10-18 14:59:46 +02:00
sparc_ksyms.c sparc: move exports to definitions 2016-08-07 23:55:43 -04:00
spiterrs.S License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
sstate.c License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
stacktrace.c treewide: Add SPDX license identifier for missed files 2019-05-21 10:50:45 +02:00
starfire.c License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
sun4d_irq.c sparc: Use of_node_name_eq for node name comparisons 2018-11-18 13:35:21 -08:00
sun4d_smp.c License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
sun4m_irq.c License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
sun4m_smp.c License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
sun4v_ivec.S License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
sun4v_mcd.S treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 482 2019-06-19 17:09:52 +02:00
sun4v_tlb_miss.S License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
sys32.S sparc: get rid of remaining SIGN... wrappers 2018-03-20 12:01:23 -04:00
sys_sparc32.c Merge branch 'misc.sparc' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs 2018-04-07 14:30:28 -07:00
sys_sparc_32.c signal: Remove the task parameter from force_sig_fault 2019-05-29 09:31:43 -05:00
sys_sparc_64.c ipc: fix sparc64 ipc() wrapper 2019-09-07 21:42:25 +02:00
syscalls.S sparc: get rid of asm wrapper for nis_syscall() 2018-03-20 12:05:17 -04:00
sysfs.c License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
systbls_32.S sparc: generate uapi header and system call table files 2018-11-18 18:52:22 -08:00
systbls_64.S sparc: generate uapi header and system call table files 2018-11-18 18:52:22 -08:00
systbls.h sparc: get rid of asm wrapper for nis_syscall() 2018-03-20 12:05:17 -04:00
time_32.c License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
time_64.c cpufreq: Call transition notifier only once for each policy 2019-05-10 12:20:36 +02:00
trampoline_32.S License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
trampoline_64.S License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
traps_32.c signal: Remove the task parameter from force_sig_fault 2019-05-29 09:31:43 -05:00
traps_64.c Merge branch 'siginfo-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/ebiederm/user-namespace 2019-07-08 21:48:15 -07:00
tsb.S License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
ttable_32.S License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
ttable_64.S sparc64: Add support for ADI register fields, ASIs and traps 2018-03-18 07:38:45 -07:00
una_asm_32.S License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
una_asm_64.S License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
unaligned_32.c Remove 'type' argument from access_ok() function 2019-01-03 18:57:57 -08:00
unaligned_64.c License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
uprobes.c treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 13 2019-05-21 11:28:45 +02:00
urtt_fill.S sparc64: Add support for ADI (Application Data Integrity) 2018-03-18 07:38:48 -07:00
utrap.S License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
vdso.c vDSO for sparc 2017-11-15 14:21:03 +09:00
vio.c sparc: Use device_type helpers to access the node type 2018-11-18 13:35:21 -08:00
viohs.c sparc64: viohs: Remove VLA usage 2018-10-07 22:42:00 -07:00
visemul.c License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
vmlinux.lds.S vmlinux.lds.h: Replace RW_DATA_SECTION with RW_DATA 2019-11-04 15:57:41 +01:00
windows.c License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
winfixup.S License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
wof.S License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
wuf.S License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00