https://source.android.com/docs/security/bulletin/2023-04-01 CVE-2022-4696 CVE-2023-20941 * tag 'ASB-2023-04-05_11-5.4' of https://android.googlesource.com/kernel/common: UPSTREAM: ext4: fix kernel BUG in 'ext4_write_inline_data_end()' UPSTREAM: hid: bigben_probe(): validate report count UPSTREAM: HID: bigben: use spinlock to safely schedule workers BACKPORT: of: base: Skip CPU nodes with "fail"/"fail-..." status UPSTREAM: HID: bigben_worker() remove unneeded check on report_field UPSTREAM: HID: bigben: use spinlock to protect concurrent accesses UPSTREAM: hwrng: virtio - add an internal buffer UPSTREAM: ext4: fix another off-by-one fsmap error on 1k block filesystems UPSTREAM: ext4: refuse to create ea block when umounted UPSTREAM: ext4: optimize ea_inode block expansion UPSTREAM: ext4: allocate extended attribute value in vmalloc area BACKPORT: FROMGIT: cgroup: Use separate src/dst nodes when preloading css_sets for migration Revert "iommu: Add gfp parameter to iommu_ops::map" Revert "iommu/amd: Pass gfp flags to iommu_map_page() in amd_iommu_map()" Revert "RDMA/usnic: use iommu_map_atomic() under spin_lock()" Linux 5.4.233 bpf: add missing header file include Revert "net/sched: taprio: make qdisc_leaf() see the per-netdev-queue pfifo child qdiscs" ext4: Fix function prototype mismatch for ext4_feat_ktype wifi: mwifiex: Add missing compatible string for SD8787 uaccess: Add speculation barrier to copy_from_user() mac80211: mesh: embedd mesh_paths and mpp_paths into ieee80211_if_mesh drm/i915/gvt: fix double free bug in split_2MB_gtt_entry alarmtimer: Prevent starvation by small intervals and SIG_IGN powerpc: dts: t208x: Disable 10G on MAC1 and MAC2 can: kvaser_usb: hydra: help gcc-13 to figure out cmd_len KVM: VMX: Execute IBPB on emulated VM-exit when guest has IBRS KVM: x86: Fail emulation during EMULTYPE_SKIP on any exception random: always mix cycle counter in add_latent_entropy() powerpc: dts: t208x: Mark MAC1 and MAC2 as 10G wifi: rtl8xxxu: gen2: Turn on the rate control drm/etnaviv: don't truncate physical page address drm: etnaviv: fix common struct sg_table related issues scatterlist: add generic wrappers for iterating over sgtable objects dma-mapping: add generic helpers for mapping sgtable objects Linux 5.4.232 iommu/amd: Pass gfp flags to iommu_map_page() in amd_iommu_map() net: sched: sch: Fix off by one in htb_activate_prios() ASoC: SOF: Intel: hda-dai: fix possible stream_tag leak nilfs2: fix underflow in second superblock position calculations kvm: initialize all of the kvm_debugregs structure before sending it to userspace i40e: Add checking for null for nlmsg_find_attr() ipv6: Fix tcp socket connection with DSCP. ipv6: Fix datagram socket connection with DSCP. ixgbe: add double of VLAN header when computing the max MTU net: mpls: fix stale pointer if allocation fails during device rename net: stmmac: Restrict warning on disabling DMA store and fwd mode bnxt_en: Fix mqprio and XDP ring checking logic net: stmmac: fix order of dwmac5 FlexPPS parametrization sequence net/usb: kalmia: Don't pass act_len in usb_bulk_msg error path dccp/tcp: Avoid negative sk_forward_alloc by ipv6_pinfo.pktoptions. sctp: sctp_sock_filter(): avoid list_entry() on possibly empty list net: bgmac: fix BCM5358 support by setting correct flags i40e: add double of VLAN header when computing the max MTU ixgbe: allow to increase MTU to 3K with XDP enabled revert "squashfs: harden sanity check in squashfs_read_xattr_id_table" net: Fix unwanted sign extension in netdev_stats_to_stats64() Revert "mm: Always release pages to the buddy allocator in memblock_free_late()." hugetlb: check for undefined shift on 32 bit architectures sched/psi: Fix use-after-free in ep_remove_wait_queue() ALSA: hda/realtek - fixed wrong gpio assigned ALSA: hda/conexant: add a new hda codec SN6180 mmc: mmc_spi: fix error handling in mmc_spi_probe() mmc: sdio: fix possible resource leaks in some error paths ipv4: Fix incorrect route flushing when source address is deleted Revert "ipv4: Fix incorrect route flushing when source address is deleted" xfs: sync lazy sb accounting on quiesce of read-only mounts xfs: prevent UAF in xfs_log_item_in_current_chkpt xfs: fix the forward progress assertion in xfs_iwalk_run_callbacks xfs: ensure inobt record walks always make forward progress xfs: fix missing CoW blocks writeback conversion retry xfs: only relog deferred intent items if free space in the log gets low xfs: expose the log push threshold xfs: periodically relog deferred intent items xfs: change the order in which child and parent defer ops are finished xfs: fix an incore inode UAF in xfs_bui_recover xfs: clean up xfs_bui_item_recover iget/trans_alloc/ilock ordering xfs: clean up bmap intent item recovery checking xfs: xfs_defer_capture should absorb remaining transaction reservation xfs: xfs_defer_capture should absorb remaining block reservations xfs: proper replay of deferred ops queued during log recovery xfs: fix finobt btree block recovery ordering xfs: log new intent items created as part of finishing recovered intent items xfs: refactor xfs_defer_finish_noroll xfs: turn dfp_intent into a xfs_log_item xfs: merge the ->diff_items defer op into ->create_intent xfs: merge the ->log_item defer op into ->create_intent xfs: factor out a xfs_defer_create_intent helper xfs: remove the xfs_inode_log_item_t typedef xfs: remove the xfs_efd_log_item_t typedef xfs: remove the xfs_efi_log_item_t typedef netfilter: nft_tproxy: restrict to prerouting hook btrfs: free device in btrfs_close_devices for a single device filesystem aio: fix mremap after fork null-deref nvme-fc: fix a missing queue put in nvmet_fc_ls_create_association s390/decompressor: specify __decompress() buf len to avoid overflow net: sched: sch: Bounds check priority net: stmmac: do not stop RX_CLK in Rx LPI state for qcs404 SoC net/rose: Fix to not accept on connected socket tools/virtio: fix the vringh test for virtio ring changes ASoC: cs42l56: fix DT probe selftests/bpf: Verify copy_register_state() preserves parent/live fields migrate: hugetlb: check for hugetlb shared PMD in node migration bpf: Always return target ifindex in bpf_fib_lookup nvme-pci: Move enumeration by class to be last in the table arm64: dts: meson-axg: Make mmc host controller interrupts level-sensitive arm64: dts: meson-g12-common: Make mmc host controller interrupts level-sensitive arm64: dts: meson-gx: Make mmc host controller interrupts level-sensitive riscv: Fixup race condition on PG_dcache_clean in flush_icache_pte ceph: flush cap releases when the session is flushed usb: typec: altmodes/displayport: Fix probe pin assign check usb: core: add quirk for Alcor Link AK9563 smartcard reader net: USB: Fix wrong-direction WARNING in plusb.c pinctrl: intel: Restore the pins that used to be in Direct IRQ mode pinctrl: single: fix potential NULL dereference pinctrl: aspeed: Fix confusing types in return value ALSA: pci: lx6464es: fix a debug loop selftests: forwarding: lib: quote the sysctl values rds: rds_rm_zerocopy_callback() use list_first_entry() ice: Do not use WQ_MEM_RECLAIM flag for workqueue ionic: clean interrupt before enabling queue to avoid credit race net: phy: meson-gxl: use MMD access dummy stubs for GXL, internal PHY bonding: fix error checking in bond_debug_reregister() xfrm: fix bug with DSCP copy to v6 from v4 tunnel RDMA/usnic: use iommu_map_atomic() under spin_lock() iommu: Add gfp parameter to iommu_ops::map IB/IPoIB: Fix legacy IPoIB due to wrong number of queues IB/hfi1: Restore allocated resources on failed copyout can: j1939: do not wait 250 ms if the same addr was already claimed tracing: Fix poll() and select() do not work on per_cpu trace_pipe and trace_pipe_raw ALSA: emux: Avoid potential array out-of-bound in snd_emux_xg_control() btrfs: zlib: zero-initialize zlib workspace btrfs: limit device extents to the device size iio:adc:twl6030: Enable measurement of VAC wifi: brcmfmac: Check the count value of channel spec to prevent out-of-bounds reads f2fs: fix to do sanity check on i_extra_isize in is_alive() fbdev: smscufx: fix error handling code in ufx_usb_probe powerpc/imc-pmu: Revert nest_init_lock to being a mutex serial: 8250_dma: Fix DMA Rx rearm race serial: 8250_dma: Fix DMA Rx completion race xprtrdma: Fix regbuf data not freed in rpcrdma_req_create() mm: swap: properly update readahead statistics in unuse_pte_range() nvmem: core: fix cell removal on error Squashfs: fix handling and sanity checking of xattr_ids count mm/swapfile: add cond_resched() in get_swap_pages() fpga: stratix10-soc: Fix return value check in s10_ops_write_init() mm: hugetlb: proc: check for hugetlb shared PMD in /proc/PID/smaps riscv: disable generation of unwind tables parisc: Wire up PTRACE_GETREGS/PTRACE_SETREGS for compat case parisc: Fix return code of pdc_iodc_print() iio:adc:twl6030: Enable measurements of VUSB, VBAT and others iio: adc: berlin2-adc: Add missing of_node_put() in error path iio: hid: fix the retval in accel_3d_capture_sample efi: Accept version 2 of memory attributes table watchdog: diag288_wdt: fix __diag288() inline assembly watchdog: diag288_wdt: do not use stack buffers for hardware data fbcon: Check font dimension limits Input: i8042 - add Clevo PCX0DX to i8042 quirk table Input: i8042 - add TUXEDO devices to i8042 quirk tables Input: i8042 - merge quirk tables Input: i8042 - move __initconst to fix code styling warning vc_screen: move load of struct vc_data pointer in vcs_read() to avoid UAF usb: gadget: f_fs: Fix unbalanced spinlock in __ffs_ep0_queue_wait usb: dwc3: qcom: enable vbus override when in OTG dr-mode usb: dwc3: dwc3-qcom: Fix typo in the dwc3 vbus override API iio: adc: stm32-dfsdm: fill module aliases net/x25: Fix to not accept on connected socket i2c: rk3x: fix a bunch of kernel-doc warnings scsi: iscsi_tcp: Fix UAF during login when accessing the shost ipaddress scsi: target: core: Fix warning on RT kernels efi: fix potential NULL deref in efi_mem_reserve_persistent net: openvswitch: fix flow memory leak in ovs_flow_cmd_new virtio-net: Keep stop() to follow mirror sequence of open() selftests: net: udpgso_bench_tx: Cater for pending datagrams zerocopy benchmarking selftests: net: udpgso_bench: Fix racing bug between the rx/tx programs selftests: net: udpgso_bench_rx/tx: Stop when wrong CLI args are provided selftests: net: udpgso_bench_rx: Fix 'used uninitialized' compiler warning ata: libata: Fix sata_down_spd_limit() when no link speed is reported can: j1939: fix errant WARN_ON_ONCE in j1939_session_deactivate net: phy: meson-gxl: Add generic dummy stubs for MMD register access squashfs: harden sanity check in squashfs_read_xattr_id_table netfilter: br_netfilter: disable sabotage_in hook after first suppression netrom: Fix use-after-free caused by accept on already connected socket fix "direction" argument of iov_iter_kvec() fix iov_iter_bvec() "direction" argument WRITE is "data source", not destination... scsi: Revert "scsi: core: map PQ=1, PDT=other values to SCSI_SCAN_TARGET_PRESENT" arm64: dts: imx8mm: Fix pad control for UART1_DTE_RX ALSA: hda/via: Avoid potential array out-of-bound in add_secret_dac_path() ASoC: Intel: bytcr_rt5651: Drop reference count of ACPI device after use bus: sunxi-rsb: Fix error handling in sunxi_rsb_init() firewire: fix memory leak for payload of request subaction to IEC 61883-1 FCP region Linux 5.4.231 Revert "xprtrdma: Fix regbuf data not freed in rpcrdma_req_create()" usb: host: xhci-plat: add wakeup entry at sysfs Bluetooth: fix null ptr deref on hci_sync_conn_complete_evt ipv6: ensure sane device mtu in tunnels exit: Use READ_ONCE() for all oops/warn limit reads docs: Fix path paste-o for /sys/kernel/warn_count panic: Expose "warn_count" to sysfs panic: Introduce warn_limit panic: Consolidate open-coded panic_on_warn checks exit: Allow oops_limit to be disabled exit: Expose "oops_count" to sysfs exit: Put an upper limit on how often we can oops ia64: make IA64_MCA_RECOVERY bool instead of tristate csky: Fix function name in csky_alignment() and die() h8300: Fix build errors from do_exit() to make_task_dead() transition hexagon: Fix function name in die() objtool: Add a missing comma to avoid string concatenation exit: Add and use make_task_dead. mm: kasan: do not panic if both panic_on_warn and kasan_multishot set panic: unset panic_on_warn inside panic() sysctl: add a new register_sysctl_init() interface dmaengine: imx-sdma: Fix a possible memory leak in sdma_transfer_init blk-cgroup: fix missing pd_online_fn() while activating policy bpf: Skip task with pid=1 in send_signal_common() ARM: dts: imx: Fix pca9547 i2c-mux node name x86/asm: Fix an assembler warning with current binutils clk: Fix pointer casting to prevent oops in devm_clk_release() perf/x86/amd: fix potential integer overflow on shift of a int netfilter: conntrack: unify established states for SCTP paths x86/i8259: Mark legacy PIC interrupts with IRQ_LEVEL block: fix and cleanup bio_check_ro nfsd: Ensure knfsd shuts down when the "nfsd" pseudofs is unmounted Revert "Input: synaptics - switch touchpad on HP Laptop 15-da3001TU to RMI mode" net: mdio-mux-meson-g12a: force internal PHY off on mux switch net: xgene: Move shared header file into include/linux net/phy/mdio-i2c: Move header file to include/linux/mdio net/tg3: resolve deadlock in tg3_reset_task() during EEH thermal: intel: int340x: Add locking to int340x_thermal_get_trip_type() net: ravb: Fix possible hang if RIS2_QFF1 happen sctp: fail if no bound addresses can be used for a given scope net/sched: sch_taprio: do not schedule in taprio_reset() netrom: Fix use-after-free of a listening socket. netfilter: conntrack: fix vtag checks for ABORT/SHUTDOWN_COMPLETE ipv4: prevent potential spectre v1 gadget in fib_metrics_match() ipv4: prevent potential spectre v1 gadget in ip_metrics_convert() netlink: annotate data races around sk_state netlink: annotate data races around dst_portid and dst_group netlink: annotate data races around nlk->portid netfilter: nft_set_rbtree: skip elements in transaction from garbage collection net: fix UaF in netns ops registration error path netlink: prevent potential spectre v1 gadgets EDAC/qcom: Do not pass llcc_driv_data as edac_device_ctl_info's pvt_info EDAC/device: Respect any driver-supplied workqueue polling value ARM: 9280/1: mm: fix warning on phys_addr_t to void pointer assignment thermal: intel: int340x: Protect trip temperature from concurrent updates KVM: x86/vmx: Do not skip segment attributes if unusable bit is set cifs: Fix oops due to uncleared server->smbd_conn in reconnect ftrace/scripts: Update the instructions for ftrace-bisect.sh trace_events_hist: add check for return value of 'create_hist_field' tracing: Make sure trace_printk() can output as soon as it can be used module: Don't wait for GOING modules scsi: hpsa: Fix allocation size for scsi_host_alloc() Bluetooth: hci_sync: cancel cmd_timer if hci_open failed Revert "Revert "xhci: Set HCD flag to defer primary roothub registration"" fs: reiserfs: remove useless new_opts in reiserfs_remount netfilter: conntrack: do not renew entry stuck in tcp SYN_SENT state Revert "selftests/bpf: check null propagation only neither reg is PTR_TO_BTF_ID" mmc: sdhci-esdhc-imx: correct the tuning start tap and step setting mmc: sdhci-esdhc-imx: disable the CMD CRC check for standard tuning mmc: sdhci-esdhc-imx: clear pending interrupt and halt cqhci lockref: stop doing cpu_relax in the cmpxchg loop platform/x86: asus-nb-wmi: Add alternate mapping for KEY_SCREENLOCK platform/x86: touchscreen_dmi: Add info for the CSL Panther Tab HD scsi: hisi_sas: Set a port invalid only if there are no devices attached when refreshing port id KVM: s390: interrupt: use READ_ONCE() before cmpxchg() spi: spidev: remove debug messages that access spidev->spi without locking ASoC: fsl-asoc-card: Fix naming of AC'97 CODEC widgets ASoC: fsl_ssi: Rename AC'97 streams to avoid collisions with AC'97 CODEC cpufreq: armada-37xx: stop using 0 as NULL pointer s390/debug: add _ASM_S390_ prefix to header guard drm: Add orientation quirk for Lenovo ideapad D330-10IGL ASoC: fsl_micfil: Correct the number of steps on SX controls cpufreq: Add Tegra234 to cpufreq-dt-platdev blocklist tcp: fix rate_app_limited to default to 1 net: dsa: microchip: ksz9477: port map correction in ALU table entry register driver core: Fix test_async_probe_init saves device in wrong array w1: fix WARNING after calling w1_process() w1: fix deadloop in __w1_remove_master_device() tcp: avoid the lookup process failing to get sk in ehash table dmaengine: xilinx_dma: call of_node_put() when breaking out of for_each_child_of_node() dmaengine: xilinx_dma: Fix devm_platform_ioremap_resource error handling dmaengine: xilinx_dma: use devm_platform_ioremap_resource() HID: betop: check shape of output reports net: macb: fix PTP TX timestamp failure due to packet padding dmaengine: Fix double increment of client_count in dma_chan_get() drm/panfrost: fix GENERIC_ATOMIC64 dependency net: mlx5: eliminate anonymous module_init & module_exit usb: gadget: f_fs: Ensure ep0req is dequeued before free_request usb: gadget: f_fs: Prevent race during ffs_ep0_queue_wait HID: revert CHERRY_MOUSE_000C quirk net: stmmac: fix invalid call to mdiobus_get_phy() HID: check empty report_list in bigben_probe() HID: check empty report_list in hid_validate_values() net: mdio: validate parameter addr in mdiobus_get_phy() net: usb: sr9700: Handle negative len l2tp: Don't sleep and disable BH under writer-side sk_callback_lock l2tp: Serialize access to sk_user_data with sk_callback_lock net: fix a concurrency bug in l2tp_tunnel_register() net/sched: sch_taprio: fix possible use-after-free wifi: rndis_wlan: Prevent buffer overflow in rndis_query_oid gpio: mxc: Always set GPIOs used as interrupt source to INPUT mode net: wan: Add checks for NULL for utdm in undo_uhdlc_init and unmap_si_regs net: nfc: Fix use-after-free in local_cleanup() phy: rockchip-inno-usb2: Fix missing clk_disable_unprepare() in rockchip_usb2phy_power_on() bpf: Fix pointer-leak due to insufficient speculative store bypass mitigation amd-xgbe: Delay AN timeout during KR training amd-xgbe: TX Flow Ctrl Registers are h/w ver dependent affs: initialize fsdata in affs_truncate() IB/hfi1: Fix expected receive setup error exit issues IB/hfi1: Reserve user expected TIDs IB/hfi1: Reject a zero-length user expected buffer RDMA/core: Fix ib block iterator counter overflow tomoyo: fix broken dependency on *.conf.default EDAC/highbank: Fix memory leak in highbank_mc_probe() HID: intel_ish-hid: Add check for ishtp_dma_tx_map ARM: imx: add missing of_node_put() ARM: imx35: Retrieve the IIM base address from devicetree ARM: imx31: Retrieve the IIM base address from devicetree ARM: imx27: Retrieve the SYSCTRL base address from devicetree ARM: dts: imx6qdl-gw560x: Remove incorrect 'uart-has-rtscts' memory: mvebu-devbus: Fix missing clk_disable_unprepare in mvebu_devbus_probe() memory: atmel-sdramc: Fix missing clk_disable_unprepare in atmel_ramc_probe() clk: Provide new devm_clk helpers for prepared and enabled clocks clk: generalize devm_clk_get() a bit Linux 5.4.230 mm/khugepaged: fix collapse_pte_mapped_thp() to allow anon_vma x86/fpu: Use _Alignof to avoid undefined behavior in TYPE_ALIGN drm/amd/display: Fix COLOR_SPACE_YCBCR2020_TYPE matrix drm/amd/display: Fix set scaling doesn's work drm/i915: re-disable RC6p on Sandy Bridge gsmi: fix null-deref in gsmi_get_variable serial: atmel: fix incorrect baudrate setup dmaengine: tegra210-adma: fix global intr clear serial: pch_uart: Pass correct sg to dma_unmap_sg() dt-bindings: phy: g12a-usb3-pcie-phy: fix compatible string documentation usb-storage: apply IGNORE_UAS only for HIKSEMI MD202 on RTL9210 usb: gadget: f_ncm: fix potential NULL ptr deref in ncm_bitrate() usb: gadget: g_webcam: Send color matching descriptor per frame usb: typec: altmodes/displayport: Fix pin assignment calculation usb: typec: altmodes/displayport: Add pin assignment helper usb: host: ehci-fsl: Fix module alias USB: serial: cp210x: add SCALANCE LPE-9000 device id USB: gadgetfs: Fix race between mounting and unmounting cifs: do not include page data when checking signature btrfs: fix race between quota rescan and disable leading to NULL pointer deref mmc: sunxi-mmc: Fix clock refcount imbalance during unbind comedi: adv_pci1760: Fix PWM instruction handling usb: core: hub: disable autosuspend for TI TUSB8041 misc: fastrpc: Fix use-after-free race condition for maps misc: fastrpc: Don't remove map on creater_process and device_release USB: misc: iowarrior: fix up header size for USB_DEVICE_ID_CODEMERCS_IOW100 USB: serial: option: add Quectel EM05CN modem USB: serial: option: add Quectel EM05CN (SG) modem USB: serial: option: add Quectel EC200U modem USB: serial: option: add Quectel EM05-G (RS) modem USB: serial: option: add Quectel EM05-G (CS) modem USB: serial: option: add Quectel EM05-G (GR) modem prlimit: do_prlimit needs to have a speculation check xhci: Detect lpm incapable xHC USB3 roothub ports from ACPI tables usb: acpi: add helper to check port lpm capability using acpi _DSM xhci: Add a flag to disable USB3 lpm on a xhci root port level. xhci: Add update_hub_device override for PCI xHCI hosts xhci: Fix null pointer dereference when host dies usb: xhci: Check endpoint is valid before dereferencing it xhci-pci: set the dma max_seg_size ALSA: hda/realtek - Turn on power early drm/i915/gt: Reset twice efi: fix userspace infinite retry read efivars after EFI runtime services page fault nilfs2: fix general protection fault in nilfs_btree_insert() Add exception protection processing for vd in axi_chan_handle_err function wifi: brcmfmac: fix regression for Broadcom PCIe wifi devices f2fs: let's avoid panic if extent_tree is not created RDMA/srp: Move large values to a new enum for gcc13 net/ethtool/ioctl: return -EOPNOTSUPP if we have no phy stats selftests/bpf: check null propagation only neither reg is PTR_TO_BTF_ID pNFS/filelayout: Fix coalescing test for single DS Revert "net: add atomic_long_t to net_device_stats fields" Revert "PM/devfreq: governor: Add a private governor_data for governor" Linux 5.4.229 tipc: call tipc_lxc_xmit without holding node_read_lock ocfs2: fix freeing uninitialized resource on ocfs2_dlm_shutdown tipc: Add a missing case of TIPC_DIRECT_MSG type tty: serial: tegra: Handle RX transfer in PIO mode if DMA wasn't started tipc: fix use-after-free in tipc_disc_rcv() Revert "usb: ulpi: defer ulpi_register on ulpi_read_id timeout" mm: Always release pages to the buddy allocator in memblock_free_late(). efi: fix NULL-deref in init error path arm64: cmpxchg_double*: hazard against entire exchange variable arm64: atomics: remove LL/SC trampolines arm64: atomics: format whitespace consistently drm/virtio: Fix GEM handle creation UAF x86/resctrl: Fix task CLOSID/RMID update race x86/resctrl: Use task_curr() instead of task_struct->on_cpu to prevent unnecessary IPI iommu/mediatek-v1: Fix an error handling path in mtk_iommu_v1_probe() iommu/mediatek-v1: Add error handle for mtk_iommu_probe net/mlx5: Fix ptp max frequency adjustment range net/mlx5: Rename ptp clock info net/sched: act_mpls: Fix warning during failed attribute validation nfc: pn533: Wait for out_urb's completion in pn533_usb_send_frame() hvc/xen: lock console list traversal tipc: fix unexpected link reset due to discovery messages tipc: eliminate checking netns if node established tipc: improve throughput between nodes in netns regulator: da9211: Use irq handler when ready EDAC/device: Fix period calculation in edac_device_reset_delay_period() x86/boot: Avoid using Intel mnemonics in AT&T syntax asm powerpc/imc-pmu: Fix use of mutex in IRQs disabled section netfilter: ipset: Fix overflow before widen in the bitmap_ip_create() function. ext4: fix uninititialized value in 'ext4_evict_inode' ext4: fix use-after-free in ext4_orphan_cleanup ext4: lost matching-pair of trace in ext4_truncate ext4: fix bug_on in __es_tree_search caused by bad quota inode quota: Factor out setup of quota inode jbd2: use the correct print format usb: ulpi: defer ulpi_register on ulpi_read_id timeout wifi: wilc1000: sdio: fix module autoloading ipv6: raw: Deduct extension header length in rawv6_push_pending_frames ixgbe: fix pci device refcount leak platform/x86: sony-laptop: Don't turn off 0x153 keyboard backlight during probe drm/msm/adreno: Make adreno quirks not overwrite each other cifs: Fix uninitialized memory read for smb311 posix symlink create ALSA: hda/hdmi: Add a HP device 0x8715 to force connect list ALSA: pcm: Move rwsem lock inside snd_ctl_elem_read to prevent UAF net/ulp: prevent ULP without clone op from entering the LISTEN status s390/percpu: add READ_ONCE() to arch_this_cpu_to_op_simple() s390/kexec: fix ipl report address for kdump perf auxtrace: Fix address filter duplicate symbol selection docs: Fix the docs build with Sphinx 6.0 efi: tpm: Avoid READ_ONCE() for accessing the event log KVM: arm64: Fix S1PTW handling on RO memslots net: sched: disallow noqueue for qdisc classes driver core: Fix bus_type.match() error handling in __driver_attach() selftests: set the BUILD variable to absolute path selftests: Fix kselftest O=objdir build from cluttering top level objdir parisc: Align parisc MADV_XXX constants with all other architectures mbcache: Avoid nesting of cache->c_list_lock under bit locks hfs/hfsplus: avoid WARN_ON() for sanity check, use proper error handling hfs/hfsplus: use WARN_ON for sanity check ext4: don't allow journal inode to have encrypt flag riscv: uaccess: fix type of 0 variable on error in get_user() nfsd: fix handling of readdir in v4root vs. mount upcall timeout x86/bugs: Flush IBP in ib_prctl_set() ASoC: Intel: bytcr_rt5640: Add quirk for the Advantech MICA-071 tablet udf: Fix extension of the last extent in the file caif: fix memory leak in cfctrl_linkup_request() drm/i915: unpin on error in intel_vgpu_shadow_mm_pin() usb: rndis_host: Secure rndis_query check against int overflow drivers/net/bonding/bond_3ad: return when there's no aggregator perf tools: Fix resources leak in perf_data__open_dir() net: sched: cbq: dont intepret cls results when asked to drop net: sched: atm: dont intepret cls results when asked to drop RDMA/mlx5: Fix validation of max_rd_atomic caps for DC RDMA/uverbs: Silence shiftTooManyBitsSigned warning net: phy: xgmiitorgmii: Fix refcount leak in xgmiitorgmii_probe net: amd-xgbe: add missed tasklet_kill vhost: fix range used in translate_desc() nfc: Fix potential resource leaks qlcnic: prevent ->dcb use-after-free on qlcnic_dcb_enable() failure net: sched: fix memory leak in tcindex_set_parms net: hns3: add interrupts re-initialization while doing VF FLR nfsd: shut down the NFSv4 state objects before the filecache bpf: pull before calling skb_postpull_rcsum() SUNRPC: ensure the matching upcall is in-flight upon downcall ext4: fix deadlock due to mbcache entry corruption mbcache: automatically delete entries from cache on freeing ext4: fix race when reusing xattr blocks ext4: unindent codeblock in ext4_xattr_block_set() ext4: remove EA inode entry from mbcache on inode eviction mbcache: add functions to delete entry if unused mbcache: don't reclaim used entries ext4: use kmemdup() to replace kmalloc + memcpy fs: ext4: initialize fsdata in pagecache_write() ext4: use memcpy_to_page() in pagecache_write() mm/highmem: Lift memcpy_[to|from]_page to core ext4: correct inconsistent error msg in nojournal mode ext4: goto right label 'failed_mount3a' ravb: Fix "failed to switch device to config mode" message during unbind KVM: nVMX: Properly expose ENABLE_USR_WAIT_PAUSE control to L1 KVM: VMX: Fix the spelling of CPU_BASED_USE_TSC_OFFSETTING KVM: VMX: Rename NMI_PENDING to NMI_WINDOW KVM: VMX: Rename INTERRUPT_PENDING to INTERRUPT_WINDOW KVM: retpolines: x86: eliminate retpoline from vmx.c exit handlers KVM: x86: optimize more exit handlers in vmx.c perf probe: Fix to get the DW_AT_decl_file and DW_AT_call_file as unsinged data perf probe: Use dwarf_attr_integrate as generic DWARF attr accessor dm thin: resume even if in FAIL mode media: s5p-mfc: Fix in register read and write for H264 media: s5p-mfc: Clear workbit to handle error condition media: s5p-mfc: Fix to handle reference queue during finishing PM/devfreq: governor: Add a private governor_data for governor btrfs: replace strncpy() with strscpy() ext4: allocate extended attribute value in vmalloc area ext4: avoid unaccounted block allocation when expanding inode ext4: initialize quota before expanding inode in setproject ioctl ext4: fix inode leak in ext4_xattr_inode_create() on an error path ext4: avoid BUG_ON when creating xattrs ext4: fix error code return to user-space in ext4_get_branch() ext4: fix corruption when online resizing a 1K bigalloc fs ext4: fix delayed allocation bug in ext4_clu_mapped for bigalloc + inline ext4: init quota for 'old.inode' in 'ext4_rename' ext4: fix bug_on in __es_tree_search caused by bad boot loader inode ext4: fix reserved cluster accounting in __es_remove_extent() ext4: add helper to check quota inums ext4: add EXT4_IGET_BAD flag to prevent unexpected bad inode ext4: fix undefined behavior in bit shift for ext4_check_flag_values ext4: add inode table check in __ext4_get_inode_loc to aovid possible infinite loop drm/vmwgfx: Validate the box size for the snooped cursor drm/connector: send hotplug uevent on connector cleanup device_cgroup: Roll back to original exceptions after copy failure parisc: led: Fix potential null-ptr-deref in start_task() iommu/amd: Fix ivrs_acpihid cmdline parsing code crypto: n2 - add missing hash statesize PCI/sysfs: Fix double free in error path PCI: Fix pci_device_is_present() for VFs by checking PF ipmi: fix use after free in _ipmi_destroy_user() ima: Fix a potential NULL pointer access in ima_restore_measurement_list mtd: spi-nor: Check for zero erase size in spi_nor_find_best_erase_type() ipmi: fix long wait in unload when IPMI disconnect efi: Add iMac Pro 2017 to uefi skip cert quirk md/bitmap: Fix bitmap chunk size overflow issues cifs: fix missing display of three mount options cifs: fix confusing debug message media: dvb-core: Fix UAF due to refcount races at releasing media: dvb-core: Fix double free in dvb_register_device() ARM: 9256/1: NWFPE: avoid compiler-generated __aeabi_uldivmod tracing: Fix infinite loop in tracing_read_pipe on overflowed print_trace_line tracing/hist: Fix wrong return value in parse_action_params() x86/microcode/intel: Do not retry microcode reloading on the APs tracing/hist: Fix out-of-bound write on 'action_data.var_ref_idx' dm cache: set needs_check flag after aborting metadata dm cache: Fix UAF in destroy() dm clone: Fix UAF in clone_dtr() dm integrity: Fix UAF in dm_integrity_dtr() dm thin: Fix UAF in run_timer_softirq() dm thin: Use last transaction's pmd->root when commit failed dm thin: Fix ABBA deadlock between shrink_slab and dm_pool_abort_metadata dm cache: Fix ABBA deadlock between shrink_slab and dm_cache_metadata_abort binfmt: Fix error return code in load_elf_fdpic_binary() binfmt: Move install_exec_creds after setup_new_exec to match binfmt_elf cpufreq: Init completion before kobject_init_and_add() selftests: Use optional USERCFLAGS and USERLDFLAGS arm64: dts: qcom: sdm850-lenovo-yoga-c630: correct I2C12 pins drive strength ARM: ux500: do not directly dereference __iomem btrfs: fix resolving backrefs for inline extent followed by prealloc mmc: sdhci-sprd: Disable CLK_AUTO when the clock is less than 400K ktest.pl minconfig: Unset configs instead of just removing them kest.pl: Fix grub2 menu handling for rebooting soc: qcom: Select REMAP_MMIO for LLCC driver media: stv0288: use explicitly signed char net/af_packet: make sure to pull mac header net/af_packet: add VLAN support for AF_PACKET SOCK_RAW GSO SUNRPC: Don't leak netobj memory when gss_read_proxy_verf() fails tpm: tpm_tis: Add the missed acpi_put_table() to fix memory leak tpm: tpm_crb: Add the missed acpi_put_table() to fix memory leak mmc: vub300: fix warning - do not call blocking ops when !TASK_RUNNING f2fs: should put a page when checking the summary info mm, compaction: fix fast_isolate_around() to stay within boundaries md: fix a crash in mempool_free pnode: terminate at peers of source ALSA: line6: fix stack overflow in line6_midi_transmit ALSA: line6: correct midi status byte when receiving data from podxt ovl: Use ovl mounter's fsuid and fsgid in ovl_link() hfsplus: fix bug causing custom uid and gid being unable to be assigned with mount HID: plantronics: Additional PIDs for double volume key presses quirk HID: multitouch: fix Asus ExpertBook P2 P2451FA trackpoint powerpc/rtas: avoid scheduling in rtas_os_term() powerpc/rtas: avoid device tree lookups in rtas_os_term() objtool: Fix SEGFAULT nvme: fix the NVME_CMD_EFFECTS_CSE_MASK definition nvme: resync include/linux/nvme.h with nvmecli ata: ahci: Fix PCS quirk application for suspend nvme-pci: fix doorbell buffer value endianness cifs: fix oops during encryption media: dvbdev: fix refcnt bug media: dvbdev: fix build warning due to comments gcov: add support for checksum field regulator: core: fix deadlock on regulator enable iio: adc128s052: add proper .data members in adc128_of_match table iio: adc: ad_sigma_delta: do not use internal iio_dev lock reiserfs: Add missing calls to reiserfs_security_free() HID: wacom: Ensure bootloader PID is usable in hidraw mode usb: dwc3: core: defer probe on ulpi_read_id timeout ALSA: hda/hdmi: Add HP Device 0x8711 to force connect list ALSA: hda/realtek: Add quirk for Lenovo TianYi510Pro-14IOB pstore: Make sure CONFIG_PSTORE_PMSG selects CONFIG_RT_MUTEXES pstore: Switch pmsg_lock to an rt_mutex to avoid priority inversion ASoC: rt5670: Remove unbalanced pm_runtime_put() ASoC: rockchip: spdif: Add missing clk_disable_unprepare() in rk_spdif_runtime_resume() ASoC: wm8994: Fix potential deadlock ASoC: rockchip: pdm: Add missing clk_disable_unprepare() in rockchip_pdm_runtime_resume() ASoC: audio-graph-card: fix refcount leak of cpu_ep in __graph_for_each_link() ASoC: mediatek: mt8173-rt5650-rt5514: fix refcount leak in mt8173_rt5650_rt5514_dev_probe() ASoC: Intel: Skylake: Fix driver hang during shutdown ALSA: hda: add snd_hdac_stop_streams() helper ALSA/ASoC: hda: move/rename snd_hdac_ext_stop_streams to hdac_stream.c orangefs: Fix kmemleak in orangefs_{kernel,client}_debug_init() orangefs: Fix kmemleak in orangefs_prepare_debugfs_help_string() drm/sti: Fix return type of sti_{dvo,hda,hdmi}_connector_mode_valid() drm/fsl-dcu: Fix return type of fsl_dcu_drm_connector_mode_valid() hugetlbfs: fix null-ptr-deref in hugetlbfs_parse_param() clk: st: Fix memory leak in st_of_quadfs_setup() media: si470x: Fix use-after-free in si470x_int_in_callback() mmc: f-sdh30: Add quirks for broken timeout clock capability regulator: core: fix use_count leakage when handling boot-on blk-mq: fix possible memleak when register 'hctx' failed media: dvb-usb: fix memory leak in dvb_usb_adapter_init() media: dvbdev: adopts refcnt to avoid UAF media: dvb-frontends: fix leak of memory fw bpf: Prevent decl_tag from being referenced in func_proto arg ppp: associate skb with a device at tx mrp: introduce active flags to prevent UAF when applicant uninit net: add atomic_long_t to net_device_stats fields md/raid1: stop mdx_raid1 thread when raid1 array run failed drivers/md/md-bitmap: check the return value of md_bitmap_get_counter() drm/sti: Use drm_mode_copy() drm/rockchip: Use drm_mode_copy() s390/lcs: Fix return type of lcs_start_xmit() s390/netiucv: Fix return type of netiucv_tx() s390/ctcm: Fix return type of ctc{mp,}m_tx() igb: Do not free q_vector unless new one was allocated wifi: brcmfmac: Fix potential shift-out-of-bounds in brcmf_fw_alloc_request() hamradio: baycom_epp: Fix return type of baycom_send_packet() net: ethernet: ti: Fix return type of netcp_ndo_start_xmit() bpf: make sure skb->len != 0 when redirecting to a tunneling device ipmi: fix memleak when unload ipmi driver ASoC: codecs: rt298: Add quirk for KBL-R RVP platform wifi: ar5523: Fix use-after-free on ar5523_cmd() timed out wifi: ath9k: verify the expected usb_endpoints are present brcmfmac: return error when getting invalid max_flowrings from dongle drm/etnaviv: add missing quirks for GC300 hfs: fix OOB Read in __hfs_brec_find acct: fix potential integer overflow in encode_comp_t() nilfs2: fix shift-out-of-bounds/overflow in nilfs_sb2_bad_offset() ACPICA: Fix error code path in acpi_ds_call_control_method() fs: jfs: fix shift-out-of-bounds in dbDiscardAG udf: Avoid double brelse() in udf_rename() fs: jfs: fix shift-out-of-bounds in dbAllocAG binfmt_misc: fix shift-out-of-bounds in check_special_flags rcu: Fix __this_cpu_read() lockdep warning in rcu_force_quiescent_state() net: stream: purge sk_error_queue in sk_stream_kill_queues() myri10ge: Fix an error handling path in myri10ge_probe() rxrpc: Fix missing unlock in rxrpc_do_sendmsg() net_sched: reject TCF_EM_SIMPLE case for complex ematch module mailbox: zynq-ipi: fix error handling while device_register() fails skbuff: Account for tail adjustment during pull operations openvswitch: Fix flow lookup to use unmasked key rtc: mxc_v2: Add missing clk_disable_unprepare() r6040: Fix kmemleak in probe and remove nfc: pn533: Clear nfc_target before being used mISDN: hfcmulti: don't call dev_kfree_skb/kfree_skb() under spin_lock_irqsave() mISDN: hfcpci: don't call dev_kfree_skb/kfree_skb() under spin_lock_irqsave() mISDN: hfcsusb: don't call dev_kfree_skb/kfree_skb() under spin_lock_irqsave() nfsd: under NFSv4.1, fix double svc_xprt_put on rpc_create failure NFSD: Add tracepoints to NFSD's duplicate reply cache nfsd: Define the file access mode enum for tracing rtc: pic32: Move devm_rtc_allocate_device earlier in pic32_rtc_probe() rtc: st-lpc: Add missing clk_disable_unprepare in st_rtc_probe() remoteproc: qcom_q6v5_pas: Fix missing of_node_put() in adsp_alloc_memory_region() remoteproc: sysmon: fix memory leak in qcom_add_sysmon_subdev() pwm: sifive: Call pwm_sifive_update_clock() while mutex is held selftests/powerpc: Fix resource leaks powerpc/hv-gpci: Fix hv_gpci event list powerpc/83xx/mpc832x_rdb: call platform_device_put() in error case in of_fsl_spi_probe() powerpc/perf: callchain validate kernel stack pointer bounds powerpc/xive: add missing iounmap() in error path in xive_spapr_populate_irq_data() cxl: Fix refcount leak in cxl_calc_capp_routing powerpc/52xx: Fix a resource leak in an error handling path macintosh/macio-adb: check the return value of ioremap() macintosh: fix possible memory leak in macio_add_one_device() iommu/fsl_pamu: Fix resource leak in fsl_pamu_probe() iommu/amd: Fix pci device refcount leak in ppr_notifier() rtc: pcf85063: Fix reading alarm rtc: snvs: Allow a time difference on clock register read include/uapi/linux/swab: Fix potentially missing __always_inline RDMA/siw: Fix pointer cast warning power: supply: fix null pointer dereferencing in power_supply_get_battery_info HSI: omap_ssi_core: Fix error handling in ssi_init() perf symbol: correction while adjusting symbol perf trace: Handle failure when trace point folder is missed perf trace: Use macro RAW_SYSCALL_ARGS_NUM to replace number perf trace: Add a strtoul() method to 'struct syscall_arg_fmt' perf trace: Allow associating scnprintf routines with well known arg names perf trace: Add the syscall_arg_fmt pointer to syscall_arg perf trace: Factor out the initialization of syscal_arg_fmt->scnprintf perf trace: Separate 'struct syscall_fmt' definition from syscall_fmts variable perf trace: Return error if a system call doesn't exist power: supply: fix residue sysfs file in error handle route of __power_supply_register() HSI: omap_ssi_core: fix possible memory leak in ssi_probe() HSI: omap_ssi_core: fix unbalanced pm_runtime_disable() fbdev: uvesafb: Fixes an error handling path in uvesafb_probe() fbdev: vermilion: decrease reference count in error path fbdev: via: Fix error in via_core_init() fbdev: pm2fb: fix missing pci_disable_device() fbdev: ssd1307fb: Drop optional dependency samples: vfio-mdev: Fix missing pci_disable_device() in mdpy_fb_probe() tracing/hist: Fix issue of losting command info in error_log usb: storage: Add check for kcalloc i2c: ismt: Fix an out-of-bounds bug in ismt_access() vme: Fix error not catched in fake_init() staging: rtl8192e: Fix potential use-after-free in rtllib_rx_Monitor() staging: rtl8192u: Fix use after free in ieee80211_rx() i2c: pxa-pci: fix missing pci_disable_device() on error in ce4100_i2c_probe chardev: fix error handling in cdev_device_add() mcb: mcb-parse: fix error handing in chameleon_parse_gdd() drivers: mcb: fix resource leak in mcb_probe() usb: gadget: f_hid: fix refcount leak on error path usb: gadget: f_hid: fix f_hidg lifetime vs cdev usb: gadget: f_hid: optional SETUP/SET_REPORT mode usb: roles: fix of node refcount leak in usb_role_switch_is_parent() counter: stm32-lptimer-cnt: fix the check on arr and cmp registers update cxl: fix possible null-ptr-deref in cxl_pci_init_afu|adapter() cxl: fix possible null-ptr-deref in cxl_guest_init_afu|adapter() misc: sgi-gru: fix use-after-free error in gru_set_context_option, gru_fault and gru_handle_user_call_os misc: tifm: fix possible memory leak in tifm_7xx1_switch_media() misc: ocxl: fix possible name leak in ocxl_file_register_afu() test_firmware: fix memory leak in test_firmware_init() serial: sunsab: Fix error handling in sunsab_init() serial: altera_uart: fix locking in polling mode tty: serial: altera_uart_{r,t}x_chars() need only uart_port tty: serial: clean up stop-tx part in altera_uart_tx_chars() serial: pch: Fix PCI device refcount leak in pch_request_dma() serial: pl011: Do not clear RX FIFO & RX interrupt in unthrottle. serial: amba-pl011: avoid SBSA UART accessing DMACR register usb: typec: tcpci: fix of node refcount leak in tcpci_register_port() usb: typec: Check for ops->exit instead of ops->enter in altmode_exit staging: vme_user: Fix possible UAF in tsi148_dma_list_add usb: fotg210-udc: Fix ages old endianness issues uio: uio_dmem_genirq: Fix deadlock between irq config and handling uio: uio_dmem_genirq: Fix missing unlock in irq configuration vfio: platform: Do not pass return buffer to ACPI _RST method class: fix possible memory leak in __class_register() serial: tegra: Read DMA status before terminating tty: serial: tegra: Activate RX DMA transfer by request drivers: dio: fix possible memory leak in dio_init() IB/IPoIB: Fix queue count inconsistency for PKEY child interfaces hwrng: geode - Fix PCI device refcount leak hwrng: amd - Fix PCI device refcount leak crypto: img-hash - Fix variable dereferenced before check 'hdev->req' orangefs: Fix sysfs not cleanup when dev init failed RDMA/hfi1: Fix error return code in parse_platform_config() crypto: omap-sham - Use pm_runtime_resume_and_get() in omap_sham_probe() f2fs: avoid victim selection from previous victim section RDMA/nldev: Add checks for nla_nest_start() in fill_stat_counter_qps() scsi: snic: Fix possible UAF in snic_tgt_create() scsi: fcoe: Fix transport not deattached when fcoe_if_init() fails scsi: ipr: Fix WARNING in ipr_init() scsi: fcoe: Fix possible name leak when device_register() fails scsi: hpsa: Fix possible memory leak in hpsa_add_sas_device() scsi: hpsa: Fix error handling in hpsa_add_sas_host() scsi: mpt3sas: Fix possible resource leaks in mpt3sas_transport_port_add() crypto: tcrypt - Fix multibuffer skcipher speed test mem leak scsi: hpsa: Fix possible memory leak in hpsa_init_one() RDMA/rxe: Fix NULL-ptr-deref in rxe_qp_do_cleanup() when socket create failed crypto: ccree - Make cc_debugfs_global_fini() available for module init function RDMA/hfi: Decrease PCI device reference count in error path PCI: Check for alloc failure in pci_request_irq() crypto: ccree - Remove debugfs when platform_driver_register failed crypto: ccree - swap SHA384 and SHA512 larval hashes at build time scsi: scsi_debug: Fix a warning in resp_write_scat() RDMA/siw: Set defined status for work completion with undefined status RDMA/nldev: Return "-EAGAIN" if the cm_id isn't from expected port RDMA/siw: Fix immediate work request flush to completion queue f2fs: fix normal discard process RDMA/core: Fix order of nldev_exit call apparmor: Use pointer to struct aa_label for lbs_cred apparmor: Fix abi check to include v8 abi apparmor: fix lockdep warning when removing a namespace apparmor: fix a memleak in multi_transaction_new() stmmac: fix potential division by 0 Bluetooth: RFCOMM: don't call kfree_skb() under spin_lock_irqsave() Bluetooth: hci_core: don't call kfree_skb() under spin_lock_irqsave() Bluetooth: hci_bcsp: don't call kfree_skb() under spin_lock_irqsave() Bluetooth: hci_h5: don't call kfree_skb() under spin_lock_irqsave() Bluetooth: hci_ll: don't call kfree_skb() under spin_lock_irqsave() Bluetooth: hci_qca: don't call kfree_skb() under spin_lock_irqsave() Bluetooth: btusb: don't call kfree_skb() under spin_lock_irqsave() ntb_netdev: Use dev_kfree_skb_any() in interrupt context net: lan9303: Fix read error execution path can: tcan4x5x: Remove invalid write in clear_interrupts net: amd-xgbe: Check only the minimum speed for active/passive cables net: amd-xgbe: Fix logic around active and passive cables net: amd: lance: don't call dev_kfree_skb() under spin_lock_irqsave() hamradio: don't call dev_kfree_skb() under spin_lock_irqsave() net: ethernet: dnet: don't call dev_kfree_skb() under spin_lock_irqsave() net: emaclite: don't call dev_kfree_skb() under spin_lock_irqsave() net: apple: bmac: don't call dev_kfree_skb() under spin_lock_irqsave() net: apple: mace: don't call dev_kfree_skb() under spin_lock_irqsave() net/tunnel: wait until all sk_user_data reader finish before releasing the sock net: farsync: Fix kmemleak when rmmods farsync ethernet: s2io: don't call dev_kfree_skb() under spin_lock_irqsave() of: overlay: fix null pointer dereferencing in find_dup_cset_node_entry() and find_dup_cset_prop() drivers: net: qlcnic: Fix potential memory leak in qlcnic_sriov_init() net: stmmac: selftests: fix potential memleak in stmmac_test_arpoffload() net: defxx: Fix missing err handling in dfx_init() net: vmw_vsock: vmci: Check memcpy_from_msg() clk: socfpga: Fix memory leak in socfpga_gate_init() clk: socfpga: use clk_hw_register for a5/c5 clk: socfpga: clk-pll: Remove unused variable 'rc' blktrace: Fix output non-blktrace event when blk_classic option enabled wifi: brcmfmac: Fix error return code in brcmf_sdio_download_firmware() wifi: rtl8xxxu: Add __packed to struct rtl8723bu_c2h spi: spi-gpio: Don't set MOSI as an input if not 3WIRE mode clk: samsung: Fix memory leak in _samsung_clk_register_pll() media: coda: Add check for kmalloc media: coda: Add check for dcoda_iram_alloc media: c8sectpfe: Add of_node_put() when breaking out of loop mmc: mmci: fix return value check of mmc_add_host() mmc: wbsd: fix return value check of mmc_add_host() mmc: via-sdmmc: fix return value check of mmc_add_host() mmc: meson-gx: fix return value check of mmc_add_host() mmc: omap_hsmmc: fix return value check of mmc_add_host() mmc: atmel-mci: fix return value check of mmc_add_host() mmc: wmt-sdmmc: fix return value check of mmc_add_host() mmc: vub300: fix return value check of mmc_add_host() mmc: toshsd: fix return value check of mmc_add_host() mmc: rtsx_usb_sdmmc: fix return value check of mmc_add_host() mmc: pxamci: fix return value check of mmc_add_host() mmc: mxcmmc: fix return value check of mmc_add_host() mmc: moxart: fix return value check of mmc_add_host() mmc: alcor: fix return value check of mmc_add_host() NFSv4.x: Fail client initialisation if state manager thread can't run SUNRPC: Fix missing release socket in rpc_sockname() xprtrdma: Fix regbuf data not freed in rpcrdma_req_create() ALSA: mts64: fix possible null-ptr-defer in snd_mts64_interrupt media: saa7164: fix missing pci_disable_device() bpf, sockmap: fix race in sock_map_free() regulator: core: fix resource leak in regulator_register() configfs: fix possible memory leak in configfs_create_dir() hsr: Avoid double remove of a node. clk: qcom: clk-krait: fix wrong div2 functions regulator: core: fix module refcount leak in set_supply() wifi: cfg80211: Fix not unregister reg_pdev when load_builtin_regdb_keys() fails spi: spidev: mask SPI_CS_HIGH in SPI_IOC_RD_MODE bonding: uninitialized variable in bond_miimon_inspect() bpf, sockmap: Fix data loss caused by using apply_bytes on ingress redirect bpf, sockmap: Fix repeated calls to sock_put() when msg has more_data netfilter: conntrack: set icmpv6 redirects as RELATED ASoC: pcm512x: Fix PM disable depth imbalance in pcm512x_probe drm/amdgpu: Fix PCI device refcount leak in amdgpu_atrm_get_bios() drm/radeon: Fix PCI device refcount leak in radeon_atrm_get_bios() ASoC: mediatek: mt8173: Enable IRQ when pdata is ready wifi: iwlwifi: mvm: fix double free on tx path. ALSA: asihpi: fix missing pci_disable_device() NFSv4: Fix a deadlock between nfs4_open_recover_helper() and delegreturn NFSv4.2: Fix initialisation of struct nfs4_label NFSv4.2: Fix a memory stomp in decode_attr_security_label NFSv4.2: Clear FATTR4_WORD2_SECURITY_LABEL when done decoding ASoC: mediatek: mtk-btcvsd: Add checks for write and read of mtk_btcvsd_snd ASoC: dt-bindings: wcd9335: fix reset line polarity in example drm/tegra: Add missing clk_disable_unprepare() in tegra_dc_probe() media: s5p-mfc: Add variant data for MFC v7 hardware for Exynos 3250 SoC media: dvb-usb: az6027: fix null-ptr-deref in az6027_i2c_xfer() media: dvb-core: Fix ignored return value in dvb_register_frontend() pinctrl: pinconf-generic: add missing of_node_put() clk: imx: replace osc_hdmi with dummy clk: imx8mn: correct the usb1_ctrl parent to be usb_bus media: imon: fix a race condition in send_packet() mtd: maps: pxa2xx-flash: fix memory leak in probe bonding: fix link recovery in mode 2 when updelay is nonzero bonding: Rename slave_arr to usable_slaves bonding: Export skip slave logic to function clk: rockchip: Fix memory leak in rockchip_clk_register_pll() regulator: core: use kfree_const() to free space conditionally ALSA: seq: fix undefined behavior in bit shift for SNDRV_SEQ_FILTER_USE_EVENT ALSA: pcm: fix undefined behavior in bit shift for SNDRV_PCM_RATE_KNOT HID: hid-sensor-custom: set fixed size for custom attributes bpf: Move skb->len == 0 checks into __bpf_redirect media: videobuf-dma-contig: use dma_mmap_coherent media: platform: exynos4-is: Fix error handling in fimc_md_init() media: solo6x10: fix possible memory leak in solo_sysfs_init() Input: elants_i2c - properly handle the reset GPIO when power is off mtd: lpddr2_nvm: Fix possible null-ptr-deref wifi: ath10k: Fix return value in ath10k_pci_init() ima: Fix misuse of dereference of pointer in template_desc_init_fields() integrity: Fix memory leakage in keyring allocation error path amdgpu/pm: prevent array underflow in vega20_odn_edit_dpm_table() regulator: core: fix unbalanced of node refcount in regulator_dev_lookup() ASoC: pxa: fix null-pointer dereference in filter() drm/mediatek: Modify dpi power on/off sequence. drm/radeon: Add the missed acpi_put_table() to fix memory leak rxrpc: Fix ack.bufferSize to be 0 when generating an ack net, proc: Provide PROC_FS=n fallback for proc_create_net_single_write() media: camss: Clean up received buffers on failed start of streaming wifi: rsi: Fix handling of 802.3 EAPOL frames sent via control port mtd: Fix device name leak when register device failed in add_mtd_device() bpf: propagate precision in ALU/ALU64 operations media: vivid: fix compose size exceed boundary ima: Handle -ESTALE returned by ima_filter_rule_match() ima: Fix fall-through warnings for Clang ima: Rename internal filter rule functions drm/panel/panel-sitronix-st7701: Remove panel on DSI attach failure spi: Update reference to struct spi_controller clk: renesas: r9a06g032: Repair grave increment error can: kvaser_usb: Compare requested bittiming parameters with actual parameters in do_set_{,data}_bittiming can: kvaser_usb: Add struct kvaser_usb_busparams can: kvaser_usb_leaf: Fix bogus restart events can: kvaser_usb_leaf: Fix wrong CAN state after stopping can: kvaser_usb_leaf: Fix improved state not being reported can: kvaser_usb_leaf: Set Warning state even without bus errors can: kvaser_usb: kvaser_usb_leaf: Handle CMD_ERROR_EVENT can: kvaser_usb: kvaser_usb_leaf: Rename {leaf,usbcan}_cmd_error_event to {leaf,usbcan}_cmd_can_error_event can: kvaser_usb: kvaser_usb_leaf: Get capabilities from device can: kvaser_usb: do not increase tx statistics when sending error message frames media: i2c: ad5820: Fix error path pata_ipx4xx_cf: Fix unsigned comparison with less than zero wifi: rtl8xxxu: Fix reading the vendor of combo chips wifi: ath9k: hif_usb: Fix use-after-free in ath9k_hif_usb_reg_in_cb() wifi: ath9k: hif_usb: fix memory leak of urbs in ath9k_hif_usb_dealloc_tx_urbs() rapidio: devices: fix missing put_device in mport_cdev_open hfs: Fix OOB Write in hfs_asc2mac relay: fix type mismatch when allocating memory in relay_create_buf() eventfd: change int to __u64 in eventfd_signal() ifndef CONFIG_EVENTFD rapidio: fix possible UAF when kfifo_alloc() fails fs: sysv: Fix sysv_nblocks() returns wrong value MIPS: OCTEON: warn only once if deprecated link status is being used MIPS: BCM63xx: Add check for NULL for clk in clk_enable platform/x86: mxm-wmi: fix memleak in mxm_wmi_call_mx[ds|mx]() PM: runtime: Do not call __rpm_callback() from rpm_idle() PM: runtime: Improve path in rpm_idle() when no callback xen/privcmd: Fix a possible warning in privcmd_ioctl_mmap_resource() x86/xen: Fix memory leak in xen_init_lock_cpu() x86/xen: Fix memory leak in xen_smp_intr_init{_pv}() xen/events: only register debug interrupt for 2-level events uprobes/x86: Allow to probe a NOP instruction with 0x66 prefix ACPICA: Fix use-after-free in acpi_ut_copy_ipackage_to_ipackage() clocksource/drivers/sh_cmt: Make sure channel clock supply is enabled rapidio: rio: fix possible name leak in rio_register_mport() rapidio: fix possible name leaks when rio_add_device() fails ocfs2: fix memory leak in ocfs2_mount_volume() ocfs2: rewrite error handling of ocfs2_fill_super ocfs2: ocfs2_mount_volume does cleanup job before return error debugfs: fix error when writing negative value to atomic_t debugfs file docs: fault-injection: fix non-working usage of negative values lib/notifier-error-inject: fix error when writing -errno to debugfs file libfs: add DEFINE_SIMPLE_ATTRIBUTE_SIGNED for signed value cpufreq: amd_freq_sensitivity: Add missing pci_dev_put() genirq/irqdesc: Don't try to remove non-existing sysfs files nfsd: don't call nfsd_file_put from client states seqfile display EDAC/i10nm: fix refcount leak in pci_get_dev_wrapper() irqchip: gic-pm: Use pm_runtime_resume_and_get() in gic_probe() perf/x86/intel/uncore: Fix reference count leak in hswep_has_limit_sbox() PNP: fix name memory leak in pnp_alloc_dev() selftests/efivarfs: Add checking of the test return value MIPS: vpe-cmp: fix possible memory leak while module exiting MIPS: vpe-mt: fix possible memory leak while module exiting ocfs2: fix memory leak in ocfs2_stack_glue_init() lib/fonts: fix undefined behavior in bit shift for get_default_font proc: fixup uptime selftest timerqueue: Use rb_entry_safe() in timerqueue_getnext() perf: Fix possible memleak in pmu_dev_alloc() selftests/ftrace: event_triggers: wait longer for test_event_enable fs: don't audit the capability check in simple_xattr_list() PM: hibernate: Fix mistake in kerneldoc comment alpha: fix syscall entry in !AUDUT_SYSCALL case cpuidle: dt: Return the correct numbers of parsed idle states tpm/tpm_crb: Fix error message in __crb_relinquish_locality() pstore: Avoid kcore oops by vmap()ing with VM_IOREMAP ARM: mmp: fix timer_read delay pstore/ram: Fix error return code in ramoops_probe() arm64: dts: armada-3720-turris-mox: Add missing interrupt for RTC ARM: dts: turris-omnia: Add switch port 6 node ARM: dts: turris-omnia: Add ethernet aliases ARM: dts: armada-39x: Fix assigned-addresses for every PCIe Root Port ARM: dts: armada-38x: Fix assigned-addresses for every PCIe Root Port ARM: dts: armada-375: Fix assigned-addresses for every PCIe Root Port ARM: dts: armada-xp: Fix assigned-addresses for every PCIe Root Port ARM: dts: armada-370: Fix assigned-addresses for every PCIe Root Port ARM: dts: dove: Fix assigned-addresses for every PCIe Root Port arm64: dts: mediatek: mt6797: Fix 26M oscillator unit name arm64: dts: mt2712-evb: Fix usb vbus regulators unit names arm64: dts: mt2712-evb: Fix vproc fixed regulators unit names arm64: dts: mt2712e: Fix unit address for pinctrl node arm64: dts: mt2712e: Fix unit_address_vs_reg warning for oscillators perf/smmuv3: Fix hotplug callback leak in arm_smmu_pmu_init() perf: arm_dsu: Fix hotplug callback leak in dsu_pmu_init() soc: ti: smartreflex: Fix PM disable depth imbalance in omap_sr_probe soc: ti: knav_qmss_queue: Fix PM disable depth imbalance in knav_queue_probe soc: ti: knav_qmss_queue: Use pm_runtime_resume_and_get instead of pm_runtime_get_sync arm: dts: spear600: Fix clcd interrupt drivers: soc: ti: knav_qmss_queue: Mark knav_acc_firmwares as static arm64: dts: qcom: sdm845-cheza: fix AP suspend pin bias ARM: dts: qcom: apq8064: fix coresight compatible usb: musb: remove extra check in musb_gadget_vbus_draw net: loopback: use NET_NAME_PREDICTABLE for name_assign_type Bluetooth: L2CAP: Fix u8 overflow HID: uclogic: Add HID_QUIRK_HIDINPUT_FORCE quirk HID: ite: Enable QUIRK_TOUCHPAD_ON_OFF_REPORT on Acer Aspire Switch V 10 HID: ite: Enable QUIRK_TOUCHPAD_ON_OFF_REPORT on Acer Aspire Switch 10E HID: ite: Add support for Acer S1002 keyboard-dock xen-netback: move removal of "hotplug-status" to the right place igb: Initialize mailbox message for VF reset USB: serial: f81534: fix division by zero on line-speed change USB: serial: f81232: fix division by zero on line-speed change USB: serial: cp210x: add Kamstrup RF sniffer PIDs USB: serial: option: add Quectel EM05-G modem usb: gadget: uvc: Prevent buffer overflow in setup handler udf: Fix extending file within last block udf: Do not bother looking for prealloc extents if i_lenExtents matches i_size udf: Fix preallocation discarding at indirect extent boundary udf: Discard preallocation before extending file with a hole tracing/ring-buffer: Only do full wait when cpu != RING_BUFFER_ALL_CPUS ANDROID: Add more hvc devices for virtio-console. Revert "can: af_can: fix NULL pointer dereference in can_rcv_filter" ANDROID: Revert "tracing/ring-buffer: Have polling block on watermark" Linux 5.4.228 ASoC: ops: Correct bounds check for second channel on SX controls can: mcba_usb: Fix termination command argument can: sja1000: fix size of OCR_MODE_MASK define pinctrl: meditatek: Startup with the IRQs disabled ASoC: ops: Check bounds for second channel in snd_soc_put_volsw_sx() nfp: fix use-after-free in area_cache_get() block: unhash blkdev part inode when the part is deleted mm/hugetlb: fix races when looking up a CONT-PTE/PMD size hugetlb page x86/smpboot: Move rcu_cpu_starting() earlier net: bpf: Allow TC programs to call BPF_FUNC_skb_change_head Linux 5.4.227 can: esd_usb: Allow REC and TEC to return to zero net: mvneta: Fix an out of bounds check ipv6: avoid use-after-free in ip6_fragment() net: plip: don't call kfree_skb/dev_kfree_skb() under spin_lock_irq() xen/netback: fix build warning ethernet: aeroflex: fix potential skb leak in greth_init_rings() ipv4: Fix incorrect route flushing when table ID 0 is used ipv4: Fix incorrect route flushing when source address is deleted tipc: Fix potential OOB in tipc_link_proto_rcv() net: hisilicon: Fix potential use-after-free in hix5hd2_rx() net: hisilicon: Fix potential use-after-free in hisi_femac_rx() net: thunderx: Fix missing destroy_workqueue of nicvf_rx_mode_wq net: stmmac: fix "snps,axi-config" node property parsing nvme initialize core quirks before calling nvme_init_subsystem NFC: nci: Bounds check struct nfc_target arrays i40e: Disallow ip4 and ip6 l4_4_bytes i40e: Fix for VF MAC address 0 i40e: Fix not setting default xps_cpus after reset net: mvneta: Prevent out of bounds read in mvneta_config_rss() xen-netfront: Fix NULL sring after live migration net: encx24j600: Fix invalid logic in reading of MISTAT register net: encx24j600: Add parentheses to fix precedence mac802154: fix missing INIT_LIST_HEAD in ieee802154_if_add() selftests: rtnetlink: correct xfrm policy rule in kci_test_ipsec_offload net: dsa: ksz: Check return value Bluetooth: Fix not cleanup led when bt_init fails Bluetooth: 6LoWPAN: add missing hci_dev_put() in get_l2cap_conn() af_unix: Get user_ns from in_skb in unix_diag_get_exact(). igb: Allocate MSI-X vector when testing e1000e: Fix TX dispatch condition gpio: amd8111: Fix PCI device reference count leak drm/bridge: ti-sn65dsi86: Fix output polarity setting bug ca8210: Fix crash by zero initializing data ieee802154: cc2520: Fix error return code in cc2520_hw_init() can: af_can: fix NULL pointer dereference in can_rcv_filter HID: core: fix shift-out-of-bounds in hid_report_raw_event HID: hid-lg4ff: Add check for empty lbuf HID: usbhid: Add ALWAYS_POLL quirk for some mice drm/shmem-helper: Remove errant put in error path KVM: s390: vsie: Fix the initialization of the epoch extension (epdx) field mm/gup: fix gup_pud_range() for dax memcg: fix possible use-after-free in memcg_write_event_control() media: v4l2-dv-timings.c: fix too strict blanking sanity checks Revert "net: dsa: b53: Fix valid setting for MDB entries" xen/netback: don't call kfree_skb() with interrupts disabled xen/netback: do some code cleanup xen/netback: Ensure protocol headers don't fall in the non-linear area mm/khugepaged: invoke MMU notifiers in shmem/file collapse paths mm/khugepaged: fix GUP-fast interaction by sending IPI mm/khugepaged: take the right locks for page table retraction net: usb: qmi_wwan: add u-blox 0x1342 composition 9p/xen: check logical size for buffer size fbcon: Use kzalloc() in fbcon_prepare_logo() regulator: twl6030: fix get status of twl6032 regulators ASoC: soc-pcm: Add NULL check in BE reparenting btrfs: send: avoid unaligned encoded writes when attempting to clone range ALSA: seq: Fix function prototype mismatch in snd_seq_expand_var_event regulator: slg51000: Wait after asserting CS pin 9p/fd: Use P9_HDRSZ for header size ARM: dts: rockchip: disable arm_global_timer on rk3066 and rk3188 ARM: 9266/1: mm: fix no-MMU ZERO_PAGE() implementation ARM: 9251/1: perf: Fix stacktraces for tracepoint events in THUMB2 kernels ARM: dts: rockchip: rk3188: fix lcdc1-rgb24 node name ARM: dts: rockchip: fix ir-receiver node names arm: dts: rockchip: fix node name for hym8563 rtc arm64: dts: rockchip: keep I2S1 disabled for GPIO function on ROCK Pi 4 series Conflicts: Documentation/devicetree/bindings/phy/amlogic,meson-g12a-usb3-pcie-phy.yaml arch/arm64/boot/dts/vendor/bindings/phy/amlogic,g12a-usb3-pcie-phy.yaml arch/arm64/boot/dts/vendor/bindings/phy/amlogic,meson-g12a-usb3-pcie-phy.yaml arch/arm64/include/asm/atomic_ll_sc.h drivers/edac/qcom_edac.c drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c drivers/net/ethernet/stmicro/stmmac/stmmac_hwtstamp.c drivers/net/ethernet/stmicro/stmmac/stmmac_main.c drivers/usb/gadget/function/f_fs.c drivers/usb/host/xhci-plat.c sound/soc/soc-pcm.c Change-Id: I4e8cffcac6c78ecf1a16d24ee01551747552fdf2
1783 lines
44 KiB
C
1783 lines
44 KiB
C
// SPDX-License-Identifier: GPL-2.0-only
|
|
/*
|
|
* linux/kernel/exit.c
|
|
*
|
|
* Copyright (C) 1991, 1992 Linus Torvalds
|
|
*/
|
|
|
|
#include <linux/mm.h>
|
|
#include <linux/slab.h>
|
|
#include <linux/sched/autogroup.h>
|
|
#include <linux/sched/mm.h>
|
|
#include <linux/sched/stat.h>
|
|
#include <linux/sched/task.h>
|
|
#include <linux/sched/task_stack.h>
|
|
#include <linux/sched/cputime.h>
|
|
#include <linux/interrupt.h>
|
|
#include <linux/module.h>
|
|
#include <linux/capability.h>
|
|
#include <linux/completion.h>
|
|
#include <linux/personality.h>
|
|
#include <linux/tty.h>
|
|
#include <linux/iocontext.h>
|
|
#include <linux/key.h>
|
|
#include <linux/cpu.h>
|
|
#include <linux/acct.h>
|
|
#include <linux/tsacct_kern.h>
|
|
#include <linux/file.h>
|
|
#include <linux/fdtable.h>
|
|
#include <linux/freezer.h>
|
|
#include <linux/binfmts.h>
|
|
#include <linux/nsproxy.h>
|
|
#include <linux/pid_namespace.h>
|
|
#include <linux/ptrace.h>
|
|
#include <linux/profile.h>
|
|
#include <linux/mount.h>
|
|
#include <linux/proc_fs.h>
|
|
#include <linux/kthread.h>
|
|
#include <linux/mempolicy.h>
|
|
#include <linux/taskstats_kern.h>
|
|
#include <linux/delayacct.h>
|
|
#include <linux/cgroup.h>
|
|
#include <linux/syscalls.h>
|
|
#include <linux/signal.h>
|
|
#include <linux/posix-timers.h>
|
|
#include <linux/cn_proc.h>
|
|
#include <linux/mutex.h>
|
|
#include <linux/futex.h>
|
|
#include <linux/pipe_fs_i.h>
|
|
#include <linux/audit.h> /* for audit_free() */
|
|
#include <linux/resource.h>
|
|
#include <linux/blkdev.h>
|
|
#include <linux/task_io_accounting_ops.h>
|
|
#include <linux/tracehook.h>
|
|
#include <linux/fs_struct.h>
|
|
#include <linux/init_task.h>
|
|
#include <linux/perf_event.h>
|
|
#include <trace/events/sched.h>
|
|
#include <linux/hw_breakpoint.h>
|
|
#include <linux/oom.h>
|
|
#include <linux/writeback.h>
|
|
#include <linux/shm.h>
|
|
#include <linux/kcov.h>
|
|
#include <linux/random.h>
|
|
#include <linux/rcuwait.h>
|
|
#include <linux/compat.h>
|
|
#include <linux/sysfs.h>
|
|
|
|
#include <linux/uaccess.h>
|
|
#include <asm/unistd.h>
|
|
#include <asm/pgtable.h>
|
|
#include <asm/mmu_context.h>
|
|
|
|
/*
|
|
* The default value should be high enough to not crash a system that randomly
|
|
* crashes its kernel from time to time, but low enough to at least not permit
|
|
* overflowing 32-bit refcounts or the ldsem writer count.
|
|
*/
|
|
static unsigned int oops_limit = 10000;
|
|
|
|
#ifdef CONFIG_SYSCTL
|
|
static struct ctl_table kern_exit_table[] = {
|
|
{
|
|
.procname = "oops_limit",
|
|
.data = &oops_limit,
|
|
.maxlen = sizeof(oops_limit),
|
|
.mode = 0644,
|
|
.proc_handler = proc_douintvec,
|
|
},
|
|
{ }
|
|
};
|
|
|
|
static __init int kernel_exit_sysctls_init(void)
|
|
{
|
|
register_sysctl_init("kernel", kern_exit_table);
|
|
return 0;
|
|
}
|
|
late_initcall(kernel_exit_sysctls_init);
|
|
#endif
|
|
|
|
static atomic_t oops_count = ATOMIC_INIT(0);
|
|
|
|
#ifdef CONFIG_SYSFS
|
|
static ssize_t oops_count_show(struct kobject *kobj, struct kobj_attribute *attr,
|
|
char *page)
|
|
{
|
|
return sysfs_emit(page, "%d\n", atomic_read(&oops_count));
|
|
}
|
|
|
|
static struct kobj_attribute oops_count_attr = __ATTR_RO(oops_count);
|
|
|
|
static __init int kernel_exit_sysfs_init(void)
|
|
{
|
|
sysfs_add_file_to_group(kernel_kobj, &oops_count_attr.attr, NULL);
|
|
return 0;
|
|
}
|
|
late_initcall(kernel_exit_sysfs_init);
|
|
#endif
|
|
|
|
static void __unhash_process(struct task_struct *p, bool group_dead)
|
|
{
|
|
nr_threads--;
|
|
detach_pid(p, PIDTYPE_PID);
|
|
if (group_dead) {
|
|
detach_pid(p, PIDTYPE_TGID);
|
|
detach_pid(p, PIDTYPE_PGID);
|
|
detach_pid(p, PIDTYPE_SID);
|
|
|
|
list_del_rcu(&p->tasks);
|
|
list_del_init(&p->sibling);
|
|
__this_cpu_dec(process_counts);
|
|
}
|
|
list_del_rcu(&p->thread_group);
|
|
list_del_rcu(&p->thread_node);
|
|
}
|
|
|
|
/*
|
|
* This function expects the tasklist_lock write-locked.
|
|
*/
|
|
static void __exit_signal(struct task_struct *tsk)
|
|
{
|
|
struct signal_struct *sig = tsk->signal;
|
|
bool group_dead = thread_group_leader(tsk);
|
|
struct sighand_struct *sighand;
|
|
struct tty_struct *uninitialized_var(tty);
|
|
u64 utime, stime;
|
|
|
|
sighand = rcu_dereference_check(tsk->sighand,
|
|
lockdep_tasklist_lock_is_held());
|
|
spin_lock(&sighand->siglock);
|
|
|
|
#ifdef CONFIG_POSIX_TIMERS
|
|
posix_cpu_timers_exit(tsk);
|
|
if (group_dead) {
|
|
posix_cpu_timers_exit_group(tsk);
|
|
} else {
|
|
/*
|
|
* This can only happen if the caller is de_thread().
|
|
* FIXME: this is the temporary hack, we should teach
|
|
* posix-cpu-timers to handle this case correctly.
|
|
*/
|
|
if (unlikely(has_group_leader_pid(tsk)))
|
|
posix_cpu_timers_exit_group(tsk);
|
|
}
|
|
#endif
|
|
|
|
if (group_dead) {
|
|
tty = sig->tty;
|
|
sig->tty = NULL;
|
|
} else {
|
|
/*
|
|
* If there is any task waiting for the group exit
|
|
* then notify it:
|
|
*/
|
|
if (sig->notify_count > 0 && !--sig->notify_count)
|
|
wake_up_process(sig->group_exit_task);
|
|
|
|
if (tsk == sig->curr_target)
|
|
sig->curr_target = next_thread(tsk);
|
|
}
|
|
|
|
add_device_randomness((const void*) &tsk->se.sum_exec_runtime,
|
|
sizeof(unsigned long long));
|
|
|
|
/*
|
|
* Accumulate here the counters for all threads as they die. We could
|
|
* skip the group leader because it is the last user of signal_struct,
|
|
* but we want to avoid the race with thread_group_cputime() which can
|
|
* see the empty ->thread_head list.
|
|
*/
|
|
task_cputime(tsk, &utime, &stime);
|
|
write_seqlock(&sig->stats_lock);
|
|
sig->utime += utime;
|
|
sig->stime += stime;
|
|
sig->gtime += task_gtime(tsk);
|
|
sig->min_flt += tsk->min_flt;
|
|
sig->maj_flt += tsk->maj_flt;
|
|
sig->nvcsw += tsk->nvcsw;
|
|
sig->nivcsw += tsk->nivcsw;
|
|
sig->inblock += task_io_get_inblock(tsk);
|
|
sig->oublock += task_io_get_oublock(tsk);
|
|
task_io_accounting_add(&sig->ioac, &tsk->ioac);
|
|
sig->sum_sched_runtime += tsk->se.sum_exec_runtime;
|
|
sig->nr_threads--;
|
|
__unhash_process(tsk, group_dead);
|
|
write_sequnlock(&sig->stats_lock);
|
|
|
|
/*
|
|
* Do this under ->siglock, we can race with another thread
|
|
* doing sigqueue_free() if we have SIGQUEUE_PREALLOC signals.
|
|
*/
|
|
flush_sigqueue(&tsk->pending);
|
|
tsk->sighand = NULL;
|
|
spin_unlock(&sighand->siglock);
|
|
|
|
__cleanup_sighand(sighand);
|
|
clear_tsk_thread_flag(tsk, TIF_SIGPENDING);
|
|
if (group_dead) {
|
|
flush_sigqueue(&sig->shared_pending);
|
|
tty_kref_put(tty);
|
|
}
|
|
}
|
|
|
|
static void delayed_put_task_struct(struct rcu_head *rhp)
|
|
{
|
|
struct task_struct *tsk = container_of(rhp, struct task_struct, rcu);
|
|
|
|
perf_event_delayed_put(tsk);
|
|
trace_sched_process_free(tsk);
|
|
put_task_struct(tsk);
|
|
}
|
|
|
|
void put_task_struct_rcu_user(struct task_struct *task)
|
|
{
|
|
if (refcount_dec_and_test(&task->rcu_users))
|
|
call_rcu(&task->rcu, delayed_put_task_struct);
|
|
}
|
|
|
|
void release_task(struct task_struct *p)
|
|
{
|
|
struct task_struct *leader;
|
|
int zap_leader;
|
|
repeat:
|
|
/* don't need to get the RCU readlock here - the process is dead and
|
|
* can't be modifying its own credentials. But shut RCU-lockdep up */
|
|
rcu_read_lock();
|
|
atomic_dec(&__task_cred(p)->user->processes);
|
|
rcu_read_unlock();
|
|
|
|
proc_flush_task(p);
|
|
cgroup_release(p);
|
|
|
|
write_lock_irq(&tasklist_lock);
|
|
ptrace_release_task(p);
|
|
__exit_signal(p);
|
|
|
|
/*
|
|
* If we are the last non-leader member of the thread
|
|
* group, and the leader is zombie, then notify the
|
|
* group leader's parent process. (if it wants notification.)
|
|
*/
|
|
zap_leader = 0;
|
|
leader = p->group_leader;
|
|
if (leader != p && thread_group_empty(leader)
|
|
&& leader->exit_state == EXIT_ZOMBIE) {
|
|
/*
|
|
* If we were the last child thread and the leader has
|
|
* exited already, and the leader's parent ignores SIGCHLD,
|
|
* then we are the one who should release the leader.
|
|
*/
|
|
zap_leader = do_notify_parent(leader, leader->exit_signal);
|
|
if (zap_leader)
|
|
leader->exit_state = EXIT_DEAD;
|
|
}
|
|
|
|
write_unlock_irq(&tasklist_lock);
|
|
release_thread(p);
|
|
put_task_struct_rcu_user(p);
|
|
|
|
p = leader;
|
|
if (unlikely(zap_leader))
|
|
goto repeat;
|
|
}
|
|
|
|
void rcuwait_wake_up(struct rcuwait *w)
|
|
{
|
|
struct task_struct *task;
|
|
|
|
rcu_read_lock();
|
|
|
|
/*
|
|
* Order condition vs @task, such that everything prior to the load
|
|
* of @task is visible. This is the condition as to why the user called
|
|
* rcuwait_trywake() in the first place. Pairs with set_current_state()
|
|
* barrier (A) in rcuwait_wait_event().
|
|
*
|
|
* WAIT WAKE
|
|
* [S] tsk = current [S] cond = true
|
|
* MB (A) MB (B)
|
|
* [L] cond [L] tsk
|
|
*/
|
|
smp_mb(); /* (B) */
|
|
|
|
task = rcu_dereference(w->task);
|
|
if (task)
|
|
wake_up_process(task);
|
|
rcu_read_unlock();
|
|
}
|
|
|
|
/*
|
|
* Determine if a process group is "orphaned", according to the POSIX
|
|
* definition in 2.2.2.52. Orphaned process groups are not to be affected
|
|
* by terminal-generated stop signals. Newly orphaned process groups are
|
|
* to receive a SIGHUP and a SIGCONT.
|
|
*
|
|
* "I ask you, have you ever known what it is to be an orphan?"
|
|
*/
|
|
static int will_become_orphaned_pgrp(struct pid *pgrp,
|
|
struct task_struct *ignored_task)
|
|
{
|
|
struct task_struct *p;
|
|
|
|
do_each_pid_task(pgrp, PIDTYPE_PGID, p) {
|
|
if ((p == ignored_task) ||
|
|
(p->exit_state && thread_group_empty(p)) ||
|
|
is_global_init(p->real_parent))
|
|
continue;
|
|
|
|
if (task_pgrp(p->real_parent) != pgrp &&
|
|
task_session(p->real_parent) == task_session(p))
|
|
return 0;
|
|
} while_each_pid_task(pgrp, PIDTYPE_PGID, p);
|
|
|
|
return 1;
|
|
}
|
|
|
|
int is_current_pgrp_orphaned(void)
|
|
{
|
|
int retval;
|
|
|
|
read_lock(&tasklist_lock);
|
|
retval = will_become_orphaned_pgrp(task_pgrp(current), NULL);
|
|
read_unlock(&tasklist_lock);
|
|
|
|
return retval;
|
|
}
|
|
|
|
static bool has_stopped_jobs(struct pid *pgrp)
|
|
{
|
|
struct task_struct *p;
|
|
|
|
do_each_pid_task(pgrp, PIDTYPE_PGID, p) {
|
|
if (p->signal->flags & SIGNAL_STOP_STOPPED)
|
|
return true;
|
|
} while_each_pid_task(pgrp, PIDTYPE_PGID, p);
|
|
|
|
return false;
|
|
}
|
|
|
|
/*
|
|
* Check to see if any process groups have become orphaned as
|
|
* a result of our exiting, and if they have any stopped jobs,
|
|
* send them a SIGHUP and then a SIGCONT. (POSIX 3.2.2.2)
|
|
*/
|
|
static void
|
|
kill_orphaned_pgrp(struct task_struct *tsk, struct task_struct *parent)
|
|
{
|
|
struct pid *pgrp = task_pgrp(tsk);
|
|
struct task_struct *ignored_task = tsk;
|
|
|
|
if (!parent)
|
|
/* exit: our father is in a different pgrp than
|
|
* we are and we were the only connection outside.
|
|
*/
|
|
parent = tsk->real_parent;
|
|
else
|
|
/* reparent: our child is in a different pgrp than
|
|
* we are, and it was the only connection outside.
|
|
*/
|
|
ignored_task = NULL;
|
|
|
|
if (task_pgrp(parent) != pgrp &&
|
|
task_session(parent) == task_session(tsk) &&
|
|
will_become_orphaned_pgrp(pgrp, ignored_task) &&
|
|
has_stopped_jobs(pgrp)) {
|
|
__kill_pgrp_info(SIGHUP, SEND_SIG_PRIV, pgrp);
|
|
__kill_pgrp_info(SIGCONT, SEND_SIG_PRIV, pgrp);
|
|
}
|
|
}
|
|
|
|
#ifdef CONFIG_MEMCG
|
|
/*
|
|
* A task is exiting. If it owned this mm, find a new owner for the mm.
|
|
*/
|
|
void mm_update_next_owner(struct mm_struct *mm)
|
|
{
|
|
struct task_struct *c, *g, *p = current;
|
|
|
|
retry:
|
|
/*
|
|
* If the exiting or execing task is not the owner, it's
|
|
* someone else's problem.
|
|
*/
|
|
if (mm->owner != p)
|
|
return;
|
|
/*
|
|
* The current owner is exiting/execing and there are no other
|
|
* candidates. Do not leave the mm pointing to a possibly
|
|
* freed task structure.
|
|
*/
|
|
if (atomic_read(&mm->mm_users) <= 1) {
|
|
WRITE_ONCE(mm->owner, NULL);
|
|
return;
|
|
}
|
|
|
|
read_lock(&tasklist_lock);
|
|
/*
|
|
* Search in the children
|
|
*/
|
|
list_for_each_entry(c, &p->children, sibling) {
|
|
if (c->mm == mm)
|
|
goto assign_new_owner;
|
|
}
|
|
|
|
/*
|
|
* Search in the siblings
|
|
*/
|
|
list_for_each_entry(c, &p->real_parent->children, sibling) {
|
|
if (c->mm == mm)
|
|
goto assign_new_owner;
|
|
}
|
|
|
|
/*
|
|
* Search through everything else, we should not get here often.
|
|
*/
|
|
for_each_process(g) {
|
|
if (g->flags & PF_KTHREAD)
|
|
continue;
|
|
for_each_thread(g, c) {
|
|
if (c->mm == mm)
|
|
goto assign_new_owner;
|
|
if (c->mm)
|
|
break;
|
|
}
|
|
}
|
|
read_unlock(&tasklist_lock);
|
|
/*
|
|
* We found no owner yet mm_users > 1: this implies that we are
|
|
* most likely racing with swapoff (try_to_unuse()) or /proc or
|
|
* ptrace or page migration (get_task_mm()). Mark owner as NULL.
|
|
*/
|
|
WRITE_ONCE(mm->owner, NULL);
|
|
return;
|
|
|
|
assign_new_owner:
|
|
BUG_ON(c == p);
|
|
get_task_struct(c);
|
|
/*
|
|
* The task_lock protects c->mm from changing.
|
|
* We always want mm->owner->mm == mm
|
|
*/
|
|
task_lock(c);
|
|
/*
|
|
* Delay read_unlock() till we have the task_lock()
|
|
* to ensure that c does not slip away underneath us
|
|
*/
|
|
read_unlock(&tasklist_lock);
|
|
if (c->mm != mm) {
|
|
task_unlock(c);
|
|
put_task_struct(c);
|
|
goto retry;
|
|
}
|
|
WRITE_ONCE(mm->owner, c);
|
|
task_unlock(c);
|
|
put_task_struct(c);
|
|
}
|
|
#endif /* CONFIG_MEMCG */
|
|
|
|
/*
|
|
* Turn us into a lazy TLB process if we
|
|
* aren't already..
|
|
*/
|
|
static void exit_mm(void)
|
|
{
|
|
struct mm_struct *mm = current->mm;
|
|
struct core_state *core_state;
|
|
|
|
exit_mm_release(current, mm);
|
|
if (!mm)
|
|
return;
|
|
sync_mm_rss(mm);
|
|
/*
|
|
* Serialize with any possible pending coredump.
|
|
* We must hold mmap_sem around checking core_state
|
|
* and clearing tsk->mm. The core-inducing thread
|
|
* will increment ->nr_threads for each thread in the
|
|
* group with ->mm != NULL.
|
|
*/
|
|
down_read(&mm->mmap_sem);
|
|
core_state = mm->core_state;
|
|
if (core_state) {
|
|
struct core_thread self;
|
|
|
|
up_read(&mm->mmap_sem);
|
|
|
|
self.task = current;
|
|
if (self.task->flags & PF_SIGNALED)
|
|
self.next = xchg(&core_state->dumper.next, &self);
|
|
else
|
|
self.task = NULL;
|
|
/*
|
|
* Implies mb(), the result of xchg() must be visible
|
|
* to core_state->dumper.
|
|
*/
|
|
if (atomic_dec_and_test(&core_state->nr_threads))
|
|
complete(&core_state->startup);
|
|
|
|
for (;;) {
|
|
set_current_state(TASK_UNINTERRUPTIBLE);
|
|
if (!self.task) /* see coredump_finish() */
|
|
break;
|
|
freezable_schedule();
|
|
}
|
|
__set_current_state(TASK_RUNNING);
|
|
down_read(&mm->mmap_sem);
|
|
}
|
|
mmgrab(mm);
|
|
BUG_ON(mm != current->active_mm);
|
|
/* more a memory barrier than a real lock */
|
|
task_lock(current);
|
|
current->mm = NULL;
|
|
up_read(&mm->mmap_sem);
|
|
enter_lazy_tlb(mm, current);
|
|
task_unlock(current);
|
|
mm_update_next_owner(mm);
|
|
mmput(mm);
|
|
if (test_thread_flag(TIF_MEMDIE))
|
|
exit_oom_victim();
|
|
}
|
|
|
|
static struct task_struct *find_alive_thread(struct task_struct *p)
|
|
{
|
|
struct task_struct *t;
|
|
|
|
for_each_thread(p, t) {
|
|
if (!(t->flags & PF_EXITING))
|
|
return t;
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
static struct task_struct *find_child_reaper(struct task_struct *father,
|
|
struct list_head *dead)
|
|
__releases(&tasklist_lock)
|
|
__acquires(&tasklist_lock)
|
|
{
|
|
struct pid_namespace *pid_ns = task_active_pid_ns(father);
|
|
struct task_struct *reaper = pid_ns->child_reaper;
|
|
struct task_struct *p, *n;
|
|
|
|
if (likely(reaper != father))
|
|
return reaper;
|
|
|
|
reaper = find_alive_thread(father);
|
|
if (reaper) {
|
|
pid_ns->child_reaper = reaper;
|
|
return reaper;
|
|
}
|
|
|
|
write_unlock_irq(&tasklist_lock);
|
|
|
|
list_for_each_entry_safe(p, n, dead, ptrace_entry) {
|
|
list_del_init(&p->ptrace_entry);
|
|
release_task(p);
|
|
}
|
|
|
|
zap_pid_ns_processes(pid_ns);
|
|
write_lock_irq(&tasklist_lock);
|
|
|
|
return father;
|
|
}
|
|
|
|
/*
|
|
* When we die, we re-parent all our children, and try to:
|
|
* 1. give them to another thread in our thread group, if such a member exists
|
|
* 2. give it to the first ancestor process which prctl'd itself as a
|
|
* child_subreaper for its children (like a service manager)
|
|
* 3. give it to the init process (PID 1) in our pid namespace
|
|
*/
|
|
static struct task_struct *find_new_reaper(struct task_struct *father,
|
|
struct task_struct *child_reaper)
|
|
{
|
|
struct task_struct *thread, *reaper;
|
|
|
|
thread = find_alive_thread(father);
|
|
if (thread)
|
|
return thread;
|
|
|
|
if (father->signal->has_child_subreaper) {
|
|
unsigned int ns_level = task_pid(father)->level;
|
|
/*
|
|
* Find the first ->is_child_subreaper ancestor in our pid_ns.
|
|
* We can't check reaper != child_reaper to ensure we do not
|
|
* cross the namespaces, the exiting parent could be injected
|
|
* by setns() + fork().
|
|
* We check pid->level, this is slightly more efficient than
|
|
* task_active_pid_ns(reaper) != task_active_pid_ns(father).
|
|
*/
|
|
for (reaper = father->real_parent;
|
|
task_pid(reaper)->level == ns_level;
|
|
reaper = reaper->real_parent) {
|
|
if (reaper == &init_task)
|
|
break;
|
|
if (!reaper->signal->is_child_subreaper)
|
|
continue;
|
|
thread = find_alive_thread(reaper);
|
|
if (thread)
|
|
return thread;
|
|
}
|
|
}
|
|
|
|
return child_reaper;
|
|
}
|
|
|
|
/*
|
|
* Any that need to be release_task'd are put on the @dead list.
|
|
*/
|
|
static void reparent_leader(struct task_struct *father, struct task_struct *p,
|
|
struct list_head *dead)
|
|
{
|
|
if (unlikely(p->exit_state == EXIT_DEAD))
|
|
return;
|
|
|
|
/* We don't want people slaying init. */
|
|
p->exit_signal = SIGCHLD;
|
|
|
|
/* If it has exited notify the new parent about this child's death. */
|
|
if (!p->ptrace &&
|
|
p->exit_state == EXIT_ZOMBIE && thread_group_empty(p)) {
|
|
if (do_notify_parent(p, p->exit_signal)) {
|
|
p->exit_state = EXIT_DEAD;
|
|
list_add(&p->ptrace_entry, dead);
|
|
}
|
|
}
|
|
|
|
kill_orphaned_pgrp(p, father);
|
|
}
|
|
|
|
/*
|
|
* This does two things:
|
|
*
|
|
* A. Make init inherit all the child processes
|
|
* B. Check to see if any process groups have become orphaned
|
|
* as a result of our exiting, and if they have any stopped
|
|
* jobs, send them a SIGHUP and then a SIGCONT. (POSIX 3.2.2.2)
|
|
*/
|
|
static void forget_original_parent(struct task_struct *father,
|
|
struct list_head *dead)
|
|
{
|
|
struct task_struct *p, *t, *reaper;
|
|
|
|
if (unlikely(!list_empty(&father->ptraced)))
|
|
exit_ptrace(father, dead);
|
|
|
|
/* Can drop and reacquire tasklist_lock */
|
|
reaper = find_child_reaper(father, dead);
|
|
if (list_empty(&father->children))
|
|
return;
|
|
|
|
reaper = find_new_reaper(father, reaper);
|
|
list_for_each_entry(p, &father->children, sibling) {
|
|
for_each_thread(p, t) {
|
|
t->real_parent = reaper;
|
|
BUG_ON((!t->ptrace) != (t->parent == father));
|
|
if (likely(!t->ptrace))
|
|
t->parent = t->real_parent;
|
|
if (t->pdeath_signal)
|
|
group_send_sig_info(t->pdeath_signal,
|
|
SEND_SIG_NOINFO, t,
|
|
PIDTYPE_TGID);
|
|
}
|
|
/*
|
|
* If this is a threaded reparent there is no need to
|
|
* notify anyone anything has happened.
|
|
*/
|
|
if (!same_thread_group(reaper, father))
|
|
reparent_leader(father, p, dead);
|
|
}
|
|
list_splice_tail_init(&father->children, &reaper->children);
|
|
}
|
|
|
|
/*
|
|
* Send signals to all our closest relatives so that they know
|
|
* to properly mourn us..
|
|
*/
|
|
static void exit_notify(struct task_struct *tsk, int group_dead)
|
|
{
|
|
bool autoreap;
|
|
struct task_struct *p, *n;
|
|
LIST_HEAD(dead);
|
|
|
|
write_lock_irq(&tasklist_lock);
|
|
forget_original_parent(tsk, &dead);
|
|
|
|
if (group_dead)
|
|
kill_orphaned_pgrp(tsk->group_leader, NULL);
|
|
|
|
tsk->exit_state = EXIT_ZOMBIE;
|
|
if (unlikely(tsk->ptrace)) {
|
|
int sig = thread_group_leader(tsk) &&
|
|
thread_group_empty(tsk) &&
|
|
!ptrace_reparented(tsk) ?
|
|
tsk->exit_signal : SIGCHLD;
|
|
autoreap = do_notify_parent(tsk, sig);
|
|
} else if (thread_group_leader(tsk)) {
|
|
autoreap = thread_group_empty(tsk) &&
|
|
do_notify_parent(tsk, tsk->exit_signal);
|
|
} else {
|
|
autoreap = true;
|
|
}
|
|
|
|
if (autoreap) {
|
|
tsk->exit_state = EXIT_DEAD;
|
|
list_add(&tsk->ptrace_entry, &dead);
|
|
}
|
|
|
|
/* mt-exec, de_thread() is waiting for group leader */
|
|
if (unlikely(tsk->signal->notify_count < 0))
|
|
wake_up_process(tsk->signal->group_exit_task);
|
|
write_unlock_irq(&tasklist_lock);
|
|
|
|
list_for_each_entry_safe(p, n, &dead, ptrace_entry) {
|
|
list_del_init(&p->ptrace_entry);
|
|
release_task(p);
|
|
}
|
|
}
|
|
|
|
#ifdef CONFIG_DEBUG_STACK_USAGE
|
|
static void check_stack_usage(void)
|
|
{
|
|
static DEFINE_SPINLOCK(low_water_lock);
|
|
static int lowest_to_date = THREAD_SIZE;
|
|
unsigned long free;
|
|
|
|
free = stack_not_used(current);
|
|
|
|
if (free >= lowest_to_date)
|
|
return;
|
|
|
|
spin_lock(&low_water_lock);
|
|
if (free < lowest_to_date) {
|
|
pr_info("%s (%d) used greatest stack depth: %lu bytes left\n",
|
|
current->comm, task_pid_nr(current), free);
|
|
lowest_to_date = free;
|
|
}
|
|
spin_unlock(&low_water_lock);
|
|
}
|
|
#else
|
|
static inline void check_stack_usage(void) {}
|
|
#endif
|
|
|
|
void __noreturn do_exit(long code)
|
|
{
|
|
struct task_struct *tsk = current;
|
|
int group_dead;
|
|
|
|
/*
|
|
* We can get here from a kernel oops, sometimes with preemption off.
|
|
* Start by checking for critical errors.
|
|
* Then fix up important state like USER_DS and preemption.
|
|
* Then do everything else.
|
|
*/
|
|
|
|
WARN_ON(blk_needs_flush_plug(tsk));
|
|
|
|
if (unlikely(in_interrupt()))
|
|
panic("Aiee, killing interrupt handler!");
|
|
if (unlikely(!tsk->pid))
|
|
panic("Attempted to kill the idle task!");
|
|
|
|
/*
|
|
* If do_exit is called because this processes oopsed, it's possible
|
|
* that get_fs() was left as KERNEL_DS, so reset it to USER_DS before
|
|
* continuing. Amongst other possible reasons, this is to prevent
|
|
* mm_release()->clear_child_tid() from writing to a user-controlled
|
|
* kernel address.
|
|
*/
|
|
set_fs(USER_DS);
|
|
|
|
if (unlikely(in_atomic())) {
|
|
pr_info("note: %s[%d] exited with preempt_count %d\n",
|
|
current->comm, task_pid_nr(current),
|
|
preempt_count());
|
|
preempt_count_set(PREEMPT_ENABLED);
|
|
}
|
|
|
|
profile_task_exit(tsk);
|
|
kcov_task_exit(tsk);
|
|
|
|
ptrace_event(PTRACE_EVENT_EXIT, code);
|
|
|
|
validate_creds_for_do_exit(tsk);
|
|
|
|
/*
|
|
* We're taking recursive faults here in do_exit. Safest is to just
|
|
* leave this task alone and wait for reboot.
|
|
*/
|
|
if (unlikely(tsk->flags & PF_EXITING)) {
|
|
pr_alert("Fixing recursive fault but reboot is needed!\n");
|
|
futex_exit_recursive(tsk);
|
|
set_current_state(TASK_UNINTERRUPTIBLE);
|
|
schedule();
|
|
}
|
|
|
|
exit_signals(tsk); /* sets PF_EXITING */
|
|
|
|
/* sync mm's RSS info before statistics gathering */
|
|
if (tsk->mm)
|
|
sync_mm_rss(tsk->mm);
|
|
acct_update_integrals(tsk);
|
|
group_dead = atomic_dec_and_test(&tsk->signal->live);
|
|
if (group_dead) {
|
|
/*
|
|
* If the last thread of global init has exited, panic
|
|
* immediately to get a useable coredump.
|
|
*/
|
|
if (unlikely(is_global_init(tsk)))
|
|
panic("Attempted to kill init! exitcode=0x%08x\n",
|
|
tsk->signal->group_exit_code ?: (int)code);
|
|
|
|
#ifdef CONFIG_POSIX_TIMERS
|
|
hrtimer_cancel(&tsk->signal->real_timer);
|
|
exit_itimers(tsk->signal);
|
|
#endif
|
|
if (tsk->mm)
|
|
setmax_mm_hiwater_rss(&tsk->signal->maxrss, tsk->mm);
|
|
}
|
|
acct_collect(code, group_dead);
|
|
if (group_dead)
|
|
tty_audit_exit();
|
|
audit_free(tsk);
|
|
|
|
tsk->exit_code = code;
|
|
taskstats_exit(tsk, group_dead);
|
|
|
|
exit_mm();
|
|
|
|
if (group_dead)
|
|
acct_process();
|
|
trace_sched_process_exit(tsk);
|
|
|
|
exit_sem(tsk);
|
|
exit_shm(tsk);
|
|
exit_files(tsk);
|
|
exit_fs(tsk);
|
|
if (group_dead)
|
|
disassociate_ctty(1);
|
|
exit_task_namespaces(tsk);
|
|
exit_task_work(tsk);
|
|
exit_thread(tsk);
|
|
exit_umh(tsk);
|
|
|
|
/*
|
|
* Flush inherited counters to the parent - before the parent
|
|
* gets woken up by child-exit notifications.
|
|
*
|
|
* because of cgroup mode, must be called before cgroup_exit()
|
|
*/
|
|
perf_event_exit_task(tsk);
|
|
|
|
sched_autogroup_exit_task(tsk);
|
|
cgroup_exit(tsk);
|
|
|
|
/*
|
|
* FIXME: do that only when needed, using sched_exit tracepoint
|
|
*/
|
|
flush_ptrace_hw_breakpoint(tsk);
|
|
|
|
exit_tasks_rcu_start();
|
|
exit_notify(tsk, group_dead);
|
|
proc_exit_connector(tsk);
|
|
mpol_put_task_policy(tsk);
|
|
#ifdef CONFIG_FUTEX
|
|
if (unlikely(current->pi_state_cache))
|
|
kfree(current->pi_state_cache);
|
|
#endif
|
|
/*
|
|
* Make sure we are holding no locks:
|
|
*/
|
|
debug_check_no_locks_held();
|
|
|
|
if (tsk->io_context)
|
|
exit_io_context(tsk);
|
|
|
|
if (tsk->splice_pipe)
|
|
free_pipe_info(tsk->splice_pipe);
|
|
|
|
if (tsk->task_frag.page)
|
|
put_page(tsk->task_frag.page);
|
|
|
|
validate_creds_for_do_exit(tsk);
|
|
|
|
check_stack_usage();
|
|
preempt_disable();
|
|
if (tsk->nr_dirtied)
|
|
__this_cpu_add(dirty_throttle_leaks, tsk->nr_dirtied);
|
|
exit_rcu();
|
|
exit_tasks_rcu_finish();
|
|
|
|
lockdep_free_task(tsk);
|
|
do_task_dead();
|
|
}
|
|
EXPORT_SYMBOL_GPL(do_exit);
|
|
|
|
void __noreturn make_task_dead(int signr)
|
|
{
|
|
/*
|
|
* Take the task off the cpu after something catastrophic has
|
|
* happened.
|
|
*/
|
|
unsigned int limit;
|
|
|
|
/*
|
|
* Every time the system oopses, if the oops happens while a reference
|
|
* to an object was held, the reference leaks.
|
|
* If the oops doesn't also leak memory, repeated oopsing can cause
|
|
* reference counters to wrap around (if they're not using refcount_t).
|
|
* This means that repeated oopsing can make unexploitable-looking bugs
|
|
* exploitable through repeated oopsing.
|
|
* To make sure this can't happen, place an upper bound on how often the
|
|
* kernel may oops without panic().
|
|
*/
|
|
limit = READ_ONCE(oops_limit);
|
|
if (atomic_inc_return(&oops_count) >= limit && limit)
|
|
panic("Oopsed too often (kernel.oops_limit is %d)", limit);
|
|
|
|
do_exit(signr);
|
|
}
|
|
|
|
void complete_and_exit(struct completion *comp, long code)
|
|
{
|
|
if (comp)
|
|
complete(comp);
|
|
|
|
do_exit(code);
|
|
}
|
|
EXPORT_SYMBOL(complete_and_exit);
|
|
|
|
SYSCALL_DEFINE1(exit, int, error_code)
|
|
{
|
|
do_exit((error_code&0xff)<<8);
|
|
}
|
|
|
|
/*
|
|
* Take down every thread in the group. This is called by fatal signals
|
|
* as well as by sys_exit_group (below).
|
|
*/
|
|
void
|
|
do_group_exit(int exit_code)
|
|
{
|
|
struct signal_struct *sig = current->signal;
|
|
|
|
BUG_ON(exit_code & 0x80); /* core dumps don't get here */
|
|
|
|
if (signal_group_exit(sig))
|
|
exit_code = sig->group_exit_code;
|
|
else if (!thread_group_empty(current)) {
|
|
struct sighand_struct *const sighand = current->sighand;
|
|
|
|
spin_lock_irq(&sighand->siglock);
|
|
if (signal_group_exit(sig))
|
|
/* Another thread got here before we took the lock. */
|
|
exit_code = sig->group_exit_code;
|
|
else {
|
|
sig->group_exit_code = exit_code;
|
|
sig->flags = SIGNAL_GROUP_EXIT;
|
|
zap_other_threads(current);
|
|
}
|
|
spin_unlock_irq(&sighand->siglock);
|
|
}
|
|
|
|
do_exit(exit_code);
|
|
/* NOTREACHED */
|
|
}
|
|
|
|
/*
|
|
* this kills every thread in the thread group. Note that any externally
|
|
* wait4()-ing process will get the correct exit code - even if this
|
|
* thread is not the thread group leader.
|
|
*/
|
|
SYSCALL_DEFINE1(exit_group, int, error_code)
|
|
{
|
|
do_group_exit((error_code & 0xff) << 8);
|
|
/* NOTREACHED */
|
|
return 0;
|
|
}
|
|
|
|
struct waitid_info {
|
|
pid_t pid;
|
|
uid_t uid;
|
|
int status;
|
|
int cause;
|
|
};
|
|
|
|
struct wait_opts {
|
|
enum pid_type wo_type;
|
|
int wo_flags;
|
|
struct pid *wo_pid;
|
|
|
|
struct waitid_info *wo_info;
|
|
int wo_stat;
|
|
struct rusage *wo_rusage;
|
|
|
|
wait_queue_entry_t child_wait;
|
|
int notask_error;
|
|
};
|
|
|
|
static int eligible_pid(struct wait_opts *wo, struct task_struct *p)
|
|
{
|
|
return wo->wo_type == PIDTYPE_MAX ||
|
|
task_pid_type(p, wo->wo_type) == wo->wo_pid;
|
|
}
|
|
|
|
static int
|
|
eligible_child(struct wait_opts *wo, bool ptrace, struct task_struct *p)
|
|
{
|
|
if (!eligible_pid(wo, p))
|
|
return 0;
|
|
|
|
/*
|
|
* Wait for all children (clone and not) if __WALL is set or
|
|
* if it is traced by us.
|
|
*/
|
|
if (ptrace || (wo->wo_flags & __WALL))
|
|
return 1;
|
|
|
|
/*
|
|
* Otherwise, wait for clone children *only* if __WCLONE is set;
|
|
* otherwise, wait for non-clone children *only*.
|
|
*
|
|
* Note: a "clone" child here is one that reports to its parent
|
|
* using a signal other than SIGCHLD, or a non-leader thread which
|
|
* we can only see if it is traced by us.
|
|
*/
|
|
if ((p->exit_signal != SIGCHLD) ^ !!(wo->wo_flags & __WCLONE))
|
|
return 0;
|
|
|
|
return 1;
|
|
}
|
|
|
|
/*
|
|
* Handle sys_wait4 work for one task in state EXIT_ZOMBIE. We hold
|
|
* read_lock(&tasklist_lock) on entry. If we return zero, we still hold
|
|
* the lock and this task is uninteresting. If we return nonzero, we have
|
|
* released the lock and the system call should return.
|
|
*/
|
|
static int wait_task_zombie(struct wait_opts *wo, struct task_struct *p)
|
|
{
|
|
int state, status;
|
|
pid_t pid = task_pid_vnr(p);
|
|
uid_t uid = from_kuid_munged(current_user_ns(), task_uid(p));
|
|
struct waitid_info *infop;
|
|
|
|
if (!likely(wo->wo_flags & WEXITED))
|
|
return 0;
|
|
|
|
if (unlikely(wo->wo_flags & WNOWAIT)) {
|
|
status = p->exit_code;
|
|
get_task_struct(p);
|
|
read_unlock(&tasklist_lock);
|
|
sched_annotate_sleep();
|
|
if (wo->wo_rusage)
|
|
getrusage(p, RUSAGE_BOTH, wo->wo_rusage);
|
|
put_task_struct(p);
|
|
goto out_info;
|
|
}
|
|
/*
|
|
* Move the task's state to DEAD/TRACE, only one thread can do this.
|
|
*/
|
|
state = (ptrace_reparented(p) && thread_group_leader(p)) ?
|
|
EXIT_TRACE : EXIT_DEAD;
|
|
if (cmpxchg(&p->exit_state, EXIT_ZOMBIE, state) != EXIT_ZOMBIE)
|
|
return 0;
|
|
/*
|
|
* We own this thread, nobody else can reap it.
|
|
*/
|
|
read_unlock(&tasklist_lock);
|
|
sched_annotate_sleep();
|
|
|
|
/*
|
|
* Check thread_group_leader() to exclude the traced sub-threads.
|
|
*/
|
|
if (state == EXIT_DEAD && thread_group_leader(p)) {
|
|
struct signal_struct *sig = p->signal;
|
|
struct signal_struct *psig = current->signal;
|
|
unsigned long maxrss;
|
|
u64 tgutime, tgstime;
|
|
|
|
/*
|
|
* The resource counters for the group leader are in its
|
|
* own task_struct. Those for dead threads in the group
|
|
* are in its signal_struct, as are those for the child
|
|
* processes it has previously reaped. All these
|
|
* accumulate in the parent's signal_struct c* fields.
|
|
*
|
|
* We don't bother to take a lock here to protect these
|
|
* p->signal fields because the whole thread group is dead
|
|
* and nobody can change them.
|
|
*
|
|
* psig->stats_lock also protects us from our sub-theads
|
|
* which can reap other children at the same time. Until
|
|
* we change k_getrusage()-like users to rely on this lock
|
|
* we have to take ->siglock as well.
|
|
*
|
|
* We use thread_group_cputime_adjusted() to get times for
|
|
* the thread group, which consolidates times for all threads
|
|
* in the group including the group leader.
|
|
*/
|
|
thread_group_cputime_adjusted(p, &tgutime, &tgstime);
|
|
spin_lock_irq(¤t->sighand->siglock);
|
|
write_seqlock(&psig->stats_lock);
|
|
psig->cutime += tgutime + sig->cutime;
|
|
psig->cstime += tgstime + sig->cstime;
|
|
psig->cgtime += task_gtime(p) + sig->gtime + sig->cgtime;
|
|
psig->cmin_flt +=
|
|
p->min_flt + sig->min_flt + sig->cmin_flt;
|
|
psig->cmaj_flt +=
|
|
p->maj_flt + sig->maj_flt + sig->cmaj_flt;
|
|
psig->cnvcsw +=
|
|
p->nvcsw + sig->nvcsw + sig->cnvcsw;
|
|
psig->cnivcsw +=
|
|
p->nivcsw + sig->nivcsw + sig->cnivcsw;
|
|
psig->cinblock +=
|
|
task_io_get_inblock(p) +
|
|
sig->inblock + sig->cinblock;
|
|
psig->coublock +=
|
|
task_io_get_oublock(p) +
|
|
sig->oublock + sig->coublock;
|
|
maxrss = max(sig->maxrss, sig->cmaxrss);
|
|
if (psig->cmaxrss < maxrss)
|
|
psig->cmaxrss = maxrss;
|
|
task_io_accounting_add(&psig->ioac, &p->ioac);
|
|
task_io_accounting_add(&psig->ioac, &sig->ioac);
|
|
write_sequnlock(&psig->stats_lock);
|
|
spin_unlock_irq(¤t->sighand->siglock);
|
|
}
|
|
|
|
if (wo->wo_rusage)
|
|
getrusage(p, RUSAGE_BOTH, wo->wo_rusage);
|
|
status = (p->signal->flags & SIGNAL_GROUP_EXIT)
|
|
? p->signal->group_exit_code : p->exit_code;
|
|
wo->wo_stat = status;
|
|
|
|
if (state == EXIT_TRACE) {
|
|
write_lock_irq(&tasklist_lock);
|
|
/* We dropped tasklist, ptracer could die and untrace */
|
|
ptrace_unlink(p);
|
|
|
|
/* If parent wants a zombie, don't release it now */
|
|
state = EXIT_ZOMBIE;
|
|
if (do_notify_parent(p, p->exit_signal))
|
|
state = EXIT_DEAD;
|
|
p->exit_state = state;
|
|
write_unlock_irq(&tasklist_lock);
|
|
}
|
|
if (state == EXIT_DEAD)
|
|
release_task(p);
|
|
|
|
out_info:
|
|
infop = wo->wo_info;
|
|
if (infop) {
|
|
if ((status & 0x7f) == 0) {
|
|
infop->cause = CLD_EXITED;
|
|
infop->status = status >> 8;
|
|
} else {
|
|
infop->cause = (status & 0x80) ? CLD_DUMPED : CLD_KILLED;
|
|
infop->status = status & 0x7f;
|
|
}
|
|
infop->pid = pid;
|
|
infop->uid = uid;
|
|
}
|
|
|
|
return pid;
|
|
}
|
|
|
|
static int *task_stopped_code(struct task_struct *p, bool ptrace)
|
|
{
|
|
if (ptrace) {
|
|
if (task_is_traced(p) && !(p->jobctl & JOBCTL_LISTENING))
|
|
return &p->exit_code;
|
|
} else {
|
|
if (p->signal->flags & SIGNAL_STOP_STOPPED)
|
|
return &p->signal->group_exit_code;
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
/**
|
|
* wait_task_stopped - Wait for %TASK_STOPPED or %TASK_TRACED
|
|
* @wo: wait options
|
|
* @ptrace: is the wait for ptrace
|
|
* @p: task to wait for
|
|
*
|
|
* Handle sys_wait4() work for %p in state %TASK_STOPPED or %TASK_TRACED.
|
|
*
|
|
* CONTEXT:
|
|
* read_lock(&tasklist_lock), which is released if return value is
|
|
* non-zero. Also, grabs and releases @p->sighand->siglock.
|
|
*
|
|
* RETURNS:
|
|
* 0 if wait condition didn't exist and search for other wait conditions
|
|
* should continue. Non-zero return, -errno on failure and @p's pid on
|
|
* success, implies that tasklist_lock is released and wait condition
|
|
* search should terminate.
|
|
*/
|
|
static int wait_task_stopped(struct wait_opts *wo,
|
|
int ptrace, struct task_struct *p)
|
|
{
|
|
struct waitid_info *infop;
|
|
int exit_code, *p_code, why;
|
|
uid_t uid = 0; /* unneeded, required by compiler */
|
|
pid_t pid;
|
|
|
|
/*
|
|
* Traditionally we see ptrace'd stopped tasks regardless of options.
|
|
*/
|
|
if (!ptrace && !(wo->wo_flags & WUNTRACED))
|
|
return 0;
|
|
|
|
if (!task_stopped_code(p, ptrace))
|
|
return 0;
|
|
|
|
exit_code = 0;
|
|
spin_lock_irq(&p->sighand->siglock);
|
|
|
|
p_code = task_stopped_code(p, ptrace);
|
|
if (unlikely(!p_code))
|
|
goto unlock_sig;
|
|
|
|
exit_code = *p_code;
|
|
if (!exit_code)
|
|
goto unlock_sig;
|
|
|
|
if (!unlikely(wo->wo_flags & WNOWAIT))
|
|
*p_code = 0;
|
|
|
|
uid = from_kuid_munged(current_user_ns(), task_uid(p));
|
|
unlock_sig:
|
|
spin_unlock_irq(&p->sighand->siglock);
|
|
if (!exit_code)
|
|
return 0;
|
|
|
|
/*
|
|
* Now we are pretty sure this task is interesting.
|
|
* Make sure it doesn't get reaped out from under us while we
|
|
* give up the lock and then examine it below. We don't want to
|
|
* keep holding onto the tasklist_lock while we call getrusage and
|
|
* possibly take page faults for user memory.
|
|
*/
|
|
get_task_struct(p);
|
|
pid = task_pid_vnr(p);
|
|
why = ptrace ? CLD_TRAPPED : CLD_STOPPED;
|
|
read_unlock(&tasklist_lock);
|
|
sched_annotate_sleep();
|
|
if (wo->wo_rusage)
|
|
getrusage(p, RUSAGE_BOTH, wo->wo_rusage);
|
|
put_task_struct(p);
|
|
|
|
if (likely(!(wo->wo_flags & WNOWAIT)))
|
|
wo->wo_stat = (exit_code << 8) | 0x7f;
|
|
|
|
infop = wo->wo_info;
|
|
if (infop) {
|
|
infop->cause = why;
|
|
infop->status = exit_code;
|
|
infop->pid = pid;
|
|
infop->uid = uid;
|
|
}
|
|
return pid;
|
|
}
|
|
|
|
/*
|
|
* Handle do_wait work for one task in a live, non-stopped state.
|
|
* read_lock(&tasklist_lock) on entry. If we return zero, we still hold
|
|
* the lock and this task is uninteresting. If we return nonzero, we have
|
|
* released the lock and the system call should return.
|
|
*/
|
|
static int wait_task_continued(struct wait_opts *wo, struct task_struct *p)
|
|
{
|
|
struct waitid_info *infop;
|
|
pid_t pid;
|
|
uid_t uid;
|
|
|
|
if (!unlikely(wo->wo_flags & WCONTINUED))
|
|
return 0;
|
|
|
|
if (!(p->signal->flags & SIGNAL_STOP_CONTINUED))
|
|
return 0;
|
|
|
|
spin_lock_irq(&p->sighand->siglock);
|
|
/* Re-check with the lock held. */
|
|
if (!(p->signal->flags & SIGNAL_STOP_CONTINUED)) {
|
|
spin_unlock_irq(&p->sighand->siglock);
|
|
return 0;
|
|
}
|
|
if (!unlikely(wo->wo_flags & WNOWAIT))
|
|
p->signal->flags &= ~SIGNAL_STOP_CONTINUED;
|
|
uid = from_kuid_munged(current_user_ns(), task_uid(p));
|
|
spin_unlock_irq(&p->sighand->siglock);
|
|
|
|
pid = task_pid_vnr(p);
|
|
get_task_struct(p);
|
|
read_unlock(&tasklist_lock);
|
|
sched_annotate_sleep();
|
|
if (wo->wo_rusage)
|
|
getrusage(p, RUSAGE_BOTH, wo->wo_rusage);
|
|
put_task_struct(p);
|
|
|
|
infop = wo->wo_info;
|
|
if (!infop) {
|
|
wo->wo_stat = 0xffff;
|
|
} else {
|
|
infop->cause = CLD_CONTINUED;
|
|
infop->pid = pid;
|
|
infop->uid = uid;
|
|
infop->status = SIGCONT;
|
|
}
|
|
return pid;
|
|
}
|
|
|
|
/*
|
|
* Consider @p for a wait by @parent.
|
|
*
|
|
* -ECHILD should be in ->notask_error before the first call.
|
|
* Returns nonzero for a final return, when we have unlocked tasklist_lock.
|
|
* Returns zero if the search for a child should continue;
|
|
* then ->notask_error is 0 if @p is an eligible child,
|
|
* or still -ECHILD.
|
|
*/
|
|
static int wait_consider_task(struct wait_opts *wo, int ptrace,
|
|
struct task_struct *p)
|
|
{
|
|
/*
|
|
* We can race with wait_task_zombie() from another thread.
|
|
* Ensure that EXIT_ZOMBIE -> EXIT_DEAD/EXIT_TRACE transition
|
|
* can't confuse the checks below.
|
|
*/
|
|
int exit_state = READ_ONCE(p->exit_state);
|
|
int ret;
|
|
|
|
if (unlikely(exit_state == EXIT_DEAD))
|
|
return 0;
|
|
|
|
ret = eligible_child(wo, ptrace, p);
|
|
if (!ret)
|
|
return ret;
|
|
|
|
if (unlikely(exit_state == EXIT_TRACE)) {
|
|
/*
|
|
* ptrace == 0 means we are the natural parent. In this case
|
|
* we should clear notask_error, debugger will notify us.
|
|
*/
|
|
if (likely(!ptrace))
|
|
wo->notask_error = 0;
|
|
return 0;
|
|
}
|
|
|
|
if (likely(!ptrace) && unlikely(p->ptrace)) {
|
|
/*
|
|
* If it is traced by its real parent's group, just pretend
|
|
* the caller is ptrace_do_wait() and reap this child if it
|
|
* is zombie.
|
|
*
|
|
* This also hides group stop state from real parent; otherwise
|
|
* a single stop can be reported twice as group and ptrace stop.
|
|
* If a ptracer wants to distinguish these two events for its
|
|
* own children it should create a separate process which takes
|
|
* the role of real parent.
|
|
*/
|
|
if (!ptrace_reparented(p))
|
|
ptrace = 1;
|
|
}
|
|
|
|
/* slay zombie? */
|
|
if (exit_state == EXIT_ZOMBIE) {
|
|
/* we don't reap group leaders with subthreads */
|
|
if (!delay_group_leader(p)) {
|
|
/*
|
|
* A zombie ptracee is only visible to its ptracer.
|
|
* Notification and reaping will be cascaded to the
|
|
* real parent when the ptracer detaches.
|
|
*/
|
|
if (unlikely(ptrace) || likely(!p->ptrace))
|
|
return wait_task_zombie(wo, p);
|
|
}
|
|
|
|
/*
|
|
* Allow access to stopped/continued state via zombie by
|
|
* falling through. Clearing of notask_error is complex.
|
|
*
|
|
* When !@ptrace:
|
|
*
|
|
* If WEXITED is set, notask_error should naturally be
|
|
* cleared. If not, subset of WSTOPPED|WCONTINUED is set,
|
|
* so, if there are live subthreads, there are events to
|
|
* wait for. If all subthreads are dead, it's still safe
|
|
* to clear - this function will be called again in finite
|
|
* amount time once all the subthreads are released and
|
|
* will then return without clearing.
|
|
*
|
|
* When @ptrace:
|
|
*
|
|
* Stopped state is per-task and thus can't change once the
|
|
* target task dies. Only continued and exited can happen.
|
|
* Clear notask_error if WCONTINUED | WEXITED.
|
|
*/
|
|
if (likely(!ptrace) || (wo->wo_flags & (WCONTINUED | WEXITED)))
|
|
wo->notask_error = 0;
|
|
} else {
|
|
/*
|
|
* @p is alive and it's gonna stop, continue or exit, so
|
|
* there always is something to wait for.
|
|
*/
|
|
wo->notask_error = 0;
|
|
}
|
|
|
|
/*
|
|
* Wait for stopped. Depending on @ptrace, different stopped state
|
|
* is used and the two don't interact with each other.
|
|
*/
|
|
ret = wait_task_stopped(wo, ptrace, p);
|
|
if (ret)
|
|
return ret;
|
|
|
|
/*
|
|
* Wait for continued. There's only one continued state and the
|
|
* ptracer can consume it which can confuse the real parent. Don't
|
|
* use WCONTINUED from ptracer. You don't need or want it.
|
|
*/
|
|
return wait_task_continued(wo, p);
|
|
}
|
|
|
|
/*
|
|
* Do the work of do_wait() for one thread in the group, @tsk.
|
|
*
|
|
* -ECHILD should be in ->notask_error before the first call.
|
|
* Returns nonzero for a final return, when we have unlocked tasklist_lock.
|
|
* Returns zero if the search for a child should continue; then
|
|
* ->notask_error is 0 if there were any eligible children,
|
|
* or still -ECHILD.
|
|
*/
|
|
static int do_wait_thread(struct wait_opts *wo, struct task_struct *tsk)
|
|
{
|
|
struct task_struct *p;
|
|
|
|
list_for_each_entry(p, &tsk->children, sibling) {
|
|
int ret = wait_consider_task(wo, 0, p);
|
|
|
|
if (ret)
|
|
return ret;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int ptrace_do_wait(struct wait_opts *wo, struct task_struct *tsk)
|
|
{
|
|
struct task_struct *p;
|
|
|
|
list_for_each_entry(p, &tsk->ptraced, ptrace_entry) {
|
|
int ret = wait_consider_task(wo, 1, p);
|
|
|
|
if (ret)
|
|
return ret;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int child_wait_callback(wait_queue_entry_t *wait, unsigned mode,
|
|
int sync, void *key)
|
|
{
|
|
struct wait_opts *wo = container_of(wait, struct wait_opts,
|
|
child_wait);
|
|
struct task_struct *p = key;
|
|
|
|
if (!eligible_pid(wo, p))
|
|
return 0;
|
|
|
|
if ((wo->wo_flags & __WNOTHREAD) && wait->private != p->parent)
|
|
return 0;
|
|
|
|
return default_wake_function(wait, mode, sync, key);
|
|
}
|
|
|
|
void __wake_up_parent(struct task_struct *p, struct task_struct *parent)
|
|
{
|
|
__wake_up_sync_key(&parent->signal->wait_chldexit,
|
|
TASK_INTERRUPTIBLE, 1, p);
|
|
}
|
|
|
|
static long do_wait(struct wait_opts *wo)
|
|
{
|
|
struct task_struct *tsk;
|
|
int retval;
|
|
|
|
trace_sched_process_wait(wo->wo_pid);
|
|
|
|
init_waitqueue_func_entry(&wo->child_wait, child_wait_callback);
|
|
wo->child_wait.private = current;
|
|
add_wait_queue(¤t->signal->wait_chldexit, &wo->child_wait);
|
|
repeat:
|
|
/*
|
|
* If there is nothing that can match our criteria, just get out.
|
|
* We will clear ->notask_error to zero if we see any child that
|
|
* might later match our criteria, even if we are not able to reap
|
|
* it yet.
|
|
*/
|
|
wo->notask_error = -ECHILD;
|
|
if ((wo->wo_type < PIDTYPE_MAX) &&
|
|
(!wo->wo_pid || hlist_empty(&wo->wo_pid->tasks[wo->wo_type])))
|
|
goto notask;
|
|
|
|
set_current_state(TASK_INTERRUPTIBLE);
|
|
read_lock(&tasklist_lock);
|
|
tsk = current;
|
|
do {
|
|
retval = do_wait_thread(wo, tsk);
|
|
if (retval)
|
|
goto end;
|
|
|
|
retval = ptrace_do_wait(wo, tsk);
|
|
if (retval)
|
|
goto end;
|
|
|
|
if (wo->wo_flags & __WNOTHREAD)
|
|
break;
|
|
} while_each_thread(current, tsk);
|
|
read_unlock(&tasklist_lock);
|
|
|
|
notask:
|
|
retval = wo->notask_error;
|
|
if (!retval && !(wo->wo_flags & WNOHANG)) {
|
|
retval = -ERESTARTSYS;
|
|
if (!signal_pending(current)) {
|
|
schedule();
|
|
goto repeat;
|
|
}
|
|
}
|
|
end:
|
|
__set_current_state(TASK_RUNNING);
|
|
remove_wait_queue(¤t->signal->wait_chldexit, &wo->child_wait);
|
|
return retval;
|
|
}
|
|
|
|
static long kernel_waitid(int which, pid_t upid, struct waitid_info *infop,
|
|
int options, struct rusage *ru)
|
|
{
|
|
struct wait_opts wo;
|
|
struct pid *pid = NULL;
|
|
enum pid_type type;
|
|
long ret;
|
|
|
|
if (options & ~(WNOHANG|WNOWAIT|WEXITED|WSTOPPED|WCONTINUED|
|
|
__WNOTHREAD|__WCLONE|__WALL))
|
|
return -EINVAL;
|
|
if (!(options & (WEXITED|WSTOPPED|WCONTINUED)))
|
|
return -EINVAL;
|
|
|
|
switch (which) {
|
|
case P_ALL:
|
|
type = PIDTYPE_MAX;
|
|
break;
|
|
case P_PID:
|
|
type = PIDTYPE_PID;
|
|
if (upid <= 0)
|
|
return -EINVAL;
|
|
|
|
pid = find_get_pid(upid);
|
|
break;
|
|
case P_PGID:
|
|
type = PIDTYPE_PGID;
|
|
if (upid < 0)
|
|
return -EINVAL;
|
|
|
|
if (upid)
|
|
pid = find_get_pid(upid);
|
|
else
|
|
pid = get_task_pid(current, PIDTYPE_PGID);
|
|
break;
|
|
case P_PIDFD:
|
|
type = PIDTYPE_PID;
|
|
if (upid < 0)
|
|
return -EINVAL;
|
|
|
|
pid = pidfd_get_pid(upid);
|
|
if (IS_ERR(pid))
|
|
return PTR_ERR(pid);
|
|
break;
|
|
default:
|
|
return -EINVAL;
|
|
}
|
|
|
|
wo.wo_type = type;
|
|
wo.wo_pid = pid;
|
|
wo.wo_flags = options;
|
|
wo.wo_info = infop;
|
|
wo.wo_rusage = ru;
|
|
ret = do_wait(&wo);
|
|
|
|
put_pid(pid);
|
|
return ret;
|
|
}
|
|
|
|
SYSCALL_DEFINE5(waitid, int, which, pid_t, upid, struct siginfo __user *,
|
|
infop, int, options, struct rusage __user *, ru)
|
|
{
|
|
struct rusage r;
|
|
struct waitid_info info = {.status = 0};
|
|
long err = kernel_waitid(which, upid, &info, options, ru ? &r : NULL);
|
|
int signo = 0;
|
|
|
|
if (err > 0) {
|
|
signo = SIGCHLD;
|
|
err = 0;
|
|
if (ru && copy_to_user(ru, &r, sizeof(struct rusage)))
|
|
return -EFAULT;
|
|
}
|
|
if (!infop)
|
|
return err;
|
|
|
|
if (!user_access_begin(infop, sizeof(*infop)))
|
|
return -EFAULT;
|
|
|
|
unsafe_put_user(signo, &infop->si_signo, Efault);
|
|
unsafe_put_user(0, &infop->si_errno, Efault);
|
|
unsafe_put_user(info.cause, &infop->si_code, Efault);
|
|
unsafe_put_user(info.pid, &infop->si_pid, Efault);
|
|
unsafe_put_user(info.uid, &infop->si_uid, Efault);
|
|
unsafe_put_user(info.status, &infop->si_status, Efault);
|
|
user_access_end();
|
|
return err;
|
|
Efault:
|
|
user_access_end();
|
|
return -EFAULT;
|
|
}
|
|
|
|
long kernel_wait4(pid_t upid, int __user *stat_addr, int options,
|
|
struct rusage *ru)
|
|
{
|
|
struct wait_opts wo;
|
|
struct pid *pid = NULL;
|
|
enum pid_type type;
|
|
long ret;
|
|
|
|
if (options & ~(WNOHANG|WUNTRACED|WCONTINUED|
|
|
__WNOTHREAD|__WCLONE|__WALL))
|
|
return -EINVAL;
|
|
|
|
/* -INT_MIN is not defined */
|
|
if (upid == INT_MIN)
|
|
return -ESRCH;
|
|
|
|
if (upid == -1)
|
|
type = PIDTYPE_MAX;
|
|
else if (upid < 0) {
|
|
type = PIDTYPE_PGID;
|
|
pid = find_get_pid(-upid);
|
|
} else if (upid == 0) {
|
|
type = PIDTYPE_PGID;
|
|
pid = get_task_pid(current, PIDTYPE_PGID);
|
|
} else /* upid > 0 */ {
|
|
type = PIDTYPE_PID;
|
|
pid = find_get_pid(upid);
|
|
}
|
|
|
|
wo.wo_type = type;
|
|
wo.wo_pid = pid;
|
|
wo.wo_flags = options | WEXITED;
|
|
wo.wo_info = NULL;
|
|
wo.wo_stat = 0;
|
|
wo.wo_rusage = ru;
|
|
ret = do_wait(&wo);
|
|
put_pid(pid);
|
|
if (ret > 0 && stat_addr && put_user(wo.wo_stat, stat_addr))
|
|
ret = -EFAULT;
|
|
|
|
return ret;
|
|
}
|
|
|
|
SYSCALL_DEFINE4(wait4, pid_t, upid, int __user *, stat_addr,
|
|
int, options, struct rusage __user *, ru)
|
|
{
|
|
struct rusage r;
|
|
long err = kernel_wait4(upid, stat_addr, options, ru ? &r : NULL);
|
|
|
|
if (err > 0) {
|
|
if (ru && copy_to_user(ru, &r, sizeof(struct rusage)))
|
|
return -EFAULT;
|
|
}
|
|
return err;
|
|
}
|
|
|
|
#ifdef __ARCH_WANT_SYS_WAITPID
|
|
|
|
/*
|
|
* sys_waitpid() remains for compatibility. waitpid() should be
|
|
* implemented by calling sys_wait4() from libc.a.
|
|
*/
|
|
SYSCALL_DEFINE3(waitpid, pid_t, pid, int __user *, stat_addr, int, options)
|
|
{
|
|
return kernel_wait4(pid, stat_addr, options, NULL);
|
|
}
|
|
|
|
#endif
|
|
|
|
#ifdef CONFIG_COMPAT
|
|
COMPAT_SYSCALL_DEFINE4(wait4,
|
|
compat_pid_t, pid,
|
|
compat_uint_t __user *, stat_addr,
|
|
int, options,
|
|
struct compat_rusage __user *, ru)
|
|
{
|
|
struct rusage r;
|
|
long err = kernel_wait4(pid, stat_addr, options, ru ? &r : NULL);
|
|
if (err > 0) {
|
|
if (ru && put_compat_rusage(&r, ru))
|
|
return -EFAULT;
|
|
}
|
|
return err;
|
|
}
|
|
|
|
COMPAT_SYSCALL_DEFINE5(waitid,
|
|
int, which, compat_pid_t, pid,
|
|
struct compat_siginfo __user *, infop, int, options,
|
|
struct compat_rusage __user *, uru)
|
|
{
|
|
struct rusage ru;
|
|
struct waitid_info info = {.status = 0};
|
|
long err = kernel_waitid(which, pid, &info, options, uru ? &ru : NULL);
|
|
int signo = 0;
|
|
if (err > 0) {
|
|
signo = SIGCHLD;
|
|
err = 0;
|
|
if (uru) {
|
|
/* kernel_waitid() overwrites everything in ru */
|
|
if (COMPAT_USE_64BIT_TIME)
|
|
err = copy_to_user(uru, &ru, sizeof(ru));
|
|
else
|
|
err = put_compat_rusage(&ru, uru);
|
|
if (err)
|
|
return -EFAULT;
|
|
}
|
|
}
|
|
|
|
if (!infop)
|
|
return err;
|
|
|
|
if (!user_access_begin(infop, sizeof(*infop)))
|
|
return -EFAULT;
|
|
|
|
unsafe_put_user(signo, &infop->si_signo, Efault);
|
|
unsafe_put_user(0, &infop->si_errno, Efault);
|
|
unsafe_put_user(info.cause, &infop->si_code, Efault);
|
|
unsafe_put_user(info.pid, &infop->si_pid, Efault);
|
|
unsafe_put_user(info.uid, &infop->si_uid, Efault);
|
|
unsafe_put_user(info.status, &infop->si_status, Efault);
|
|
user_access_end();
|
|
return err;
|
|
Efault:
|
|
user_access_end();
|
|
return -EFAULT;
|
|
}
|
|
#endif
|
|
|
|
__weak void abort(void)
|
|
{
|
|
BUG();
|
|
|
|
/* if that doesn't kill us, halt */
|
|
panic("Oops failed to kill thread");
|
|
}
|
|
EXPORT_SYMBOL(abort);
|