Merge 4.9.228 into android-4.9-q
Linux 4.9.228
perf symbols: Fix debuginfo search for Ubuntu
perf probe: Do not show the skipped events
w1: omap-hdq: cleanup to add missing newline for some dev_dbg
mtd: rawnand: pasemi: Fix the probe error path
mtd: rawnand: brcmnand: fix hamming oob layout
* sunrpc: clean up properly in gss_mech_unregister()
include/linux/sunrpc/gss_api.h
sunrpc: svcauth_gss_register_pseudoflavor must reject duplicate registrations.
* kbuild: force to build vmlinux if CONFIG_MODVERSION=y
Makefile
drivers/macintosh: Fix memleak in windfarm_pm112 driver
ARM: tegra: Correct PL310 Auxiliary Control Register initialization
* kernel/cpu_pm: Fix uninitted local in cpu_pm
kernel/cpu_pm.c
sparc64: fix misuses of access_process_vm() in genregs32_[sg]et()
sparc32: fix register window handling in genregs32_[gs]et()
pinctrl: samsung: Save/restore eint_mask over suspend for EINT_TYPE GPIOs
power: vexpress: add suppress_bind_attrs to true
igb: Report speed and duplex as unknown when device is runtime suspended
b43_legacy: Fix connection problem with WPA3
b43: Fix connection problem with WPA3
b43legacy: Fix case where channel status is corrupted
media: go7007: fix a miss of snd_card_free
carl9170: remove P2P_GO support
e1000e: Relax condition to trigger reset for ME workaround
* PCI: Program MPS for RCiEP devices
drivers/pci/probe.c
* blk-mq: move blk_mq_update_nr_hw_queues synchronize_rcu call
block/blk-mq.c
btrfs: fix error handling when submitting direct I/O bio
* ext4: fix race between ext4_sync_parent() and rename()
fs/ext4/fsync.c
* ext4: fix EXT_MAX_EXTENT/INDEX to check for zeroed eh_max
fs/ext4/ext4_extents.h
evm: Fix possible memory leak in evm_calc_hmac_or_hash()
ima: Directly assign the ima_default_policy pointer to ima_rules
ima: Fix ima digest hash table key calculation
mm: thp: make the THP mapcount atomic against __split_huge_pmd_locked()
btrfs: send: emit file capabilities after chown
* cpuidle: Fix three reference count leaks
drivers/cpuidle/sysfs.c
spi: dw: Return any value retrieved from the dma_transfer callback
mmc: sdhci-esdhc-imx: fix the mask for tuning start point
ixgbe: fix signed-integer-overflow warning
staging: greybus: sdio: Respect the cmd->busy_timeout from the mmc core
MIPS: Fix IRQ tracing when call handle_fpe() and handle_msa_fpe()
* PCI: Don't disable decoding when mmio_always_on is set
drivers/pci/probe.c
macvlan: Skip loopback packets in RX handler
m68k: mac: Don't call via_flush_cache() on Mac IIfx
x86/mm: Stop printing BRK addresses
mips: Add udelay lpj numbers adjustment
x86/boot: Correct relocation destination on old linkers
mwifiex: Fix memory corruption in dump_station
rtlwifi: Fix a double free in _rtl_usb_tx_urb_setup()
md: don't flush workqueue unconditionally in md_open
* kgdb: Fix spurious true from in_dbg_master()
include/linux/kgdb.h
mips: cm: Fix an invalid error code of INTVN_*_ERR
MIPS: Truncate link address into 32bit for 32bit kernel
powerpc/spufs: fix copy_to_user while atomic
net: allwinner: Fix use correct return type for ndo_start_xmit()
net: lpc-enet: fix error return code in lpc_mii_init()
* exit: Move preemption fixup up, move blocking operations down
kernel/exit.c
* lib/mpi: Fix 64-bit MIPS build with Clang
lib/mpi/longlong.h
netfilter: nft_nat: return EOPNOTSUPP if type or flags are not supported
MIPS: Make sparse_init() using top-down allocation
media: platform: fcp: Set appropriate DMA parameters
media: dvb: return -EREMOTEIO on i2c transfer failure.
dt-bindings: display: mediatek: control dpi pins mode to avoid leakage
e1000: Distribute switch variables for initialization
* staging: android: ion: use vmap instead of vm_map_ram
drivers/staging/android/ion/ion_heap.c
net: vmxnet3: fix possible buffer overflow caused by bad DMA value in vmxnet3_get_rss()
* x86/kvm/hyper-v: Explicitly align hcall param for kvm_hyperv_exit
include/uapi/linux/kvm.h
ARM: 8978/1: mm: make act_mm() respect THREAD_SIZE
btrfs: do not ignore error from btrfs_next_leaf() when inserting checksums
clocksource: dw_apb_timer_of: Fix missing clockevent timers
spi: dw: Enable interrupts in accordance with DMA xfer mode
* kgdb: Prevent infinite recursive entries to the debugger
kernel/debug/debug_core.c
* Bluetooth: Add SCO fallback for invalid LMP parameters error
net/bluetooth/hci_event.c
spi: dw: Zero DMA Tx and Rx configurations on stack
net: ena: fix error returning in ena_com_get_hash_function()
objtool: Ignore empty alternatives
media: si2157: Better check for running tuner in init
ACPI: GED: use correct trigger type field in _Exx / _Lxx handling
* media: dvb_frontend: ensure that inital front end status initialized
drivers/media/dvb-core/dvb_frontend.c
include/uapi/linux/dvb/frontend.h
can: kvaser_usb: kvaser_usb_leaf: Fix some info-leaks to USB devices
agp/intel: Reinforce the barrier after GTT updates
* perf: Add cond_resched() to task_function_call()
kernel/events/core.c
* fat: don't allow to mount if the FAT length == 0
fs/fat/inode.c
* mm/slub: fix a memory leak in sysfs_slab_add()
mm/slub.c
* Smack: slab-out-of-bounds in vsscanf
security/smack/smackfs.c
ath9k: Fix general protection fault in ath9k_hif_usb_rx_cb
ath9x: Fix stack-out-of-bounds Write in ath9k_hif_usb_rx_cb
ath9k: Fix use-after-free Write in ath9k_htc_rx_msg
ath9k: Fix use-after-free Read in ath9k_wmi_ctrl_rx
* KVM: arm64: Make vcpu_cp1x() work on Big Endian hosts
arch/arm64/include/asm/kvm_host.h
KVM: MIPS: Fix VPN2_MASK definition for variable cpu_vmbits
KVM: MIPS: Define KVM_ENTRYHI_ASID to cpu_asid_mask(&boot_cpu_data)
KVM: nVMX: Consult only the "basic" exit reason when routing nested exit
KVM: nSVM: leave ASID aside in copy_vmcb_control_area
video: fbdev: w100fb: Fix a potential double free.
* proc: Use new_inode not new_inode_pseudo
fs/proc/inode.c
fs/proc/self.c
fs/proc/thread_self.c
* ovl: initialize error in ovl_copy_xattr
fs/overlayfs/copy_up.c
spi: bcm2835: Fix controller unregister order
spi: pxa2xx: Fix controller unregister order
* spi: Fix controller unregister order
drivers/spi/spi.c
* spi: No need to assign dummy value in spi_unregister_controller()
drivers/spi/spi.c
spi: dw: Fix controller unregister order
spi: dw: fix possible race condition
x86/speculation: PR_SPEC_FORCE_DISABLE enforcement for indirect branches.
x86/speculation: Avoid force-disabling IBPB based on STIBP and enhanced IBRS.
x86/speculation: Add support for STIBP always-on preferred mode
x86/speculation: Change misspelled STIPB to STIBP
* ALSA: pcm: disallow linking stream to itself
sound/core/pcm_native.c
spi: bcm-qspi: when tx/rx buffer is NULL set to 0
spi: bcm2835aux: Fix controller unregister order
nilfs2: fix null pointer dereference at nilfs_segctor_do_construct()
* cgroup, blkcg: Prepare some symbols for module and !CONFIG_CGROUP usages
fs/fs-writeback.c
ACPI: PM: Avoid using power resources if there are none for D0
ACPI: GED: add support for _Exx / _Lxx handler methods
ACPI: CPPC: Fix reference count leak in acpi_cppc_processor_probe()
ACPI: sysfs: Fix reference count leak in acpi_sysfs_add_hotplug_profile()
* ALSA: usb-audio: Fix inconsistent card PM state after resume
sound/usb/card.c
sound/usb/usbaudio.h
ALSA: es1688: Add the missed snd_card_free()
efi/efivars: Add missing kobject_put() in sysfs entry creation error path
x86/reboot/quirks: Add MacBook6,1 reboot quirk
x86/speculation: Prevent rogue cross-process SSBD shutdown
x86/PCI: Mark Intel C620 MROMs as having non-compliant BARs
x86_64: Fix jiffies ODR violation
ath9k_htc: Silence undersized packet warnings
drivers/net/ibmvnic: Update VNIC protocol version reporting
* sched/fair: Don't NUMA balance for kthreads
kernel/sched/fair.c
ARM: 8977/1: ptrace: Fix mask for thumb breakpoint hook
crypto: talitos - fix ECB and CBC algs ivsize
* scsi: return correct blkprep status code in case scsi_init_io() fails.
drivers/scsi/scsi_lib.c
vxlan: Avoid infinite loop when suppressing NS messages with invalid options
* ipv6: fix IPV6_ADDRFORM operation logic
net/ipv6/ipv6_sockglue.c
Merge 4.9.227 into android-4.9-q
Linux 4.9.227
uprobes: ensure that uprobe->offset and ->ref_ctr_offset are properly aligned
iio: vcnl4000: Fix i2c swapped word reading.
x86/speculation: Add Ivy Bridge to affected list
x86/speculation: Add SRBDS vulnerability and mitigation documentation
* x86/speculation: Add Special Register Buffer Data Sampling (SRBDS) mitigation
drivers/base/cpu.c
x86/cpu: Add 'table' argument to cpu_matches()
* x86/cpu: Add a steppings field to struct x86_cpu_id
include/linux/mod_devicetable.h
* nvmem: qfprom: remove incorrect write support
drivers/nvmem/qfprom.c
staging: rtl8712: Fix IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK
tty: hvc_console, fix crashes on parallel open/close
* vt: keyboard: avoid signed integer overflow in k_ascii
drivers/tty/vt/keyboard.c
usb: musb: Fix runtime PM imbalance on error
USB: serial: option: add Telit LE910C1-EUX compositions
USB: serial: usb_wwan: do not resubmit rx urb on fatal errors
USB: serial: qcserial: add DW5816e QDL support
* l2tp: add sk_family checks to l2tp_validate_socket
net/l2tp/l2tp_core.c
vsock: fix timeout in vsock_accept()
NFC: st21nfca: add missed kfree_skb() in an error path
net: usb: qmi_wwan: add Telit LE910C1-EUX composition
* l2tp: do not use inet_hash()/inet_unhash()
net/l2tp/l2tp_ip.c
net/l2tp/l2tp_ip6.c
* devinet: fix memleak in inetdev_init()
net/ipv4/devinet.c
airo: Fix read overflows sending packets
* scsi: ufs: Release clock if DMA map fails
drivers/scsi/ufs/ufshcd.c
slip: not call free_netdev before rtnl_unlock in slip_open
slcan: Fix double-free on slcan_open() error path
* mmc: fix compilation of user API
include/uapi/linux/mmc/ioctl.h
kernel/relay.c: handle alloc_percpu returning NULL in relay_open
p54usb: add AirVasT USB stick device-id
HID: i2c-hid: add Schneider SCL142ALM to descriptor override
* mm: Fix mremap not considering huge pmd devmap
mm/mremap.c
* pppoe: only process PADT targeted at local interfaces
drivers/net/ppp/pppoe.c
net: smsc911x: Fix runtime PM imbalance on error
net: ethernet: stmmac: Enable interface clocks on probe for IPQ806x
net/ethernet/freescale: rework quiesce/activate for ucc_geth
net: bmac: Fix read of MAC address from ROM
x86/mmiotrace: Use cpumask_available() for cpumask_var_t variables
ARC: Fix ICCM & DCCM runtime size checks
s390/ftrace: save traced function caller
spi: dw: use "smp_mb()" to avoid sending spi data error
* esp6: fix memleak on error path in esp6_input
net/ipv6/esp6.c
usb: gadget: f_uac2: fix error handling in afunc_bind (again)
* scsi: scsi_devinfo: fixup string compare
drivers/scsi/scsi_devinfo.c
Merge 4.9.226 into android-4.9-q
Linux 4.9.226
scsi: zfcp: fix request object use-after-free in send path causing wrong traces
net: hns: Fixes the missing put_device in positive leg for roce reset
sc16is7xx: move label 'err_spi' to correct section
* mm/vmalloc.c: don't dereference possible NULL pointer in __vunmap()
mm/vmalloc.c
* net: rtnl_configure_link: fix dev flags changes arg to __dev_notify_flags
net/core/rtnetlink.c
genirq/generic_pending: Do not lose pending affinity update
* netfilter: nf_conntrack_pptp: fix compilation warning with W=1 build
include/linux/netfilter/nf_conntrack_pptp.h
net/netfilter/nf_conntrack_pptp.c
* bonding: Fix reference count leak in bond_sysfs_slave_add.
drivers/net/bonding/bond_sysfs_slave.c
qlcnic: fix missing release in qlcnic_83xx_interrupt_test.
* netfilter: nf_conntrack_pptp: prevent buffer overflows in debug code
include/linux/netfilter/nf_conntrack_pptp.h
net/ipv4/netfilter/nf_nat_pptp.c
net/netfilter/nf_conntrack_pptp.c
netfilter: ipset: Fix subcounter update skip
netfilter: nft_reject_bridge: enable reject with bridge vlan
* ip_vti: receive ipip packet by calling ip_tunnel_rcv
net/ipv4/ip_vti.c
* vti4: eliminated some duplicate code.
net/ipv4/ip_vti.c
* xfrm: fix a NULL-ptr deref in xfrm_local_error
net/xfrm/xfrm_output.c
* xfrm: fix a warning in xfrm_policy_insert_list
net/xfrm/xfrm_policy.c
* xfrm: allow to accept packets with ipv6 NEXTHDR_HOP in xfrm_input
net/xfrm/xfrm_input.c
x86/dma: Fix max PFN arithmetic overflow on 32 bit systems
mac80211: mesh: fix discovery timer re-arming issue / crash
parisc: Fix kernel panic in mem_init()
* iommu: Fix reference count leak in iommu_group_alloc.
drivers/iommu/iommu.c
* include/asm-generic/topology.h: guard cpumask_of_node() macro argument
include/asm-generic/topology.h
* fs/binfmt_elf.c: allocate initialized memory in fill_thread_core_info()
fs/binfmt_elf.c
* mm: remove VM_BUG_ON(PageSlab()) from page_mapcount()
include/linux/mm.h
libceph: ignore pool overlay and cache logic on redirects
* exec: Always set cap_ambient in cap_bprm_set_creds
security/commoncap.c
* ALSA: usb-audio: mixer: volume quirk for ESS Technology Asus USB DAC
sound/usb/mixer.c
* ALSA: hwdep: fix a left shifting 1 by 31 UB bug
sound/core/hwdep.c
ARM: dts/imx6q-bx50v3: Set display interface clock parents
ARM: dts: imx6q-bx50v3: Add internal switch
ARM: dts: imx: Correct B850v3 clock assignment
IB/qib: Call kobject_put() when kobject_init_and_add() fails
Input: synaptics-rmi4 - fix error return code in rmi_driver_probe()
Input: i8042 - add ThinkPad S230u to i8042 reset list
* Input: xpad - add custom init packet for Xbox One S controllers
drivers/input/joystick/xpad.c
* Input: evdev - call input_flush_device() on release(), not flush()
drivers/input/evdev.c
Input: usbtouchscreen - add support for BonXeon TP
cifs: Fix null pointer check in cifs_read
usb: gadget: legacy: fix redundant initialization warnings
cachefiles: Fix race between read_waiter and read_copier involving op->to_do
gfs2: move privileged user check to gfs2_quota_lock_check
net: microchip: encx24j600: add missed kthread_stop
gpio: tegra: mask GPIO IRQs during IRQ shutdown
IB/cma: Fix reference count leak when no ipv4 addresses are set
* uapi: fix linux/if_pppol2tp.h userspace compilation errors
include/uapi/linux/l2tp.h
net/mlx4_core: fix a memory leak bug.
net: sun: fix missing release regions in cas_init_one().
net/mlx5: Add command entry handling completion
net: qrtr: Fix passing invalid reference to qrtr_local_enqueue()
net/mlx5e: Update netdev txq on completions during closure
sctp: Start shutdown on association restart if in SHUTDOWN-SENT state and socket is closed
* net sched: fix reporting the first-time use timestamp
include/net/act_api.h
* net: revert "net: get rid of an signed integer overflow in ip_idents_reserve()"
net/ipv4/route.c
net: ipip: fix wrong address family in init error path
ax25: fix setsockopt(SO_BINDTODEVICE)
ANDROID: cuttlefish defconfig - enable mount/net/uts namespaces.
Merge 4.9.225 into android-4.9-q
Linux 4.9.225
iio: sca3000: Remove an erroneous 'get_device()'
rapidio: fix an error in get_user_pages_fast() error handling
mei: release me_cl object reference
iio: dac: vf610: Fix an error handling path in 'vf610_dac_probe()'
staging: greybus: Fix uninitialized scalar variable
staging: iio: ad2s1210: Fix SPI reading
Revert "gfs2: Don't demote a glock until its revokes are written"
cxgb4/cxgb4vf: Fix mac_hlist initialization and free
cxgb4: free mac_hlist properly
libnvdimm/btt: Remove unnecessary code in btt_freelist_init
platform/x86: alienware-wmi: fix kfree on potentially uninitialized pointer
* ubsan: build ubsan.c more conservatively
lib/Makefile
* x86/uaccess, ubsan: Fix UBSAN vs. SMAP
lib/Makefile
* l2tp: device MTU setup, tunnel socket needs a lock
include/linux/net.h
net/l2tp/l2tp_eth.c
net/socket.c
dmaengine: tegra210-adma: Fix an error handling path in 'tegra_adma_probe()'
* ALSA: pcm: fix incorrect hw_base increase
sound/core/pcm_lib.c
* l2tp: initialise PPP sessions before registering them
net/l2tp/l2tp_ppp.c
* l2tp: protect sock pointer of struct pppol2tp_session with RCU
net/l2tp/l2tp_ppp.c
* l2tp: initialise l2tp_eth sessions before registering them
net/l2tp/l2tp_eth.c
* l2tp: don't register sessions in l2tp_session_create()
net/l2tp/l2tp_core.c
net/l2tp/l2tp_core.h
net/l2tp/l2tp_eth.c
net/l2tp/l2tp_ppp.c
* l2tp: fix l2tp_eth module loading
net/l2tp/l2tp_eth.c
* l2tp: pass tunnel pointer to ->session_create()
net/l2tp/l2tp_core.h
net/l2tp/l2tp_eth.c
net/l2tp/l2tp_netlink.c
net/l2tp/l2tp_ppp.c
* l2tp: prevent creation of sessions on terminated tunnels
net/l2tp/l2tp_core.c
net/l2tp/l2tp_core.h
* l2tp: hold tunnel used while creating sessions with netlink
net/l2tp/l2tp_netlink.c
* l2tp: hold tunnel while handling genl TUNNEL_GET commands
net/l2tp/l2tp_netlink.c
* l2tp: hold tunnel while handling genl tunnel updates
net/l2tp/l2tp_netlink.c
* l2tp: hold tunnel while processing genl delete command
net/l2tp/l2tp_netlink.c
* l2tp: hold tunnel while looking up sessions in l2tp_netlink
net/l2tp/l2tp_core.c
net/l2tp/l2tp_core.h
net/l2tp/l2tp_netlink.c
* l2tp: initialise session's refcount before making it reachable
net/l2tp/l2tp_core.c
* l2tp: define parameters of l2tp_tunnel_find*() as "const"
net/l2tp/l2tp_core.c
net/l2tp/l2tp_core.h
* l2tp: define parameters of l2tp_session_get*() as "const"
net/l2tp/l2tp_core.c
net/l2tp/l2tp_core.h
* l2tp: remove l2tp_session_find()
net/l2tp/l2tp_core.c
net/l2tp/l2tp_core.h
* l2tp: remove useless duplicate session detection in l2tp_netlink
net/l2tp/l2tp_netlink.c
* L2TP:Adjust intf MTU, add underlay L3, L2 hdrs.
net/l2tp/l2tp_eth.c
* New kernel function to get IP overhead on a socket.
include/linux/net.h
net/socket.c
* net: l2tp: ppp: change PPPOL2TP_MSG_* => L2TP_MSG_*
net/l2tp/l2tp_ppp.c
* net: l2tp: deprecate PPPOL2TP_MSG_* in favour of L2TP_MSG_*
include/uapi/linux/if_pppol2tp.h
* net: l2tp: export debug flags to UAPI
include/uapi/linux/l2tp.h
net/l2tp/l2tp_core.h
* watchdog: Fix the race between the release of watchdog_core_data and cdev
drivers/watchdog/watchdog_dev.c
arm64: fix the flush_icache_range arguments in machine_kexec
padata: purge get_cpu and reorder_via_wq from padata_do_serial
padata: initialize pd->cpu with effective cpumask
padata: Replace delayed timer with immediate workqueue in padata_reorder
padata: set cpu_index of unused CPUs to -1
* i2c: dev: Fix the race between the release of i2c_dev and cdev
drivers/i2c/i2c-dev.c
ARM: futex: Address build warning
platform/x86: asus-nb-wmi: Do not load on Asus T100TA and T200TA
* USB: core: Fix misleading driver bug report
drivers/usb/core/message.c
ceph: fix double unlock in handle_cap_export()
gtp: set NLM_F_MULTI flag in gtp_genl_dump_pdp()
* component: Silence bind error on -EPROBE_DEFER
drivers/base/component.c
* configfs: fix config_item refcnt leak in configfs_rmdir()
fs/configfs/dir.c
* HID: multitouch: add eGalaxTouch P80H84 support
drivers/hid/hid-ids.h
drivers/hid/hid-multitouch.c
* gcc-common.h: Update for GCC 10
scripts/gcc-plugins/Makefile
i2c: mux: demux-pinctrl: Fix an error handling path in 'i2c_demux_pinctrl_probe()'
iommu/amd: Fix over-read of ACPI UID from IVRS table
* fix multiplication overflow in copy_fdtable()
fs/file.c
ima: Fix return value of ima_write_policy()
evm: Check also if *tfm is an error pointer in init_desc()
padata: ensure padata_do_serial() runs on the correct CPU
padata: ensure the reorder timer callback runs on the correct CPU
padata: get_next is never NULL
padata: Remove unused but set variables
igb: use igb_adapter->io_addr instead of e1000_hw->hw_addr
Merge 4.9.224 into android-4.9-q
Linux 4.9.224
* Makefile: disallow data races on gcc-10 as well
Makefile
KVM: x86: Fix off-by-one error in kvm_vcpu_ioctl_x86_setup_mce
ARM: dts: r8a7740: Add missing extal2 to CPG node
ARM: dts: r8a73a4: Add missing CMT1 interrupts
Revert "ALSA: hda/realtek: Fix pop noise on ALC225"
usb: gadget: legacy: fix error return code in cdc_bind()
usb: gadget: legacy: fix error return code in gncm_bind()
usb: gadget: audio: Fix a missing error return value in audio_bind()
usb: gadget: net2272: Fix a memory leak in an error handling path in 'net2272_plat_probe()'
* exec: Move would_dump into flush_old_exec
fs/exec.c
* x86: Fix early boot crash on gcc-10, third try
include/linux/compiler.h
init/main.c
ARM: dts: imx27-phytec-phycard-s-rdk: Fix the I2C1 pinctrl entries
* usb: xhci: Fix NULL pointer dereference when enqueuing trbs from urb sg list
drivers/usb/host/xhci-ring.c
* USB: gadget: fix illegal array access in binding with UDC
drivers/usb/gadget/configfs.c
* ALSA: usb-audio: Add control message quirk delay for Kingston HyperX headset
sound/usb/quirks.c
* ALSA: rawmidi: Fix racy buffer resize under concurrent accesses
include/sound/rawmidi.h
sound/core/rawmidi.c
* ALSA: rawmidi: Initialize allocated buffers
sound/core/rawmidi.c
ALSA: hda/realtek - Limit int mic boost for Thinkpad T530
netprio_cgroup: Fix unlimited memory leak of v2 cgroups
* net: ipv4: really enforce backoff for redirects
net/ipv4/route.c
* Revert "ipv6: add mtu lock check in __ip6_rt_update_pmtu"
net/ipv6/route.c
* netlabel: cope with NULL catmap
net/ipv4/cipso_ipv4.c
net/ipv6/calipso.c
net/netlabel/netlabel_kapi.c
* net: fix a potential recursive NETDEV_FEAT_CHANGE
net/core/dev.c
* gcc-10: disable 'restrict' warning for now
Makefile
* gcc-10: disable 'stringop-overflow' warning for now
Makefile
* gcc-10: disable 'array-bounds' warning for now
Makefile
* gcc-10: disable 'zero-length-bounds' warning for now
Makefile
* gcc-10: avoid shadowing standard library 'free()' in crypto
crypto/xts.c
net: phy: micrel: Use strlcpy() for ethtool::get_strings
* Stop the ad-hoc games with -Wno-maybe-initialized
Makefile
init/Kconfig
kernel/trace/Kconfig
* kbuild: compute false-positive -Wmaybe-uninitialized cases in Kconfig
Makefile
init/Kconfig
kernel/trace/Kconfig
* gcc-10 warnings: fix low-hanging fruit
include/linux/fs.h
include/linux/tty.h
pnp: Use list_for_each_entry() instead of open coding
IB/mlx4: Test return value of calls to ib_get_cached_pkey
* netfilter: conntrack: avoid gcc-10 zero-length-bounds warning
include/net/netfilter/nf_conntrack.h
net/netfilter/nf_conntrack_core.c
i40iw: Fix error handling in i40iw_manage_arp_cache()
pinctrl: cherryview: Add missing spinlock usage in chv_gpio_irq_handler
ipc/util.c: sysvipc_find_ipc() incorrectly updates position index
drm/qxl: lost qxl_bo_kunmap_atomic_page in qxl_image_init_helper()
ALSA: hda/hdmi: fix race in monitor detection during probe
dmaengine: mmp_tdma: Reset channel error on release
dmaengine: pch_dma.c: Avoid data race between probe and irq handler
cifs: Fix a race condition with cifs_echo_request
cifs: Check for timeout on Negotiate stage
spi: spi-dw: Add lock protect dw_spi rx/tx to prevent concurrent calls
* scsi: sg: add sg_remove_request in sg_write
drivers/scsi/sg.c
drop_monitor: work around gcc-10 stringop-overflow warning
net: moxa: Fix a potential double 'free_irq()'
net/sonic: Fix a resource leak in an error handling path in 'jazz_sonic_probe()'
* shmem: fix possible deadlocks on shmlock_user_lock
mm/shmem.c
ptp: free ptp device pin descriptors properly
* ptp: fix the race between the release of ptp_clock and cdev
include/linux/posix-clock.h
kernel/time/posix-clock.c
ptp: Fix pass zero to ERR_PTR() in ptp_clock_register
* chardev: add helper function to register char devs with a struct device
fs/char_dev.c
include/linux/cdev.h
ptp: create "pins" together with the rest of attributes
ptp: use is_visible method to hide unused attributes
ptp: do not explicitly set drvdata in ptp_clock_register()
* blktrace: fix dereference after null check
kernel/trace/blktrace.c
* blktrace: Protect q->blk_trace with RCU
include/linux/blkdev.h
include/linux/blktrace_api.h
kernel/trace/blktrace.c
* blktrace: fix trace mutex deadlock
kernel/trace/blktrace.c
* blktrace: fix unlocked access to init/start-stop/teardown
kernel/trace/blktrace.c
* blktrace: Fix potential deadlock between delete & sysfs ops
block/blk-core.c
include/linux/blkdev.h
kernel/trace/blktrace.c
* net: ipv6_stub: use ip6_dst_lookup_flow instead of ip6_dst_lookup
include/net/addrconf.h
net/ipv6/addrconf_core.c
net/ipv6/af_inet6.c
* net: ipv6: add net argument to ip6_dst_lookup_flow
include/net/ipv6.h
net/ipv6/af_inet6.c
net/ipv6/datagram.c
net/ipv6/inet6_connection_sock.c
net/ipv6/ip6_output.c
net/ipv6/raw.c
net/ipv6/tcp_ipv6.c
net/l2tp/l2tp_ip6.c
* ext4: add cond_resched() to ext4_protect_reserved_inode
fs/ext4/block_validity.c
* binfmt_elf: Do not move brk for INTERP-less ET_EXEC
fs/binfmt_elf.c
scripts/decodecode: fix trapping instruction formatting
objtool: Fix stack offset tracking for indirect CFAs
batman-adv: Fix refcnt leak in batadv_v_ogm_process
batman-adv: Fix refcnt leak in batadv_store_throughput_override
batman-adv: Fix refcnt leak in batadv_show_throughput_override
batman-adv: fix batadv_nc_random_weight_tq
* mm/page_alloc: fix watchdog soft lockups during set_zone_contiguous()
mm/page_alloc.c
* tracing: Add a vmalloc_sync_mappings() for safe measure
kernel/trace/trace.c
USB: serial: garmin_gps: add sanity checking for data length
USB: uas: add quirk for LaCie 2Big Quadra
* binfmt_elf: move brk out of mmap when doing direct loader exec
fs/binfmt_elf.c
Revert "ACPI / video: Add force_native quirk for HP Pavilion dv6"
bnxt_en: Improve AER slot reset.
net/mlx5: Fix command entry leak in Internal Error State
net/mlx5: Fix forced completion access non initialized command entry
bnxt_en: Fix VLAN acceleration handling in bnxt_fix_features().
sch_sfq: validate silly quantum values
sch_choke: avoid potential panic in choke_reset()
net: usb: qmi_wwan: add support for DW5816e
net/mlx4_core: Fix use of ENOSPC around mlx4_counter_alloc()
net: macsec: preserve ingress frame ordering
* fq_codel: fix TCA_FQ_CODEL_DROP_BATCH_SIZE sanity checks
net/sched/sch_fq_codel.c
dp83640: reverse arguments to list_add_tail
USB: serial: qcserial: Add DW5816e support
* ANDROID: hid: steam: remove BT controller matching
drivers/hid/hid-core.c
drivers/hid/hid-ids.h
* UPSTREAM: HID: steam: Fix input device disappearing
drivers/hid/hid-steam.c
Change-Id: I03104a17738ef3d28a296ca370185f58396c9262
Signed-off-by: lucaswei <lucaswei@google.com>
1126 lines
32 KiB
C
1126 lines
32 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>
|
|
|
|
#ifdef CONFIG_ANDROID_PARANOID_NETWORK
|
|
#include <linux/android_aid.h>
|
|
#endif
|
|
|
|
/*
|
|
* 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;
|
|
|
|
/* 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;
|
|
|
|
/* Have we tried all of the parent namespaces? */
|
|
if (ns == &init_user_ns)
|
|
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)
|
|
{
|
|
int ret = __cap_capable(cred, targ_ns, cap, audit);
|
|
|
|
#ifdef CONFIG_ANDROID_PARANOID_NETWORK
|
|
if (ret != 0 && cap == CAP_NET_RAW && in_egroup_p(AID_NET_RAW)) {
|
|
printk("Process %s granted CAP_NET_RAW from Android group net_raw.\n", current->comm);
|
|
printk(" Please update the .rc file to explictly set 'capabilities NET_RAW'\n");
|
|
printk(" Implicit grants are deprecated and will be removed in the future.\n");
|
|
return 0;
|
|
}
|
|
if (ret != 0 && cap == CAP_NET_ADMIN && in_egroup_p(AID_NET_ADMIN)) {
|
|
printk("Process %s granted CAP_NET_ADMIN from Android group net_admin.\n", current->comm);
|
|
printk(" Please update the .rc file to explictly set 'capabilities NET_ADMIN'\n");
|
|
printk(" Implicit grants are deprecated and will be removed in the future.\n");
|
|
return 0;
|
|
}
|
|
#endif
|
|
return ret;
|
|
}
|
|
/**
|
|
* 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;
|
|
}
|
|
|
|
/*
|
|
* Clear proposed capability sets for execve().
|
|
*/
|
|
static inline void bprm_clear_caps(struct linux_binprm *bprm)
|
|
{
|
|
cap_clear(bprm->cred->cap_permitted);
|
|
bprm->cap_effective = false;
|
|
}
|
|
|
|
/**
|
|
* 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 0 if granted; +ve if granted, but inode_killpriv() is required; and
|
|
* -ve to deny the change.
|
|
*/
|
|
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;
|
|
}
|
|
|
|
/*
|
|
* 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_cap_data caps;
|
|
|
|
memset(cpu_caps, 0, sizeof(struct cpu_vfs_cap_data));
|
|
|
|
if (!inode)
|
|
return -ENODATA;
|
|
|
|
size = __vfs_getxattr((struct dentry *)dentry, inode,
|
|
XATTR_NAME_CAPS, &caps, 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);
|
|
|
|
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;
|
|
default:
|
|
return -EINVAL;
|
|
}
|
|
|
|
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;
|
|
|
|
bprm_clear_caps(bprm);
|
|
|
|
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 "%s: get_vfs_caps_from_disk returned %d for %s\n",
|
|
__func__, rc, 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)
|
|
bprm_clear_caps(bprm);
|
|
|
|
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_CAP) {
|
|
/* downgrade; they get no more than they had, and maybe less */
|
|
if (!capable(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;
|
|
|
|
bprm->cap_effective = effective;
|
|
|
|
/*
|
|
* 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;
|
|
|
|
return 0;
|
|
}
|
|
|
|
/**
|
|
* cap_bprm_secureexec - Determine whether a secure execution is required
|
|
* @bprm: The execution parameters
|
|
*
|
|
* Determine whether a secure execution is required, return 1 if it is, and 0
|
|
* if it is not.
|
|
*
|
|
* The credentials have been committed by this point, and so are no longer
|
|
* available through @bprm->cred.
|
|
*/
|
|
int cap_bprm_secureexec(struct linux_binprm *bprm)
|
|
{
|
|
const struct cred *cred = current_cred();
|
|
kuid_t root_uid = make_kuid(cred->user_ns, 0);
|
|
|
|
if (!uid_eq(cred->uid, root_uid)) {
|
|
if (bprm->cap_effective)
|
|
return 1;
|
|
if (!cap_issubset(cred->cap_permitted, cred->cap_ambient))
|
|
return 1;
|
|
}
|
|
|
|
return (!uid_eq(cred->euid, cred->uid) ||
|
|
!gid_eq(cred->egid, cred->gid));
|
|
}
|
|
|
|
/**
|
|
* 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)
|
|
{
|
|
if (!strcmp(name, XATTR_NAME_CAPS)) {
|
|
if (!capable(CAP_SETFCAP))
|
|
return -EPERM;
|
|
return 0;
|
|
}
|
|
|
|
if (!strncmp(name, XATTR_SECURITY_PREFIX,
|
|
sizeof(XATTR_SECURITY_PREFIX) - 1) &&
|
|
!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)
|
|
{
|
|
if (!strcmp(name, XATTR_NAME_CAPS)) {
|
|
if (!capable(CAP_SETFCAP))
|
|
return -EPERM;
|
|
return 0;
|
|
}
|
|
|
|
if (!strncmp(name, XATTR_SECURITY_PREFIX,
|
|
sizeof(XATTR_SECURITY_PREFIX) - 1) &&
|
|
!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(bprm_secureexec, cap_bprm_secureexec),
|
|
LSM_HOOK_INIT(inode_need_killpriv, cap_inode_need_killpriv),
|
|
LSM_HOOK_INIT(inode_killpriv, cap_inode_killpriv),
|
|
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));
|
|
}
|
|
|
|
#endif /* CONFIG_SECURITY */
|