Files
Wilson Sung 394a00276f Merge android-4.14-stable (4.14.299) into android-msm-pixel-4.14-tm-lts
Merge 4.14.299 into android-4.14-stable
    Merge 4.14.298 into android-4.14-stable
Linux 4.14.299
    wifi: brcmfmac: Fix potential buffer overflow in brcmf_fweh_event_worker()
  * linux/bits.h: make BIT(), GENMASK(), and friends available in assembly
      include/linux/bits.h
  * linux/const.h: move UL() macro to include/linux/const.h
      arch/arm64/include/asm/memory.h
      include/linux/const.h
      include/uapi/linux/const.h
  * linux/const.h: prefix include guard of uapi/linux/const.h with _UAPI
      include/uapi/linux/const.h
    KVM: x86: emulator: update the emulation mode after CR0 write
    KVM: x86: emulator: introduce emulator_recalc_and_set_mode
    KVM: x86: emulator: em_sysexit should update ctxt->mode
    KVM: x86: Mask off reserved bits in CPUID.80000008H
  * ext4: fix warning in 'ext4_da_release_space'
      fs/ext4/migrate.c
    parisc: Export iosapic_serial_irq() symbol for serial port driver
  * parisc: Make 8250_gsc driver dependend on CONFIG_PARISC
      drivers/tty/serial/8250/Kconfig
  * efi: random: reduce seed size to 32 bytes
      include/linux/efi.h
  * ALSA: usb-audio: Add quirks for MacroSilicon MS2100/MS2106 devices
      sound/usb/quirks-table.h
      sound/usb/quirks.c
  * capabilities: fix potential memleak on error path from vfs_getxattr_alloc()
      security/commoncap.c
  * tcp/udp: Make early_demux back namespacified.
      include/net/protocol.h
      include/net/tcp.h
      include/net/udp.h
      net/ipv4/af_inet.c
      net/ipv4/ip_input.c
      net/ipv4/sysctl_net_ipv4.c
      net/ipv6/ip6_input.c
      net/ipv6/tcp_ipv6.c
      net/ipv6/udp.c
    btrfs: fix type of parameter generation in btrfs_get_dentry
    block, bfq: protect 'bfqd->queued' by 'bfqd->lock'
  * Bluetooth: L2CAP: Fix attempting to access uninitialized memory
      net/bluetooth/l2cap_core.c
    i2c: xiic: Add platform module alias
    media: dvb-frontends/drxk: initialize err to 0
    media: s5p_cec: limit msg.len to CEC_MAX_MSG_SIZE
  * net, neigh: Fix null-ptr-deref in neigh_table_clear()
      net/core/neighbour.c
  * net: mdio: fix undefined behavior in bit shift for __mdiobus_register
      drivers/net/phy/mdio_bus.c
  * Bluetooth: L2CAP: fix use-after-free in l2cap_conn_del()
      net/bluetooth/l2cap_core.c
  * Bluetooth: L2CAP: Fix use-after-free caused by l2cap_reassemble_sdu
      net/bluetooth/l2cap_core.c
    btrfs: fix ulist leaks in error paths of qgroup self tests
    btrfs: fix inode list leak during backref walking at resolve_indirect_refs()
    isdn: mISDN: netjet: fix wrong check of device registration
    mISDN: fix possible memory leak in mISDN_register_device()
    rose: Fix NULL pointer dereference in rose_send_frame()
    ipvs: use explicitly signed chars
    net: sched: Fix use after free in red_enqueue()
    ata: pata_legacy: fix pdc20230_set_piomode()
    net: fec: fix improper use of NETDEV_TX_BUSY
    nfc: nfcmrvl: Fix potential memory leak in nfcmrvl_i2c_nci_send()
    nfc: s3fwrn5: Fix potential memory leak in s3fwrn5_nci_send()
    net: dsa: Fix possible memory leaks in dsa_loop_init()
    nfs4: Fix kmemleak when allocate slot failed
    NFSv4.1: We must always send RECLAIM_COMPLETE after a reboot
    NFSv4.1: Handle RECLAIM_COMPLETE trunking errors
  * UPSTREAM: linux/const.h: move UL() macro to include/linux/const.h
      arch/arm64/include/asm/memory.h
      include/linux/const.h
      include/uapi/linux/const.h
  * UPSTREAM: linux/const.h: prefix include guard of uapi/linux/const.h with _UAPI
      include/uapi/linux/const.h
  * UPSTREAM: linux/bits.h: make BIT(), GENMASK(), and friends available in assembly
      include/linux/bits.h
Linux 4.14.298
    can: rcar_canfd: rcar_canfd_handle_global_receive(): fix IRQ storm on global FIFO receive
    net: ehea: fix possible memory leak in ehea_register_port()
    openvswitch: switch from WARN to pr_warn
    ALSA: aoa: Fix I2S device accounting
    ALSA: aoa: i2sbus: fix possible memory leak in i2sbus_add_dev()
  * PM: domains: Fix handling of unavailable/disabled idle states
      drivers/base/power/domain.c
    net: ksz884x: fix missing pci_disable_device() on error in pcidev_init()
    i40e: Fix flow-type by setting GL_HASH_INSET registers
    i40e: Fix ethtool rx-flow-hash setting for X722
  * media: videodev2.h: V4L2_DV_BT_BLANKING_HEIGHT should check 'interlaced'
      include/uapi/linux/videodev2.h
  * media: v4l2-dv-timings: add sanity checks for blanking values
      drivers/media/v4l2-core/v4l2-dv-timings.c
    media: vivid: dev->bitmap_cap wasn't freed in all cases
    media: vivid: s_fbuf: add more sanity checks
    PM: hibernate: Allow hybrid sleep to work with s2idle
    can: mscan: mpc5xxx: mpc5xxx_can_probe(): add missing put_clock() in error path
  * tcp: fix indefinite deferral of RTO with SACK reneging
      net/ipv4/tcp_input.c
    net: lantiq_etop: don't free skb when returning NETDEV_TX_BUSY
    kcm: annotate data-races around kcm->rx_wait
    kcm: annotate data-races around kcm->rx_psock
    amd-xgbe: add the bit rate quirk for Molex cables
    amd-xgbe: fix the SFP compliance codes check for DAC cables
    x86/unwind/orc: Fix unreliable stack dump with gcov
    ALSA: ac97: fix possible memory leak in snd_ac97_dev_register()
    arc: iounmap() arg is volatile
    drm/msm: Fix return type of mdp4_lvds_connector_mode_valid
    net: ieee802154: fix error return code in dgram_bind()
    mm,hugetlb: take hugetlb_lock before decrementing h->resv_huge_pages
    xen/gntdev: Prevent leaking grants
    Xen/gntdev: don't ignore kernel unmapping error
    s390/futex: add missing EX_TABLE entry to __futex_atomic_op()
  * kernfs: fix use-after-free in __kernfs_remove
      fs/kernfs/dir.c
    mmc: core: Fix kernel panic when remove non-standard SDIO card
    drm/msm/hdmi: fix memory corruption with too many bridges
    mac802154: Fix LQI recording
    fbdev: smscufx: Fix several use-after-free bugs
    iio: light: tsl2583: Fix module unloading
    tools: iio: iio_utils: fix digit calculation
  * xhci: Remove device endpoints from bandwidth list when freeing the device
      drivers/usb/host/xhci-mem.c
  * usb: xhci: add XHCI_SPURIOUS_SUCCESS to ASM1042 despite being a V0.96 controller
      drivers/usb/host/xhci-pci.c
    usb: bdc: change state when port disconnected
  * usb: dwc3: gadget: Don't set IMI for no_interrupt
      drivers/usb/dwc3/gadget.c
  * USB: add RESET_RESUME quirk for NVIDIA Jetson devices in RCM
      drivers/usb/core/quirks.c
    ALSA: au88x0: use explicitly signed char
    ALSA: Use del_timer_sync() before freeing timer
    ACPI: video: Force backlight native for more TongFang devices
  * media: v4l2-mem2mem: Apply DST_QUEUE_OFF_BASE on MMAP buffers across ioctls
      drivers/media/v4l2-core/v4l2-mem2mem.c
    iommu/vt-d: Clean up si_domain in the init_dmars() error path
    net: hns: fix possible memory leak in hnae_ae_register()
    net/atm: fix proc_mpc_write incorrect return value
  * HID: magicmouse: Do not set BTN_MOUSE on double report
      drivers/hid/hid-magicmouse.c
    ACPI: extlog: Handle multiple records
    btrfs: fix processing of delayed data refs during backref walking
  * r8152: add PID for the Lenovo OneLink+ Dock
      drivers/net/usb/cdc_ether.c
      drivers/net/usb/r8152.c
  * arm64: errata: Remove AES hwcap for COMPAT tasks
      arch/arm64/Kconfig
      arch/arm64/include/asm/cpucaps.h
      arch/arm64/kernel/cpu_errata.c
      arch/arm64/kernel/cpufeature.c
    KVM: arm64: vgic: Fix exit condition in scan_its_table()
    ata: ahci: Match EM_MAX_SLOTS with SATA_PMP_MAX_PORTS
    ata: ahci-imx: Fix MODULE_ALIAS
    x86/microcode/AMD: Apply the patch early on every logical thread
    ocfs2: fix BUG when iput after ocfs2_mknod fails
    ocfs2: clear dinode links count in case of error
    Merge 4.14.297 into android-4.14-stable
Linux 4.14.297
    x86/speculation: Add RSB VM Exit protections
    x86/bugs: Warn when "ibrs" mitigation is selected on Enhanced IBRS parts
    x86/speculation: Use DECLARE_PER_CPU for x86_spec_ctrl_current
    x86/speculation: Disable RRSBA behavior
    x86/bugs: Add Cannon lake to RETBleed affected CPU list
    x86/cpu/amd: Enumerate BTC_NO
    x86/common: Stamp out the stepping madness
    x86/speculation: Fill RSB on vmexit for IBRS
    KVM: VMX: Fix IBRS handling after vmexit
    KVM: VMX: Prevent guest RSB poisoning attacks with eIBRS
    x86/speculation: Remove x86_spec_ctrl_mask
    x86/speculation: Use cached host SPEC_CTRL value for guest entry/exit
    x86/speculation: Fix SPEC_CTRL write on SMT state change
    x86/speculation: Fix firmware entry SPEC_CTRL handling
    x86/speculation: Fix RSB filling with CONFIG_RETPOLINE=n
    x86/speculation: Add LFENCE to RSB fill sequence
    x86/speculation: Change FILL_RETURN_BUFFER to work with objtool
    entel_idle: Disable IBRS during long idle
    x86/bugs: Report Intel retbleed vulnerability
    x86/bugs: Split spectre_v2_select_mitigation() and spectre_v2_user_select_mitigation()
    x86/speculation: Add spectre_v2=ibrs option to support Kernel IBRS
    x86/bugs: Optimize SPEC_CTRL MSR writes
    x86/entry: Add kernel IBRS implementation
    x86/bugs: Keep a per-CPU IA32_SPEC_CTRL value
    x86/bugs: Add AMD retbleed= boot parameter
  * x86/bugs: Report AMD retbleed vulnerability
      drivers/base/cpu.c
      include/linux/cpu.h
    x86/cpufeatures: Move RETPOLINE flags to word 11
    x86/entry: Remove skip_r11rcx
  * x86/cpu: Add a steppings field to struct x86_cpu_id
      include/linux/mod_devicetable.h
    x86/cpu: Add consistent CPU match macros
  * x86/devicetable: Move x86 specific macro out of generic code
      include/linux/mod_devicetable.h
    x86/cpufeature: Fix various quality problems in the <asm/cpu_device_hd.h> header
    x86/cpufeature: Add facility to check for min microcode revisions
  * Revert "x86/cpu: Add a steppings field to struct x86_cpu_id"
      include/linux/mod_devicetable.h
    Merge 4.14.296 into android-4.14-stable
Linux 4.14.296
    thermal: intel_powerclamp: Use first online CPU as control_cpu
  * inet: fully convert sk->sk_rx_dst to RCU rules
      include/net/sock.h
      net/ipv4/af_inet.c
      net/ipv4/tcp.c
      net/ipv4/tcp_input.c
      net/ipv4/tcp_ipv4.c
      net/ipv4/udp.c
      net/ipv6/tcp_ipv6.c
      net/ipv6/udp.c
    efi: libstub: drop pointless get_memory_map() call
    md: Replace snprintf with scnprintf
  * ext4: continue to expand file system when the target size doesn't reach
      fs/ext4/resize.c
    net/ieee802154: don't warn zero-sized raw_sendmsg()
    net: ieee802154: return -EINVAL for unknown addr type
    perf intel-pt: Fix segfault in intel_pt_print_info() with uClibc
    usb: idmouse: fix an uninit-value in idmouse_open
  * Revert "usb: storage: Add quirk for Samsung Fit flash"
      drivers/usb/storage/unusual_devs.h
    usb: musb: Fix musb_gadget.c rxstate overflow bug
  * usb: host: xhci: Fix potential memory leak in xhci_alloc_stream_info()
      drivers/usb/host/xhci-mem.c
    md/raid5: Wait for MD_SB_CHANGE_PENDING in raid5d
    HID: roccat: Fix use-after-free in roccat_read()
    nbd: Fix hung when signal interrupts nbd_start_device_ioctl()
    scsi: 3w-9xxx: Avoid disabling device if failing to enable it
    media: cx88: Fix a null-ptr-deref bug in buffer_prepare()
    ARM: dts: imx6sl: add missing properties for sram
    ARM: dts: imx6qp: add missing properties for sram
    ARM: dts: imx6dl: add missing properties for sram
    ARM: dts: imx6q: add missing properties for sram
    ARM: dts: imx7d-sdb: config the max pressure for tsc2046
    drm/amdgpu: fix initial connector audio value
    platform/x86: msi-laptop: Change DMI match / alias strings to fix module autoloading
    drm/vc4: vec: Fix timings for VEC modes
  * drm: Prevent drm_copy_field() to attempt copying a NULL pointer
      drivers/gpu/drm/drm_ioctl.c
  * drm: Use size_t type for len variable in drm_copy_field()
      drivers/gpu/drm/drm_ioctl.c
  * r8152: Rate limit overflow messages
      drivers/net/usb/r8152.c
  * Bluetooth: L2CAP: Fix user-after-free
      net/bluetooth/l2cap_core.c
  * net: If sock is dead don't access sock's sk_wq in sk_stream_wait_memory
      net/core/stream.c
    wifi: rt2x00: correctly set BBP register 86 for MT7620
    wifi: rt2x00: set SoC wmac clock register
    wifi: rt2x00: set correct TX_SW_CFG1 MAC register for MT7620
    wifi: rt2x00: don't run Rt5592 IQ calibration on MT7620
    can: bcm: check the result of can_send() in bcm_can_tx()
  * Bluetooth: hci_sysfs: Fix attempting to call device_add multiple times
      net/bluetooth/hci_sysfs.c
  * Bluetooth: L2CAP: initialize delayed works at l2cap_chan_create()
      net/bluetooth/l2cap_core.c
    wifi: brcmfmac: fix use-after-free bug in brcmf_netdev_start_xmit()
  * xfrm: Update ipcomp_scratches with NULL when freed
      net/xfrm/xfrm_ipcomp.c
    wifi: ath9k: avoid uninit memory read in ath9k_htc_rx_msg()
  * tcp: annotate data-race around tcp_md5sig_pool_populated
      net/ipv4/tcp.c
    openvswitch: Fix overreporting of drops in dropwatch
    openvswitch: Fix double reporting of drops in dropwatch
    wifi: brcmfmac: fix invalid address access when enabling SCAN log level
    NFSD: Return nfserr_serverfault if splice_ok but buf->pages have data
    thermal: intel_powerclamp: Use get_cpu() instead of smp_processor_id() to avoid crash
    powercap: intel_rapl: fix UBSAN shift-out-of-bounds issue
    MIPS: BCM47XX: Cast memcmp() of function to (void *)
    ACPI: video: Add Toshiba Satellite/Portege Z830 quirk
  * f2fs: fix race condition on setting FI_NO_EXTENT flag
      fs/f2fs/extent_cache.c
    crypto: cavium - prevent integer overflow loading firmware
  * iommu/iova: Fix module config properly
      include/linux/iova.h
    iommu/omap: Fix buffer overflow in debugfs
    powerpc: Fix SPE Power ISA properties for e500v1 platforms
    powerpc/powernv: add missing of_node_put() in opal_export_attrs()
    powerpc/pci_dn: Add missing of_node_put()
    powerpc/sysdev/fsl_msi: Add missing of_node_put()
    powerpc/math_emu/efp: Include module.h
    mailbox: bcm-ferxrm-mailbox: Fix error check for dma_map_sg
    clk: ti: dra7-atl: Fix reference leak in of_dra7_atl_clk_probe
    clk: bcm2835: fix bcm2835_clock_rate_from_divisor declaration
  * spmi: pmic-arb: correct duplicate APID to PPID mapping logic
      drivers/spmi/spmi-pmic-arb.c
    dmaengine: ioat: stop mod_timer from resurrecting deleted timer in __cleanup()
    mfd: sm501: Add check for platform_driver_register()
    mfd: lp8788: Fix an error handling path in lp8788_irq_init() and lp8788_irq_init()
    mfd: lp8788: Fix an error handling path in lp8788_probe()
    mfd: fsl-imx25: Fix an error handling path in mx25_tsadc_setup_irq()
    mfd: intel_soc_pmic: Fix an error handling path in intel_soc_pmic_i2c_probe()
    fsi: core: Check error number after calling ida_simple_get
    serial: 8250: Fix restoring termios speed after suspend
    firmware: google: Test spinlock on panic path to avoid lockups
    phy: qualcomm: call clk_disable_unprepare in the error handling
    drivers: serial: jsm: fix some leaks in probe
    usb: gadget: function: fix dangling pnp_string in f_printer.c
  * xhci: Don't show warning for reinit on known broken suspend
      drivers/usb/host/xhci.c
    md/raid5: Ensure stripe_fill happens on non-read IO with journal
    ata: fix ata_id_has_dipm()
    ata: fix ata_id_has_ncq_autosense()
    ata: fix ata_id_has_devslp()
    ata: fix ata_id_sense_reporting_enabled() and ata_id_has_sense_reporting()
  * dyndbg: let query-modname override actual module name
      lib/dynamic_debug.c
  * dyndbg: fix module.dyndbg handling
      include/linux/dynamic_debug.h
    RDMA/rxe: Fix the error caused by qp->sk
    RDMA/rxe: Fix "kernel NULL pointer dereference" error
    media: xilinx: vipp: Fix refcount leak in xvip_graph_dma_init
    tty: xilinx_uartps: Fix the ignore_status
    media: exynos4-is: fimc-is: Add of_node_put() when breaking out of loop
    HSI: omap_ssi_port: Fix dma_map_sg error check
    HSI: omap_ssi: Fix refcount leak in ssi_probe
    clk: tegra20: Fix refcount leak in tegra20_clock_init
    clk: tegra: Fix refcount leak in tegra114_clock_init
    clk: tegra: Fix refcount leak in tegra210_clock_init
    clk: oxnas: Hold reference returned by of_get_parent()
    iio: ABI: Fix wrong format of differential capacitance channel ABI.
  * iio: inkern: only release the device node when done with it
      drivers/iio/inkern.c
    iio: adc: at91-sama5d2_adc: fix AT91_SAMA5D2_MR_TRACKTIM_MAX
    ARM: dts: exynos: fix polarity of VBUS GPIO of Origen
    ARM: Drop CMDLINE_* dependency on ATAGS
    ARM: dts: kirkwood: lsxl: remove first ethernet port
    ARM: dts: kirkwood: lsxl: fix serial line
    ARM: dts: turris-omnia: Fix mpp26 pin name and comment
  * soc: qcom: smem_state: Add refcounting for the 'state->of_node'
      drivers/soc/qcom/smem_state.c
    soc: qcom: smsm: Fix refcount leak bugs in qcom_smsm_probe()
    memory: of: Fix refcount leak bug in of_get_ddr_timings()
    mmc: wmt-sdmmc: Fix an error handling path in wmt_mci_probe()
    ALSA: dmaengine: increment buffer pointer atomically
    ASoC: eureka-tlv320: Hold reference returned from of_find_xxx API
    mmc: au1xmmc: Fix an error handling path in au1xmmc_probe()
    drm/bridge: megachips: Fix a null pointer dereference bug
    platform/x86: msi-laptop: Fix resource cleanup
    platform/x86: msi-laptop: Fix old-ec check for backlight registering
  * drm/mipi-dsi: Detach devices when removing the host
      drivers/gpu/drm/drm_mipi_dsi.c
    bnx2x: fix potential memory leak in bnx2x_tpa_stop()
    net: rds: don't hold sock lock when cancelling work from rds_tcp_reset_callbacks()
  * tcp: fix tcp_cwnd_validate() to not forget is_cwnd_limited
      include/linux/tcp.h
      include/net/tcp.h
      net/ipv4/tcp.c
      net/ipv4/tcp_output.c
    mISDN: fix use-after-free bugs in l1oip timer handlers
    vhost/vsock: Use kvmalloc/kvfree for larger packets.
    spi: s3c64xx: Fix large transfers with DMA
    netfilter: nft_fib: Fix for rpath check with VRF devices
    spi/omap100k:Fix PM disable depth imbalance in omap1_spi100k_probe
    net: fs_enet: Fix wrong check in do_pd_setup
    wifi: rtl8xxxu: gen2: Fix mistake in path B IQ calibration
    wifi: rtl8xxxu: Fix skb misuse in TX queue selection
    spi: qup: add missing clk_disable_unprepare on error in spi_qup_pm_resume_runtime()
    spi: qup: add missing clk_disable_unprepare on error in spi_qup_resume()
    wifi: rtl8xxxu: tighten bounds checking in rtl8xxxu_read_efuse()
    wifi: mac80211: allow bw change during channel switch in mesh
    wifi: ath10k: add peer map clean up for peer delete in ath10k_sta_state()
    sh: machvec: Use char[] for section boundaries
    selinux: use "grep -E" instead of "egrep"
    gcov: support GCC 12.1 and newer compilers
    KVM: nVMX: Unconditionally purge queued/injected events on nested "exit"
    KVM: x86/emulator: Fix handing of POP SS to correctly set interruptibility
  * ring-buffer: Fix race between reset page and reading page
      kernel/trace/ring_buffer.c
  * ring-buffer: Check pending waiters when doing wake ups as well
      kernel/trace/ring_buffer.c
  * ring-buffer: Allow splice to read previous partially read pages
      kernel/trace/ring_buffer.c
    ftrace: Properly unset FTRACE_HASH_FL_MOD
    livepatch: fix race between fork and KLP transition
  * ext4: place buffer head allocation before handle start
      fs/ext4/inode.c
  * ext4: make ext4_lazyinit_thread freezable
      fs/ext4/super.c
  * ext4: fix null-ptr-deref in ext4_write_info
      fs/ext4/super.c
  * ext4: avoid crash when inline data creation follows DIO write
      fs/ext4/file.c
    nilfs2: fix lockdep warnings during disk space reclamation
    nilfs2: fix lockdep warnings in page operations for btree nodes
    nilfs2: fix use-after-free bug of struct nilfs_root
    fbdev: smscufx: Fix use-after-free in ufx_ops_open()
  * PCI: Sanitise firmware BAR assignments behind a PCI-PCI bridge
      drivers/pci/setup-res.c
    UM: cpuinfo: Fix a warning for CONFIG_CPUMASK_OFFSTACK
    parisc: fbdev/stifb: Align graphics memory size to 4MB
  * Revert "fs: check FMODE_LSEEK to control internal pipe splicing"
      fs/splice.c
    regulator: qcom_rpm: Fix circular deferral regression
  * quota: Check next/prev free block number after reading from quota file
      fs/quota/quota_tree.c
  * HID: multitouch: Add memory barriers
      drivers/hid/hid-multitouch.c
    fs: dlm: handle -EBUSY first in lock arg validation
    fs: dlm: fix race between test_bit() and queue_work()
    iio: dac: ad5593r: Fix i2c read protocol requirements
  * ALSA: usb-audio: Fix NULL dererence at error path
      sound/usb/endpoint.c
  * ALSA: usb-audio: Fix potential memory leaks
      sound/usb/endpoint.c
  * ALSA: rawmidi: Drop register_mutex in snd_rawmidi_free()
      sound/core/rawmidi.c
    ALSA: oss: Fix potential deadlock at unregistration
  * random: use expired timer rather than wq for mixing fast pool
      drivers/char/random.c
  * Input: xpad - fix wireless 360 controller breaking after suspend
      drivers/input/joystick/xpad.c
  * Input: xpad - add supported devices as contributed on github
      drivers/input/joystick/xpad.c
    wifi: mac80211_hwsim: avoid mac80211 warning on bad rate
  * random: avoid reading two cache lines on irq randomness
      drivers/char/random.c
  * random: restore O_NONBLOCK support
      drivers/char/mem.c
      drivers/char/random.c
    USB: serial: qcserial: add new usb-id for Dell branded EM7455
  * scsi: stex: Properly zero out the passthrough command structure
      include/scsi/scsi_cmnd.h
    ALSA: hda: Fix position reporting on Poulsbo
  * random: clamp credited irq bits to maximum mixed
      drivers/char/random.c
    ceph: don't truncate file in atomic_open
    nilfs2: replace WARN_ONs by nilfs_error for checkpoint acquisition failure
    nilfs2: fix leak of nilfs_root in case of writer thread creation failure
    nilfs2: fix NULL pointer dereference at nilfs_bmap_lookup_at_level()
  * netfilter: nf_queue: fix socket leak
      net/netfilter/nf_queue.c
  * rpmsg: qcom: glink: replace strncpy() with strscpy_pad()
      drivers/rpmsg/qcom_glink_native.c
    mmc: core: Terminate infinite loop in SD-UHS voltage switch
    mmc: core: Replace with already defined values for readability
    USB: serial: ftdi_sio: fix 300 bps rate for SIO
    usb: mon: make mmapped memory read only
    um: Cleanup compiler warning in arch/x86/um/tls_32.c
    um: Cleanup syscall_handler_t cast in syscalls_32.h
    net/ieee802154: fix uninit value bug in dgram_sendmsg
    ARM: dts: fix Moxa SDIO 'compatible', remove 'sdhci' misnomer
    dmaengine: xilinx_dma: Report error in case of dma_set_mask_and_coherent API failure
    dmaengine: xilinx_dma: cleanup for fetching xlnx,num-fstores property
  * fs: fix UAF/GPF bug in nilfs_mdt_destroy
      fs/inode.c
    ARM: fix function graph tracer and unwinder dependencies
  * i2c: dev: prevent ZERO_SIZE_PTR deref in i2cdev_ioctl_rdwr()
      drivers/i2c/i2c-dev.c
  * Makefile.extrawarn: Move -Wcast-function-type-strict to W=1
      scripts/Makefile.extrawarn
    clk: iproc: Do not rely on node name for correct PLL setup
    clk: iproc: Minor tidy up of iproc pll data structures
    selftests: Fix the if conditions of in test_extra_filter()
    nvme: Fix IOC_PR_CLEAR and IOC_PR_RELEASE ioctls for nvme devices
    nvme: add new line after variable declatation
  * usbnet: Fix memory leak in usbnet_disconnect()
      drivers/net/usb/usbnet.c
    Input: melfas_mip4 - fix return value check in mip4_probe()
    Revert "drm: bridge: analogix/dp: add panel prepare/unprepare in suspend/resume time"
    soc: sunxi: sram: Fix debugfs info for A64 SRAM C
    soc: sunxi: sram: Actually claim SRAM regions
  * mm/migrate_device.c: flush TLB while holding PTL
      mm/migrate.c
  * mm: prevent page_frag_alloc() from corrupting the memory
      mm/page_alloc.c
  * mm/page_alloc: fix race condition between build_all_zonelists and page allocation
      mm/page_alloc.c
    mmc: moxart: fix 4-bit bus width and remove 8-bit bus width
    ntfs: fix BUG_ON in ntfs_lookup_inode_by_name()
    net: usb: qmi_wwan: Add new usb-id for Dell branded EM7455
    uas: ignore UAS for Thinkplus chips
    usb-storage: Add Hiksemi USB3-FW to IGNORE_UAS
    uas: add no-uas quirk for Hiksemi usb_disk
  * ANDROID: kbuild: Wrap zero trivial-auto-var-init enablement flag with cc-option
      Makefile
  * UPSTREAM: f2fs: guarantee to write dirty data when enabling checkpoint back
      fs/f2fs/file.c
      fs/f2fs/super.c

Bug: 260299968
Change-Id: I3d8686e6dfa612ff0de4a72686637be0ce678aa6
Signed-off-by: Wilson Sung <wilsonsung@google.com>
Signed-off-by: JohnnLee <johnnlee@google.com>
2022-12-14 02:47:57 +00:00

1343 lines
38 KiB
C

/* Common capabilities, needed by capability.o.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
*/
#include <linux/capability.h>
#include <linux/audit.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/lsm_hooks.h>
#include <linux/file.h>
#include <linux/mm.h>
#include <linux/mman.h>
#include <linux/pagemap.h>
#include <linux/swap.h>
#include <linux/skbuff.h>
#include <linux/netlink.h>
#include <linux/ptrace.h>
#include <linux/xattr.h>
#include <linux/hugetlb.h>
#include <linux/mount.h>
#include <linux/sched.h>
#include <linux/prctl.h>
#include <linux/securebits.h>
#include <linux/user_namespace.h>
#include <linux/binfmts.h>
#include <linux/personality.h>
/*
* If a non-root user executes a setuid-root binary in
* !secure(SECURE_NOROOT) mode, then we raise capabilities.
* However if fE is also set, then the intent is for only
* the file capabilities to be applied, and the setuid-root
* bit is left on either to change the uid (plausible) or
* to get full privilege on a kernel without file capabilities
* support. So in that case we do not raise capabilities.
*
* Warn if that happens, once per boot.
*/
static void warn_setuid_and_fcaps_mixed(const char *fname)
{
static int warned;
if (!warned) {
printk(KERN_INFO "warning: `%s' has both setuid-root and"
" effective capabilities. Therefore not raising all"
" capabilities.\n", fname);
warned = 1;
}
}
/**
* __cap_capable - Determine whether a task has a particular effective capability
* @cred: The credentials to use
* @ns: The user namespace in which we need the capability
* @cap: The capability to check for
* @audit: Whether to write an audit message or not
*
* Determine whether the nominated task has the specified capability amongst
* its effective set, returning 0 if it does, -ve if it does not.
*
* NOTE WELL: cap_has_capability() cannot be used like the kernel's capable()
* and has_capability() functions. That is, it has the reverse semantics:
* cap_has_capability() returns 0 when a task has a capability, but the
* kernel's capable() and has_capability() returns 1 for this case.
*/
int __cap_capable(const struct cred *cred, struct user_namespace *targ_ns,
int cap, int audit)
{
struct user_namespace *ns = targ_ns;
#ifdef CONFIG_ANDROID_PARANOID_NETWORK
if (cap == CAP_NET_RAW && in_egroup_p(AID_NET_RAW))
return 0;
if (cap == CAP_NET_ADMIN && in_egroup_p(AID_NET_ADMIN))
return 0;
#endif
/* See if cred has the capability in the target user namespace
* by examining the target user namespace and all of the target
* user namespace's parents.
*/
for (;;) {
/* Do we have the necessary capabilities? */
if (ns == cred->user_ns)
return cap_raised(cred->cap_effective, cap) ? 0 : -EPERM;
/*
* If we're already at a lower level than we're looking for,
* we're done searching.
*/
if (ns->level <= cred->user_ns->level)
return -EPERM;
/*
* The owner of the user namespace in the parent of the
* user namespace has all caps.
*/
if ((ns->parent == cred->user_ns) && uid_eq(ns->owner, cred->euid))
return 0;
/*
* If you have a capability in a parent user ns, then you have
* it over all children user namespaces as well.
*/
ns = ns->parent;
}
/* We never get here */
}
int cap_capable(const struct cred *cred, struct user_namespace *targ_ns,
int cap, int audit)
{
return __cap_capable(cred, targ_ns, cap, audit);
}
/**
* cap_settime - Determine whether the current process may set the system clock
* @ts: The time to set
* @tz: The timezone to set
*
* Determine whether the current process may set the system clock and timezone
* information, returning 0 if permission granted, -ve if denied.
*/
int cap_settime(const struct timespec64 *ts, const struct timezone *tz)
{
if (!capable(CAP_SYS_TIME))
return -EPERM;
return 0;
}
/**
* cap_ptrace_access_check - Determine whether the current process may access
* another
* @child: The process to be accessed
* @mode: The mode of attachment.
*
* If we are in the same or an ancestor user_ns and have all the target
* task's capabilities, then ptrace access is allowed.
* If we have the ptrace capability to the target user_ns, then ptrace
* access is allowed.
* Else denied.
*
* Determine whether a process may access another, returning 0 if permission
* granted, -ve if denied.
*/
int cap_ptrace_access_check(struct task_struct *child, unsigned int mode)
{
int ret = 0;
const struct cred *cred, *child_cred;
const kernel_cap_t *caller_caps;
rcu_read_lock();
cred = current_cred();
child_cred = __task_cred(child);
if (mode & PTRACE_MODE_FSCREDS)
caller_caps = &cred->cap_effective;
else
caller_caps = &cred->cap_permitted;
if (cred->user_ns == child_cred->user_ns &&
cap_issubset(child_cred->cap_permitted, *caller_caps))
goto out;
if (ns_capable(child_cred->user_ns, CAP_SYS_PTRACE))
goto out;
ret = -EPERM;
out:
rcu_read_unlock();
return ret;
}
/**
* cap_ptrace_traceme - Determine whether another process may trace the current
* @parent: The task proposed to be the tracer
*
* If parent is in the same or an ancestor user_ns and has all current's
* capabilities, then ptrace access is allowed.
* If parent has the ptrace capability to current's user_ns, then ptrace
* access is allowed.
* Else denied.
*
* Determine whether the nominated task is permitted to trace the current
* process, returning 0 if permission is granted, -ve if denied.
*/
int cap_ptrace_traceme(struct task_struct *parent)
{
int ret = 0;
const struct cred *cred, *child_cred;
rcu_read_lock();
cred = __task_cred(parent);
child_cred = current_cred();
if (cred->user_ns == child_cred->user_ns &&
cap_issubset(child_cred->cap_permitted, cred->cap_permitted))
goto out;
if (has_ns_capability(parent, child_cred->user_ns, CAP_SYS_PTRACE))
goto out;
ret = -EPERM;
out:
rcu_read_unlock();
return ret;
}
/**
* cap_capget - Retrieve a task's capability sets
* @target: The task from which to retrieve the capability sets
* @effective: The place to record the effective set
* @inheritable: The place to record the inheritable set
* @permitted: The place to record the permitted set
*
* This function retrieves the capabilities of the nominated task and returns
* them to the caller.
*/
int cap_capget(struct task_struct *target, kernel_cap_t *effective,
kernel_cap_t *inheritable, kernel_cap_t *permitted)
{
const struct cred *cred;
/* Derived from kernel/capability.c:sys_capget. */
rcu_read_lock();
cred = __task_cred(target);
*effective = cred->cap_effective;
*inheritable = cred->cap_inheritable;
*permitted = cred->cap_permitted;
rcu_read_unlock();
return 0;
}
/*
* Determine whether the inheritable capabilities are limited to the old
* permitted set. Returns 1 if they are limited, 0 if they are not.
*/
static inline int cap_inh_is_capped(void)
{
/* they are so limited unless the current task has the CAP_SETPCAP
* capability
*/
if (cap_capable(current_cred(), current_cred()->user_ns,
CAP_SETPCAP, SECURITY_CAP_AUDIT) == 0)
return 0;
return 1;
}
/**
* cap_capset - Validate and apply proposed changes to current's capabilities
* @new: The proposed new credentials; alterations should be made here
* @old: The current task's current credentials
* @effective: A pointer to the proposed new effective capabilities set
* @inheritable: A pointer to the proposed new inheritable capabilities set
* @permitted: A pointer to the proposed new permitted capabilities set
*
* This function validates and applies a proposed mass change to the current
* process's capability sets. The changes are made to the proposed new
* credentials, and assuming no error, will be committed by the caller of LSM.
*/
int cap_capset(struct cred *new,
const struct cred *old,
const kernel_cap_t *effective,
const kernel_cap_t *inheritable,
const kernel_cap_t *permitted)
{
if (cap_inh_is_capped() &&
!cap_issubset(*inheritable,
cap_combine(old->cap_inheritable,
old->cap_permitted)))
/* incapable of using this inheritable set */
return -EPERM;
if (!cap_issubset(*inheritable,
cap_combine(old->cap_inheritable,
old->cap_bset)))
/* no new pI capabilities outside bounding set */
return -EPERM;
/* verify restrictions on target's new Permitted set */
if (!cap_issubset(*permitted, old->cap_permitted))
return -EPERM;
/* verify the _new_Effective_ is a subset of the _new_Permitted_ */
if (!cap_issubset(*effective, *permitted))
return -EPERM;
new->cap_effective = *effective;
new->cap_inheritable = *inheritable;
new->cap_permitted = *permitted;
/*
* Mask off ambient bits that are no longer both permitted and
* inheritable.
*/
new->cap_ambient = cap_intersect(new->cap_ambient,
cap_intersect(*permitted,
*inheritable));
if (WARN_ON(!cap_ambient_invariant_ok(new)))
return -EINVAL;
return 0;
}
/**
* cap_inode_need_killpriv - Determine if inode change affects privileges
* @dentry: The inode/dentry in being changed with change marked ATTR_KILL_PRIV
*
* Determine if an inode having a change applied that's marked ATTR_KILL_PRIV
* affects the security markings on that inode, and if it is, should
* inode_killpriv() be invoked or the change rejected.
*
* Returns 1 if security.capability has a value, meaning inode_killpriv()
* is required, 0 otherwise, meaning inode_killpriv() is not required.
*/
int cap_inode_need_killpriv(struct dentry *dentry)
{
struct inode *inode = d_backing_inode(dentry);
int error;
error = __vfs_getxattr(dentry, inode, XATTR_NAME_CAPS, NULL, 0);
return error > 0;
}
/**
* cap_inode_killpriv - Erase the security markings on an inode
* @dentry: The inode/dentry to alter
*
* Erase the privilege-enhancing security markings on an inode.
*
* Returns 0 if successful, -ve on error.
*/
int cap_inode_killpriv(struct dentry *dentry)
{
int error;
error = __vfs_removexattr(dentry, XATTR_NAME_CAPS);
if (error == -EOPNOTSUPP)
error = 0;
return error;
}
static bool rootid_owns_currentns(kuid_t kroot)
{
struct user_namespace *ns;
if (!uid_valid(kroot))
return false;
for (ns = current_user_ns(); ; ns = ns->parent) {
if (from_kuid(ns, kroot) == 0)
return true;
if (ns == &init_user_ns)
break;
}
return false;
}
static __u32 sansflags(__u32 m)
{
return m & ~VFS_CAP_FLAGS_EFFECTIVE;
}
static bool is_v2header(size_t size, const struct vfs_cap_data *cap)
{
if (size != XATTR_CAPS_SZ_2)
return false;
return sansflags(le32_to_cpu(cap->magic_etc)) == VFS_CAP_REVISION_2;
}
static bool is_v3header(size_t size, const struct vfs_cap_data *cap)
{
if (size != XATTR_CAPS_SZ_3)
return false;
return sansflags(le32_to_cpu(cap->magic_etc)) == VFS_CAP_REVISION_3;
}
/*
* getsecurity: We are called for security.* before any attempt to read the
* xattr from the inode itself.
*
* This gives us a chance to read the on-disk value and convert it. If we
* return -EOPNOTSUPP, then vfs_getxattr() will call the i_op handler.
*
* Note we are not called by vfs_getxattr_alloc(), but that is only called
* by the integrity subsystem, which really wants the unconverted values -
* so that's good.
*/
int cap_inode_getsecurity(struct inode *inode, const char *name, void **buffer,
bool alloc)
{
int size, ret;
kuid_t kroot;
u32 nsmagic, magic;
uid_t root, mappedroot;
char *tmpbuf = NULL;
struct vfs_cap_data *cap;
struct vfs_ns_cap_data *nscap = NULL;
struct dentry *dentry;
struct user_namespace *fs_ns;
if (strcmp(name, "capability") != 0)
return -EOPNOTSUPP;
dentry = d_find_any_alias(inode);
if (!dentry)
return -EINVAL;
size = sizeof(struct vfs_ns_cap_data);
ret = (int) vfs_getxattr_alloc(dentry, XATTR_NAME_CAPS,
&tmpbuf, size, GFP_NOFS);
dput(dentry);
if (ret < 0 || !tmpbuf) {
size = ret;
goto out_free;
}
fs_ns = inode->i_sb->s_user_ns;
cap = (struct vfs_cap_data *) tmpbuf;
if (is_v2header((size_t) ret, cap)) {
root = 0;
} else if (is_v3header((size_t) ret, cap)) {
nscap = (struct vfs_ns_cap_data *) tmpbuf;
root = le32_to_cpu(nscap->rootid);
} else {
size = -EINVAL;
goto out_free;
}
kroot = make_kuid(fs_ns, root);
/* If the root kuid maps to a valid uid in current ns, then return
* this as a nscap. */
mappedroot = from_kuid(current_user_ns(), kroot);
if (mappedroot != (uid_t)-1 && mappedroot != (uid_t)0) {
size = sizeof(struct vfs_ns_cap_data);
if (alloc) {
if (!nscap) {
/* v2 -> v3 conversion */
nscap = kzalloc(size, GFP_ATOMIC);
if (!nscap) {
size = -ENOMEM;
goto out_free;
}
nsmagic = VFS_CAP_REVISION_3;
magic = le32_to_cpu(cap->magic_etc);
if (magic & VFS_CAP_FLAGS_EFFECTIVE)
nsmagic |= VFS_CAP_FLAGS_EFFECTIVE;
memcpy(&nscap->data, &cap->data, sizeof(__le32) * 2 * VFS_CAP_U32);
nscap->magic_etc = cpu_to_le32(nsmagic);
} else {
/* use allocated v3 buffer */
tmpbuf = NULL;
}
nscap->rootid = cpu_to_le32(mappedroot);
*buffer = nscap;
}
goto out_free;
}
if (!rootid_owns_currentns(kroot)) {
size = -EOVERFLOW;
goto out_free;
}
/* This comes from a parent namespace. Return as a v2 capability */
size = sizeof(struct vfs_cap_data);
if (alloc) {
if (nscap) {
/* v3 -> v2 conversion */
cap = kzalloc(size, GFP_ATOMIC);
if (!cap) {
size = -ENOMEM;
goto out_free;
}
magic = VFS_CAP_REVISION_2;
nsmagic = le32_to_cpu(nscap->magic_etc);
if (nsmagic & VFS_CAP_FLAGS_EFFECTIVE)
magic |= VFS_CAP_FLAGS_EFFECTIVE;
memcpy(&cap->data, &nscap->data, sizeof(__le32) * 2 * VFS_CAP_U32);
cap->magic_etc = cpu_to_le32(magic);
} else {
/* use unconverted v2 */
tmpbuf = NULL;
}
*buffer = cap;
}
out_free:
kfree(tmpbuf);
return size;
}
static kuid_t rootid_from_xattr(const void *value, size_t size,
struct user_namespace *task_ns)
{
const struct vfs_ns_cap_data *nscap = value;
uid_t rootid = 0;
if (size == XATTR_CAPS_SZ_3)
rootid = le32_to_cpu(nscap->rootid);
return make_kuid(task_ns, rootid);
}
static bool validheader(size_t size, const struct vfs_cap_data *cap)
{
return is_v2header(size, cap) || is_v3header(size, cap);
}
/*
* User requested a write of security.capability. If needed, update the
* xattr to change from v2 to v3, or to fixup the v3 rootid.
*
* If all is ok, we return the new size, on error return < 0.
*/
int cap_convert_nscap(struct dentry *dentry, void **ivalue, size_t size)
{
struct vfs_ns_cap_data *nscap;
uid_t nsrootid;
const struct vfs_cap_data *cap = *ivalue;
__u32 magic, nsmagic;
struct inode *inode = d_backing_inode(dentry);
struct user_namespace *task_ns = current_user_ns(),
*fs_ns = inode->i_sb->s_user_ns;
kuid_t rootid;
size_t newsize;
if (!*ivalue)
return -EINVAL;
if (!validheader(size, cap))
return -EINVAL;
if (!capable_wrt_inode_uidgid(inode, CAP_SETFCAP))
return -EPERM;
if (size == XATTR_CAPS_SZ_2)
if (ns_capable(inode->i_sb->s_user_ns, CAP_SETFCAP))
/* user is privileged, just write the v2 */
return size;
rootid = rootid_from_xattr(*ivalue, size, task_ns);
if (!uid_valid(rootid))
return -EINVAL;
nsrootid = from_kuid(fs_ns, rootid);
if (nsrootid == -1)
return -EINVAL;
newsize = sizeof(struct vfs_ns_cap_data);
nscap = kmalloc(newsize, GFP_ATOMIC);
if (!nscap)
return -ENOMEM;
nscap->rootid = cpu_to_le32(nsrootid);
nsmagic = VFS_CAP_REVISION_3;
magic = le32_to_cpu(cap->magic_etc);
if (magic & VFS_CAP_FLAGS_EFFECTIVE)
nsmagic |= VFS_CAP_FLAGS_EFFECTIVE;
nscap->magic_etc = cpu_to_le32(nsmagic);
memcpy(&nscap->data, &cap->data, sizeof(__le32) * 2 * VFS_CAP_U32);
kvfree(*ivalue);
*ivalue = nscap;
return newsize;
}
/*
* Calculate the new process capability sets from the capability sets attached
* to a file.
*/
static inline int bprm_caps_from_vfs_caps(struct cpu_vfs_cap_data *caps,
struct linux_binprm *bprm,
bool *effective,
bool *has_cap)
{
struct cred *new = bprm->cred;
unsigned i;
int ret = 0;
if (caps->magic_etc & VFS_CAP_FLAGS_EFFECTIVE)
*effective = true;
if (caps->magic_etc & VFS_CAP_REVISION_MASK)
*has_cap = true;
CAP_FOR_EACH_U32(i) {
__u32 permitted = caps->permitted.cap[i];
__u32 inheritable = caps->inheritable.cap[i];
/*
* pP' = (X & fP) | (pI & fI)
* The addition of pA' is handled later.
*/
new->cap_permitted.cap[i] =
(new->cap_bset.cap[i] & permitted) |
(new->cap_inheritable.cap[i] & inheritable);
if (permitted & ~new->cap_permitted.cap[i])
/* insufficient to execute correctly */
ret = -EPERM;
}
/*
* For legacy apps, with no internal support for recognizing they
* do not have enough capabilities, we return an error if they are
* missing some "forced" (aka file-permitted) capabilities.
*/
return *effective ? ret : 0;
}
/*
* Extract the on-exec-apply capability sets for an executable file.
*/
int get_vfs_caps_from_disk(const struct dentry *dentry, struct cpu_vfs_cap_data *cpu_caps)
{
struct inode *inode = d_backing_inode(dentry);
__u32 magic_etc;
unsigned tocopy, i;
int size;
struct vfs_ns_cap_data data, *nscaps = &data;
struct vfs_cap_data *caps = (struct vfs_cap_data *) &data;
kuid_t rootkuid;
struct user_namespace *fs_ns;
memset(cpu_caps, 0, sizeof(struct cpu_vfs_cap_data));
if (!inode)
return -ENODATA;
fs_ns = inode->i_sb->s_user_ns;
size = __vfs_getxattr((struct dentry *)dentry, inode,
XATTR_NAME_CAPS, &data, XATTR_CAPS_SZ);
if (size == -ENODATA || size == -EOPNOTSUPP)
/* no data, that's ok */
return -ENODATA;
if (size < 0)
return size;
if (size < sizeof(magic_etc))
return -EINVAL;
cpu_caps->magic_etc = magic_etc = le32_to_cpu(caps->magic_etc);
rootkuid = make_kuid(fs_ns, 0);
switch (magic_etc & VFS_CAP_REVISION_MASK) {
case VFS_CAP_REVISION_1:
if (size != XATTR_CAPS_SZ_1)
return -EINVAL;
tocopy = VFS_CAP_U32_1;
break;
case VFS_CAP_REVISION_2:
if (size != XATTR_CAPS_SZ_2)
return -EINVAL;
tocopy = VFS_CAP_U32_2;
break;
case VFS_CAP_REVISION_3:
if (size != XATTR_CAPS_SZ_3)
return -EINVAL;
tocopy = VFS_CAP_U32_3;
rootkuid = make_kuid(fs_ns, le32_to_cpu(nscaps->rootid));
break;
default:
return -EINVAL;
}
/* Limit the caps to the mounter of the filesystem
* or the more limited uid specified in the xattr.
*/
if (!rootid_owns_currentns(rootkuid))
return -ENODATA;
CAP_FOR_EACH_U32(i) {
if (i >= tocopy)
break;
cpu_caps->permitted.cap[i] = le32_to_cpu(caps->data[i].permitted);
cpu_caps->inheritable.cap[i] = le32_to_cpu(caps->data[i].inheritable);
}
cpu_caps->permitted.cap[CAP_LAST_U32] &= CAP_LAST_U32_VALID_MASK;
cpu_caps->inheritable.cap[CAP_LAST_U32] &= CAP_LAST_U32_VALID_MASK;
return 0;
}
/*
* Attempt to get the on-exec apply capability sets for an executable file from
* its xattrs and, if present, apply them to the proposed credentials being
* constructed by execve().
*/
static int get_file_caps(struct linux_binprm *bprm, bool *effective, bool *has_cap)
{
int rc = 0;
struct cpu_vfs_cap_data vcaps;
cap_clear(bprm->cred->cap_permitted);
if (!file_caps_enabled)
return 0;
if (!mnt_may_suid(bprm->file->f_path.mnt))
return 0;
/*
* This check is redundant with mnt_may_suid() but is kept to make
* explicit that capability bits are limited to s_user_ns and its
* descendants.
*/
if (!current_in_userns(bprm->file->f_path.mnt->mnt_sb->s_user_ns))
return 0;
rc = get_vfs_caps_from_disk(bprm->file->f_path.dentry, &vcaps);
if (rc < 0) {
if (rc == -EINVAL)
printk(KERN_NOTICE "Invalid argument reading file caps for %s\n",
bprm->filename);
else if (rc == -ENODATA)
rc = 0;
goto out;
}
rc = bprm_caps_from_vfs_caps(&vcaps, bprm, effective, has_cap);
if (rc == -EINVAL)
printk(KERN_NOTICE "%s: cap_from_disk returned %d for %s\n",
__func__, rc, bprm->filename);
out:
if (rc)
cap_clear(bprm->cred->cap_permitted);
return rc;
}
/**
* cap_bprm_set_creds - Set up the proposed credentials for execve().
* @bprm: The execution parameters, including the proposed creds
*
* Set up the proposed credentials for a new execution context being
* constructed by execve(). The proposed creds in @bprm->cred is altered,
* which won't take effect immediately. Returns 0 if successful, -ve on error.
*/
int cap_bprm_set_creds(struct linux_binprm *bprm)
{
const struct cred *old = current_cred();
struct cred *new = bprm->cred;
bool effective, has_cap = false, is_setid;
int ret;
kuid_t root_uid;
new->cap_ambient = old->cap_ambient;
if (WARN_ON(!cap_ambient_invariant_ok(old)))
return -EPERM;
effective = false;
ret = get_file_caps(bprm, &effective, &has_cap);
if (ret < 0)
return ret;
root_uid = make_kuid(new->user_ns, 0);
if (!issecure(SECURE_NOROOT)) {
/*
* If the legacy file capability is set, then don't set privs
* for a setuid root binary run by a non-root user. Do set it
* for a root user just to cause least surprise to an admin.
*/
if (has_cap && !uid_eq(new->uid, root_uid) && uid_eq(new->euid, root_uid)) {
warn_setuid_and_fcaps_mixed(bprm->filename);
goto skip;
}
/*
* To support inheritance of root-permissions and suid-root
* executables under compatibility mode, we override the
* capability sets for the file.
*
* If only the real uid is 0, we do not set the effective bit.
*/
if (uid_eq(new->euid, root_uid) || uid_eq(new->uid, root_uid)) {
/* pP' = (cap_bset & ~0) | (pI & ~0) */
new->cap_permitted = cap_combine(old->cap_bset,
old->cap_inheritable);
}
if (uid_eq(new->euid, root_uid))
effective = true;
}
skip:
/* if we have fs caps, clear dangerous personality flags */
if (!cap_issubset(new->cap_permitted, old->cap_permitted))
bprm->per_clear |= PER_CLEAR_ON_SETID;
/* Don't let someone trace a set[ug]id/setpcap binary with the revised
* credentials unless they have the appropriate permit.
*
* In addition, if NO_NEW_PRIVS, then ensure we get no new privs.
*/
is_setid = !uid_eq(new->euid, old->uid) || !gid_eq(new->egid, old->gid);
if ((is_setid ||
!cap_issubset(new->cap_permitted, old->cap_permitted)) &&
((bprm->unsafe & ~LSM_UNSAFE_PTRACE) ||
!ptracer_capable(current, new->user_ns))) {
/* downgrade; they get no more than they had, and maybe less */
if (!ns_capable(new->user_ns, CAP_SETUID) ||
(bprm->unsafe & LSM_UNSAFE_NO_NEW_PRIVS)) {
new->euid = new->uid;
new->egid = new->gid;
}
new->cap_permitted = cap_intersect(new->cap_permitted,
old->cap_permitted);
}
new->suid = new->fsuid = new->euid;
new->sgid = new->fsgid = new->egid;
/* File caps or setid cancels ambient. */
if (has_cap || is_setid)
cap_clear(new->cap_ambient);
/*
* Now that we've computed pA', update pP' to give:
* pP' = (X & fP) | (pI & fI) | pA'
*/
new->cap_permitted = cap_combine(new->cap_permitted, new->cap_ambient);
/*
* Set pE' = (fE ? pP' : pA'). Because pA' is zero if fE is set,
* this is the same as pE' = (fE ? pP' : 0) | pA'.
*/
if (effective)
new->cap_effective = new->cap_permitted;
else
new->cap_effective = new->cap_ambient;
if (WARN_ON(!cap_ambient_invariant_ok(new)))
return -EPERM;
/*
* Audit candidate if current->cap_effective is set
*
* We do not bother to audit if 3 things are true:
* 1) cap_effective has all caps
* 2) we are root
* 3) root is supposed to have all caps (SECURE_NOROOT)
* Since this is just a normal root execing a process.
*
* Number 1 above might fail if you don't have a full bset, but I think
* that is interesting information to audit.
*/
if (!cap_issubset(new->cap_effective, new->cap_ambient)) {
if (!cap_issubset(CAP_FULL_SET, new->cap_effective) ||
!uid_eq(new->euid, root_uid) || !uid_eq(new->uid, root_uid) ||
issecure(SECURE_NOROOT)) {
ret = audit_log_bprm_fcaps(bprm, new, old);
if (ret < 0)
return ret;
}
}
new->securebits &= ~issecure_mask(SECURE_KEEP_CAPS);
if (WARN_ON(!cap_ambient_invariant_ok(new)))
return -EPERM;
/* Check for privilege-elevated exec. */
bprm->cap_elevated = 0;
if (is_setid) {
bprm->cap_elevated = 1;
} else if (!uid_eq(new->uid, root_uid)) {
if (effective ||
!cap_issubset(new->cap_permitted, new->cap_ambient))
bprm->cap_elevated = 1;
}
return 0;
}
/**
* cap_inode_setxattr - Determine whether an xattr may be altered
* @dentry: The inode/dentry being altered
* @name: The name of the xattr to be changed
* @value: The value that the xattr will be changed to
* @size: The size of value
* @flags: The replacement flag
*
* Determine whether an xattr may be altered or set on an inode, returning 0 if
* permission is granted, -ve if denied.
*
* This is used to make sure security xattrs don't get updated or set by those
* who aren't privileged to do so.
*/
int cap_inode_setxattr(struct dentry *dentry, const char *name,
const void *value, size_t size, int flags)
{
/* Ignore non-security xattrs */
if (strncmp(name, XATTR_SECURITY_PREFIX,
sizeof(XATTR_SECURITY_PREFIX) - 1) != 0)
return 0;
/*
* For XATTR_NAME_CAPS the check will be done in
* cap_convert_nscap(), called by setxattr()
*/
if (strcmp(name, XATTR_NAME_CAPS) == 0)
return 0;
if (!capable(CAP_SYS_ADMIN))
return -EPERM;
return 0;
}
/**
* cap_inode_removexattr - Determine whether an xattr may be removed
* @dentry: The inode/dentry being altered
* @name: The name of the xattr to be changed
*
* Determine whether an xattr may be removed from an inode, returning 0 if
* permission is granted, -ve if denied.
*
* This is used to make sure security xattrs don't get removed by those who
* aren't privileged to remove them.
*/
int cap_inode_removexattr(struct dentry *dentry, const char *name)
{
/* Ignore non-security xattrs */
if (strncmp(name, XATTR_SECURITY_PREFIX,
sizeof(XATTR_SECURITY_PREFIX) - 1) != 0)
return 0;
if (strcmp(name, XATTR_NAME_CAPS) == 0) {
/* security.capability gets namespaced */
struct inode *inode = d_backing_inode(dentry);
if (!inode)
return -EINVAL;
if (!capable_wrt_inode_uidgid(inode, CAP_SETFCAP))
return -EPERM;
return 0;
}
if (!capable(CAP_SYS_ADMIN))
return -EPERM;
return 0;
}
/*
* cap_emulate_setxuid() fixes the effective / permitted capabilities of
* a process after a call to setuid, setreuid, or setresuid.
*
* 1) When set*uiding _from_ one of {r,e,s}uid == 0 _to_ all of
* {r,e,s}uid != 0, the permitted and effective capabilities are
* cleared.
*
* 2) When set*uiding _from_ euid == 0 _to_ euid != 0, the effective
* capabilities of the process are cleared.
*
* 3) When set*uiding _from_ euid != 0 _to_ euid == 0, the effective
* capabilities are set to the permitted capabilities.
*
* fsuid is handled elsewhere. fsuid == 0 and {r,e,s}uid!= 0 should
* never happen.
*
* -astor
*
* cevans - New behaviour, Oct '99
* A process may, via prctl(), elect to keep its capabilities when it
* calls setuid() and switches away from uid==0. Both permitted and
* effective sets will be retained.
* Without this change, it was impossible for a daemon to drop only some
* of its privilege. The call to setuid(!=0) would drop all privileges!
* Keeping uid 0 is not an option because uid 0 owns too many vital
* files..
* Thanks to Olaf Kirch and Peter Benie for spotting this.
*/
static inline void cap_emulate_setxuid(struct cred *new, const struct cred *old)
{
kuid_t root_uid = make_kuid(old->user_ns, 0);
if ((uid_eq(old->uid, root_uid) ||
uid_eq(old->euid, root_uid) ||
uid_eq(old->suid, root_uid)) &&
(!uid_eq(new->uid, root_uid) &&
!uid_eq(new->euid, root_uid) &&
!uid_eq(new->suid, root_uid))) {
if (!issecure(SECURE_KEEP_CAPS)) {
cap_clear(new->cap_permitted);
cap_clear(new->cap_effective);
}
/*
* Pre-ambient programs expect setresuid to nonroot followed
* by exec to drop capabilities. We should make sure that
* this remains the case.
*/
cap_clear(new->cap_ambient);
}
if (uid_eq(old->euid, root_uid) && !uid_eq(new->euid, root_uid))
cap_clear(new->cap_effective);
if (!uid_eq(old->euid, root_uid) && uid_eq(new->euid, root_uid))
new->cap_effective = new->cap_permitted;
}
/**
* cap_task_fix_setuid - Fix up the results of setuid() call
* @new: The proposed credentials
* @old: The current task's current credentials
* @flags: Indications of what has changed
*
* Fix up the results of setuid() call before the credential changes are
* actually applied, returning 0 to grant the changes, -ve to deny them.
*/
int cap_task_fix_setuid(struct cred *new, const struct cred *old, int flags)
{
switch (flags) {
case LSM_SETID_RE:
case LSM_SETID_ID:
case LSM_SETID_RES:
/* juggle the capabilities to follow [RES]UID changes unless
* otherwise suppressed */
if (!issecure(SECURE_NO_SETUID_FIXUP))
cap_emulate_setxuid(new, old);
break;
case LSM_SETID_FS:
/* juggle the capabilties to follow FSUID changes, unless
* otherwise suppressed
*
* FIXME - is fsuser used for all CAP_FS_MASK capabilities?
* if not, we might be a bit too harsh here.
*/
if (!issecure(SECURE_NO_SETUID_FIXUP)) {
kuid_t root_uid = make_kuid(old->user_ns, 0);
if (uid_eq(old->fsuid, root_uid) && !uid_eq(new->fsuid, root_uid))
new->cap_effective =
cap_drop_fs_set(new->cap_effective);
if (!uid_eq(old->fsuid, root_uid) && uid_eq(new->fsuid, root_uid))
new->cap_effective =
cap_raise_fs_set(new->cap_effective,
new->cap_permitted);
}
break;
default:
return -EINVAL;
}
return 0;
}
/*
* Rationale: code calling task_setscheduler, task_setioprio, and
* task_setnice, assumes that
* . if capable(cap_sys_nice), then those actions should be allowed
* . if not capable(cap_sys_nice), but acting on your own processes,
* then those actions should be allowed
* This is insufficient now since you can call code without suid, but
* yet with increased caps.
* So we check for increased caps on the target process.
*/
static int cap_safe_nice(struct task_struct *p)
{
int is_subset, ret = 0;
rcu_read_lock();
is_subset = cap_issubset(__task_cred(p)->cap_permitted,
current_cred()->cap_permitted);
if (!is_subset && !ns_capable(__task_cred(p)->user_ns, CAP_SYS_NICE))
ret = -EPERM;
rcu_read_unlock();
return ret;
}
/**
* cap_task_setscheduler - Detemine if scheduler policy change is permitted
* @p: The task to affect
*
* Detemine if the requested scheduler policy change is permitted for the
* specified task, returning 0 if permission is granted, -ve if denied.
*/
int cap_task_setscheduler(struct task_struct *p)
{
return cap_safe_nice(p);
}
/**
* cap_task_ioprio - Detemine if I/O priority change is permitted
* @p: The task to affect
* @ioprio: The I/O priority to set
*
* Detemine if the requested I/O priority change is permitted for the specified
* task, returning 0 if permission is granted, -ve if denied.
*/
int cap_task_setioprio(struct task_struct *p, int ioprio)
{
return cap_safe_nice(p);
}
/**
* cap_task_ioprio - Detemine if task priority change is permitted
* @p: The task to affect
* @nice: The nice value to set
*
* Detemine if the requested task priority change is permitted for the
* specified task, returning 0 if permission is granted, -ve if denied.
*/
int cap_task_setnice(struct task_struct *p, int nice)
{
return cap_safe_nice(p);
}
/*
* Implement PR_CAPBSET_DROP. Attempt to remove the specified capability from
* the current task's bounding set. Returns 0 on success, -ve on error.
*/
static int cap_prctl_drop(unsigned long cap)
{
struct cred *new;
if (!ns_capable(current_user_ns(), CAP_SETPCAP))
return -EPERM;
if (!cap_valid(cap))
return -EINVAL;
new = prepare_creds();
if (!new)
return -ENOMEM;
cap_lower(new->cap_bset, cap);
return commit_creds(new);
}
/**
* cap_task_prctl - Implement process control functions for this security module
* @option: The process control function requested
* @arg2, @arg3, @arg4, @arg5: The argument data for this function
*
* Allow process control functions (sys_prctl()) to alter capabilities; may
* also deny access to other functions not otherwise implemented here.
*
* Returns 0 or +ve on success, -ENOSYS if this function is not implemented
* here, other -ve on error. If -ENOSYS is returned, sys_prctl() and other LSM
* modules will consider performing the function.
*/
int cap_task_prctl(int option, unsigned long arg2, unsigned long arg3,
unsigned long arg4, unsigned long arg5)
{
const struct cred *old = current_cred();
struct cred *new;
switch (option) {
case PR_CAPBSET_READ:
if (!cap_valid(arg2))
return -EINVAL;
return !!cap_raised(old->cap_bset, arg2);
case PR_CAPBSET_DROP:
return cap_prctl_drop(arg2);
/*
* The next four prctl's remain to assist with transitioning a
* system from legacy UID=0 based privilege (when filesystem
* capabilities are not in use) to a system using filesystem
* capabilities only - as the POSIX.1e draft intended.
*
* Note:
*
* PR_SET_SECUREBITS =
* issecure_mask(SECURE_KEEP_CAPS_LOCKED)
* | issecure_mask(SECURE_NOROOT)
* | issecure_mask(SECURE_NOROOT_LOCKED)
* | issecure_mask(SECURE_NO_SETUID_FIXUP)
* | issecure_mask(SECURE_NO_SETUID_FIXUP_LOCKED)
*
* will ensure that the current process and all of its
* children will be locked into a pure
* capability-based-privilege environment.
*/
case PR_SET_SECUREBITS:
if ((((old->securebits & SECURE_ALL_LOCKS) >> 1)
& (old->securebits ^ arg2)) /*[1]*/
|| ((old->securebits & SECURE_ALL_LOCKS & ~arg2)) /*[2]*/
|| (arg2 & ~(SECURE_ALL_LOCKS | SECURE_ALL_BITS)) /*[3]*/
|| (cap_capable(current_cred(),
current_cred()->user_ns, CAP_SETPCAP,
SECURITY_CAP_AUDIT) != 0) /*[4]*/
/*
* [1] no changing of bits that are locked
* [2] no unlocking of locks
* [3] no setting of unsupported bits
* [4] doing anything requires privilege (go read about
* the "sendmail capabilities bug")
*/
)
/* cannot change a locked bit */
return -EPERM;
new = prepare_creds();
if (!new)
return -ENOMEM;
new->securebits = arg2;
return commit_creds(new);
case PR_GET_SECUREBITS:
return old->securebits;
case PR_GET_KEEPCAPS:
return !!issecure(SECURE_KEEP_CAPS);
case PR_SET_KEEPCAPS:
if (arg2 > 1) /* Note, we rely on arg2 being unsigned here */
return -EINVAL;
if (issecure(SECURE_KEEP_CAPS_LOCKED))
return -EPERM;
new = prepare_creds();
if (!new)
return -ENOMEM;
if (arg2)
new->securebits |= issecure_mask(SECURE_KEEP_CAPS);
else
new->securebits &= ~issecure_mask(SECURE_KEEP_CAPS);
return commit_creds(new);
case PR_CAP_AMBIENT:
if (arg2 == PR_CAP_AMBIENT_CLEAR_ALL) {
if (arg3 | arg4 | arg5)
return -EINVAL;
new = prepare_creds();
if (!new)
return -ENOMEM;
cap_clear(new->cap_ambient);
return commit_creds(new);
}
if (((!cap_valid(arg3)) | arg4 | arg5))
return -EINVAL;
if (arg2 == PR_CAP_AMBIENT_IS_SET) {
return !!cap_raised(current_cred()->cap_ambient, arg3);
} else if (arg2 != PR_CAP_AMBIENT_RAISE &&
arg2 != PR_CAP_AMBIENT_LOWER) {
return -EINVAL;
} else {
if (arg2 == PR_CAP_AMBIENT_RAISE &&
(!cap_raised(current_cred()->cap_permitted, arg3) ||
!cap_raised(current_cred()->cap_inheritable,
arg3) ||
issecure(SECURE_NO_CAP_AMBIENT_RAISE)))
return -EPERM;
new = prepare_creds();
if (!new)
return -ENOMEM;
if (arg2 == PR_CAP_AMBIENT_RAISE)
cap_raise(new->cap_ambient, arg3);
else
cap_lower(new->cap_ambient, arg3);
return commit_creds(new);
}
default:
/* No functionality available - continue with default */
return -ENOSYS;
}
}
/**
* cap_vm_enough_memory - Determine whether a new virtual mapping is permitted
* @mm: The VM space in which the new mapping is to be made
* @pages: The size of the mapping
*
* Determine whether the allocation of a new virtual mapping by the current
* task is permitted, returning 1 if permission is granted, 0 if not.
*/
int cap_vm_enough_memory(struct mm_struct *mm, long pages)
{
int cap_sys_admin = 0;
if (cap_capable(current_cred(), &init_user_ns, CAP_SYS_ADMIN,
SECURITY_CAP_NOAUDIT) == 0)
cap_sys_admin = 1;
return cap_sys_admin;
}
/*
* cap_mmap_addr - check if able to map given addr
* @addr: address attempting to be mapped
*
* If the process is attempting to map memory below dac_mmap_min_addr they need
* CAP_SYS_RAWIO. The other parameters to this function are unused by the
* capability security module. Returns 0 if this mapping should be allowed
* -EPERM if not.
*/
int cap_mmap_addr(unsigned long addr)
{
int ret = 0;
if (addr < dac_mmap_min_addr) {
ret = cap_capable(current_cred(), &init_user_ns, CAP_SYS_RAWIO,
SECURITY_CAP_AUDIT);
/* set PF_SUPERPRIV if it turns out we allow the low mmap */
if (ret == 0)
current->flags |= PF_SUPERPRIV;
}
return ret;
}
int cap_mmap_file(struct file *file, unsigned long reqprot,
unsigned long prot, unsigned long flags)
{
return 0;
}
#ifdef CONFIG_SECURITY
struct security_hook_list capability_hooks[] __lsm_ro_after_init = {
LSM_HOOK_INIT(capable, cap_capable),
LSM_HOOK_INIT(settime, cap_settime),
LSM_HOOK_INIT(ptrace_access_check, cap_ptrace_access_check),
LSM_HOOK_INIT(ptrace_traceme, cap_ptrace_traceme),
LSM_HOOK_INIT(capget, cap_capget),
LSM_HOOK_INIT(capset, cap_capset),
LSM_HOOK_INIT(bprm_set_creds, cap_bprm_set_creds),
LSM_HOOK_INIT(inode_need_killpriv, cap_inode_need_killpriv),
LSM_HOOK_INIT(inode_killpriv, cap_inode_killpriv),
LSM_HOOK_INIT(inode_getsecurity, cap_inode_getsecurity),
LSM_HOOK_INIT(mmap_addr, cap_mmap_addr),
LSM_HOOK_INIT(mmap_file, cap_mmap_file),
LSM_HOOK_INIT(task_fix_setuid, cap_task_fix_setuid),
LSM_HOOK_INIT(task_prctl, cap_task_prctl),
LSM_HOOK_INIT(task_setscheduler, cap_task_setscheduler),
LSM_HOOK_INIT(task_setioprio, cap_task_setioprio),
LSM_HOOK_INIT(task_setnice, cap_task_setnice),
LSM_HOOK_INIT(vm_enough_memory, cap_vm_enough_memory),
};
void __init capability_add_hooks(void)
{
security_add_hooks(capability_hooks, ARRAY_SIZE(capability_hooks),
"capability");
}
#endif /* CONFIG_SECURITY */