mirror of
https://github.com/team-infusion-developers/android_kernel_samsung_msm8976.git
synced 2024-09-20 19:34:46 +00:00
8b08aa9e75
-----BEGIN PGP SIGNATURE----- Version: GnuPG v2 iQIcBAABCAAGBQJUyuGRAAoJEDjbvchgkmk+7EwQALYPOeh+AManQFB1MQvFuOgZ /4ulpjhGXw/RPTKHMeyHo8vRfUhMOx8UPF62uql+g1l9b/Zt2bs6qXu4QcxRRsQc trSTUpi+U14y1hkgqOVOcFYP2ZaTjNEBQgLJ4eGn46CliLqme+rfoyRYm2GXzcR4 6cbSAr3mufdFIpi9/8Dn62Gv0aws5lIv3qkHJXznyuux3tisPT5y6Ux2KJoivPn/ SqADtRpwo+7lTjl15fE++9AqNsGMorV6toT2OO/7nXP+824psInKLmREAT2qC99b BG61vcYdxOuHtzmwrvCf1jSRjxhvZT0j2xhBr/vCKcxy08AT0vDv68zrV1r6TIuu U7/CKXtFBY95cjfnkTLJuswBSuIA/+sQHV6DaddH0V8fcZ6rQMLrblQ9ZcFFFkmT 2SG6lmlXqZvcEKYGMnL/Dcow1rkRhB5stiGgTkYxjiRSRpzAHISRJ/GGpsT+rRqK HpBs5p9JshvRl7RWKwAu+DNGaEK1X/WYxc4/jw6dZFWX7lEWSMIPlr9zXgZCZ39y V6lV1VVlT9/CSs1swKHUyhHHehlFsnIlQ6Fkiycr/KkuqBLs92Hyb7WhpVa819yX osXdxSm6J54skiOLKYpBWHpnY09Tc+p28VEfMpErTExgp2oE8F34K7kdhoQPQb97 2mHiXNa+J4CLUNQ+sRmw =HDBo -----END PGP SIGNATURE----- Merge commit 'v3.10.67' into msm-3.10 This merge brings us up to date with upstream kernel.org tag v3.10.67. It also contains changes to allow forbidden warnings introduced in the commit 'core, nfqueue, openvswitch: Orphan frags in skb_zerocopy and handle errors'. Once upstream has corrected these warnings, the changes to scripts/gcc-wrapper.py, in this commit, can be reverted. * commit 'v3.10.67' (915 commits) Linux 3.10.67 md/raid5: fetch_block must fetch all the blocks handle_stripe_dirtying wants. ext4: fix warning in ext4_da_update_reserve_space() quota: provide interface for readding allocated space into reserved space crypto: add missing crypto module aliases crypto: include crypto- module prefix in template crypto: prefix module autoloading with "crypto-" drbd: merge_bvec_fn: properly remap bvm->bi_bdev Revert "swiotlb-xen: pass dev_addr to swiotlb_tbl_unmap_single" ipvs: uninitialized data with IP_VS_IPV6 KEYS: close race between key lookup and freeing sata_dwc_460ex: fix resource leak on error path x86/asm/traps: Disable tracing and kprobes in fixup_bad_iret and sync_regs x86, tls: Interpret an all-zero struct user_desc as "no segment" x86, tls, ldt: Stop checking lm in LDT_empty x86/tsc: Change Fast TSC calibration failed from error to info x86, hyperv: Mark the Hyper-V clocksource as being continuous clocksource: exynos_mct: Fix bitmask regression for exynos4_mct_write can: dev: fix crtlmode_supported check bus: mvebu-mbus: fix support of MBus window 13 ARM: dts: imx25: Fix PWM "per" clocks time: adjtimex: Validate the ADJ_FREQUENCY values time: settimeofday: Validate the values of tv from user dm cache: share cache-metadata object across inactive and active DM tables ipr: wait for aborted command responses drm/i915: Fix mutex->owner inspection race under DEBUG_MUTEXES scripts/recordmcount.pl: There is no -m32 gcc option on Super-H anymore ALSA: usb-audio: Add mic volume fix quirk for Logitech Webcam C210 libata: prevent HSM state change race between ISR and PIO pinctrl: Fix two deadlocks gpio: sysfs: fix gpio device-attribute leak gpio: sysfs: fix gpio-chip device-attribute leak Linux 3.10.66 s390/3215: fix tty output containing tabs s390/3215: fix hanging console issue fsnotify: next_i is freed during fsnotify_unmount_inodes. netfilter: ipset: small potential read beyond the end of buffer mmc: sdhci: Fix sleep in atomic after inserting SD card LOCKD: Fix a race when initialising nlmsvc_timeout x86, um: actually mark system call tables readonly um: Skip futex_atomic_cmpxchg_inatomic() test decompress_bunzip2: off by one in get_next_block() ARM: shmobile: sh73a0 legacy: Set .control_parent for all irqpin instances ARM: omap5/dra7xx: Fix frequency typos ARM: clk-imx6q: fix video divider for rev T0 1.0 ARM: imx6q: drop unnecessary semicolon ARM: dts: imx25: Fix the SPI1 clocks Input: I8042 - add Acer Aspire 7738 to the nomux list Input: i8042 - reset keyboard to fix Elantech touchpad detection can: kvaser_usb: Don't send a RESET_CHIP for non-existing channels can: kvaser_usb: Reset all URB tx contexts upon channel close can: kvaser_usb: Don't free packets when tight on URBs USB: keyspan: fix null-deref at probe USB: cp210x: add IDs for CEL USB sticks and MeshWorks devices USB: cp210x: fix ID for production CEL MeshConnect USB Stick usb: dwc3: gadget: Stop TRB preparation after limit is reached usb: dwc3: gadget: Fix TRB preparation during SG OHCI: add a quirk for ULi M5237 blocking on reset gpiolib: of: Correct error handling in of_get_named_gpiod_flags NFSv4.1: Fix client id trunking on Linux ftrace/jprobes/x86: Fix conflict between jprobes and function graph tracing vfio-pci: Fix the check on pci device type in vfio_pci_probe() uvcvideo: Fix destruction order in uvc_delete() smiapp: Take mutex during PLL update in sensor initialisation af9005: fix kernel panic on init if compiled without IR smiapp-pll: Correct clock debug prints video/logo: prevent use of logos after they have been freed storvsc: ring buffer failures may result in I/O freeze iscsi-target: Fail connection on short sendmsg writes hp_accel: Add support for HP ZBook 15 cfg80211: Fix 160 MHz channels with 80+80 and 160 MHz drivers ARC: [nsimosci] move peripherals to match model to FPGA drm/i915: Force the CS stall for invalidate flushes drm/i915: Invalidate media caches on gen7 drm/radeon: properly filter DP1.2 4k modes on non-DP1.2 hw drm/radeon: check the right ring in radeon_evict_flags() drm/vmwgfx: Fix fence event code enic: fix rx skb checksum alx: fix alx_poll() tcp: Do not apply TSO segment limit to non-TSO packets tg3: tg3_disable_ints using uninitialized mailbox value to disable interrupts netlink: Don't reorder loads/stores before marking mmap netlink frame as available netlink: Always copy on mmap TX. Linux 3.10.65 mm: Don't count the stack guard page towards RLIMIT_STACK mm: propagate error from stack expansion even for guard page mm, vmscan: prevent kswapd livelock due to pfmemalloc-throttled process being killed perf session: Do not fail on processing out of order event perf: Fix events installation during moving group perf/x86/intel/uncore: Make sure only uncore events are collected Btrfs: don't delay inode ref updates during log replay ARM: mvebu: disable I/O coherency on non-SMP situations on Armada 370/375/38x/XP scripts/kernel-doc: don't eat struct members with __aligned nilfs2: fix the nilfs_iget() vs. nilfs_new_inode() races nfsd4: fix xdr4 inclusion of escaped char fs: nfsd: Fix signedness bug in compare_blob serial: samsung: wait for transfer completion before clock disable writeback: fix a subtle race condition in I_DIRTY clearing cdc-acm: memory leak in error case genhd: check for int overflow in disk_expand_part_tbl() USB: cdc-acm: check for valid interfaces ALSA: hda - Fix wrong gpio_dir & gpio_mask hint setups for IDT/STAC codecs ALSA: hda - using uninitialized data ALSA: usb-audio: extend KEF X300A FU 10 tweak to Arcam rPAC driver core: Fix unbalanced device reference in drivers_probe x86, vdso: Use asm volatile in __getcpu x86_64, vdso: Fix the vdso address randomization algorithm HID: Add a new id 0x501a for Genius MousePen i608X HID: add battery quirk for USB_DEVICE_ID_APPLE_ALU_WIRELESS_2011_ISO keyboard HID: roccat: potential out of bounds in pyra_sysfs_write_settings() HID: i2c-hid: prevent buffer overflow in early IRQ HID: i2c-hid: fix race condition reading reports iommu/vt-d: Fix an off-by-one bug in __domain_mapping() UBI: Fix double free after do_sync_erase() UBI: Fix invalid vfree() pstore-ram: Allow optional mapping with pgprot_noncached pstore-ram: Fix hangs by using write-combine mappings PCI: Restore detection of read-only BARs ASoC: dwc: Ensure FIFOs are flushed to prevent channel swap ASoC: max98090: Fix ill-defined sidetone route ASoC: sigmadsp: Refuse to load firmware files with a non-supported version ath5k: fix hardware queue index assignment swiotlb-xen: pass dev_addr to swiotlb_tbl_unmap_single can: peak_usb: fix memset() usage can: peak_usb: fix cleanup sequence order in case of error during init ath9k: fix BE/BK queue order ath9k_hw: fix hardware queue allocation ocfs2: fix journal commit deadlock Linux 3.10.64 Btrfs: fix fs corruption on transaction abort if device supports discard Btrfs: do not move em to modified list when unpinning eCryptfs: Remove buggy and unnecessary write in file name decode routine eCryptfs: Force RO mount when encrypted view is enabled udf: Verify symlink size before loading it exit: pidns: alloc_pid() leaks pid_namespace if child_reaper is exiting ncpfs: return proper error from NCP_IOC_SETROOT ioctl crypto: af_alg - fix backlog handling userns: Unbreak the unprivileged remount tests userns: Allow setting gid_maps without privilege when setgroups is disabled userns: Add a knob to disable setgroups on a per user namespace basis userns: Rename id_map_mutex to userns_state_mutex userns: Only allow the creator of the userns unprivileged mappings userns: Check euid no fsuid when establishing an unprivileged uid mapping userns: Don't allow unprivileged creation of gid mappings userns: Don't allow setgroups until a gid mapping has been setablished userns: Document what the invariant required for safe unprivileged mappings. groups: Consolidate the setgroups permission checks umount: Disallow unprivileged mount force mnt: Update unprivileged remount test mnt: Implicitly add MNT_NODEV on remount when it was implicitly added by mount mac80211: free management frame keys when removing station mac80211: fix multicast LED blinking and counter KEYS: Fix stale key registration at error path isofs: Fix unchecked printing of ER records x86/tls: Don't validate lm in set_thread_area() after all dm space map metadata: fix sm_bootstrap_get_nr_blocks() dm bufio: fix memleak when using a dm_buffer's inline bio nfs41: fix nfs4_proc_layoutget error handling megaraid_sas: corrected return of wait_event from abort frame path mmc: block: add newline to sysfs display of force_ro mfd: tc6393xb: Fail ohci suspend if full state restore is required md/bitmap: always wait for writes on unplug. x86, kvm: Clear paravirt_enabled on KVM guests for espfix32's benefit x86_64, switch_to(): Load TLS descriptors before switching DS and ES x86/tls: Disallow unusual TLS segments x86/tls: Validate TLS entries to protect espfix isofs: Fix infinite looping over CE entries Linux 3.10.63 ALSA: usb-audio: Don't resubmit pending URBs at MIDI error recovery powerpc: 32 bit getcpu VDSO function uses 64 bit instructions ARM: sched_clock: Load cycle count after epoch stabilizes igb: bring link up when PHY is powered up ext2: Fix oops in ext2_get_block() called from ext2_quota_write() nEPT: Nested INVEPT net: sctp: use MAX_HEADER for headroom reserve in output path net: mvneta: fix Tx interrupt delay rtnetlink: release net refcnt on error in do_setlink() net/mlx4_core: Limit count field to 24 bits in qp_alloc_res tg3: fix ring init when there are more TX than RX channels ipv6: gre: fix wrong skb->protocol in WCCP sata_fsl: fix error handling of irq_of_parse_and_map ahci: disable MSI on SAMSUNG 0xa800 SSD AHCI: Add DeviceIDs for Sunrise Point-LP SATA controller media: smiapp: Only some selection targets are settable drm/i915: Unlock panel even when LVDS is disabled drm/radeon: kernel panic in drm_calc_vbltimestamp_from_scanoutpos with 3.18.0-rc6 i2c: davinci: generate STP always when NACK is received i2c: omap: fix i207 errata handling i2c: omap: fix NACK and Arbitration Lost irq handling xen-netfront: Remove BUGs on paged skb data which crosses a page boundary mm: fix swapoff hang after page migration and fork mm: frontswap: invalidate expired data on a dup-store failure Linux 3.10.62 nfsd: Fix ACL null pointer deref powerpc/powernv: Honor the generic "no_64bit_msi" flag bnx2fc: do not add shared skbs to the fcoe_rx_list nfsd4: fix leak of inode reference on delegation failure nfsd: Fix slot wake up race in the nfsv4.1 callback code rt2x00: do not align payload on modern H/W can: dev: avoid calling kfree_skb() from interrupt context spi: dw: Fix dynamic speed change. iser-target: Handle DEVICE_REMOVAL event on network portal listener correctly target: Don't call TFO->write_pending if data_length == 0 srp-target: Retry when QP creation fails with ENOMEM Input: xpad - use proper endpoint type ARM: 8222/1: mvebu: enable strex backoff delay ARM: 8216/1: xscale: correct auxiliary register in suspend/resume ALSA: usb-audio: Add ctrl message delay quirk for Marantz/Denon devices can: esd_usb2: fix memory leak on disconnect USB: xhci: don't start a halted endpoint before its new dequeue is set usb-quirks: Add reset-resume quirk for MS Wireless Laser Mouse 6000 usb: serial: ftdi_sio: add PIDs for Matrix Orbital products USB: serial: cp210x: add IDs for CEL MeshConnect USB Stick USB: keyspan: fix tty line-status reporting USB: keyspan: fix overrun-error reporting USB: ssu100: fix overrun-error reporting iio: Fix IIO_EVENT_CODE_EXTRACT_DIR bit mask powerpc/pseries: Fix endiannes issue in RTAS call from xmon powerpc/pseries: Honor the generic "no_64bit_msi" flag of/base: Fix PowerPC address parsing hack ASoC: wm_adsp: Avoid attempt to free buffers that might still be in use ASoC: sgtl5000: Fix SMALL_POP bit definition PCI/MSI: Add device flag indicating that 64-bit MSIs don't work ipx: fix locking regression in ipx_sendmsg and ipx_recvmsg pptp: fix stack info leak in pptp_getname() qmi_wwan: Add support for HP lt4112 LTE/HSPA+ Gobi 4G Modem ieee802154: fix error handling in ieee802154fake_probe() ipv4: Fix incorrect error code when adding an unreachable route inetdevice: fixed signed integer overflow sparc64: Fix constraints on swab helpers. uprobes, x86: Fix _TIF_UPROBE vs _TIF_NOTIFY_RESUME x86, mm: Set NX across entire PMD at boot x86: Require exact match for 'noxsave' command line option x86_64, traps: Rework bad_iret x86_64, traps: Stop using IST for #SS x86_64, traps: Fix the espfix64 #DF fixup and rewrite it in C MIPS: Loongson: Make platform serial setup always built-in. MIPS: oprofile: Fix backtrace on 64-bit kernel Linux 3.10.61 mm: memcg: handle non-error OOM situations more gracefully mm: memcg: do not trap chargers with full callstack on OOM mm: memcg: rework and document OOM waiting and wakeup mm: memcg: enable memcg OOM killer only for user faults x86: finish user fault error path with fatal signal arch: mm: pass userspace fault flag to generic fault handler arch: mm: do not invoke OOM killer on kernel fault OOM arch: mm: remove obsolete init OOM protection mm: invoke oom-killer from remaining unconverted page fault handlers net: sctp: fix skb_over_panic when receiving malformed ASCONF chunks net: sctp: fix panic on duplicate ASCONF chunks net: sctp: fix remote memory pressure from excessive queueing KVM: x86: Don't report guest userspace emulation error to userspace SCSI: hpsa: fix a race in cmd_free/scsi_done net/mlx4_en: Fix BlueFlame race ARM: Correct BUG() assembly to ensure it is endian-agnostic perf/x86/intel: Use proper dTLB-load-misses event on IvyBridge mei: bus: fix possible boundaries violation perf: Handle compat ioctl MIPS: Fix forgotten preempt_enable() when CPU has inclusive pcaches dell-wmi: Fix access out of memory ARM: probes: fix instruction fetch order with <asm/opcodes.h> br: fix use of ->rx_handler_data in code executed on non-rx_handler path netfilter: nf_nat: fix oops on netns removal netfilter: xt_bpf: add mising opaque struct sk_filter definition netfilter: nf_log: release skbuff on nlmsg put failure netfilter: nfnetlink_log: fix maximum packet length logged to userspace netfilter: nf_log: account for size of NLMSG_DONE attribute ipc: always handle a new value of auto_msgmni clocksource: Remove "weak" from clocksource_default_clock() declaration kgdb: Remove "weak" from kgdb_arch_pc() declaration media: ttusb-dec: buffer overflow in ioctl NFSv4: Fix races between nfs_remove_bad_delegation() and delegation return nfs: Fix use of uninitialized variable in nfs_getattr() NFS: Don't try to reclaim delegation open state if recovery failed NFSv4: Ensure that we remove NFSv4.0 delegations when state has expired Input: alps - allow up to 2 invalid packets without resetting device Input: alps - ignore potential bare packets when device is out of sync dm raid: ensure superblock's size matches device's logical block size dm btree: fix a recursion depth bug in btree walking code block: Fix computation of merged request priority parisc: Use compat layer for msgctl, shmat, shmctl and semtimedop syscalls scsi: only re-lock door after EH on devices that were reset nfs: fix pnfs direct write memory leak firewire: cdev: prevent kernel stack leaking into ioctl arguments arm64: __clear_user: handle exceptions on strb ARM: 8198/1: make kuser helpers depend on MMU drm/radeon: add missing crtc unlock when setting up the MC mac80211: fix use-after-free in defragmentation macvtap: Fix csum_start when VLAN tags are present iwlwifi: configure the LTR libceph: do not crash on large auth tickets xtensa: re-wire umount syscall to sys_oldumount ALSA: usb-audio: Fix memory leak in FTU quirk ahci: disable MSI instead of NCQ on Samsung pci-e SSDs on macbooks ahci: Add Device IDs for Intel Sunrise Point PCH audit: keep inode pinned x86, x32, audit: Fix x32's AUDIT_ARCH wrt audit sparc32: Implement xchg and atomic_xchg using ATOMIC_HASH locks sparc64: Do irq_{enter,exit}() around generic_smp_call_function*(). sparc64: Fix crashes in schizo_pcierr_intr_other(). sunvdc: don't call VD_OP_GET_VTOC vio: fix reuse of vio_dring slot sunvdc: limit each sg segment to a page sunvdc: compute vdisk geometry from capacity sunvdc: add cdrom and v1.1 protocol support net: sctp: fix memory leak in auth key management net: sctp: fix NULL pointer dereference in af->from_addr_param on malformed packet gre6: Move the setting of dev->iflink into the ndo_init functions. ip6_tunnel: Use ip6_tnl_dev_init as the ndo_init function. Linux 3.10.60 libceph: ceph-msgr workqueue needs a resque worker Btrfs: fix kfree on list_head in btrfs_lookup_csums_range error cleanup of: Fix overflow bug in string property parsing functions sysfs: driver core: Fix glue dir race condition by gdp_mutex i2c: at91: don't account as iowait acer-wmi: Add acpi_backlight=video quirk for the Acer KAV80 rbd: Fix error recovery in rbd_obj_read_sync() drm/radeon: remove invalid pci id usb: gadget: udc: core: fix kernel oops with soft-connect usb: gadget: function: acm: make f_acm pass USB20CV Chapter9 usb: dwc3: gadget: fix set_halt() bug with pending transfers crypto: algif - avoid excessive use of socket buffer in skcipher mm: Remove false WARN_ON from pagecache_isize_extended() x86, apic: Handle a bad TSC more gracefully posix-timers: Fix stack info leak in timer_create() mac80211: fix typo in starting baserate for rts_cts_rate_idx PM / Sleep: fix recovery during resuming from hibernation tty: Fix high cpu load if tty is unreleaseable quota: Properly return errors from dquot_writeback_dquots() ext3: Don't check quota format when there are no quota files nfsd4: fix crash on unknown operation number cpc925_edac: Report UE events properly e7xxx_edac: Report CE events properly i3200_edac: Report CE events properly i82860_edac: Report CE events properly scsi: Fix error handling in SCSI_IOCTL_SEND_COMMAND lib/bitmap.c: fix undefined shift in __bitmap_shift_{left|right}() cgroup/kmemleak: add kmemleak_free() for cgroup deallocations. usb: Do not allow usb_alloc_streams on unconfigured devices USB: opticon: fix non-atomic allocation in write path usb-storage: handle a skipped data phase spi: pxa2xx: toggle clocks on suspend if not disabled by runtime PM spi: pl022: Fix incorrect dma_unmap_sg usb: dwc3: gadget: Properly initialize LINK TRB wireless: rt2x00: add new rt2800usb device USB: option: add Haier CE81B CDMA modem usb: option: add support for Telit LE910 USB: cdc-acm: only raise DTR on transitions from B0 USB: cdc-acm: add device id for GW Instek AFG-2225 usb: serial: ftdi_sio: add "bricked" FTDI device PID usb: serial: ftdi_sio: add Awinda Station and Dongle products USB: serial: cp210x: add Silicon Labs 358x VID and PID serial: Fix divide-by-zero fault in uart_get_divisor() staging:iio:ade7758: Remove "raw" from channel name staging:iio:ade7758: Fix check if channels are enabled in prenable staging:iio:ade7758: Fix NULL pointer deref when enabling buffer staging:iio:ad5933: Drop "raw" from channel names staging:iio:ad5933: Fix NULL pointer deref when enabling buffer OOM, PM: OOM killed task shouldn't escape PM suspend freezer: Do not freeze tasks killed by OOM killer ext4: fix oops when loading block bitmap failed cpufreq: intel_pstate: Fix setting max_perf_pct in performance policy ext4: fix overflow when updating superblock backups after resize ext4: check s_chksum_driver when looking for bg csum presence ext4: fix reservation overflow in ext4_da_write_begin ext4: add ext4_iget_normal() which is to be used for dir tree lookups ext4: grab missed write_count for EXT4_IOC_SWAP_BOOT ext4: don't check quota format when there are no quota files ext4: check EA value offset when loading jbd2: free bh when descriptor block checksum fails MIPS: tlbex: Properly fix HUGE TLB Refill exception handler target: Fix APTPL metadata handling for dynamic MappedLUNs target: Fix queue full status NULL pointer for SCF_TRANSPORT_TASK_SENSE qla_target: don't delete changed nacls ARC: Update order of registers in KGDB to match GDB 7.5 ARC: [nsimosci] Allow "headless" models to boot KVM: x86: Emulator fixes for eip canonical checks on near branches KVM: x86: Fix wrong masking on relative jump/call kvm: x86: don't kill guest on unknown exit reason KVM: x86: Check non-canonical addresses upon WRMSR KVM: x86: Improve thread safety in pit KVM: x86: Prevent host from panicking on shared MSR writes. kvm: fix excessive pages un-pinning in kvm_iommu_map error path. media: tda7432: Fix setting TDA7432_MUTE bit for TDA7432_RF register media: ds3000: fix LNB supply voltage on Tevii S480 on initialization media: em28xx-v4l: give back all active video buffers to the vb2 core properly on streaming stop media: v4l2-common: fix overflow in v4l_bound_align_image() drm/nouveau/bios: memset dcb struct to zero before parsing drm/tilcdc: Fix the error path in tilcdc_load() drm/ast: Fix HW cursor image Input: i8042 - quirks for Fujitsu Lifebook A544 and Lifebook AH544 Input: i8042 - add noloop quirk for Asus X750LN framebuffer: fix border color modules, lock around setting of MODULE_STATE_UNFORMED dm log userspace: fix memory leak in dm_ulog_tfr_init failure path block: fix alignment_offset math that assumes io_min is a power-of-2 drbd: compute the end before rb_insert_augmented() dm bufio: update last_accessed when relinking a buffer virtio_pci: fix virtio spec compliance on restore selinux: fix inode security list corruption pstore: Fix duplicate {console,ftrace}-efi entries mfd: rtsx_pcr: Fix MSI enable error handling mnt: Prevent pivot_root from creating a loop in the mount tree UBI: add missing kmem_cache_free() in process_pool_aeb error path random: add and use memzero_explicit() for clearing data crypto: more robust crypto_memneq fix misuses of f_count() in ppp and netlink kill wbuf_queued/wbuf_dwork_lock ALSA: pcm: Zero-clear reserved fields of PCM status ioctl in compat mode evm: check xattr value length and type in evm_inode_setxattr() x86, pageattr: Prevent overflow in slow_virt_to_phys() for X86_PAE x86_64, entry: Fix out of bounds read on sysenter x86_64, entry: Filter RFLAGS.NT on entry from userspace x86, flags: Rename X86_EFLAGS_BIT1 to X86_EFLAGS_FIXED x86, fpu: shift drop_init_fpu() from save_xstate_sig() to handle_signal() x86, fpu: __restore_xstate_sig()->math_state_restore() needs preempt_disable() x86: Reject x32 executables if x32 ABI not supported vfs: fix data corruption when blocksize < pagesize for mmaped data UBIFS: fix free log space calculation UBIFS: fix a race condition UBIFS: remove mst_mutex fs: Fix theoretical division by 0 in super_cache_scan(). fs: make cont_expand_zero interruptible mmc: rtsx_pci_sdmmc: fix incorrect last byte in R2 response libata-sff: Fix controllers with no ctl port pata_serverworks: disable 64-KB DMA transfers on Broadcom OSB4 IDE Controller Revert "percpu: free percpu allocation info for uniprocessor system" lockd: Try to reconnect if statd has moved drivers/net: macvtap and tun depend on INET ipv4: dst_entry leak in ip_send_unicast_reply() ax88179_178a: fix bonding failure ipv4: fix nexthop attlen check in fib_nh_match tracing/syscalls: Ignore numbers outside NR_syscalls' range Linux 3.10.59 ecryptfs: avoid to access NULL pointer when write metadata in xattr ARM: at91/PMC: don't forget to write PMC_PCDR register to disable clocks ALSA: usb-audio: Add support for Steinberg UR22 USB interface ALSA: emu10k1: Fix deadlock in synth voice lookup ALSA: pcm: use the same dma mmap codepath both for arm and arm64 arm64: compat: fix compat types affecting struct compat_elf_prpsinfo spi: dw-mid: terminate ongoing transfers at exit kernel: add support for gcc 5 fanotify: enable close-on-exec on events' fd when requested in fanotify_init() mm: clear __GFP_FS when PF_MEMALLOC_NOIO is set Bluetooth: Fix issue with USB suspend in btusb driver Bluetooth: Fix HCI H5 corrupted ack value rt2800: correct BBP1_TX_POWER_CTRL mask PCI: Generate uppercase hex for modalias interface class PCI: Increase IBM ipr SAS Crocodile BARs to at least system page size iwlwifi: Add missing PCI IDs for the 7260 series NFSv4.1: Fix an NFSv4.1 state renewal regression NFSv4: fix open/lock state recovery error handling NFSv4: Fix lock recovery when CREATE_SESSION/SETCLIENTID_CONFIRM fails lzo: check for length overrun in variable length encoding. Revert "lzo: properly check for overruns" Documentation: lzo: document part of the encoding m68k: Disable/restore interrupts in hwreg_present()/hwreg_write() Drivers: hv: vmbus: Fix a bug in vmbus_open() Drivers: hv: vmbus: Cleanup vmbus_establish_gpadl() Drivers: hv: vmbus: Cleanup vmbus_teardown_gpadl() Drivers: hv: vmbus: Cleanup vmbus_post_msg() firmware_class: make sure fw requests contain a name qla2xxx: Use correct offset to req-q-out for reserve calculation mptfusion: enable no_write_same for vmware scsi disks be2iscsi: check ip buffer before copying regmap: fix NULL pointer dereference in _regmap_write/read regmap: debugfs: fix possbile NULL pointer dereference spi: dw-mid: check that DMA was inited before exit spi: dw-mid: respect 8 bit mode x86/intel/quark: Switch off CR4.PGE so TLB flush uses CR3 instead kvm: don't take vcpu mutex for obviously invalid vcpu ioctls KVM: s390: unintended fallthrough for external call kvm: x86: fix stale mmio cache bug fs: Add a missing permission check to do_umount Btrfs: fix race in WAIT_SYNC ioctl Btrfs: fix build_backref_tree issue with multiple shared blocks Btrfs: try not to ENOSPC on log replay Linux 3.10.58 USB: cp210x: add support for Seluxit USB dongle USB: serial: cp210x: added Ketra N1 wireless interface support USB: Add device quirk for ASUS T100 Base Station keyboard ipv6: reallocate addrconf router for ipv6 address when lo device up tcp: fixing TLP's FIN recovery sctp: handle association restarts when the socket is closed. ip6_gre: fix flowi6_proto value in xmit path hyperv: Fix a bug in netvsc_start_xmit() tg3: Allow for recieve of full-size 8021AD frames tg3: Work around HW/FW limitations with vlan encapsulated frames l2tp: fix race while getting PMTU on PPP pseudo-wire openvswitch: fix panic with multiple vlan headers packet: handle too big packets for PACKET_V3 tcp: fix tcp_release_cb() to dispatch via address family for mtu_reduced() sit: Fix ipip6_tunnel_lookup device matching criteria myri10ge: check for DMA mapping errors Linux 3.10.57 cpufreq: ondemand: Change the calculation of target frequency cpufreq: Fix wrong time unit conversion nl80211: clear skb cb before passing to netlink drbd: fix regression 'out of mem, failed to invoke fence-peer helper' jiffies: Fix timeval conversion to jiffies md/raid5: disable 'DISCARD' by default due to safety concerns. media: vb2: fix VBI/poll regression mm: numa: Do not mark PTEs pte_numa when splitting huge pages mm, thp: move invariant bug check out of loop in __split_huge_page_map ring-buffer: Fix infinite spin in reading buffer init/Kconfig: Fix HAVE_FUTEX_CMPXCHG to not break up the EXPERT menu perf: fix perf bug in fork() udf: Avoid infinite loop when processing indirect ICBs Linux 3.10.56 vm_is_stack: use for_each_thread() rather then buggy while_each_thread() oom_kill: add rcu_read_lock() into find_lock_task_mm() oom_kill: has_intersects_mems_allowed() needs rcu_read_lock() oom_kill: change oom_kill.c to use for_each_thread() introduce for_each_thread() to replace the buggy while_each_thread() kernel/fork.c:copy_process(): unify CLONE_THREAD-or-thread_group_leader code arm: multi_v7_defconfig: Enable Zynq UART driver ext2: Fix fs corruption in ext2_get_xip_mem() serial: 8250_dma: check the result of TX buffer mapping ARM: 7748/1: oabi: handle faults when loading swi instruction from userspace netfilter: nf_conntrack: avoid large timeout for mid-stream pickup PM / sleep: Use valid_state() for platform-dependent sleep states only PM / sleep: Add state field to pm_states[] entries ipvs: fix ipv6 hook registration for local replies ipvs: Maintain all DSCP and ECN bits for ipv6 tun forwarding ipvs: avoid netns exit crash on ip_vs_conn_drop_conntrack md/raid1: fix_read_error should act on all non-faulty devices. media: cx18: fix kernel oops with tda8290 tuner Fix nasty 32-bit overflow bug in buffer i/o code. perf kmem: Make it work again on non NUMA machines perf: Fix a race condition in perf_remove_from_context() alarmtimer: Lock k_itimer during timer callback alarmtimer: Do not signal SIGEV_NONE timers parisc: Only use -mfast-indirect-calls option for 32-bit kernel builds powerpc/perf: Fix ABIv2 kernel backtraces sched: Fix unreleased llc_shared_mask bit during CPU hotplug ocfs2/dlm: do not get resource spinlock if lockres is new nilfs2: fix data loss with mmap() fs/notify: don't show f_handle if exportfs_encode_inode_fh failed fsnotify/fdinfo: use named constants instead of hardcoded values kcmp: fix standard comparison bug Revert "mac80211: disable uAPSD if all ACs are under ACM" usb: dwc3: core: fix ordering for PHY suspend usb: dwc3: core: fix order of PM runtime calls usb: host: xhci: fix compliance mode workaround genhd: fix leftover might_sleep() in blk_free_devt() lockd: fix rpcbind crash on lockd startup failure rtlwifi: rtl8192cu: Add new ID percpu: perform tlb flush after pcpu_map_pages() failure percpu: fix pcpu_alloc_pages() failure path percpu: free percpu allocation info for uniprocessor system ata_piix: Add Device IDs for Intel 9 Series PCH Input: i8042 - add nomux quirk for Avatar AVIU-145A6 Input: i8042 - add Fujitsu U574 to no_timeout dmi table Input: atkbd - do not try 'deactivate' keyboard on any LG laptops Input: elantech - fix detection of touchpad on ASUS s301l Input: synaptics - add support for ForcePads Input: serport - add compat handling for SPIOCSTYPE ioctl dm crypt: fix access beyond the end of allocated space block: Fix dev_t minor allocation lifetime workqueue: apply __WQ_ORDERED to create_singlethread_workqueue() Revert "iwlwifi: dvm: don't enable CTS to self" SCSI: libiscsi: fix potential buffer overrun in __iscsi_conn_send_pdu NFC: microread: Potential overflows in microread_target_discovered() iscsi-target: Fix memory corruption in iscsit_logout_post_handler_diffcid iscsi-target: avoid NULL pointer in iscsi_copy_param_list failure Target/iser: Don't put isert_conn inside disconnected handler Target/iser: Get isert_conn reference once got to connected_handler iio:inkern: fix overwritten -EPROBE_DEFER in of_iio_channel_get_by_name iio:magnetometer: bugfix magnetometers gain values iio: adc: ad_sigma_delta: Fix indio_dev->trig assignment iio: st_sensors: Fix indio_dev->trig assignment iio: meter: ade7758: Fix indio_dev->trig assignment iio: inv_mpu6050: Fix indio_dev->trig assignment iio: gyro: itg3200: Fix indio_dev->trig assignment iio:trigger: modify return value for iio_trigger_get CIFS: Fix SMB2 readdir error handling CIFS: Fix directory rename error ASoC: davinci-mcasp: Correct rx format unit configuration shmem: fix nlink for rename overwrite directory x86 early_ioremap: Increase FIX_BTMAPS_SLOTS to 8 KVM: x86: handle idiv overflow at kvm_write_tsc regmap: Fix handling of volatile registers for format_write() chips ACPICA: Update to GPIO region handler interface. MIPS: mcount: Adjust stack pointer for static trace in MIPS32 MIPS: ZBOOT: add missing <linux/string.h> include ARM: 8165/1: alignment: don't break misaligned NEON load/store ARM: 7897/1: kexec: Use the right ISA for relocate_new_kernel ARM: 8133/1: use irq_set_affinity with force=false when migrating irqs ARM: 8128/1: abort: don't clear the exclusive monitors NFSv4: Fix another bug in the close/open_downgrade code NFSv4: nfs4_state_manager() vs. nfs_server_remove_lists() usb:hub set hub->change_bits when over-current happens usb: dwc3: omap: fix ordering for runtime pm calls USB: EHCI: unlink QHs even after the controller has stopped USB: storage: Add quirks for Entrega/Xircom USB to SCSI converters USB: storage: Add quirk for Ariston Technologies iConnect USB to SCSI adapter USB: storage: Add quirk for Adaptec USBConnect 2000 USB-to-SCSI Adapter storage: Add single-LUN quirk for Jaz USB Adapter usb: hub: take hub->hdev reference when processing from eventlist xhci: fix oops when xhci resumes from hibernate with hw lpm capable devices xhci: Fix null pointer dereference if xhci initialization fails USB: zte_ev: fix removed PIDs USB: ftdi_sio: add support for NOVITUS Bono E thermal printer USB: sierra: add 1199:68AA device ID USB: sierra: avoid CDC class functions on "68A3" devices USB: zte_ev: remove duplicate Qualcom PID USB: zte_ev: remove duplicate Gobi PID Revert "USB: option,zte_ev: move most ZTE CDMA devices to zte_ev" USB: option: add VIA Telecom CDS7 chipset device id USB: option: reduce interrupt-urb logging verbosity USB: serial: fix potential heap buffer overflow USB: sisusb: add device id for Magic Control USB video USB: serial: fix potential stack buffer overflow USB: serial: pl2303: add device id for ztek device xtensa: fix a6 and a7 handling in fast_syscall_xtensa xtensa: fix TLBTEMP_BASE_2 region handling in fast_second_level_miss xtensa: fix access to THREAD_RA/THREAD_SP/THREAD_DS xtensa: fix address checks in dma_{alloc,free}_coherent xtensa: replace IOCTL code definitions with constants drm/radeon: add connector quirk for fujitsu board drm/vmwgfx: Fix a potential infinite spin waiting for fifo idle drm/ast: AST2000 cannot be detected correctly drm/i915: Wait for vblank before enabling the TV encoder drm/i915: Remove bogus __init annotation from DMI callbacks HID: logitech-dj: prevent false errors to be shown HID: magicmouse: sanity check report size in raw_event() callback HID: picolcd: sanity check report size in raw_event() callback cfq-iosched: Fix wrong children_weight calculation ALSA: pcm: fix fifo_size frame calculation ALSA: hda - Fix invalid pin powermap without jack detection ALSA: hda - Fix COEF setups for ALC1150 codec ALSA: core: fix buffer overflow in snd_info_get_line() arm64: ptrace: fix compat hardware watchpoint reporting trace: Fix epoll hang when we race with new entries i2c: at91: Fix a race condition during signal handling in at91_do_twi_xfer. i2c: at91: add bound checking on SMBus block length bytes arm64: flush TLS registers during exec ibmveth: Fix endian issues with rx_no_buffer statistic ahci: add pcid for Marvel 0x9182 controller ahci: Add Device IDs for Intel 9 Series PCH pata_scc: propagate return value of scc_wait_after_reset drm/i915: read HEAD register back in init_ring_common() to enforce ordering drm/radeon: load the lm63 driver for an lm64 thermal chip. drm/ttm: Choose a pool to shrink correctly in ttm_dma_pool_shrink_scan(). drm/ttm: Fix possible division by 0 in ttm_dma_pool_shrink_scan(). drm/tilcdc: fix double kfree drm/tilcdc: fix release order on exit drm/tilcdc: panel: fix leak when unloading the module drm/tilcdc: tfp410: fix dangling sysfs connector node drm/tilcdc: slave: fix dangling sysfs connector node drm/tilcdc: panel: fix dangling sysfs connector node carl9170: fix sending URBs with wrong type when using full-speed Linux 3.10.55 libceph: gracefully handle large reply messages from the mon libceph: rename ceph_msg::front_max to front_alloc_len tpm: Provide a generic means to override the chip returned timeouts vfs: fix bad hashing of dentries dcache.c: get rid of pointless macros IB/srp: Fix deadlock between host removal and multipathd blkcg: don't call into policy draining if root_blkg is already gone mtd: nand: omap: Fix 1-bit Hamming code scheme, omap_calculate_ecc() mtd/ftl: fix the double free of the buffers allocated in build_maps() CIFS: Fix wrong restart readdir for SMB1 CIFS: Fix wrong filename length for SMB2 CIFS: Fix wrong directory attributes after rename CIFS: Possible null ptr deref in SMB2_tcon CIFS: Fix async reading on reconnects CIFS: Fix STATUS_CANNOT_DELETE error mapping for SMB2 libceph: do not hard code max auth ticket len libceph: add process_one_ticket() helper libceph: set last_piece in ceph_msg_data_pages_cursor_init() correctly md/raid1,raid10: always abort recover on write error. xfs: don't zero partial page cache pages during O_DIRECT writes xfs: don't zero partial page cache pages during O_DIRECT writes xfs: don't dirty buffers beyond EOF xfs: quotacheck leaves dquot buffers without verifiers RDMA/iwcm: Use a default listen backlog if needed md/raid10: Fix memory leak when raid10 reshape completes. md/raid10: fix memory leak when reshaping a RAID10. md/raid6: avoid data corruption during recovery of double-degraded RAID6 Bluetooth: Avoid use of session socket after the session gets freed Bluetooth: never linger on process exit mnt: Add tests for unprivileged remount cases that have found to be faulty mnt: Change the default remount atime from relatime to the existing value mnt: Correct permission checks in do_remount mnt: Move the test for MNT_LOCK_READONLY from change_mount_flags into do_remount mnt: Only change user settable mount flags in remount ring-buffer: Up rb_iter_peek() loop count to 3 ring-buffer: Always reset iterator to reader page ACPI / cpuidle: fix deadlock between cpuidle_lock and cpu_hotplug.lock ACPI: Run fixed event device notifications in process context ACPICA: Utilities: Fix memory leak in acpi_ut_copy_iobject_to_iobject bfa: Fix undefined bit shift on big-endian architectures with 32-bit DMA address ASoC: pxa-ssp: drop SNDRV_PCM_FMTBIT_S24_LE ASoC: max98090: Fix missing free_irq ASoC: samsung: Correct I2S DAI suspend/resume ops ASoC: wm_adsp: Add missing MODULE_LICENSE ASoC: pcm: fix dpcm_path_put in dpcm runtime update openrisc: Rework signal handling MIPS: Fix accessing to per-cpu data when flushing the cache MIPS: OCTEON: make get_system_type() thread-safe MIPS: asm: thread_info: Add _TIF_SECCOMP flag MIPS: Cleanup flags in syscall flags handlers. MIPS: asm/reg.h: Make 32- and 64-bit definitions available at the same time MIPS: Remove BUG_ON(!is_fpu_owner()) in do_ade() MIPS: tlbex: Fix a missing statement for HUGETLB MIPS: Prevent user from setting FCSR cause bits MIPS: GIC: Prevent array overrun drivers: scsi: storvsc: Correctly handle TEST_UNIT_READY failure Drivers: scsi: storvsc: Implement a eh_timed_out handler powerpc/pseries: Failure on removing device node powerpc/mm: Use read barrier when creating real_pte powerpc/mm/numa: Fix break placement regulator: arizona-ldo1: remove bypass functionality mfd: omap-usb-host: Fix improper mask use. kernel/smp.c:on_each_cpu_cond(): fix warning in fallback path CAPABILITIES: remove undefined caps from all processes tpm: missing tpm_chip_put in tpm_get_random() firmware: Do not use WARN_ON(!spin_is_locked()) spi: omap2-mcspi: Configure hardware when slave driver changes mode spi: orion: fix incorrect handling of cell-index DT property iommu/amd: Fix cleanup_domain for mass device removal media: media-device: Remove duplicated memset() in media_enum_entities() media: au0828: Only alt setting logic when needed media: xc4000: Fix get_frequency() media: xc5000: Fix get_frequency() Linux 3.10.54 USB: fix build error with CONFIG_PM_RUNTIME disabled NFSv4: Fix problems with close in the presence of a delegation NFSv3: Fix another acl regression svcrdma: Select NFSv4.1 backchannel transport based on forward channel NFSD: Decrease nfsd_users in nfsd_startup_generic fail usb: hub: Prevent hub autosuspend if usbcore.autosuspend is -1 USB: whiteheat: Added bounds checking for bulk command response USB: ftdi_sio: Added PID for new ekey device USB: ftdi_sio: add Basic Micro ATOM Nano USB2Serial PID ARM: OMAP2+: hwmod: Rearm wake-up interrupts for DT when MUSB is idled usb: xhci: amd chipset also needs short TX quirk xhci: Treat not finding the event_seg on COMP_STOP the same as COMP_STOP_INVAL Staging: speakup: Update __speakup_paste_selection() tty (ab)usage to match vt jbd2: fix infinite loop when recovering corrupt journal blocks mei: nfc: fix memory leak in error path mei: reset client state on queued connect request Btrfs: fix csum tree corruption, duplicate and outdated checksums hpsa: fix bad -ENOMEM return value in hpsa_big_passthru_ioctl x86/efi: Enforce CONFIG_RELOCATABLE for EFI boot stub x86_64/vsyscall: Fix warn_bad_vsyscall log output x86: don't exclude low BIOS area when allocating address space for non-PCI cards drm/radeon: add additional SI pci ids ext4: fix BUG_ON in mb_free_blocks() kvm: iommu: fix the third parameter of kvm_iommu_put_pages (CVE-2014-3601) Revert "KVM: x86: Increase the number of fixed MTRR regs to 10" KVM: nVMX: fix "acknowledge interrupt on exit" when APICv is in use KVM: x86: always exit on EOIs for interrupts listed in the IOAPIC redir table KVM: x86: Inter-privilege level ret emulation is not implemeneted crypto: ux500 - make interrupt mode plausible serial: core: Preserve termios c_cflag for console resume ext4: fix ext4_discard_allocated_blocks() if we can't allocate the pa struct drivers/i2c/busses: use correct type for dma_map/unmap hwmon: (dme1737) Prevent overflow problem when writing large limits hwmon: (ads1015) Fix out-of-bounds array access hwmon: (lm85) Fix various errors on attribute writes hwmon: (ads1015) Fix off-by-one for valid channel index checking hwmon: (gpio-fan) Prevent overflow problem when writing large limits hwmon: (lm78) Fix overflow problems seen when writing large temperature limits hwmon: (sis5595) Prevent overflow problem when writing large limits drm: omapdrm: fix compiler errors ARM: OMAP3: Fix choice of omap3_restore_es function in OMAP34XX rev3.1.2 case. mei: start disconnect request timer consistently ALSA: hda/realtek - Avoid setting wrong COEF on ALC269 & co ALSA: hda/ca0132 - Don't try loading firmware at resume when already failed ALSA: virtuoso: add Xonar Essence STX II support ALSA: hda - fix an external mic jack problem on a HP machine USB: Fix persist resume of some SS USB devices USB: ehci-pci: USB host controller support for Intel Quark X1000 USB: serial: ftdi_sio: Add support for new Xsens devices USB: serial: ftdi_sio: Annotate the current Xsens PID assignments USB: OHCI: don't lose track of EDs when a controller dies isofs: Fix unbounded recursion when processing relocated directories HID: fix a couple of off-by-ones HID: logitech: perform bounds checking on device_id early enough stable_kernel_rules: Add pointer to netdev-FAQ for network patches Linux 3.10.53 arch/sparc/math-emu/math_32.c: drop stray break operator sparc64: ldc_connect() should not return EINVAL when handshake is in progress. sunsab: Fix detection of BREAK on sunsab serial console bbc-i2c: Fix BBC I2C envctrl on SunBlade 2000 sparc64: Guard against flushing openfirmware mappings. sparc64: Do not insert non-valid PTEs into the TSB hash table. sparc64: Add membar to Niagara2 memcpy code. sparc64: Fix huge TSB mapping on pre-UltraSPARC-III cpus. sparc64: Don't bark so loudly about 32-bit tasks generating 64-bit fault addresses. sparc64: Fix top-level fault handling bugs. sparc64: Handle 32-bit tasks properly in compute_effective_address(). sparc64: Make itc_sync_lock raw sparc64: Fix argument sign extension for compat_sys_futex(). sctp: fix possible seqlock seadlock in sctp_packet_transmit() iovec: make sure the caller actually wants anything in memcpy_fromiovecend net: Correctly set segment mac_len in skb_segment(). macvlan: Initialize vlan_features to turn on offload support. net: sctp: inherit auth_capable on INIT collisions tcp: Fix integer-overflow in TCP vegas tcp: Fix integer-overflows in TCP veno net: sendmsg: fix NULL pointer dereference ip: make IP identifiers less predictable inetpeer: get rid of ip_id_count bnx2x: fix crash during TSO tunneling Linux 3.10.52 x86/espfix/xen: Fix allocation of pages for paravirt page tables lib/btree.c: fix leak of whole btree nodes net/l2tp: don't fall back on UDP [get|set]sockopt net: mvneta: replace Tx timer with a real interrupt net: mvneta: add missing bit descriptions for interrupt masks and causes net: mvneta: do not schedule in mvneta_tx_timeout net: mvneta: use per_cpu stats to fix an SMP lock up net: mvneta: increase the 64-bit rx/tx stats out of the hot path Revert "mac80211: move "bufferable MMPDU" check to fix AP mode scan" staging: vt6655: Fix Warning on boot handle_irq_event_percpu. x86_64/entry/xen: Do not invoke espfix64 on Xen x86, espfix: Make it possible to disable 16-bit support x86, espfix: Make espfix64 a Kconfig option, fix UML x86, espfix: Fix broken header guard x86, espfix: Move espfix definitions into a separate header file x86-64, espfix: Don't leak bits 31:16 of %esp returning to 16-bit stack Revert "x86-64, modify_ldt: Make support for 16-bit segments a runtime option" timer: Fix lock inversion between hrtimer_bases.lock and scheduler locks printk: rename printk_sched to printk_deferred iio: buffer: Fix demux table creation staging: vt6655: Fix disassociated messages every 10 seconds mm, thp: do not allow thp faults to avoid cpuset restrictions scsi: handle flush errors properly rapidio/tsi721_dma: fix failure to obtain transaction descriptor cfg80211: fix mic_failure tracing ARM: 8115/1: LPAE: reduce damage caused by idmap to virtual memory layout crypto: af_alg - properly label AF_ALG socket Linux 3.10.51 core, nfqueue, openvswitch: Orphan frags in skb_zerocopy and handle errors x86/efi: Include a .bss section within the PE/COFF headers s390/ptrace: fix PSW mask check Fix gcc-4.9.0 miscompilation of load_balance() in scheduler mm: hugetlb: fix copy_hugetlb_page_range() x86_32, entry: Store badsys error code in %eax hwmon: (smsc47m192) Fix temperature limit and vrm write operations parisc: Remove SA_RESTORER define coredump: fix the setting of PF_DUMPCORE Input: fix defuzzing logic slab_common: fix the check for duplicate slab names slab_common: Do not check for duplicate slab names tracing: Fix wraparound problems in "uptime" trace clock blkcg: don't call into policy draining if root_blkg is already gone ahci: add support for the Promise FastTrak TX8660 SATA HBA (ahci mode) libata: introduce ata_host->n_tags to avoid oops on SAS controllers libata: support the ata host which implements a queue depth less than 32 block: don't assume last put of shared tags is for the host block: provide compat ioctl for BLKZEROOUT media: tda10071: force modulation to QPSK on DVB-S media: hdpvr: fix two audio bugs Linux 3.10.50 ARC: Implement ptrace(PTRACE_GET_THREAD_AREA) sched: Fix possible divide by zero in avg_atom() calculation locking/mutex: Disable optimistic spinning on some architectures PM / sleep: Fix request_firmware() error at resume dm cache metadata: do not allow the data block size to change dm thin metadata: do not allow the data block size to change alarmtimer: Fix bug where relative alarm timers were treated as absolute drm/radeon: avoid leaking edid data drm/qxl: return IRQ_NONE if it was not our irq drm/radeon: set default bl level to something reasonable irqchip: gic: Fix core ID calculation when topology is read from DT irqchip: gic: Add support for cortex a7 compatible string ring-buffer: Fix polling on trace_pipe mwifiex: fix Tx timeout issue perf/x86/intel: ignore CondChgd bit to avoid false NMI handling ipv4: fix buffer overflow in ip_options_compile() dns_resolver: Null-terminate the right string dns_resolver: assure that dns_query() result is null-terminated sunvnet: clean up objects created in vnet_new() on vnet_exit() net: pppoe: use correct channel MTU when using Multilink PPP net: sctp: fix information leaks in ulpevent layer tipc: clear 'next'-pointer of message fragments before reassembly be2net: set EQ DB clear-intr bit in be_open() netlink: Fix handling of error from netlink_dump(). net: mvneta: Fix big endian issue in mvneta_txq_desc_csum() net: mvneta: fix operation in 10 Mbit/s mode appletalk: Fix socket referencing in skb tcp: fix false undo corner cases igmp: fix the problem when mc leave group net: qmi_wwan: add two Sierra Wireless/Netgear devices net: qmi_wwan: Add ID for Telewell TW-LTE 4G v2 ipv4: icmp: Fix pMTU handling for rare case tcp: Fix divide by zero when pushing during tcp-repair bnx2x: fix possible panic under memory stress net: fix sparse warning in sk_dst_set() ipv4: irq safe sk_dst_[re]set() and ipv4_sk_update_pmtu() fix ipv4: fix dst race in sk_dst_get() 8021q: fix a potential memory leak net: sctp: check proc_dointvec result in proc_sctp_do_auth tcp: fix tcp_match_skb_to_sack() for unaligned SACK at end of an skb ip_tunnel: fix ip_tunnel_lookup shmem: fix splicing from a hole while it's punched shmem: fix faulting into a hole, not taking i_mutex shmem: fix faulting into a hole while it's punched iwlwifi: dvm: don't enable CTS to self igb: do a reset on SR-IOV re-init if device is down hwmon: (adt7470) Fix writes to temperature limit registers hwmon: (da9052) Don't use dash in the name attribute hwmon: (da9055) Don't use dash in the name attribute tracing: Add ftrace_trace_stack into __trace_puts/__trace_bputs tracing: Fix graph tracer with stack tracer on other archs fuse: handle large user and group ID Bluetooth: Ignore H5 non-link packets in non-active state Drivers: hv: util: Fix a bug in the KVP code media: gspca_pac7302: Add new usb-id for Genius i-Look 317 usb: Check if port status is equal to RxDetect Signed-off-by: Ian Maund <imaund@codeaurora.org>
2022 lines
48 KiB
C
2022 lines
48 KiB
C
/*
|
|
* linux/kernel/fork.c
|
|
*
|
|
* Copyright (C) 1991, 1992 Linus Torvalds
|
|
*/
|
|
|
|
/*
|
|
* 'fork.c' contains the help-routines for the 'fork' system call
|
|
* (see also entry.S and others).
|
|
* Fork is rather simple, once you get the hang of it, but the memory
|
|
* management can be a bitch. See 'mm/memory.c': 'copy_page_range()'
|
|
*/
|
|
|
|
#include <linux/slab.h>
|
|
#include <linux/init.h>
|
|
#include <linux/unistd.h>
|
|
#include <linux/module.h>
|
|
#include <linux/vmalloc.h>
|
|
#include <linux/completion.h>
|
|
#include <linux/personality.h>
|
|
#include <linux/mempolicy.h>
|
|
#include <linux/sem.h>
|
|
#include <linux/file.h>
|
|
#include <linux/fdtable.h>
|
|
#include <linux/iocontext.h>
|
|
#include <linux/key.h>
|
|
#include <linux/binfmts.h>
|
|
#include <linux/mman.h>
|
|
#include <linux/mmu_notifier.h>
|
|
#include <linux/fs.h>
|
|
#include <linux/nsproxy.h>
|
|
#include <linux/capability.h>
|
|
#include <linux/cpu.h>
|
|
#include <linux/cgroup.h>
|
|
#include <linux/security.h>
|
|
#include <linux/hugetlb.h>
|
|
#include <linux/seccomp.h>
|
|
#include <linux/swap.h>
|
|
#include <linux/syscalls.h>
|
|
#include <linux/jiffies.h>
|
|
#include <linux/futex.h>
|
|
#include <linux/compat.h>
|
|
#include <linux/kthread.h>
|
|
#include <linux/task_io_accounting_ops.h>
|
|
#include <linux/rcupdate.h>
|
|
#include <linux/ptrace.h>
|
|
#include <linux/mount.h>
|
|
#include <linux/audit.h>
|
|
#include <linux/memcontrol.h>
|
|
#include <linux/ftrace.h>
|
|
#include <linux/proc_fs.h>
|
|
#include <linux/profile.h>
|
|
#include <linux/rmap.h>
|
|
#include <linux/ksm.h>
|
|
#include <linux/acct.h>
|
|
#include <linux/tsacct_kern.h>
|
|
#include <linux/cn_proc.h>
|
|
#include <linux/freezer.h>
|
|
#include <linux/delayacct.h>
|
|
#include <linux/taskstats_kern.h>
|
|
#include <linux/random.h>
|
|
#include <linux/tty.h>
|
|
#include <linux/blkdev.h>
|
|
#include <linux/fs_struct.h>
|
|
#include <linux/magic.h>
|
|
#include <linux/perf_event.h>
|
|
#include <linux/posix-timers.h>
|
|
#include <linux/user-return-notifier.h>
|
|
#include <linux/oom.h>
|
|
#include <linux/khugepaged.h>
|
|
#include <linux/signalfd.h>
|
|
#include <linux/uprobes.h>
|
|
#include <linux/aio.h>
|
|
|
|
#include <asm/pgtable.h>
|
|
#include <asm/pgalloc.h>
|
|
#include <asm/uaccess.h>
|
|
#include <asm/mmu_context.h>
|
|
#include <asm/cacheflush.h>
|
|
#include <asm/tlbflush.h>
|
|
|
|
#include <trace/events/sched.h>
|
|
|
|
#define CREATE_TRACE_POINTS
|
|
#include <trace/events/task.h>
|
|
|
|
/*
|
|
* Protected counters by write_lock_irq(&tasklist_lock)
|
|
*/
|
|
unsigned long total_forks; /* Handle normal Linux uptimes. */
|
|
int nr_threads; /* The idle threads do not count.. */
|
|
|
|
int max_threads; /* tunable limit on nr_threads */
|
|
|
|
DEFINE_PER_CPU(unsigned long, process_counts) = 0;
|
|
|
|
__cacheline_aligned DEFINE_RWLOCK(tasklist_lock); /* outer */
|
|
|
|
#ifdef CONFIG_PROVE_RCU
|
|
int lockdep_tasklist_lock_is_held(void)
|
|
{
|
|
return lockdep_is_held(&tasklist_lock);
|
|
}
|
|
EXPORT_SYMBOL_GPL(lockdep_tasklist_lock_is_held);
|
|
#endif /* #ifdef CONFIG_PROVE_RCU */
|
|
|
|
int nr_processes(void)
|
|
{
|
|
int cpu;
|
|
int total = 0;
|
|
|
|
for_each_possible_cpu(cpu)
|
|
total += per_cpu(process_counts, cpu);
|
|
|
|
return total;
|
|
}
|
|
|
|
void __weak arch_release_task_struct(struct task_struct *tsk)
|
|
{
|
|
}
|
|
|
|
#ifndef CONFIG_ARCH_TASK_STRUCT_ALLOCATOR
|
|
static struct kmem_cache *task_struct_cachep;
|
|
|
|
static inline struct task_struct *alloc_task_struct_node(int node)
|
|
{
|
|
return kmem_cache_alloc_node(task_struct_cachep, GFP_KERNEL, node);
|
|
}
|
|
|
|
static inline void free_task_struct(struct task_struct *tsk)
|
|
{
|
|
kmem_cache_free(task_struct_cachep, tsk);
|
|
}
|
|
#endif
|
|
|
|
void __weak arch_release_thread_info(struct thread_info *ti)
|
|
{
|
|
}
|
|
|
|
#ifndef CONFIG_ARCH_THREAD_INFO_ALLOCATOR
|
|
|
|
/*
|
|
* Allocate pages if THREAD_SIZE is >= PAGE_SIZE, otherwise use a
|
|
* kmemcache based allocator.
|
|
*/
|
|
# if THREAD_SIZE >= PAGE_SIZE
|
|
static struct thread_info *alloc_thread_info_node(struct task_struct *tsk,
|
|
int node)
|
|
{
|
|
struct page *page = alloc_pages_node(node, THREADINFO_GFP_ACCOUNTED,
|
|
THREAD_SIZE_ORDER);
|
|
|
|
return page ? page_address(page) : NULL;
|
|
}
|
|
|
|
static inline void free_thread_info(struct thread_info *ti)
|
|
{
|
|
free_memcg_kmem_pages((unsigned long)ti, THREAD_SIZE_ORDER);
|
|
}
|
|
# else
|
|
static struct kmem_cache *thread_info_cache;
|
|
|
|
static struct thread_info *alloc_thread_info_node(struct task_struct *tsk,
|
|
int node)
|
|
{
|
|
return kmem_cache_alloc_node(thread_info_cache, THREADINFO_GFP, node);
|
|
}
|
|
|
|
static void free_thread_info(struct thread_info *ti)
|
|
{
|
|
kmem_cache_free(thread_info_cache, ti);
|
|
}
|
|
|
|
void thread_info_cache_init(void)
|
|
{
|
|
thread_info_cache = kmem_cache_create("thread_info", THREAD_SIZE,
|
|
THREAD_SIZE, 0, NULL);
|
|
BUG_ON(thread_info_cache == NULL);
|
|
}
|
|
# endif
|
|
#endif
|
|
|
|
/* SLAB cache for signal_struct structures (tsk->signal) */
|
|
static struct kmem_cache *signal_cachep;
|
|
|
|
/* SLAB cache for sighand_struct structures (tsk->sighand) */
|
|
struct kmem_cache *sighand_cachep;
|
|
|
|
/* SLAB cache for files_struct structures (tsk->files) */
|
|
struct kmem_cache *files_cachep;
|
|
|
|
/* SLAB cache for fs_struct structures (tsk->fs) */
|
|
struct kmem_cache *fs_cachep;
|
|
|
|
/* SLAB cache for vm_area_struct structures */
|
|
struct kmem_cache *vm_area_cachep;
|
|
|
|
/* SLAB cache for mm_struct structures (tsk->mm) */
|
|
static struct kmem_cache *mm_cachep;
|
|
|
|
/* Notifier list called when a task struct is freed */
|
|
static ATOMIC_NOTIFIER_HEAD(task_free_notifier);
|
|
|
|
static void account_kernel_stack(struct thread_info *ti, int account)
|
|
{
|
|
struct zone *zone = page_zone(virt_to_page(ti));
|
|
|
|
mod_zone_page_state(zone, NR_KERNEL_STACK, account);
|
|
}
|
|
|
|
void free_task(struct task_struct *tsk)
|
|
{
|
|
account_kernel_stack(tsk->stack, -1);
|
|
arch_release_thread_info(tsk->stack);
|
|
free_thread_info(tsk->stack);
|
|
rt_mutex_debug_task_free(tsk);
|
|
ftrace_graph_exit_task(tsk);
|
|
put_seccomp_filter(tsk);
|
|
arch_release_task_struct(tsk);
|
|
free_task_struct(tsk);
|
|
}
|
|
EXPORT_SYMBOL(free_task);
|
|
|
|
static inline void free_signal_struct(struct signal_struct *sig)
|
|
{
|
|
taskstats_tgid_free(sig);
|
|
sched_autogroup_exit(sig);
|
|
kmem_cache_free(signal_cachep, sig);
|
|
}
|
|
|
|
static inline void put_signal_struct(struct signal_struct *sig)
|
|
{
|
|
if (atomic_dec_and_test(&sig->sigcnt))
|
|
free_signal_struct(sig);
|
|
}
|
|
|
|
int task_free_register(struct notifier_block *n)
|
|
{
|
|
return atomic_notifier_chain_register(&task_free_notifier, n);
|
|
}
|
|
EXPORT_SYMBOL(task_free_register);
|
|
|
|
int task_free_unregister(struct notifier_block *n)
|
|
{
|
|
return atomic_notifier_chain_unregister(&task_free_notifier, n);
|
|
}
|
|
EXPORT_SYMBOL(task_free_unregister);
|
|
|
|
void __put_task_struct(struct task_struct *tsk)
|
|
{
|
|
WARN_ON(!tsk->exit_state);
|
|
WARN_ON(atomic_read(&tsk->usage));
|
|
WARN_ON(tsk == current);
|
|
|
|
security_task_free(tsk);
|
|
exit_creds(tsk);
|
|
delayacct_tsk_free(tsk);
|
|
put_signal_struct(tsk->signal);
|
|
|
|
atomic_notifier_call_chain(&task_free_notifier, 0, tsk);
|
|
if (!profile_handoff_task(tsk))
|
|
free_task(tsk);
|
|
}
|
|
EXPORT_SYMBOL_GPL(__put_task_struct);
|
|
|
|
void __init __weak arch_task_cache_init(void) { }
|
|
|
|
void __init fork_init(unsigned long mempages)
|
|
{
|
|
#ifndef CONFIG_ARCH_TASK_STRUCT_ALLOCATOR
|
|
#ifndef ARCH_MIN_TASKALIGN
|
|
#define ARCH_MIN_TASKALIGN L1_CACHE_BYTES
|
|
#endif
|
|
/* create a slab on which task_structs can be allocated */
|
|
task_struct_cachep =
|
|
kmem_cache_create("task_struct", sizeof(struct task_struct),
|
|
ARCH_MIN_TASKALIGN, SLAB_PANIC | SLAB_NOTRACK, NULL);
|
|
#endif
|
|
|
|
/* do the arch specific task caches init */
|
|
arch_task_cache_init();
|
|
|
|
/*
|
|
* The default maximum number of threads is set to a safe
|
|
* value: the thread structures can take up at most half
|
|
* of memory.
|
|
*/
|
|
max_threads = mempages / (8 * THREAD_SIZE / PAGE_SIZE);
|
|
|
|
/*
|
|
* we need to allow at least 20 threads to boot a system
|
|
*/
|
|
if (max_threads < 20)
|
|
max_threads = 20;
|
|
|
|
init_task.signal->rlim[RLIMIT_NPROC].rlim_cur = max_threads/2;
|
|
init_task.signal->rlim[RLIMIT_NPROC].rlim_max = max_threads/2;
|
|
init_task.signal->rlim[RLIMIT_SIGPENDING] =
|
|
init_task.signal->rlim[RLIMIT_NPROC];
|
|
}
|
|
|
|
int __attribute__((weak)) arch_dup_task_struct(struct task_struct *dst,
|
|
struct task_struct *src)
|
|
{
|
|
*dst = *src;
|
|
return 0;
|
|
}
|
|
|
|
static struct task_struct *dup_task_struct(struct task_struct *orig)
|
|
{
|
|
struct task_struct *tsk;
|
|
struct thread_info *ti;
|
|
unsigned long *stackend;
|
|
int node = tsk_fork_get_node(orig);
|
|
int err;
|
|
|
|
tsk = alloc_task_struct_node(node);
|
|
if (!tsk)
|
|
return NULL;
|
|
|
|
ti = alloc_thread_info_node(tsk, node);
|
|
if (!ti)
|
|
goto free_tsk;
|
|
|
|
err = arch_dup_task_struct(tsk, orig);
|
|
if (err)
|
|
goto free_ti;
|
|
|
|
tsk->stack = ti;
|
|
#ifdef CONFIG_SECCOMP
|
|
/*
|
|
* We must handle setting up seccomp filters once we're under
|
|
* the sighand lock in case orig has changed between now and
|
|
* then. Until then, filter must be NULL to avoid messing up
|
|
* the usage counts on the error path calling free_task.
|
|
*/
|
|
tsk->seccomp.filter = NULL;
|
|
#endif
|
|
|
|
setup_thread_stack(tsk, orig);
|
|
clear_user_return_notifier(tsk);
|
|
clear_tsk_need_resched(tsk);
|
|
stackend = end_of_stack(tsk);
|
|
*stackend = STACK_END_MAGIC; /* for overflow detection */
|
|
|
|
#ifdef CONFIG_CC_STACKPROTECTOR
|
|
tsk->stack_canary = get_random_int();
|
|
#endif
|
|
|
|
/*
|
|
* One for us, one for whoever does the "release_task()" (usually
|
|
* parent)
|
|
*/
|
|
atomic_set(&tsk->usage, 2);
|
|
#ifdef CONFIG_BLK_DEV_IO_TRACE
|
|
tsk->btrace_seq = 0;
|
|
#endif
|
|
tsk->splice_pipe = NULL;
|
|
tsk->task_frag.page = NULL;
|
|
|
|
account_kernel_stack(ti, 1);
|
|
|
|
return tsk;
|
|
|
|
free_ti:
|
|
free_thread_info(ti);
|
|
free_tsk:
|
|
free_task_struct(tsk);
|
|
return NULL;
|
|
}
|
|
|
|
#ifdef CONFIG_MMU
|
|
static int dup_mmap(struct mm_struct *mm, struct mm_struct *oldmm)
|
|
{
|
|
struct vm_area_struct *mpnt, *tmp, *prev, **pprev;
|
|
struct rb_node **rb_link, *rb_parent;
|
|
int retval;
|
|
unsigned long charge;
|
|
struct mempolicy *pol;
|
|
|
|
uprobe_start_dup_mmap();
|
|
down_write(&oldmm->mmap_sem);
|
|
flush_cache_dup_mm(oldmm);
|
|
uprobe_dup_mmap(oldmm, mm);
|
|
/*
|
|
* Not linked in yet - no deadlock potential:
|
|
*/
|
|
down_write_nested(&mm->mmap_sem, SINGLE_DEPTH_NESTING);
|
|
|
|
mm->locked_vm = 0;
|
|
mm->mmap = NULL;
|
|
mm->mmap_cache = NULL;
|
|
mm->map_count = 0;
|
|
cpumask_clear(mm_cpumask(mm));
|
|
mm->mm_rb = RB_ROOT;
|
|
rb_link = &mm->mm_rb.rb_node;
|
|
rb_parent = NULL;
|
|
pprev = &mm->mmap;
|
|
retval = ksm_fork(mm, oldmm);
|
|
if (retval)
|
|
goto out;
|
|
retval = khugepaged_fork(mm, oldmm);
|
|
if (retval)
|
|
goto out;
|
|
|
|
prev = NULL;
|
|
for (mpnt = oldmm->mmap; mpnt; mpnt = mpnt->vm_next) {
|
|
struct file *file;
|
|
|
|
if (mpnt->vm_flags & VM_DONTCOPY) {
|
|
vm_stat_account(mm, mpnt->vm_flags, mpnt->vm_file,
|
|
-vma_pages(mpnt));
|
|
continue;
|
|
}
|
|
charge = 0;
|
|
if (mpnt->vm_flags & VM_ACCOUNT) {
|
|
unsigned long len = vma_pages(mpnt);
|
|
|
|
if (security_vm_enough_memory_mm(oldmm, len)) /* sic */
|
|
goto fail_nomem;
|
|
charge = len;
|
|
}
|
|
tmp = kmem_cache_alloc(vm_area_cachep, GFP_KERNEL);
|
|
if (!tmp)
|
|
goto fail_nomem;
|
|
*tmp = *mpnt;
|
|
INIT_LIST_HEAD(&tmp->anon_vma_chain);
|
|
pol = mpol_dup(vma_policy(mpnt));
|
|
retval = PTR_ERR(pol);
|
|
if (IS_ERR(pol))
|
|
goto fail_nomem_policy;
|
|
vma_set_policy(tmp, pol);
|
|
tmp->vm_mm = mm;
|
|
if (anon_vma_fork(tmp, mpnt))
|
|
goto fail_nomem_anon_vma_fork;
|
|
tmp->vm_flags &= ~VM_LOCKED;
|
|
tmp->vm_next = tmp->vm_prev = NULL;
|
|
file = tmp->vm_file;
|
|
if (file) {
|
|
struct inode *inode = file_inode(file);
|
|
struct address_space *mapping = file->f_mapping;
|
|
|
|
get_file(file);
|
|
if (tmp->vm_flags & VM_DENYWRITE)
|
|
atomic_dec(&inode->i_writecount);
|
|
mutex_lock(&mapping->i_mmap_mutex);
|
|
if (tmp->vm_flags & VM_SHARED)
|
|
mapping->i_mmap_writable++;
|
|
flush_dcache_mmap_lock(mapping);
|
|
/* insert tmp into the share list, just after mpnt */
|
|
if (unlikely(tmp->vm_flags & VM_NONLINEAR))
|
|
vma_nonlinear_insert(tmp,
|
|
&mapping->i_mmap_nonlinear);
|
|
else
|
|
vma_interval_tree_insert_after(tmp, mpnt,
|
|
&mapping->i_mmap);
|
|
flush_dcache_mmap_unlock(mapping);
|
|
mutex_unlock(&mapping->i_mmap_mutex);
|
|
}
|
|
|
|
/*
|
|
* Clear hugetlb-related page reserves for children. This only
|
|
* affects MAP_PRIVATE mappings. Faults generated by the child
|
|
* are not guaranteed to succeed, even if read-only
|
|
*/
|
|
if (is_vm_hugetlb_page(tmp))
|
|
reset_vma_resv_huge_pages(tmp);
|
|
|
|
/*
|
|
* Link in the new vma and copy the page table entries.
|
|
*/
|
|
*pprev = tmp;
|
|
pprev = &tmp->vm_next;
|
|
tmp->vm_prev = prev;
|
|
prev = tmp;
|
|
|
|
__vma_link_rb(mm, tmp, rb_link, rb_parent);
|
|
rb_link = &tmp->vm_rb.rb_right;
|
|
rb_parent = &tmp->vm_rb;
|
|
|
|
mm->map_count++;
|
|
retval = copy_page_range(mm, oldmm, mpnt);
|
|
|
|
if (tmp->vm_ops && tmp->vm_ops->open)
|
|
tmp->vm_ops->open(tmp);
|
|
|
|
if (retval)
|
|
goto out;
|
|
}
|
|
/* a new mm has just been created */
|
|
arch_dup_mmap(oldmm, mm);
|
|
retval = 0;
|
|
out:
|
|
up_write(&mm->mmap_sem);
|
|
flush_tlb_mm(oldmm);
|
|
up_write(&oldmm->mmap_sem);
|
|
uprobe_end_dup_mmap();
|
|
return retval;
|
|
fail_nomem_anon_vma_fork:
|
|
mpol_put(pol);
|
|
fail_nomem_policy:
|
|
kmem_cache_free(vm_area_cachep, tmp);
|
|
fail_nomem:
|
|
retval = -ENOMEM;
|
|
vm_unacct_memory(charge);
|
|
goto out;
|
|
}
|
|
|
|
static inline int mm_alloc_pgd(struct mm_struct *mm)
|
|
{
|
|
mm->pgd = pgd_alloc(mm);
|
|
if (unlikely(!mm->pgd))
|
|
return -ENOMEM;
|
|
return 0;
|
|
}
|
|
|
|
static inline void mm_free_pgd(struct mm_struct *mm)
|
|
{
|
|
pgd_free(mm, mm->pgd);
|
|
}
|
|
#else
|
|
#define dup_mmap(mm, oldmm) (0)
|
|
#define mm_alloc_pgd(mm) (0)
|
|
#define mm_free_pgd(mm)
|
|
#endif /* CONFIG_MMU */
|
|
|
|
__cacheline_aligned_in_smp DEFINE_SPINLOCK(mmlist_lock);
|
|
|
|
#define allocate_mm() (kmem_cache_alloc(mm_cachep, GFP_KERNEL))
|
|
#define free_mm(mm) (kmem_cache_free(mm_cachep, (mm)))
|
|
|
|
static unsigned long default_dump_filter = MMF_DUMP_FILTER_DEFAULT;
|
|
|
|
static int __init coredump_filter_setup(char *s)
|
|
{
|
|
default_dump_filter =
|
|
(simple_strtoul(s, NULL, 0) << MMF_DUMP_FILTER_SHIFT) &
|
|
MMF_DUMP_FILTER_MASK;
|
|
return 1;
|
|
}
|
|
|
|
__setup("coredump_filter=", coredump_filter_setup);
|
|
|
|
#include <linux/init_task.h>
|
|
|
|
static void mm_init_aio(struct mm_struct *mm)
|
|
{
|
|
#ifdef CONFIG_AIO
|
|
spin_lock_init(&mm->ioctx_lock);
|
|
INIT_HLIST_HEAD(&mm->ioctx_list);
|
|
#endif
|
|
}
|
|
|
|
static struct mm_struct *mm_init(struct mm_struct *mm, struct task_struct *p)
|
|
{
|
|
atomic_set(&mm->mm_users, 1);
|
|
atomic_set(&mm->mm_count, 1);
|
|
init_rwsem(&mm->mmap_sem);
|
|
INIT_LIST_HEAD(&mm->mmlist);
|
|
mm->flags = (current->mm) ?
|
|
(current->mm->flags & MMF_INIT_MASK) : default_dump_filter;
|
|
mm->core_state = NULL;
|
|
mm->nr_ptes = 0;
|
|
memset(&mm->rss_stat, 0, sizeof(mm->rss_stat));
|
|
spin_lock_init(&mm->page_table_lock);
|
|
mm_init_aio(mm);
|
|
mm_init_owner(mm, p);
|
|
clear_tlb_flush_pending(mm);
|
|
|
|
if (likely(!mm_alloc_pgd(mm))) {
|
|
mm->def_flags = 0;
|
|
mmu_notifier_mm_init(mm);
|
|
return mm;
|
|
}
|
|
|
|
free_mm(mm);
|
|
return NULL;
|
|
}
|
|
|
|
static void check_mm(struct mm_struct *mm)
|
|
{
|
|
int i;
|
|
|
|
for (i = 0; i < NR_MM_COUNTERS; i++) {
|
|
long x = atomic_long_read(&mm->rss_stat.count[i]);
|
|
|
|
if (unlikely(x))
|
|
printk(KERN_ALERT "BUG: Bad rss-counter state "
|
|
"mm:%p idx:%d val:%ld\n", mm, i, x);
|
|
}
|
|
|
|
#ifdef CONFIG_TRANSPARENT_HUGEPAGE
|
|
VM_BUG_ON(mm->pmd_huge_pte);
|
|
#endif
|
|
}
|
|
|
|
/*
|
|
* Allocate and initialize an mm_struct.
|
|
*/
|
|
struct mm_struct *mm_alloc(void)
|
|
{
|
|
struct mm_struct *mm;
|
|
|
|
mm = allocate_mm();
|
|
if (!mm)
|
|
return NULL;
|
|
|
|
memset(mm, 0, sizeof(*mm));
|
|
mm_init_cpumask(mm);
|
|
return mm_init(mm, current);
|
|
}
|
|
|
|
/*
|
|
* Called when the last reference to the mm
|
|
* is dropped: either by a lazy thread or by
|
|
* mmput. Free the page directory and the mm.
|
|
*/
|
|
void __mmdrop(struct mm_struct *mm)
|
|
{
|
|
BUG_ON(mm == &init_mm);
|
|
mm_free_pgd(mm);
|
|
destroy_context(mm);
|
|
mmu_notifier_mm_destroy(mm);
|
|
check_mm(mm);
|
|
free_mm(mm);
|
|
}
|
|
EXPORT_SYMBOL_GPL(__mmdrop);
|
|
|
|
/*
|
|
* Decrement the use count and release all resources for an mm.
|
|
*/
|
|
int mmput(struct mm_struct *mm)
|
|
{
|
|
int mm_freed = 0;
|
|
might_sleep();
|
|
|
|
if (atomic_dec_and_test(&mm->mm_users)) {
|
|
uprobe_clear_state(mm);
|
|
exit_aio(mm);
|
|
ksm_exit(mm);
|
|
khugepaged_exit(mm); /* must run before exit_mmap */
|
|
exit_mmap(mm);
|
|
set_mm_exe_file(mm, NULL);
|
|
if (!list_empty(&mm->mmlist)) {
|
|
spin_lock(&mmlist_lock);
|
|
list_del(&mm->mmlist);
|
|
spin_unlock(&mmlist_lock);
|
|
}
|
|
if (mm->binfmt)
|
|
module_put(mm->binfmt->module);
|
|
mmdrop(mm);
|
|
mm_freed = 1;
|
|
}
|
|
return mm_freed;
|
|
}
|
|
EXPORT_SYMBOL_GPL(mmput);
|
|
|
|
void set_mm_exe_file(struct mm_struct *mm, struct file *new_exe_file)
|
|
{
|
|
if (new_exe_file)
|
|
get_file(new_exe_file);
|
|
if (mm->exe_file)
|
|
fput(mm->exe_file);
|
|
mm->exe_file = new_exe_file;
|
|
}
|
|
|
|
struct file *get_mm_exe_file(struct mm_struct *mm)
|
|
{
|
|
struct file *exe_file;
|
|
|
|
/* We need mmap_sem to protect against races with removal of exe_file */
|
|
down_read(&mm->mmap_sem);
|
|
exe_file = mm->exe_file;
|
|
if (exe_file)
|
|
get_file(exe_file);
|
|
up_read(&mm->mmap_sem);
|
|
return exe_file;
|
|
}
|
|
|
|
static void dup_mm_exe_file(struct mm_struct *oldmm, struct mm_struct *newmm)
|
|
{
|
|
/* It's safe to write the exe_file pointer without exe_file_lock because
|
|
* this is called during fork when the task is not yet in /proc */
|
|
newmm->exe_file = get_mm_exe_file(oldmm);
|
|
}
|
|
|
|
/**
|
|
* get_task_mm - acquire a reference to the task's mm
|
|
*
|
|
* Returns %NULL if the task has no mm. Checks PF_KTHREAD (meaning
|
|
* this kernel workthread has transiently adopted a user mm with use_mm,
|
|
* to do its AIO) is not set and if so returns a reference to it, after
|
|
* bumping up the use count. User must release the mm via mmput()
|
|
* after use. Typically used by /proc and ptrace.
|
|
*/
|
|
struct mm_struct *get_task_mm(struct task_struct *task)
|
|
{
|
|
struct mm_struct *mm;
|
|
|
|
task_lock(task);
|
|
mm = task->mm;
|
|
if (mm) {
|
|
if (task->flags & PF_KTHREAD)
|
|
mm = NULL;
|
|
else
|
|
atomic_inc(&mm->mm_users);
|
|
}
|
|
task_unlock(task);
|
|
return mm;
|
|
}
|
|
EXPORT_SYMBOL_GPL(get_task_mm);
|
|
|
|
struct mm_struct *mm_access(struct task_struct *task, unsigned int mode)
|
|
{
|
|
struct mm_struct *mm;
|
|
int err;
|
|
|
|
err = mutex_lock_killable(&task->signal->cred_guard_mutex);
|
|
if (err)
|
|
return ERR_PTR(err);
|
|
|
|
mm = get_task_mm(task);
|
|
if (mm && mm != current->mm &&
|
|
!ptrace_may_access(task, mode) &&
|
|
!capable(CAP_SYS_RESOURCE)) {
|
|
mmput(mm);
|
|
mm = ERR_PTR(-EACCES);
|
|
}
|
|
mutex_unlock(&task->signal->cred_guard_mutex);
|
|
|
|
return mm;
|
|
}
|
|
|
|
static void complete_vfork_done(struct task_struct *tsk)
|
|
{
|
|
struct completion *vfork;
|
|
|
|
task_lock(tsk);
|
|
vfork = tsk->vfork_done;
|
|
if (likely(vfork)) {
|
|
tsk->vfork_done = NULL;
|
|
complete(vfork);
|
|
}
|
|
task_unlock(tsk);
|
|
}
|
|
|
|
static int wait_for_vfork_done(struct task_struct *child,
|
|
struct completion *vfork)
|
|
{
|
|
int killed;
|
|
|
|
freezer_do_not_count();
|
|
killed = wait_for_completion_killable(vfork);
|
|
freezer_count();
|
|
|
|
if (killed) {
|
|
task_lock(child);
|
|
child->vfork_done = NULL;
|
|
task_unlock(child);
|
|
}
|
|
|
|
put_task_struct(child);
|
|
return killed;
|
|
}
|
|
|
|
/* Please note the differences between mmput and mm_release.
|
|
* mmput is called whenever we stop holding onto a mm_struct,
|
|
* error success whatever.
|
|
*
|
|
* mm_release is called after a mm_struct has been removed
|
|
* from the current process.
|
|
*
|
|
* This difference is important for error handling, when we
|
|
* only half set up a mm_struct for a new process and need to restore
|
|
* the old one. Because we mmput the new mm_struct before
|
|
* restoring the old one. . .
|
|
* Eric Biederman 10 January 1998
|
|
*/
|
|
void mm_release(struct task_struct *tsk, struct mm_struct *mm)
|
|
{
|
|
/* Get rid of any futexes when releasing the mm */
|
|
#ifdef CONFIG_FUTEX
|
|
if (unlikely(tsk->robust_list)) {
|
|
exit_robust_list(tsk);
|
|
tsk->robust_list = NULL;
|
|
}
|
|
#ifdef CONFIG_COMPAT
|
|
if (unlikely(tsk->compat_robust_list)) {
|
|
compat_exit_robust_list(tsk);
|
|
tsk->compat_robust_list = NULL;
|
|
}
|
|
#endif
|
|
if (unlikely(!list_empty(&tsk->pi_state_list)))
|
|
exit_pi_state_list(tsk);
|
|
#endif
|
|
|
|
uprobe_free_utask(tsk);
|
|
|
|
/* Get rid of any cached register state */
|
|
deactivate_mm(tsk, mm);
|
|
|
|
/*
|
|
* If we're exiting normally, clear a user-space tid field if
|
|
* requested. We leave this alone when dying by signal, to leave
|
|
* the value intact in a core dump, and to save the unnecessary
|
|
* trouble, say, a killed vfork parent shouldn't touch this mm.
|
|
* Userland only wants this done for a sys_exit.
|
|
*/
|
|
if (tsk->clear_child_tid) {
|
|
if (!(tsk->flags & PF_SIGNALED) &&
|
|
atomic_read(&mm->mm_users) > 1) {
|
|
/*
|
|
* We don't check the error code - if userspace has
|
|
* not set up a proper pointer then tough luck.
|
|
*/
|
|
put_user(0, tsk->clear_child_tid);
|
|
sys_futex(tsk->clear_child_tid, FUTEX_WAKE,
|
|
1, NULL, NULL, 0);
|
|
}
|
|
tsk->clear_child_tid = NULL;
|
|
}
|
|
|
|
/*
|
|
* All done, finally we can wake up parent and return this mm to him.
|
|
* Also kthread_stop() uses this completion for synchronization.
|
|
*/
|
|
if (tsk->vfork_done)
|
|
complete_vfork_done(tsk);
|
|
}
|
|
|
|
/*
|
|
* Allocate a new mm structure and copy contents from the
|
|
* mm structure of the passed in task structure.
|
|
*/
|
|
struct mm_struct *dup_mm(struct task_struct *tsk)
|
|
{
|
|
struct mm_struct *mm, *oldmm = current->mm;
|
|
int err;
|
|
|
|
if (!oldmm)
|
|
return NULL;
|
|
|
|
mm = allocate_mm();
|
|
if (!mm)
|
|
goto fail_nomem;
|
|
|
|
memcpy(mm, oldmm, sizeof(*mm));
|
|
mm_init_cpumask(mm);
|
|
|
|
#ifdef CONFIG_TRANSPARENT_HUGEPAGE
|
|
mm->pmd_huge_pte = NULL;
|
|
#endif
|
|
#ifdef CONFIG_NUMA_BALANCING
|
|
mm->first_nid = NUMA_PTE_SCAN_INIT;
|
|
#endif
|
|
if (!mm_init(mm, tsk))
|
|
goto fail_nomem;
|
|
|
|
if (init_new_context(tsk, mm))
|
|
goto fail_nocontext;
|
|
|
|
dup_mm_exe_file(oldmm, mm);
|
|
|
|
err = dup_mmap(mm, oldmm);
|
|
if (err)
|
|
goto free_pt;
|
|
|
|
mm->hiwater_rss = get_mm_rss(mm);
|
|
mm->hiwater_vm = mm->total_vm;
|
|
|
|
if (mm->binfmt && !try_module_get(mm->binfmt->module))
|
|
goto free_pt;
|
|
|
|
return mm;
|
|
|
|
free_pt:
|
|
/* don't put binfmt in mmput, we haven't got module yet */
|
|
mm->binfmt = NULL;
|
|
mmput(mm);
|
|
|
|
fail_nomem:
|
|
return NULL;
|
|
|
|
fail_nocontext:
|
|
/*
|
|
* If init_new_context() failed, we cannot use mmput() to free the mm
|
|
* because it calls destroy_context()
|
|
*/
|
|
mm_free_pgd(mm);
|
|
free_mm(mm);
|
|
return NULL;
|
|
}
|
|
|
|
static int copy_mm(unsigned long clone_flags, struct task_struct *tsk)
|
|
{
|
|
struct mm_struct *mm, *oldmm;
|
|
int retval;
|
|
|
|
tsk->min_flt = tsk->maj_flt = 0;
|
|
tsk->nvcsw = tsk->nivcsw = 0;
|
|
#ifdef CONFIG_DETECT_HUNG_TASK
|
|
tsk->last_switch_count = tsk->nvcsw + tsk->nivcsw;
|
|
#endif
|
|
|
|
tsk->mm = NULL;
|
|
tsk->active_mm = NULL;
|
|
|
|
/*
|
|
* Are we cloning a kernel thread?
|
|
*
|
|
* We need to steal a active VM for that..
|
|
*/
|
|
oldmm = current->mm;
|
|
if (!oldmm)
|
|
return 0;
|
|
|
|
if (clone_flags & CLONE_VM) {
|
|
atomic_inc(&oldmm->mm_users);
|
|
mm = oldmm;
|
|
goto good_mm;
|
|
}
|
|
|
|
retval = -ENOMEM;
|
|
mm = dup_mm(tsk);
|
|
if (!mm)
|
|
goto fail_nomem;
|
|
|
|
good_mm:
|
|
tsk->mm = mm;
|
|
tsk->active_mm = mm;
|
|
return 0;
|
|
|
|
fail_nomem:
|
|
return retval;
|
|
}
|
|
|
|
static int copy_fs(unsigned long clone_flags, struct task_struct *tsk)
|
|
{
|
|
struct fs_struct *fs = current->fs;
|
|
if (clone_flags & CLONE_FS) {
|
|
/* tsk->fs is already what we want */
|
|
spin_lock(&fs->lock);
|
|
if (fs->in_exec) {
|
|
spin_unlock(&fs->lock);
|
|
return -EAGAIN;
|
|
}
|
|
fs->users++;
|
|
spin_unlock(&fs->lock);
|
|
return 0;
|
|
}
|
|
tsk->fs = copy_fs_struct(fs);
|
|
if (!tsk->fs)
|
|
return -ENOMEM;
|
|
return 0;
|
|
}
|
|
|
|
static int copy_files(unsigned long clone_flags, struct task_struct *tsk)
|
|
{
|
|
struct files_struct *oldf, *newf;
|
|
int error = 0;
|
|
|
|
/*
|
|
* A background process may not have any files ...
|
|
*/
|
|
oldf = current->files;
|
|
if (!oldf)
|
|
goto out;
|
|
|
|
if (clone_flags & CLONE_FILES) {
|
|
atomic_inc(&oldf->count);
|
|
goto out;
|
|
}
|
|
|
|
newf = dup_fd(oldf, &error);
|
|
if (!newf)
|
|
goto out;
|
|
|
|
tsk->files = newf;
|
|
error = 0;
|
|
out:
|
|
return error;
|
|
}
|
|
|
|
static int copy_io(unsigned long clone_flags, struct task_struct *tsk)
|
|
{
|
|
#ifdef CONFIG_BLOCK
|
|
struct io_context *ioc = current->io_context;
|
|
struct io_context *new_ioc;
|
|
|
|
if (!ioc)
|
|
return 0;
|
|
/*
|
|
* Share io context with parent, if CLONE_IO is set
|
|
*/
|
|
if (clone_flags & CLONE_IO) {
|
|
ioc_task_link(ioc);
|
|
tsk->io_context = ioc;
|
|
} else if (ioprio_valid(ioc->ioprio)) {
|
|
new_ioc = get_task_io_context(tsk, GFP_KERNEL, NUMA_NO_NODE);
|
|
if (unlikely(!new_ioc))
|
|
return -ENOMEM;
|
|
|
|
new_ioc->ioprio = ioc->ioprio;
|
|
put_io_context(new_ioc);
|
|
}
|
|
#endif
|
|
return 0;
|
|
}
|
|
|
|
static int copy_sighand(unsigned long clone_flags, struct task_struct *tsk)
|
|
{
|
|
struct sighand_struct *sig;
|
|
|
|
if (clone_flags & CLONE_SIGHAND) {
|
|
atomic_inc(¤t->sighand->count);
|
|
return 0;
|
|
}
|
|
sig = kmem_cache_alloc(sighand_cachep, GFP_KERNEL);
|
|
rcu_assign_pointer(tsk->sighand, sig);
|
|
if (!sig)
|
|
return -ENOMEM;
|
|
atomic_set(&sig->count, 1);
|
|
memcpy(sig->action, current->sighand->action, sizeof(sig->action));
|
|
return 0;
|
|
}
|
|
|
|
void __cleanup_sighand(struct sighand_struct *sighand)
|
|
{
|
|
if (atomic_dec_and_test(&sighand->count)) {
|
|
signalfd_cleanup(sighand);
|
|
kmem_cache_free(sighand_cachep, sighand);
|
|
}
|
|
}
|
|
|
|
|
|
/*
|
|
* Initialize POSIX timer handling for a thread group.
|
|
*/
|
|
static void posix_cpu_timers_init_group(struct signal_struct *sig)
|
|
{
|
|
unsigned long cpu_limit;
|
|
|
|
/* Thread group counters. */
|
|
thread_group_cputime_init(sig);
|
|
|
|
cpu_limit = ACCESS_ONCE(sig->rlim[RLIMIT_CPU].rlim_cur);
|
|
if (cpu_limit != RLIM_INFINITY) {
|
|
sig->cputime_expires.prof_exp = secs_to_cputime(cpu_limit);
|
|
sig->cputimer.running = 1;
|
|
}
|
|
|
|
/* The timer lists. */
|
|
INIT_LIST_HEAD(&sig->cpu_timers[0]);
|
|
INIT_LIST_HEAD(&sig->cpu_timers[1]);
|
|
INIT_LIST_HEAD(&sig->cpu_timers[2]);
|
|
}
|
|
|
|
static int copy_signal(unsigned long clone_flags, struct task_struct *tsk)
|
|
{
|
|
struct signal_struct *sig;
|
|
|
|
if (clone_flags & CLONE_THREAD)
|
|
return 0;
|
|
|
|
sig = kmem_cache_zalloc(signal_cachep, GFP_KERNEL);
|
|
tsk->signal = sig;
|
|
if (!sig)
|
|
return -ENOMEM;
|
|
|
|
sig->nr_threads = 1;
|
|
atomic_set(&sig->live, 1);
|
|
atomic_set(&sig->sigcnt, 1);
|
|
|
|
/* list_add(thread_node, thread_head) without INIT_LIST_HEAD() */
|
|
sig->thread_head = (struct list_head)LIST_HEAD_INIT(tsk->thread_node);
|
|
tsk->thread_node = (struct list_head)LIST_HEAD_INIT(sig->thread_head);
|
|
|
|
init_waitqueue_head(&sig->wait_chldexit);
|
|
sig->curr_target = tsk;
|
|
init_sigpending(&sig->shared_pending);
|
|
INIT_LIST_HEAD(&sig->posix_timers);
|
|
|
|
hrtimer_init(&sig->real_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
|
|
sig->real_timer.function = it_real_fn;
|
|
|
|
task_lock(current->group_leader);
|
|
memcpy(sig->rlim, current->signal->rlim, sizeof sig->rlim);
|
|
task_unlock(current->group_leader);
|
|
|
|
posix_cpu_timers_init_group(sig);
|
|
|
|
tty_audit_fork(sig);
|
|
sched_autogroup_fork(sig);
|
|
|
|
#ifdef CONFIG_CGROUPS
|
|
init_rwsem(&sig->group_rwsem);
|
|
#endif
|
|
|
|
sig->oom_score_adj = current->signal->oom_score_adj;
|
|
sig->oom_score_adj_min = current->signal->oom_score_adj_min;
|
|
|
|
sig->has_child_subreaper = current->signal->has_child_subreaper ||
|
|
current->signal->is_child_subreaper;
|
|
|
|
mutex_init(&sig->cred_guard_mutex);
|
|
|
|
return 0;
|
|
}
|
|
|
|
static void copy_flags(unsigned long clone_flags, struct task_struct *p)
|
|
{
|
|
unsigned long new_flags = p->flags;
|
|
|
|
new_flags &= ~(PF_SUPERPRIV | PF_WQ_WORKER);
|
|
new_flags |= PF_FORKNOEXEC;
|
|
p->flags = new_flags;
|
|
}
|
|
|
|
static void copy_seccomp(struct task_struct *p)
|
|
{
|
|
#ifdef CONFIG_SECCOMP
|
|
/*
|
|
* Must be called with sighand->lock held, which is common to
|
|
* all threads in the group. Holding cred_guard_mutex is not
|
|
* needed because this new task is not yet running and cannot
|
|
* be racing exec.
|
|
*/
|
|
assert_spin_locked(¤t->sighand->siglock);
|
|
|
|
/* Ref-count the new filter user, and assign it. */
|
|
get_seccomp_filter(current);
|
|
p->seccomp = current->seccomp;
|
|
|
|
/*
|
|
* Explicitly enable no_new_privs here in case it got set
|
|
* between the task_struct being duplicated and holding the
|
|
* sighand lock. The seccomp state and nnp must be in sync.
|
|
*/
|
|
if (task_no_new_privs(current))
|
|
task_set_no_new_privs(p);
|
|
|
|
/*
|
|
* If the parent gained a seccomp mode after copying thread
|
|
* flags and between before we held the sighand lock, we have
|
|
* to manually enable the seccomp thread flag here.
|
|
*/
|
|
if (p->seccomp.mode != SECCOMP_MODE_DISABLED)
|
|
set_tsk_thread_flag(p, TIF_SECCOMP);
|
|
#endif
|
|
}
|
|
|
|
SYSCALL_DEFINE1(set_tid_address, int __user *, tidptr)
|
|
{
|
|
current->clear_child_tid = tidptr;
|
|
|
|
return task_pid_vnr(current);
|
|
}
|
|
|
|
static void rt_mutex_init_task(struct task_struct *p)
|
|
{
|
|
raw_spin_lock_init(&p->pi_lock);
|
|
#ifdef CONFIG_RT_MUTEXES
|
|
plist_head_init(&p->pi_waiters);
|
|
p->pi_blocked_on = NULL;
|
|
#endif
|
|
}
|
|
|
|
#ifdef CONFIG_MM_OWNER
|
|
void mm_init_owner(struct mm_struct *mm, struct task_struct *p)
|
|
{
|
|
mm->owner = p;
|
|
}
|
|
#endif /* CONFIG_MM_OWNER */
|
|
|
|
/*
|
|
* Initialize POSIX timer handling for a single task.
|
|
*/
|
|
static void posix_cpu_timers_init(struct task_struct *tsk)
|
|
{
|
|
tsk->cputime_expires.prof_exp = 0;
|
|
tsk->cputime_expires.virt_exp = 0;
|
|
tsk->cputime_expires.sched_exp = 0;
|
|
INIT_LIST_HEAD(&tsk->cpu_timers[0]);
|
|
INIT_LIST_HEAD(&tsk->cpu_timers[1]);
|
|
INIT_LIST_HEAD(&tsk->cpu_timers[2]);
|
|
}
|
|
|
|
/*
|
|
* This creates a new process as a copy of the old one,
|
|
* but does not actually start it yet.
|
|
*
|
|
* It copies the registers, and all the appropriate
|
|
* parts of the process environment (as per the clone
|
|
* flags). The actual kick-off is left to the caller.
|
|
*/
|
|
static struct task_struct *copy_process(unsigned long clone_flags,
|
|
unsigned long stack_start,
|
|
unsigned long stack_size,
|
|
int __user *child_tidptr,
|
|
struct pid *pid,
|
|
int trace)
|
|
{
|
|
int retval;
|
|
struct task_struct *p;
|
|
|
|
if ((clone_flags & (CLONE_NEWNS|CLONE_FS)) == (CLONE_NEWNS|CLONE_FS))
|
|
return ERR_PTR(-EINVAL);
|
|
|
|
if ((clone_flags & (CLONE_NEWUSER|CLONE_FS)) == (CLONE_NEWUSER|CLONE_FS))
|
|
return ERR_PTR(-EINVAL);
|
|
|
|
/*
|
|
* Thread groups must share signals as well, and detached threads
|
|
* can only be started up within the thread group.
|
|
*/
|
|
if ((clone_flags & CLONE_THREAD) && !(clone_flags & CLONE_SIGHAND))
|
|
return ERR_PTR(-EINVAL);
|
|
|
|
/*
|
|
* Shared signal handlers imply shared VM. By way of the above,
|
|
* thread groups also imply shared VM. Blocking this case allows
|
|
* for various simplifications in other code.
|
|
*/
|
|
if ((clone_flags & CLONE_SIGHAND) && !(clone_flags & CLONE_VM))
|
|
return ERR_PTR(-EINVAL);
|
|
|
|
/*
|
|
* Siblings of global init remain as zombies on exit since they are
|
|
* not reaped by their parent (swapper). To solve this and to avoid
|
|
* multi-rooted process trees, prevent global and container-inits
|
|
* from creating siblings.
|
|
*/
|
|
if ((clone_flags & CLONE_PARENT) &&
|
|
current->signal->flags & SIGNAL_UNKILLABLE)
|
|
return ERR_PTR(-EINVAL);
|
|
|
|
/*
|
|
* If the new process will be in a different pid namespace don't
|
|
* allow it to share a thread group or signal handlers with the
|
|
* forking task.
|
|
*/
|
|
if ((clone_flags & (CLONE_SIGHAND | CLONE_NEWPID)) &&
|
|
(task_active_pid_ns(current) != current->nsproxy->pid_ns))
|
|
return ERR_PTR(-EINVAL);
|
|
|
|
retval = security_task_create(clone_flags);
|
|
if (retval)
|
|
goto fork_out;
|
|
|
|
retval = -ENOMEM;
|
|
p = dup_task_struct(current);
|
|
if (!p)
|
|
goto fork_out;
|
|
|
|
ftrace_graph_init_task(p);
|
|
|
|
rt_mutex_init_task(p);
|
|
|
|
#ifdef CONFIG_PROVE_LOCKING
|
|
DEBUG_LOCKS_WARN_ON(!p->hardirqs_enabled);
|
|
DEBUG_LOCKS_WARN_ON(!p->softirqs_enabled);
|
|
#endif
|
|
retval = -EAGAIN;
|
|
if (atomic_read(&p->real_cred->user->processes) >=
|
|
task_rlimit(p, RLIMIT_NPROC)) {
|
|
if (!capable(CAP_SYS_ADMIN) && !capable(CAP_SYS_RESOURCE) &&
|
|
p->real_cred->user != INIT_USER)
|
|
goto bad_fork_free;
|
|
}
|
|
current->flags &= ~PF_NPROC_EXCEEDED;
|
|
|
|
retval = copy_creds(p, clone_flags);
|
|
if (retval < 0)
|
|
goto bad_fork_free;
|
|
|
|
/*
|
|
* If multiple threads are within copy_process(), then this check
|
|
* triggers too late. This doesn't hurt, the check is only there
|
|
* to stop root fork bombs.
|
|
*/
|
|
retval = -EAGAIN;
|
|
if (nr_threads >= max_threads)
|
|
goto bad_fork_cleanup_count;
|
|
|
|
if (!try_module_get(task_thread_info(p)->exec_domain->module))
|
|
goto bad_fork_cleanup_count;
|
|
|
|
p->did_exec = 0;
|
|
delayacct_tsk_init(p); /* Must remain after dup_task_struct() */
|
|
copy_flags(clone_flags, p);
|
|
INIT_LIST_HEAD(&p->children);
|
|
INIT_LIST_HEAD(&p->sibling);
|
|
rcu_copy_process(p);
|
|
p->vfork_done = NULL;
|
|
spin_lock_init(&p->alloc_lock);
|
|
|
|
init_sigpending(&p->pending);
|
|
|
|
p->utime = p->stime = p->gtime = 0;
|
|
p->utimescaled = p->stimescaled = 0;
|
|
#ifndef CONFIG_VIRT_CPU_ACCOUNTING_NATIVE
|
|
p->prev_cputime.utime = p->prev_cputime.stime = 0;
|
|
#endif
|
|
#ifdef CONFIG_VIRT_CPU_ACCOUNTING_GEN
|
|
seqlock_init(&p->vtime_seqlock);
|
|
p->vtime_snap = 0;
|
|
p->vtime_snap_whence = VTIME_SLEEPING;
|
|
#endif
|
|
|
|
#if defined(SPLIT_RSS_COUNTING)
|
|
memset(&p->rss_stat, 0, sizeof(p->rss_stat));
|
|
#endif
|
|
|
|
p->default_timer_slack_ns = current->timer_slack_ns;
|
|
|
|
task_io_accounting_init(&p->ioac);
|
|
acct_clear_integrals(p);
|
|
|
|
posix_cpu_timers_init(p);
|
|
|
|
do_posix_clock_monotonic_gettime(&p->start_time);
|
|
p->real_start_time = p->start_time;
|
|
monotonic_to_bootbased(&p->real_start_time);
|
|
p->io_context = NULL;
|
|
p->audit_context = NULL;
|
|
if (clone_flags & CLONE_THREAD)
|
|
threadgroup_change_begin(current);
|
|
cgroup_fork(p);
|
|
#ifdef CONFIG_NUMA
|
|
p->mempolicy = mpol_dup(p->mempolicy);
|
|
if (IS_ERR(p->mempolicy)) {
|
|
retval = PTR_ERR(p->mempolicy);
|
|
p->mempolicy = NULL;
|
|
goto bad_fork_cleanup_cgroup;
|
|
}
|
|
mpol_fix_fork_child_flag(p);
|
|
#endif
|
|
#ifdef CONFIG_CPUSETS
|
|
p->cpuset_mem_spread_rotor = NUMA_NO_NODE;
|
|
p->cpuset_slab_spread_rotor = NUMA_NO_NODE;
|
|
seqcount_init(&p->mems_allowed_seq);
|
|
#endif
|
|
#ifdef CONFIG_TRACE_IRQFLAGS
|
|
p->irq_events = 0;
|
|
p->hardirqs_enabled = 0;
|
|
p->hardirq_enable_ip = 0;
|
|
p->hardirq_enable_event = 0;
|
|
p->hardirq_disable_ip = _THIS_IP_;
|
|
p->hardirq_disable_event = 0;
|
|
p->softirqs_enabled = 1;
|
|
p->softirq_enable_ip = _THIS_IP_;
|
|
p->softirq_enable_event = 0;
|
|
p->softirq_disable_ip = 0;
|
|
p->softirq_disable_event = 0;
|
|
p->hardirq_context = 0;
|
|
p->softirq_context = 0;
|
|
#endif
|
|
#ifdef CONFIG_LOCKDEP
|
|
p->lockdep_depth = 0; /* no locks held yet */
|
|
p->curr_chain_key = 0;
|
|
p->lockdep_recursion = 0;
|
|
#endif
|
|
|
|
#ifdef CONFIG_DEBUG_MUTEXES
|
|
p->blocked_on = NULL; /* not blocked yet */
|
|
#endif
|
|
#ifdef CONFIG_MEMCG
|
|
p->memcg_batch.do_batch = 0;
|
|
p->memcg_batch.memcg = NULL;
|
|
#endif
|
|
#ifdef CONFIG_BCACHE
|
|
p->sequential_io = 0;
|
|
p->sequential_io_avg = 0;
|
|
#endif
|
|
|
|
/* Perform scheduler related setup. Assign this task to a CPU. */
|
|
sched_fork(p);
|
|
|
|
retval = perf_event_init_task(p);
|
|
if (retval)
|
|
goto bad_fork_cleanup_policy;
|
|
retval = audit_alloc(p);
|
|
if (retval)
|
|
goto bad_fork_cleanup_perf;
|
|
/* copy all the process information */
|
|
retval = copy_semundo(clone_flags, p);
|
|
if (retval)
|
|
goto bad_fork_cleanup_audit;
|
|
retval = copy_files(clone_flags, p);
|
|
if (retval)
|
|
goto bad_fork_cleanup_semundo;
|
|
retval = copy_fs(clone_flags, p);
|
|
if (retval)
|
|
goto bad_fork_cleanup_files;
|
|
retval = copy_sighand(clone_flags, p);
|
|
if (retval)
|
|
goto bad_fork_cleanup_fs;
|
|
retval = copy_signal(clone_flags, p);
|
|
if (retval)
|
|
goto bad_fork_cleanup_sighand;
|
|
retval = copy_mm(clone_flags, p);
|
|
if (retval)
|
|
goto bad_fork_cleanup_signal;
|
|
retval = copy_namespaces(clone_flags, p);
|
|
if (retval)
|
|
goto bad_fork_cleanup_mm;
|
|
retval = copy_io(clone_flags, p);
|
|
if (retval)
|
|
goto bad_fork_cleanup_namespaces;
|
|
retval = copy_thread(clone_flags, stack_start, stack_size, p);
|
|
if (retval)
|
|
goto bad_fork_cleanup_io;
|
|
|
|
if (pid != &init_struct_pid) {
|
|
retval = -ENOMEM;
|
|
pid = alloc_pid(p->nsproxy->pid_ns);
|
|
if (!pid)
|
|
goto bad_fork_cleanup_io;
|
|
}
|
|
|
|
p->pid = pid_nr(pid);
|
|
p->tgid = p->pid;
|
|
if (clone_flags & CLONE_THREAD)
|
|
p->tgid = current->tgid;
|
|
|
|
p->set_child_tid = (clone_flags & CLONE_CHILD_SETTID) ? child_tidptr : NULL;
|
|
/*
|
|
* Clear TID on mm_release()?
|
|
*/
|
|
p->clear_child_tid = (clone_flags & CLONE_CHILD_CLEARTID) ? child_tidptr : NULL;
|
|
#ifdef CONFIG_BLOCK
|
|
p->plug = NULL;
|
|
#endif
|
|
#ifdef CONFIG_FUTEX
|
|
p->robust_list = NULL;
|
|
#ifdef CONFIG_COMPAT
|
|
p->compat_robust_list = NULL;
|
|
#endif
|
|
INIT_LIST_HEAD(&p->pi_state_list);
|
|
p->pi_state_cache = NULL;
|
|
#endif
|
|
uprobe_copy_process(p);
|
|
/*
|
|
* sigaltstack should be cleared when sharing the same VM
|
|
*/
|
|
if ((clone_flags & (CLONE_VM|CLONE_VFORK)) == CLONE_VM)
|
|
p->sas_ss_sp = p->sas_ss_size = 0;
|
|
|
|
/*
|
|
* Syscall tracing and stepping should be turned off in the
|
|
* child regardless of CLONE_PTRACE.
|
|
*/
|
|
user_disable_single_step(p);
|
|
clear_tsk_thread_flag(p, TIF_SYSCALL_TRACE);
|
|
#ifdef TIF_SYSCALL_EMU
|
|
clear_tsk_thread_flag(p, TIF_SYSCALL_EMU);
|
|
#endif
|
|
clear_all_latency_tracing(p);
|
|
|
|
/* ok, now we should be set up.. */
|
|
if (clone_flags & CLONE_THREAD)
|
|
p->exit_signal = -1;
|
|
else if (clone_flags & CLONE_PARENT)
|
|
p->exit_signal = current->group_leader->exit_signal;
|
|
else
|
|
p->exit_signal = (clone_flags & CSIGNAL);
|
|
|
|
p->pdeath_signal = 0;
|
|
p->exit_state = 0;
|
|
|
|
p->nr_dirtied = 0;
|
|
p->nr_dirtied_pause = 128 >> (PAGE_SHIFT - 10);
|
|
p->dirty_paused_when = 0;
|
|
|
|
/*
|
|
* Ok, make it visible to the rest of the system.
|
|
* We dont wake it up yet.
|
|
*/
|
|
p->group_leader = p;
|
|
INIT_LIST_HEAD(&p->thread_group);
|
|
p->task_works = NULL;
|
|
|
|
/* Need tasklist lock for parent etc handling! */
|
|
write_lock_irq(&tasklist_lock);
|
|
|
|
/* CLONE_PARENT re-uses the old parent */
|
|
if (clone_flags & (CLONE_PARENT|CLONE_THREAD)) {
|
|
p->real_parent = current->real_parent;
|
|
p->parent_exec_id = current->parent_exec_id;
|
|
} else {
|
|
p->real_parent = current;
|
|
p->parent_exec_id = current->self_exec_id;
|
|
}
|
|
|
|
spin_lock(¤t->sighand->siglock);
|
|
|
|
/*
|
|
* Copy seccomp details explicitly here, in case they were changed
|
|
* before holding sighand lock.
|
|
*/
|
|
copy_seccomp(p);
|
|
|
|
/*
|
|
* Process group and session signals need to be delivered to just the
|
|
* parent before the fork or both the parent and the child after the
|
|
* fork. Restart if a signal comes in before we add the new process to
|
|
* it's process group.
|
|
* A fatal signal pending means that current will exit, so the new
|
|
* thread can't slip out of an OOM kill (or normal SIGKILL).
|
|
*/
|
|
recalc_sigpending();
|
|
if (signal_pending(current)) {
|
|
spin_unlock(¤t->sighand->siglock);
|
|
write_unlock_irq(&tasklist_lock);
|
|
retval = -ERESTARTNOINTR;
|
|
goto bad_fork_free_pid;
|
|
}
|
|
|
|
if (likely(p->pid)) {
|
|
ptrace_init_task(p, (clone_flags & CLONE_PTRACE) || trace);
|
|
|
|
if (thread_group_leader(p)) {
|
|
if (is_child_reaper(pid)) {
|
|
ns_of_pid(pid)->child_reaper = p;
|
|
p->signal->flags |= SIGNAL_UNKILLABLE;
|
|
}
|
|
|
|
p->signal->leader_pid = pid;
|
|
p->signal->tty = tty_kref_get(current->signal->tty);
|
|
attach_pid(p, PIDTYPE_PGID, task_pgrp(current));
|
|
attach_pid(p, PIDTYPE_SID, task_session(current));
|
|
list_add_tail(&p->sibling, &p->real_parent->children);
|
|
list_add_tail_rcu(&p->tasks, &init_task.tasks);
|
|
__this_cpu_inc(process_counts);
|
|
} else {
|
|
current->signal->nr_threads++;
|
|
atomic_inc(¤t->signal->live);
|
|
atomic_inc(¤t->signal->sigcnt);
|
|
p->group_leader = current->group_leader;
|
|
list_add_tail_rcu(&p->thread_group,
|
|
&p->group_leader->thread_group);
|
|
list_add_tail_rcu(&p->thread_node,
|
|
&p->signal->thread_head);
|
|
}
|
|
attach_pid(p, PIDTYPE_PID, pid);
|
|
nr_threads++;
|
|
}
|
|
|
|
total_forks++;
|
|
spin_unlock(¤t->sighand->siglock);
|
|
syscall_tracepoint_update(p);
|
|
write_unlock_irq(&tasklist_lock);
|
|
|
|
proc_fork_connector(p);
|
|
cgroup_post_fork(p);
|
|
if (clone_flags & CLONE_THREAD)
|
|
threadgroup_change_end(current);
|
|
perf_event_fork(p);
|
|
|
|
trace_task_newtask(p, clone_flags);
|
|
|
|
return p;
|
|
|
|
bad_fork_free_pid:
|
|
if (pid != &init_struct_pid)
|
|
free_pid(pid);
|
|
bad_fork_cleanup_io:
|
|
if (p->io_context)
|
|
exit_io_context(p);
|
|
bad_fork_cleanup_namespaces:
|
|
exit_task_namespaces(p);
|
|
bad_fork_cleanup_mm:
|
|
if (p->mm)
|
|
mmput(p->mm);
|
|
bad_fork_cleanup_signal:
|
|
if (!(clone_flags & CLONE_THREAD))
|
|
free_signal_struct(p->signal);
|
|
bad_fork_cleanup_sighand:
|
|
__cleanup_sighand(p->sighand);
|
|
bad_fork_cleanup_fs:
|
|
exit_fs(p); /* blocking */
|
|
bad_fork_cleanup_files:
|
|
exit_files(p); /* blocking */
|
|
bad_fork_cleanup_semundo:
|
|
exit_sem(p);
|
|
bad_fork_cleanup_audit:
|
|
audit_free(p);
|
|
bad_fork_cleanup_perf:
|
|
perf_event_free_task(p);
|
|
bad_fork_cleanup_policy:
|
|
#ifdef CONFIG_NUMA
|
|
mpol_put(p->mempolicy);
|
|
bad_fork_cleanup_cgroup:
|
|
#endif
|
|
if (clone_flags & CLONE_THREAD)
|
|
threadgroup_change_end(current);
|
|
cgroup_exit(p, 0);
|
|
delayacct_tsk_free(p);
|
|
module_put(task_thread_info(p)->exec_domain->module);
|
|
bad_fork_cleanup_count:
|
|
atomic_dec(&p->cred->user->processes);
|
|
exit_creds(p);
|
|
bad_fork_free:
|
|
free_task(p);
|
|
fork_out:
|
|
return ERR_PTR(retval);
|
|
}
|
|
|
|
static inline void init_idle_pids(struct pid_link *links)
|
|
{
|
|
enum pid_type type;
|
|
|
|
for (type = PIDTYPE_PID; type < PIDTYPE_MAX; ++type) {
|
|
INIT_HLIST_NODE(&links[type].node); /* not really needed */
|
|
links[type].pid = &init_struct_pid;
|
|
}
|
|
}
|
|
|
|
struct task_struct * __cpuinit fork_idle(int cpu)
|
|
{
|
|
struct task_struct *task;
|
|
task = copy_process(CLONE_VM, 0, 0, NULL, &init_struct_pid, 0);
|
|
if (!IS_ERR(task)) {
|
|
init_idle_pids(task->pids);
|
|
init_idle(task, cpu);
|
|
}
|
|
|
|
return task;
|
|
}
|
|
|
|
/*
|
|
* Ok, this is the main fork-routine.
|
|
*
|
|
* It copies the process, and if successful kick-starts
|
|
* it and waits for it to finish using the VM if required.
|
|
*/
|
|
long do_fork(unsigned long clone_flags,
|
|
unsigned long stack_start,
|
|
unsigned long stack_size,
|
|
int __user *parent_tidptr,
|
|
int __user *child_tidptr)
|
|
{
|
|
struct task_struct *p;
|
|
int trace = 0;
|
|
long nr;
|
|
|
|
/*
|
|
* Do some preliminary argument and permissions checking before we
|
|
* actually start allocating stuff
|
|
*/
|
|
if (clone_flags & (CLONE_NEWUSER | CLONE_NEWPID)) {
|
|
if (clone_flags & (CLONE_THREAD|CLONE_PARENT))
|
|
return -EINVAL;
|
|
}
|
|
|
|
/*
|
|
* Determine whether and which event to report to ptracer. When
|
|
* called from kernel_thread or CLONE_UNTRACED is explicitly
|
|
* requested, no event is reported; otherwise, report if the event
|
|
* for the type of forking is enabled.
|
|
*/
|
|
if (!(clone_flags & CLONE_UNTRACED)) {
|
|
if (clone_flags & CLONE_VFORK)
|
|
trace = PTRACE_EVENT_VFORK;
|
|
else if ((clone_flags & CSIGNAL) != SIGCHLD)
|
|
trace = PTRACE_EVENT_CLONE;
|
|
else
|
|
trace = PTRACE_EVENT_FORK;
|
|
|
|
if (likely(!ptrace_event_enabled(current, trace)))
|
|
trace = 0;
|
|
}
|
|
|
|
p = copy_process(clone_flags, stack_start, stack_size,
|
|
child_tidptr, NULL, trace);
|
|
/*
|
|
* Do this prior waking up the new thread - the thread pointer
|
|
* might get invalid after that point, if the thread exits quickly.
|
|
*/
|
|
if (!IS_ERR(p)) {
|
|
struct completion vfork;
|
|
struct pid *pid;
|
|
|
|
trace_sched_process_fork(current, p);
|
|
|
|
pid = get_task_pid(p, PIDTYPE_PID);
|
|
nr = pid_vnr(pid);
|
|
|
|
if (clone_flags & CLONE_PARENT_SETTID)
|
|
put_user(nr, parent_tidptr);
|
|
|
|
if (clone_flags & CLONE_VFORK) {
|
|
p->vfork_done = &vfork;
|
|
init_completion(&vfork);
|
|
get_task_struct(p);
|
|
}
|
|
|
|
wake_up_new_task(p);
|
|
|
|
/* forking complete and child started to run, tell ptracer */
|
|
if (unlikely(trace))
|
|
ptrace_event_pid(trace, pid);
|
|
|
|
if (clone_flags & CLONE_VFORK) {
|
|
if (!wait_for_vfork_done(p, &vfork))
|
|
ptrace_event_pid(PTRACE_EVENT_VFORK_DONE, pid);
|
|
}
|
|
|
|
put_pid(pid);
|
|
} else {
|
|
nr = PTR_ERR(p);
|
|
}
|
|
return nr;
|
|
}
|
|
|
|
/*
|
|
* Create a kernel thread.
|
|
*/
|
|
pid_t kernel_thread(int (*fn)(void *), void *arg, unsigned long flags)
|
|
{
|
|
return do_fork(flags|CLONE_VM|CLONE_UNTRACED, (unsigned long)fn,
|
|
(unsigned long)arg, NULL, NULL);
|
|
}
|
|
|
|
#ifdef __ARCH_WANT_SYS_FORK
|
|
SYSCALL_DEFINE0(fork)
|
|
{
|
|
#ifdef CONFIG_MMU
|
|
return do_fork(SIGCHLD, 0, 0, NULL, NULL);
|
|
#else
|
|
/* can not support in nommu mode */
|
|
return(-EINVAL);
|
|
#endif
|
|
}
|
|
#endif
|
|
|
|
#ifdef __ARCH_WANT_SYS_VFORK
|
|
SYSCALL_DEFINE0(vfork)
|
|
{
|
|
return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, 0,
|
|
0, NULL, NULL);
|
|
}
|
|
#endif
|
|
|
|
#ifdef __ARCH_WANT_SYS_CLONE
|
|
#ifdef CONFIG_CLONE_BACKWARDS
|
|
SYSCALL_DEFINE5(clone, unsigned long, clone_flags, unsigned long, newsp,
|
|
int __user *, parent_tidptr,
|
|
int, tls_val,
|
|
int __user *, child_tidptr)
|
|
#elif defined(CONFIG_CLONE_BACKWARDS2)
|
|
SYSCALL_DEFINE5(clone, unsigned long, newsp, unsigned long, clone_flags,
|
|
int __user *, parent_tidptr,
|
|
int __user *, child_tidptr,
|
|
int, tls_val)
|
|
#elif defined(CONFIG_CLONE_BACKWARDS3)
|
|
SYSCALL_DEFINE6(clone, unsigned long, clone_flags, unsigned long, newsp,
|
|
int, stack_size,
|
|
int __user *, parent_tidptr,
|
|
int __user *, child_tidptr,
|
|
int, tls_val)
|
|
#else
|
|
SYSCALL_DEFINE5(clone, unsigned long, clone_flags, unsigned long, newsp,
|
|
int __user *, parent_tidptr,
|
|
int __user *, child_tidptr,
|
|
int, tls_val)
|
|
#endif
|
|
{
|
|
return do_fork(clone_flags, newsp, 0, parent_tidptr, child_tidptr);
|
|
}
|
|
#endif
|
|
|
|
#ifndef ARCH_MIN_MMSTRUCT_ALIGN
|
|
#define ARCH_MIN_MMSTRUCT_ALIGN 0
|
|
#endif
|
|
|
|
static void sighand_ctor(void *data)
|
|
{
|
|
struct sighand_struct *sighand = data;
|
|
|
|
spin_lock_init(&sighand->siglock);
|
|
init_waitqueue_head(&sighand->signalfd_wqh);
|
|
}
|
|
|
|
void __init proc_caches_init(void)
|
|
{
|
|
sighand_cachep = kmem_cache_create("sighand_cache",
|
|
sizeof(struct sighand_struct), 0,
|
|
SLAB_HWCACHE_ALIGN|SLAB_PANIC|SLAB_DESTROY_BY_RCU|
|
|
SLAB_NOTRACK, sighand_ctor);
|
|
signal_cachep = kmem_cache_create("signal_cache",
|
|
sizeof(struct signal_struct), 0,
|
|
SLAB_HWCACHE_ALIGN|SLAB_PANIC|SLAB_NOTRACK, NULL);
|
|
files_cachep = kmem_cache_create("files_cache",
|
|
sizeof(struct files_struct), 0,
|
|
SLAB_HWCACHE_ALIGN|SLAB_PANIC|SLAB_NOTRACK, NULL);
|
|
fs_cachep = kmem_cache_create("fs_cache",
|
|
sizeof(struct fs_struct), 0,
|
|
SLAB_HWCACHE_ALIGN|SLAB_PANIC|SLAB_NOTRACK, NULL);
|
|
/*
|
|
* FIXME! The "sizeof(struct mm_struct)" currently includes the
|
|
* whole struct cpumask for the OFFSTACK case. We could change
|
|
* this to *only* allocate as much of it as required by the
|
|
* maximum number of CPU's we can ever have. The cpumask_allocation
|
|
* is at the end of the structure, exactly for that reason.
|
|
*/
|
|
mm_cachep = kmem_cache_create("mm_struct",
|
|
sizeof(struct mm_struct), ARCH_MIN_MMSTRUCT_ALIGN,
|
|
SLAB_HWCACHE_ALIGN|SLAB_PANIC|SLAB_NOTRACK, NULL);
|
|
vm_area_cachep = KMEM_CACHE(vm_area_struct, SLAB_PANIC);
|
|
mmap_init();
|
|
nsproxy_cache_init();
|
|
}
|
|
|
|
/*
|
|
* Check constraints on flags passed to the unshare system call.
|
|
*/
|
|
static int check_unshare_flags(unsigned long unshare_flags)
|
|
{
|
|
if (unshare_flags & ~(CLONE_THREAD|CLONE_FS|CLONE_NEWNS|CLONE_SIGHAND|
|
|
CLONE_VM|CLONE_FILES|CLONE_SYSVSEM|
|
|
CLONE_NEWUTS|CLONE_NEWIPC|CLONE_NEWNET|
|
|
CLONE_NEWUSER|CLONE_NEWPID))
|
|
return -EINVAL;
|
|
/*
|
|
* Not implemented, but pretend it works if there is nothing to
|
|
* unshare. Note that unsharing CLONE_THREAD or CLONE_SIGHAND
|
|
* needs to unshare vm.
|
|
*/
|
|
if (unshare_flags & (CLONE_THREAD | CLONE_SIGHAND | CLONE_VM)) {
|
|
/* FIXME: get_task_mm() increments ->mm_users */
|
|
if (atomic_read(¤t->mm->mm_users) > 1)
|
|
return -EINVAL;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
/*
|
|
* Unshare the filesystem structure if it is being shared
|
|
*/
|
|
static int unshare_fs(unsigned long unshare_flags, struct fs_struct **new_fsp)
|
|
{
|
|
struct fs_struct *fs = current->fs;
|
|
|
|
if (!(unshare_flags & CLONE_FS) || !fs)
|
|
return 0;
|
|
|
|
/* don't need lock here; in the worst case we'll do useless copy */
|
|
if (fs->users == 1)
|
|
return 0;
|
|
|
|
*new_fsp = copy_fs_struct(fs);
|
|
if (!*new_fsp)
|
|
return -ENOMEM;
|
|
|
|
return 0;
|
|
}
|
|
|
|
/*
|
|
* Unshare file descriptor table if it is being shared
|
|
*/
|
|
static int unshare_fd(unsigned long unshare_flags, struct files_struct **new_fdp)
|
|
{
|
|
struct files_struct *fd = current->files;
|
|
int error = 0;
|
|
|
|
if ((unshare_flags & CLONE_FILES) &&
|
|
(fd && atomic_read(&fd->count) > 1)) {
|
|
*new_fdp = dup_fd(fd, &error);
|
|
if (!*new_fdp)
|
|
return error;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
/*
|
|
* unshare allows a process to 'unshare' part of the process
|
|
* context which was originally shared using clone. copy_*
|
|
* functions used by do_fork() cannot be used here directly
|
|
* because they modify an inactive task_struct that is being
|
|
* constructed. Here we are modifying the current, active,
|
|
* task_struct.
|
|
*/
|
|
SYSCALL_DEFINE1(unshare, unsigned long, unshare_flags)
|
|
{
|
|
struct fs_struct *fs, *new_fs = NULL;
|
|
struct files_struct *fd, *new_fd = NULL;
|
|
struct cred *new_cred = NULL;
|
|
struct nsproxy *new_nsproxy = NULL;
|
|
int do_sysvsem = 0;
|
|
int err;
|
|
|
|
/*
|
|
* If unsharing a user namespace must also unshare the thread.
|
|
*/
|
|
if (unshare_flags & CLONE_NEWUSER)
|
|
unshare_flags |= CLONE_THREAD | CLONE_FS;
|
|
/*
|
|
* If unsharing a pid namespace must also unshare the thread.
|
|
*/
|
|
if (unshare_flags & CLONE_NEWPID)
|
|
unshare_flags |= CLONE_THREAD;
|
|
/*
|
|
* If unsharing a thread from a thread group, must also unshare vm.
|
|
*/
|
|
if (unshare_flags & CLONE_THREAD)
|
|
unshare_flags |= CLONE_VM;
|
|
/*
|
|
* If unsharing vm, must also unshare signal handlers.
|
|
*/
|
|
if (unshare_flags & CLONE_VM)
|
|
unshare_flags |= CLONE_SIGHAND;
|
|
/*
|
|
* If unsharing namespace, must also unshare filesystem information.
|
|
*/
|
|
if (unshare_flags & CLONE_NEWNS)
|
|
unshare_flags |= CLONE_FS;
|
|
|
|
err = check_unshare_flags(unshare_flags);
|
|
if (err)
|
|
goto bad_unshare_out;
|
|
/*
|
|
* CLONE_NEWIPC must also detach from the undolist: after switching
|
|
* to a new ipc namespace, the semaphore arrays from the old
|
|
* namespace are unreachable.
|
|
*/
|
|
if (unshare_flags & (CLONE_NEWIPC|CLONE_SYSVSEM))
|
|
do_sysvsem = 1;
|
|
err = unshare_fs(unshare_flags, &new_fs);
|
|
if (err)
|
|
goto bad_unshare_out;
|
|
err = unshare_fd(unshare_flags, &new_fd);
|
|
if (err)
|
|
goto bad_unshare_cleanup_fs;
|
|
err = unshare_userns(unshare_flags, &new_cred);
|
|
if (err)
|
|
goto bad_unshare_cleanup_fd;
|
|
err = unshare_nsproxy_namespaces(unshare_flags, &new_nsproxy,
|
|
new_cred, new_fs);
|
|
if (err)
|
|
goto bad_unshare_cleanup_cred;
|
|
|
|
if (new_fs || new_fd || do_sysvsem || new_cred || new_nsproxy) {
|
|
if (do_sysvsem) {
|
|
/*
|
|
* CLONE_SYSVSEM is equivalent to sys_exit().
|
|
*/
|
|
exit_sem(current);
|
|
}
|
|
|
|
if (new_nsproxy)
|
|
switch_task_namespaces(current, new_nsproxy);
|
|
|
|
task_lock(current);
|
|
|
|
if (new_fs) {
|
|
fs = current->fs;
|
|
spin_lock(&fs->lock);
|
|
current->fs = new_fs;
|
|
if (--fs->users)
|
|
new_fs = NULL;
|
|
else
|
|
new_fs = fs;
|
|
spin_unlock(&fs->lock);
|
|
}
|
|
|
|
if (new_fd) {
|
|
fd = current->files;
|
|
current->files = new_fd;
|
|
new_fd = fd;
|
|
}
|
|
|
|
task_unlock(current);
|
|
|
|
if (new_cred) {
|
|
/* Install the new user namespace */
|
|
commit_creds(new_cred);
|
|
new_cred = NULL;
|
|
}
|
|
}
|
|
|
|
bad_unshare_cleanup_cred:
|
|
if (new_cred)
|
|
put_cred(new_cred);
|
|
bad_unshare_cleanup_fd:
|
|
if (new_fd)
|
|
put_files_struct(new_fd);
|
|
|
|
bad_unshare_cleanup_fs:
|
|
if (new_fs)
|
|
free_fs_struct(new_fs);
|
|
|
|
bad_unshare_out:
|
|
return err;
|
|
}
|
|
|
|
/*
|
|
* Helper to unshare the files of the current task.
|
|
* We don't want to expose copy_files internals to
|
|
* the exec layer of the kernel.
|
|
*/
|
|
|
|
int unshare_files(struct files_struct **displaced)
|
|
{
|
|
struct task_struct *task = current;
|
|
struct files_struct *copy = NULL;
|
|
int error;
|
|
|
|
error = unshare_fd(CLONE_FILES, ©);
|
|
if (error || !copy) {
|
|
*displaced = NULL;
|
|
return error;
|
|
}
|
|
*displaced = task->files;
|
|
task_lock(task);
|
|
task->files = copy;
|
|
task_unlock(task);
|
|
return 0;
|
|
}
|