1
0
Files

2951 lines
69 KiB
C
Raw Permalink Normal View History

/*
* NET4: Implementation of BSD Unix domain sockets.
*
* Authors: Alan Cox, <alan@lxorguk.ukuu.org.uk>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*
* Fixes:
* Linus Torvalds : Assorted bug cures.
* Niibe Yutaka : async I/O support.
* Carsten Paeth : PF_UNIX check, address fixes.
* Alan Cox : Limit size of allocated blocks.
* Alan Cox : Fixed the stupid socketpair bug.
* Alan Cox : BSD compatibility fine tuning.
* Alan Cox : Fixed a bug in connect when interrupted.
* Alan Cox : Sorted out a proper draft version of
* file descriptor passing hacked up from
* Mike Shaver's work.
* Marty Leisner : Fixes to fd passing
* Nick Nevin : recvmsg bugfix.
* Alan Cox : Started proper garbage collector
* Heiko EiBfeldt : Missing verify_area check
* Alan Cox : Started POSIXisms
* Andreas Schwab : Replace inode by dentry for proper
* reference counting
* Kirk Petersen : Made this a module
* Christoph Rohland : Elegant non-blocking accept/connect algorithm.
* Lots of bug fixes.
* Alexey Kuznetosv : Repaired (I hope) bugs introduces
* by above two patches.
* Andrea Arcangeli : If possible we block in connect(2)
* if the max backlog of the listen socket
* is been reached. This won't break
* old apps and it will avoid huge amount
* of socks hashed (this for unix_gc()
* performances reasons).
* Security fix that limits the max
* number of socks to 2*max_files and
* the number of skb queueable in the
* dgram receiver.
* Artur Skawina : Hash function optimizations
* Alexey Kuznetsov : Full scale SMP. Lot of bugs are introduced 8)
* Malcolm Beattie : Set peercred for socketpair
* Michal Ostrowski : Module initialization cleanup.
* Arnaldo C. Melo : Remove MOD_{INC,DEC}_USE_COUNT,
* the core infrastructure is doing that
* for all net proto families now (2.5.69+)
*
*
* Known differences from reference BSD that was tested:
*
* [TO FIX]
* ECONNREFUSED is not returned from one end of a connected() socket to the
* other the moment one end closes.
* fstat() doesn't return st_dev=0, and give the blksize as high water mark
* and a fake inode identifier (nor the BSD first socket fstat twice bug).
* [NOT TO FIX]
* accept() returns a path name even if the connecting socket has closed
* in the meantime (BSD loses the path and gives up).
* accept() returns 0 length path for an unbound connector. BSD returns 16
* and a null first byte in the path (but not for gethost/peername - BSD bug ??)
* socketpair(...SOCK_RAW..) doesn't panic the kernel.
* BSD af_unix apparently has connect forgetting to block properly.
* (need to check this with the POSIX spec in detail)
*
* Differences from 2.0.0-11-... (ANK)
* Bug fixes and improvements.
* - client shutdown killed server socket.
* - removed all useless cli/sti pairs.
*
* Semantic changes/extensions.
* - generic control message passing.
* - SCM_CREDENTIALS control message.
* - "Abstract" (not FS based) socket bindings.
* Abstract names are sequences of bytes (not zero terminated)
* started by 0, so that this name space does not intersect
* with BSD names.
*/
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/signal.h>
#include <linux/sched.h>
#include <linux/errno.h>
#include <linux/string.h>
#include <linux/stat.h>
#include <linux/dcache.h>
#include <linux/namei.h>
#include <linux/socket.h>
#include <linux/un.h>
#include <linux/fcntl.h>
#include <linux/termios.h>
#include <linux/sockios.h>
#include <linux/net.h>
#include <linux/in.h>
#include <linux/fs.h>
#include <linux/slab.h>
#include <asm/uaccess.h>
#include <linux/skbuff.h>
#include <linux/netdevice.h>
#include <net/net_namespace.h>
#include <net/sock.h>
#include <net/tcp_states.h>
#include <net/af_unix.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
#include <net/scm.h>
#include <linux/init.h>
#include <linux/poll.h>
#include <linux/rtnetlink.h>
#include <linux/mount.h>
#include <net/checksum.h>
#include <linux/security.h>
#include <linux/freezer.h>
Merge 4.9.278 into android-4.9-q Changes in 4.9.278 iommu/amd: Fix backport of 140456f994195b568ecd7fc2287a34eadffef3ca tipc: Fix backport of b77413446408fdd256599daf00d5be72b5f3e7c6 net: split out functions related to registering inflight socket files af_unix: fix garbage collect vs MSG_PEEK workqueue: fix UAF in pwq_unbound_release_workfn() net/802/mrp: fix memleak in mrp_request_join() net/802/garp: fix memleak in garp_request_join() sctp: move 198 addresses from unusable to private scope hfs: add missing clean-up in hfs_fill_super hfs: fix high memory mapping in hfs_bnode_read hfs: add lock nesting notation to hfs_find_init ARM: dts: versatile: Fix up interrupt controller node names lib/string.c: add multibyte memset functions ARM: ensure the signal page contains defined contents x86/kvm: fix vcpu-id indexed array sizes ocfs2: fix zero out valid data ocfs2: issue zeroout to EOF blocks can: usb_8dev: fix memory leak can: ems_usb: fix memory leak can: esd_usb2: fix memory leak NIU: fix incorrect error return, missed in previous revert nfc: nfcsim: fix use after free during module unload x86/asm: Ensure asm/proto.h can be included stand-alone cfg80211: Fix possible memory leak in function cfg80211_bss_update netfilter: conntrack: adjust stop timestamp to real expiry value netfilter: nft_nat: allow to specify layer 4 protocol NAT only tipc: fix sleeping in tipc accept routine mlx4: Fix missing error code in mlx4_load_one() net: llc: fix skb_over_panic net/mlx5: Fix flow table chaining tulip: windbond-840: Fix missing pci_disable_device() in probe and remove sis900: Fix missing pci_disable_device() in probe and remove Linux 4.9.278 Signed-off-by: Greg Kroah-Hartman <gregkh@google.com> Change-Id: Ib4a913f4321ead750bc71245e283aae9cb02681b
2021-08-04 12:49:31 +02:00
#include "scm.h"
struct hlist_head unix_socket_table[2 * UNIX_HASH_SIZE];
EXPORT_SYMBOL_GPL(unix_socket_table);
DEFINE_SPINLOCK(unix_table_lock);
EXPORT_SYMBOL_GPL(unix_table_lock);
static atomic_long_t unix_nr_socks;
static struct hlist_head *unix_sockets_unbound(void *addr)
{
unsigned long hash = (unsigned long)addr;
hash ^= hash >> 16;
hash ^= hash >> 8;
hash %= UNIX_HASH_SIZE;
return &unix_socket_table[UNIX_HASH_SIZE + hash];
}
#define UNIX_ABSTRACT(sk) (unix_sk(sk)->addr->hash < UNIX_HASH_SIZE)
#ifdef CONFIG_SECURITY_NETWORK
static void unix_get_secdata(struct scm_cookie *scm, struct sk_buff *skb)
{
UNIXCB(skb).secid = scm->secid;
}
static inline void unix_set_secdata(struct scm_cookie *scm, struct sk_buff *skb)
{
scm->secid = UNIXCB(skb).secid;
}
static inline bool unix_secdata_eq(struct scm_cookie *scm, struct sk_buff *skb)
{
return (scm->secid == UNIXCB(skb).secid);
}
#else
static inline void unix_get_secdata(struct scm_cookie *scm, struct sk_buff *skb)
{ }
static inline void unix_set_secdata(struct scm_cookie *scm, struct sk_buff *skb)
{ }
static inline bool unix_secdata_eq(struct scm_cookie *scm, struct sk_buff *skb)
{
return true;
}
#endif /* CONFIG_SECURITY_NETWORK */
/*
* SMP locking strategy:
* hash table is protected with spinlock unix_table_lock
* each socket state is protected by separate spin lock.
*/
static inline unsigned int unix_hash_fold(__wsum n)
{
unsigned int hash = (__force unsigned int)csum_fold(n);
hash ^= hash>>8;
return hash&(UNIX_HASH_SIZE-1);
}
#define unix_peer(sk) (unix_sk(sk)->peer)
static inline int unix_our_peer(struct sock *sk, struct sock *osk)
{
return unix_peer(osk) == sk;
}
static inline int unix_may_send(struct sock *sk, struct sock *osk)
{
return unix_peer(osk) == NULL || unix_our_peer(sk, osk);
}
Merge 4.9.238 into android-4.9-q Changes in 4.9.238 af_key: pfkey_dump needs parameter validation KVM: fix memory leak in kvm_io_bus_unregister_dev() kprobes: fix kill kprobe which has been marked as gone RDMA/ucma: ucma_context reference leak in error path mtd: Fix comparison in map_word_andequal() hdlc_ppp: add range checks in ppp_cp_parse_cr() ip: fix tos reflection in ack and reset packets tipc: use skb_unshare() instead in tipc_buf_append() bnxt_en: Protect bnxt_set_eee() and bnxt_set_pauseparam() with mutex. net: phy: Avoid NPD upon phy_detach() when driver is unbound net/hsr: Check skb_put_padto() return value net: add __must_check to skb_put_padto() serial: 8250: Avoid error message on reprobe scsi: aacraid: fix illegal IO beyond last LBA m68k: q40: Fix info-leak in rtc_ioctl gma/gma500: fix a memory disclosure bug due to uninitialized bytes ASoC: kirkwood: fix IRQ error handling ALSA: usb-audio: Add delay quirk for H570e USB headsets PM / devfreq: tegra30: Fix integer overflow on CPU's freq max out clk/ti/adpll: allocate room for terminating null mtd: cfi_cmdset_0002: don't free cfi->cfiq in error path of cfi_amdstd_setup() mfd: mfd-core: Protect against NULL call-back function pointer tracing: Adding NULL checks for trace_array descriptor pointer bcache: fix a lost wake-up problem caused by mca_cannibalize_lock RDMA/i40iw: Fix potential use after free xfs: fix attr leaf header freemap.size underflow RDMA/iw_cgxb4: Fix an error handling path in 'c4iw_connect()' debugfs: Fix !DEBUG_FS debugfs_create_automount CIFS: Properly process SMB3 lease breaks kernel/sys.c: avoid copying possible padding bytes in copy_to_user neigh_stat_seq_next() should increase position index rt_cpu_seq_next should increase position index seqlock: Require WRITE_ONCE surrounding raw_seqcount_barrier media: ti-vpe: cal: Restrict DMA to avoid memory corruption ACPI: EC: Reference count query handlers under lock dmaengine: zynqmp_dma: fix burst length configuration tracing: Set kernel_stack's caller size properly ar5523: Add USB ID of SMCWUSBT-G2 wireless adapter Bluetooth: Fix refcount use-after-free issue mm: pagewalk: fix termination condition in walk_pte_range() Bluetooth: prefetch channel before killing sock KVM: fix overflow of zero page refcount with ksm running ALSA: hda: Clear RIRB status before reading WP skbuff: fix a data race in skb_queue_len() audit: CONFIG_CHANGE don't log internal bookkeeping as an event selinux: sel_avc_get_stat_idx should increase position index scsi: lpfc: Fix RQ buffer leakage when no IOCBs available scsi: lpfc: Fix coverity errors in fmdi attribute handling drm/omap: fix possible object reference leak RDMA/rxe: Fix configuration of atomic queue pair attributes KVM: x86: fix incorrect comparison in trace event x86/pkeys: Add check for pkey "overflow" bpf: Remove recursion prevention from rcu free callback dmaengine: tegra-apb: Prevent race conditions on channel's freeing media: go7007: Fix URB type for interrupt handling Bluetooth: guard against controllers sending zero'd events timekeeping: Prevent 32bit truncation in scale64_check_overflow() drm/amdgpu: increase atombios cmd timeout Bluetooth: L2CAP: handle l2cap config request during open state media: tda10071: fix unsigned sign extension overflow xfs: don't ever return a stale pointer from __xfs_dir3_free_read tpm: ibmvtpm: Wait for buffer to be set before proceeding tracing: Use address-of operator on section symbols serial: 8250_port: Don't service RX FIFO if throttled serial: 8250_omap: Fix sleeping function called from invalid context during probe serial: 8250: 8250_omap: Terminate DMA before pushing data on RX timeout cpufreq: powernv: Fix frame-size-overflow in powernv_cpufreq_work_fn tools: gpio-hammer: Avoid potential overflow in main SUNRPC: Fix a potential buffer overflow in 'svc_print_xprts()' svcrdma: Fix leak of transport addresses ubifs: Fix out-of-bounds memory access caused by abnormal value of node_len ALSA: usb-audio: Fix case when USB MIDI interface has more than one extra endpoint descriptor mm/filemap.c: clear page error before actual read mm/mmap.c: initialize align_offset explicitly for vm_unmapped_area KVM: Remove CREATE_IRQCHIP/SET_PIT2 race bdev: Reduce time holding bd_mutex in sync in blkdev_close() drivers: char: tlclk.c: Avoid data race between init and interrupt handler dt-bindings: sound: wm8994: Correct required supplies based on actual implementaion atm: fix a memory leak of vcc->user_back phy: samsung: s5pv210-usb2: Add delay after reset Bluetooth: Handle Inquiry Cancel error after Inquiry Complete USB: EHCI: ehci-mv: fix error handling in mv_ehci_probe() tty: serial: samsung: Correct clock selection logic ALSA: hda: Fix potential race in unsol event handler fuse: don't check refcount after stealing page USB: EHCI: ehci-mv: fix less than zero comparison of an unsigned int e1000: Do not perform reset in reset_task if we are already down printk: handle blank console arguments passed in. btrfs: don't force read-only after error in drop snapshot vfio/pci: fix memory leaks of eventfd ctx perf util: Fix memory leak of prefix_if_not_in perf kcore_copy: Fix module map when there are no modules loaded mtd: rawnand: omap_elm: Fix runtime PM imbalance on error ceph: fix potential race in ceph_check_caps mtd: parser: cmdline: Support MTD names containing one or more colons x86/speculation/mds: Mark mds_user_clear_cpu_buffers() __always_inline vfio/pci: Clear error and request eventfd ctx after releasing cifs: Fix double add page to memcg when cifs_readpages selftests/x86/syscall_nt: Clear weird flags after each test vfio/pci: fix racy on error and request eventfd ctx s390/init: add missing __init annotations i2c: core: Call i2c_acpi_install_space_handler() before i2c_acpi_register_devices() objtool: Fix noreturn detection for ignored functions ieee802154/adf7242: check status of adf7242_read_reg clocksource/drivers/h8300_timer8: Fix wrong return value in h8300_8timer_init() mwifiex: Increase AES key storage size to 256 bits batman-adv: bla: fix type misuse for backbone_gw hash indexing atm: eni: fix the missed pci_disable_device() for eni_init_one() batman-adv: mcast/TT: fix wrongly dropped or rerouted packets mac802154: tx: fix use-after-free batman-adv: Add missing include for in_interrupt() batman-adv: mcast: fix duplicate mcast packets in BLA backbone from mesh ALSA: asihpi: fix iounmap in error handler MIPS: Add the missing 'CPU_1074K' into __get_cpu_type() kprobes: Fix to check probe enabled before disarm_kprobe_ftrace() lib/string.c: implement stpcpy ata: define AC_ERR_OK ata: make qc_prep return ata_completion_errors ata: sata_mv, avoid trigerrable BUG_ON Linux 4.9.238 Signed-off-by: Greg Kroah-Hartman <gregkh@google.com> Change-Id: I799877db3bc49e473bbc023ab948cd241755beff
2020-10-02 09:20:19 +02:00
static inline int unix_recvq_full(const struct sock *sk)
{
return skb_queue_len(&sk->sk_receive_queue) > sk->sk_max_ack_backlog;
}
Merge 4.9.238 into android-4.9-q Changes in 4.9.238 af_key: pfkey_dump needs parameter validation KVM: fix memory leak in kvm_io_bus_unregister_dev() kprobes: fix kill kprobe which has been marked as gone RDMA/ucma: ucma_context reference leak in error path mtd: Fix comparison in map_word_andequal() hdlc_ppp: add range checks in ppp_cp_parse_cr() ip: fix tos reflection in ack and reset packets tipc: use skb_unshare() instead in tipc_buf_append() bnxt_en: Protect bnxt_set_eee() and bnxt_set_pauseparam() with mutex. net: phy: Avoid NPD upon phy_detach() when driver is unbound net/hsr: Check skb_put_padto() return value net: add __must_check to skb_put_padto() serial: 8250: Avoid error message on reprobe scsi: aacraid: fix illegal IO beyond last LBA m68k: q40: Fix info-leak in rtc_ioctl gma/gma500: fix a memory disclosure bug due to uninitialized bytes ASoC: kirkwood: fix IRQ error handling ALSA: usb-audio: Add delay quirk for H570e USB headsets PM / devfreq: tegra30: Fix integer overflow on CPU's freq max out clk/ti/adpll: allocate room for terminating null mtd: cfi_cmdset_0002: don't free cfi->cfiq in error path of cfi_amdstd_setup() mfd: mfd-core: Protect against NULL call-back function pointer tracing: Adding NULL checks for trace_array descriptor pointer bcache: fix a lost wake-up problem caused by mca_cannibalize_lock RDMA/i40iw: Fix potential use after free xfs: fix attr leaf header freemap.size underflow RDMA/iw_cgxb4: Fix an error handling path in 'c4iw_connect()' debugfs: Fix !DEBUG_FS debugfs_create_automount CIFS: Properly process SMB3 lease breaks kernel/sys.c: avoid copying possible padding bytes in copy_to_user neigh_stat_seq_next() should increase position index rt_cpu_seq_next should increase position index seqlock: Require WRITE_ONCE surrounding raw_seqcount_barrier media: ti-vpe: cal: Restrict DMA to avoid memory corruption ACPI: EC: Reference count query handlers under lock dmaengine: zynqmp_dma: fix burst length configuration tracing: Set kernel_stack's caller size properly ar5523: Add USB ID of SMCWUSBT-G2 wireless adapter Bluetooth: Fix refcount use-after-free issue mm: pagewalk: fix termination condition in walk_pte_range() Bluetooth: prefetch channel before killing sock KVM: fix overflow of zero page refcount with ksm running ALSA: hda: Clear RIRB status before reading WP skbuff: fix a data race in skb_queue_len() audit: CONFIG_CHANGE don't log internal bookkeeping as an event selinux: sel_avc_get_stat_idx should increase position index scsi: lpfc: Fix RQ buffer leakage when no IOCBs available scsi: lpfc: Fix coverity errors in fmdi attribute handling drm/omap: fix possible object reference leak RDMA/rxe: Fix configuration of atomic queue pair attributes KVM: x86: fix incorrect comparison in trace event x86/pkeys: Add check for pkey "overflow" bpf: Remove recursion prevention from rcu free callback dmaengine: tegra-apb: Prevent race conditions on channel's freeing media: go7007: Fix URB type for interrupt handling Bluetooth: guard against controllers sending zero'd events timekeeping: Prevent 32bit truncation in scale64_check_overflow() drm/amdgpu: increase atombios cmd timeout Bluetooth: L2CAP: handle l2cap config request during open state media: tda10071: fix unsigned sign extension overflow xfs: don't ever return a stale pointer from __xfs_dir3_free_read tpm: ibmvtpm: Wait for buffer to be set before proceeding tracing: Use address-of operator on section symbols serial: 8250_port: Don't service RX FIFO if throttled serial: 8250_omap: Fix sleeping function called from invalid context during probe serial: 8250: 8250_omap: Terminate DMA before pushing data on RX timeout cpufreq: powernv: Fix frame-size-overflow in powernv_cpufreq_work_fn tools: gpio-hammer: Avoid potential overflow in main SUNRPC: Fix a potential buffer overflow in 'svc_print_xprts()' svcrdma: Fix leak of transport addresses ubifs: Fix out-of-bounds memory access caused by abnormal value of node_len ALSA: usb-audio: Fix case when USB MIDI interface has more than one extra endpoint descriptor mm/filemap.c: clear page error before actual read mm/mmap.c: initialize align_offset explicitly for vm_unmapped_area KVM: Remove CREATE_IRQCHIP/SET_PIT2 race bdev: Reduce time holding bd_mutex in sync in blkdev_close() drivers: char: tlclk.c: Avoid data race between init and interrupt handler dt-bindings: sound: wm8994: Correct required supplies based on actual implementaion atm: fix a memory leak of vcc->user_back phy: samsung: s5pv210-usb2: Add delay after reset Bluetooth: Handle Inquiry Cancel error after Inquiry Complete USB: EHCI: ehci-mv: fix error handling in mv_ehci_probe() tty: serial: samsung: Correct clock selection logic ALSA: hda: Fix potential race in unsol event handler fuse: don't check refcount after stealing page USB: EHCI: ehci-mv: fix less than zero comparison of an unsigned int e1000: Do not perform reset in reset_task if we are already down printk: handle blank console arguments passed in. btrfs: don't force read-only after error in drop snapshot vfio/pci: fix memory leaks of eventfd ctx perf util: Fix memory leak of prefix_if_not_in perf kcore_copy: Fix module map when there are no modules loaded mtd: rawnand: omap_elm: Fix runtime PM imbalance on error ceph: fix potential race in ceph_check_caps mtd: parser: cmdline: Support MTD names containing one or more colons x86/speculation/mds: Mark mds_user_clear_cpu_buffers() __always_inline vfio/pci: Clear error and request eventfd ctx after releasing cifs: Fix double add page to memcg when cifs_readpages selftests/x86/syscall_nt: Clear weird flags after each test vfio/pci: fix racy on error and request eventfd ctx s390/init: add missing __init annotations i2c: core: Call i2c_acpi_install_space_handler() before i2c_acpi_register_devices() objtool: Fix noreturn detection for ignored functions ieee802154/adf7242: check status of adf7242_read_reg clocksource/drivers/h8300_timer8: Fix wrong return value in h8300_8timer_init() mwifiex: Increase AES key storage size to 256 bits batman-adv: bla: fix type misuse for backbone_gw hash indexing atm: eni: fix the missed pci_disable_device() for eni_init_one() batman-adv: mcast/TT: fix wrongly dropped or rerouted packets mac802154: tx: fix use-after-free batman-adv: Add missing include for in_interrupt() batman-adv: mcast: fix duplicate mcast packets in BLA backbone from mesh ALSA: asihpi: fix iounmap in error handler MIPS: Add the missing 'CPU_1074K' into __get_cpu_type() kprobes: Fix to check probe enabled before disarm_kprobe_ftrace() lib/string.c: implement stpcpy ata: define AC_ERR_OK ata: make qc_prep return ata_completion_errors ata: sata_mv, avoid trigerrable BUG_ON Linux 4.9.238 Signed-off-by: Greg Kroah-Hartman <gregkh@google.com> Change-Id: I799877db3bc49e473bbc023ab948cd241755beff
2020-10-02 09:20:19 +02:00
static inline int unix_recvq_full_lockless(const struct sock *sk)
{
return skb_queue_len_lockless(&sk->sk_receive_queue) >
READ_ONCE(sk->sk_max_ack_backlog);
}
struct sock *unix_peer_get(struct sock *s)
{
struct sock *peer;
unix_state_lock(s);
peer = unix_peer(s);
if (peer)
sock_hold(peer);
unix_state_unlock(s);
return peer;
}
EXPORT_SYMBOL_GPL(unix_peer_get);
static inline void unix_release_addr(struct unix_address *addr)
{
if (atomic_dec_and_test(&addr->refcnt))
kfree(addr);
}
/*
* Check unix socket name:
* - should be not zero length.
* - if started by not zero, should be NULL terminated (FS object)
* - if started by zero, it is abstract name.
*/
static int unix_mkname(struct sockaddr_un *sunaddr, int len, unsigned int *hashp)
{
Merge 4.9.204 into android-4.9-q Changes in 4.9.204 net/mlx4_en: fix mlx4 ethtool -N insertion net: rtnetlink: prevent underflows in do_setvfinfo() sfc: Only cancel the PPS workqueue if it exists net/mlx5e: Fix set vf link state error flow net/sched: act_pedit: fix WARN() in the traffic path gpio: max77620: Fixup debounce delays tools: gpio: Correctly add make dependencies for gpio_utils Revert "fs: ocfs2: fix possible null-pointer dereferences in ocfs2_xa_prepare_entry()" mm/ksm.c: don't WARN if page is still mapped in remove_stable_node() platform/x86: asus-nb-wmi: Support ALS on the Zenbook UX430UQ platform/x86: asus-wmi: Only Tell EC the OS will handle display hotkeys from asus_nb_wmi mwifiex: Fix NL80211_TX_POWER_LIMITED ALSA: isight: fix leak of reference to firewire unit in error path of .probe callback printk: fix integer overflow in setup_log_buf() gfs2: Fix marking bitmaps non-full synclink_gt(): fix compat_ioctl() powerpc: Fix signedness bug in update_flash_db() powerpc/eeh: Fix use of EEH_PE_KEEP on wrong field brcmsmac: AP mode: update beacon when TIM changes ath10k: allocate small size dma memory in ath10k_pci_diag_write_mem spi: sh-msiof: fix deferred probing mmc: mediatek: fix cannot receive new request when msdc_cmd_is_ready fail btrfs: handle error of get_old_root gsmi: Fix bug in append_to_eventlog sysfs handler misc: mic: fix a DMA pool free failure m68k: fix command-line parsing when passed from u-boot amiflop: clean up on errors during setup scsi: ips: fix missing break in switch KVM/x86: Fix invvpid and invept register operand size in 64-bit mode scsi: isci: Use proper enumerated type in atapi_d2h_reg_frame_handler scsi: isci: Change sci_controller_start_task's return type to sci_status scsi: iscsi_tcp: Explicitly cast param in iscsi_sw_tcp_host_get_param clk: mmp2: fix the clock id for sdh2_clk and sdh3_clk ASoC: tegra_sgtl5000: fix device_node refcounting scsi: dc395x: fix dma API usage in srb_done scsi: dc395x: fix DMA API usage in sg_update_list net: fix warning in af_unix net: ena: Fix Kconfig dependency on X86 xfs: fix use-after-free race in xfs_buf_rele kprobes, x86/ptrace.h: Make regs_get_kernel_stack_nth() not fault on bad stack ALSA: i2c/cs8427: Fix int to char conversion macintosh/windfarm_smu_sat: Fix debug output USB: misc: appledisplay: fix backlight update_status return code usbip: tools: fix atoi() on non-null terminated string SUNRPC: Fix a compile warning for cmpxchg64() sunrpc: safely reallow resvport min/max inversion atm: zatm: Fix empty body Clang warnings s390/perf: Return error when debug_register fails spi: omap2-mcspi: Set FIFO DMA trigger level to word length sparc: Fix parport build warnings. ceph: fix dentry leak in ceph_readdir_prepopulate rtc: s35390a: Change buf's type to u8 in s35390a_init f2fs: fix to spread clear_cold_data() mISDN: Fix type of switch control variable in ctrl_teimanager qlcnic: fix a return in qlcnic_dcb_get_capability() net: ethernet: ti: cpsw: unsync mcast entries while switch promisc mode mfd: arizona: Correct calling of runtime_put_sync mfd: mc13xxx-core: Fix PMIC shutdown when reading ADC values mfd: max8997: Enale irq-wakeup unconditionally selftests/ftrace: Fix to test kprobe $comm arg only if available thermal: rcar_thermal: Prevent hardware access during system suspend powerpc/process: Fix flush_all_to_thread for SPE sparc64: Rework xchg() definition to avoid warnings. fs/ocfs2/dlm/dlmdebug.c: fix a sleep-in-atomic-context bug in dlm_print_one_mle() mm/page-writeback.c: fix range_cyclic writeback vs writepages deadlock macsec: update operstate when lower device changes macsec: let the administrator set UP state even if lowerdev is down um: Make line/tty semantics use true write IRQ linux/bitmap.h: handle constant zero-size bitmaps correctly linux/bitmap.h: fix type of nbits in bitmap_shift_right() hfsplus: fix BUG on bnode parent update hfs: fix BUG on bnode parent update hfsplus: prevent btree data loss on ENOSPC hfs: prevent btree data loss on ENOSPC hfsplus: fix return value of hfsplus_get_block() hfs: fix return value of hfs_get_block() hfsplus: update timestamps on truncate() hfs: update timestamp on truncate() fs/hfs/extent.c: fix array out of bounds read of array extent mm/memory_hotplug: make add_memory() take the device_hotplug_lock igb: shorten maximum PHC timecounter update interval ntb_netdev: fix sleep time mismatch ntb: intel: fix return value for ndev_vec_mask() arm64: makefile fix build of .i file in external module case ocfs2: don't put and assigning null to bh allocated outside ocfs2: fix clusters leak in ocfs2_defrag_extent() net: do not abort bulk send on BQL status sched/fair: Don't increase sd->balance_interval on newidle balance audit: print empty EXECVE args wlcore: Fix the return value in case of error in 'wlcore_vendor_cmd_smart_config_start()' rtl8xxxu: Fix missing break in switch brcmsmac: never log "tid x is not agg'able" by default wireless: airo: potential buffer overflow in sprintf() rtlwifi: rtl8192de: Fix misleading REG_MCUFWDL information scsi: mpt3sas: Fix Sync cache command failure during driver unload scsi: mpt3sas: Fix driver modifying persistent data in Manufacturing page11 scsi: megaraid_sas: Fix msleep granularity scsi: lpfc: fcoe: Fix link down issue after 1000+ link bounces dlm: fix invalid free dlm: don't leak kernel pointer to userspace ACPICA: Use %d for signed int print formatting instead of %u net: bcmgenet: return correct value 'ret' from bcmgenet_power_down sock: Reset dst when changing sk_mark via setsockopt pinctrl: qcom: spmi-gpio: fix gpio-hog related boot issues pinctrl: lpc18xx: Use define directive for PIN_CONFIG_GPIO_PIN_INT pinctrl: zynq: Use define directive for PIN_CONFIG_IO_STANDARD PCI: keystone: Use quirk to limit MRRS for K2G spi: omap2-mcspi: Fix DMA and FIFO event trigger size mismatch mm/memory_hotplug: Do not unlock when fails to take the device_hotplug_lock Bluetooth: Fix invalid-free in bcsp_close() KVM: MMU: Do not treat ZONE_DEVICE pages as being reserved ath9k_hw: fix uninitialized variable data dm: use blk_set_queue_dying() in __dm_destroy() arm64: fix for bad_mode() handler to always result in panic cpufreq: Skip cpufreq resume if it's not suspended ocfs2: remove ocfs2_is_o2cb_active() ARM: 8904/1: skip nomap memblocks while finding the lowmem/highmem boundary ARC: perf: Accommodate big-endian CPU x86/insn: Fix awk regexp warnings x86/speculation: Fix incorrect MDS/TAA mitigation status x86/speculation: Fix redundant MDS mitigation message nfc: port100: handle command failure cleanly l2tp: don't use l2tp_tunnel_find() in l2tp_ip and l2tp_ip6 media: vivid: Set vid_cap_streaming and vid_out_streaming to true media: vivid: Fix wrong locking that causes race conditions on streaming stop media: usbvision: Fix races among open, close, and disconnect cpufreq: Add NULL checks to show() and store() methods of cpufreq media: uvcvideo: Fix error path in control parsing failure media: b2c2-flexcop-usb: add sanity checking media: cxusb: detect cxusb_ctrl_msg error in query media: imon: invalid dereference in imon_touch_event virtio_console: reset on out of memory virtio_console: don't tie bufs to a vq virtio_console: allocate inbufs in add_port() only if it is needed virtio_ring: fix return code on DMA mapping fails virtio_console: fix uninitialized variable use virtio_console: drop custom control queue cleanup virtio_console: move removal code usbip: tools: fix fd leakage in the function of read_attr_usbip_status usb-serial: cp201x: support Mark-10 digital force gauge USB: chaoskey: fix error case of a timeout appledisplay: fix error handling in the scheduled work USB: serial: mos7840: add USB ID to support Moxa UPort 2210 USB: serial: mos7720: fix remote wakeup USB: serial: mos7840: fix remote wakeup USB: serial: option: add support for DW5821e with eSIM support USB: serial: option: add support for Foxconn T77W968 LTE modules staging: comedi: usbduxfast: usbduxfast_ai_cmdtest rounding error powerpc/64s: support nospectre_v2 cmdline option powerpc/book3s64: Fix link stack flush on context switch KVM: PPC: Book3S HV: Flush link stack on guest exit to host kernel Linux 4.9.204 Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
2019-11-28 18:47:59 +01:00
*hashp = 0;
if (len <= sizeof(short) || len > sizeof(*sunaddr))
return -EINVAL;
if (!sunaddr || sunaddr->sun_family != AF_UNIX)
return -EINVAL;
if (sunaddr->sun_path[0]) {
/*
* This may look like an off by one error but it is a bit more
* subtle. 108 is the longest valid AF_UNIX path for a binding.
* sun_path[108] doesn't as such exist. However in kernel space
* we are guaranteed that it is a valid memory location in our
* kernel address buffer.
*/
((char *)sunaddr)[len] = 0;
len = strlen(sunaddr->sun_path)+1+sizeof(short);
return len;
}
*hashp = unix_hash_fold(csum_partial(sunaddr, len, 0));
return len;
}
static void __unix_remove_socket(struct sock *sk)
{
sk_del_node_init(sk);
}
static void __unix_insert_socket(struct hlist_head *list, struct sock *sk)
{
WARN_ON(!sk_unhashed(sk));
sk_add_node(sk, list);
}
static inline void unix_remove_socket(struct sock *sk)
{
spin_lock(&unix_table_lock);
__unix_remove_socket(sk);
spin_unlock(&unix_table_lock);
}
static inline void unix_insert_socket(struct hlist_head *list, struct sock *sk)
{
spin_lock(&unix_table_lock);
__unix_insert_socket(list, sk);
spin_unlock(&unix_table_lock);
}
static struct sock *__unix_find_socket_byname(struct net *net,
struct sockaddr_un *sunname,
int len, int type, unsigned int hash)
{
struct sock *s;
sk_for_each(s, &unix_socket_table[hash ^ type]) {
struct unix_sock *u = unix_sk(s);
if (!net_eq(sock_net(s), net))
continue;
if (u->addr->len == len &&
!memcmp(u->addr->name, sunname, len))
goto found;
}
s = NULL;
found:
return s;
}
static inline struct sock *unix_find_socket_byname(struct net *net,
struct sockaddr_un *sunname,
int len, int type,
unsigned int hash)
{
struct sock *s;
spin_lock(&unix_table_lock);
s = __unix_find_socket_byname(net, sunname, len, type, hash);
if (s)
sock_hold(s);
spin_unlock(&unix_table_lock);
return s;
}
static struct sock *unix_find_socket_byinode(struct inode *i)
{
struct sock *s;
spin_lock(&unix_table_lock);
sk_for_each(s,
&unix_socket_table[i->i_ino & (UNIX_HASH_SIZE - 1)]) {
struct dentry *dentry = unix_sk(s)->path.dentry;
if (dentry && d_real_inode(dentry) == i) {
sock_hold(s);
goto found;
}
}
s = NULL;
found:
spin_unlock(&unix_table_lock);
return s;
}
/* Support code for asymmetrically connected dgram sockets
*
* If a datagram socket is connected to a socket not itself connected
* to the first socket (eg, /dev/log), clients may only enqueue more
* messages if the present receive queue of the server socket is not
* "too large". This means there's a second writeability condition
* poll and sendmsg need to test. The dgram recv code will do a wake
* up on the peer_wait wait queue of a socket upon reception of a
* datagram which needs to be propagated to sleeping would-be writers
* since these might not have sent anything so far. This can't be
* accomplished via poll_wait because the lifetime of the server
* socket might be less than that of its clients if these break their
* association with it or if the server socket is closed while clients
* are still connected to it and there's no way to inform "a polling
* implementation" that it should let go of a certain wait queue
*
* In order to propagate a wake up, a wait_queue_t of the client
* socket is enqueued on the peer_wait queue of the server socket
* whose wake function does a wake_up on the ordinary client socket
* wait queue. This connection is established whenever a write (or
* poll for write) hit the flow control condition and broken when the
* association to the server socket is dissolved or after a wake up
* was relayed.
*/
static int unix_dgram_peer_wake_relay(wait_queue_t *q, unsigned mode, int flags,
void *key)
{
struct unix_sock *u;
wait_queue_head_t *u_sleep;
u = container_of(q, struct unix_sock, peer_wake);
__remove_wait_queue(&unix_sk(u->peer_wake.private)->peer_wait,
q);
u->peer_wake.private = NULL;
/* relaying can only happen while the wq still exists */
u_sleep = sk_sleep(&u->sk);
if (u_sleep)
wake_up_interruptible_poll(u_sleep, key);
return 0;
}
static int unix_dgram_peer_wake_connect(struct sock *sk, struct sock *other)
{
struct unix_sock *u, *u_other;
int rc;
u = unix_sk(sk);
u_other = unix_sk(other);
rc = 0;
spin_lock(&u_other->peer_wait.lock);
if (!u->peer_wake.private) {
u->peer_wake.private = other;
__add_wait_queue(&u_other->peer_wait, &u->peer_wake);
rc = 1;
}
spin_unlock(&u_other->peer_wait.lock);
return rc;
}
static void unix_dgram_peer_wake_disconnect(struct sock *sk,
struct sock *other)
{
struct unix_sock *u, *u_other;
u = unix_sk(sk);
u_other = unix_sk(other);
spin_lock(&u_other->peer_wait.lock);
if (u->peer_wake.private == other) {
__remove_wait_queue(&u_other->peer_wait, &u->peer_wake);
u->peer_wake.private = NULL;
}
spin_unlock(&u_other->peer_wait.lock);
}
static void unix_dgram_peer_wake_disconnect_wakeup(struct sock *sk,
struct sock *other)
{
unix_dgram_peer_wake_disconnect(sk, other);
wake_up_interruptible_poll(sk_sleep(sk),
POLLOUT |
POLLWRNORM |
POLLWRBAND);
}
/* preconditions:
* - unix_peer(sk) == other
* - association is stable
*/
static int unix_dgram_peer_wake_me(struct sock *sk, struct sock *other)
{
int connected;
connected = unix_dgram_peer_wake_connect(sk, other);
if (unix_recvq_full(other))
return 1;
if (connected)
unix_dgram_peer_wake_disconnect(sk, other);
return 0;
}
static int unix_writable(const struct sock *sk)
{
return sk->sk_state != TCP_LISTEN &&
(atomic_read(&sk->sk_wmem_alloc) << 2) <= sk->sk_sndbuf;
}
static void unix_write_space(struct sock *sk)
{
struct socket_wq *wq;
rcu_read_lock();
if (unix_writable(sk)) {
wq = rcu_dereference(sk->sk_wq);
if (skwq_has_sleeper(wq))
wake_up_interruptible_sync_poll(&wq->wait,
POLLOUT | POLLWRNORM | POLLWRBAND);
sk_wake_async(sk, SOCK_WAKE_SPACE, POLL_OUT);
}
rcu_read_unlock();
}
/* When dgram socket disconnects (or changes its peer), we clear its receive
* queue of packets arrived from previous peer. First, it allows to do
* flow control based only on wmem_alloc; second, sk connected to peer
* may receive messages only from that peer. */
static void unix_dgram_disconnected(struct sock *sk, struct sock *other)
{
if (!skb_queue_empty(&sk->sk_receive_queue)) {
skb_queue_purge(&sk->sk_receive_queue);
wake_up_interruptible_all(&unix_sk(sk)->peer_wait);
/* If one link of bidirectional dgram pipe is disconnected,
* we signal error. Messages are lost. Do not make this,
* when peer was not connected to us.
*/
if (!sock_flag(other, SOCK_DEAD) && unix_peer(other) == sk) {
other->sk_err = ECONNRESET;
other->sk_error_report(other);
}
}
}
static void unix_sock_destructor(struct sock *sk)
{
struct unix_sock *u = unix_sk(sk);
skb_queue_purge(&sk->sk_receive_queue);
WARN_ON(atomic_read(&sk->sk_wmem_alloc));
WARN_ON(!sk_unhashed(sk));
WARN_ON(sk->sk_socket);
if (!sock_flag(sk, SOCK_DEAD)) {
pr_info("Attempt to release alive unix socket: %p\n", sk);
return;
}
if (u->addr)
unix_release_addr(u->addr);
atomic_long_dec(&unix_nr_socks);
local_bh_disable();
sock_prot_inuse_add(sock_net(sk), sk->sk_prot, -1);
local_bh_enable();
#ifdef UNIX_REFCNT_DEBUG
pr_debug("UNIX %p is destroyed, %ld are still alive.\n", sk,
atomic_long_read(&unix_nr_socks));
#endif
}
static void unix_release_sock(struct sock *sk, int embrion)
{
struct unix_sock *u = unix_sk(sk);
struct path path;
struct sock *skpair;
struct sk_buff *skb;
int state;
unix_remove_socket(sk);
/* Clear state */
unix_state_lock(sk);
sock_orphan(sk);
sk->sk_shutdown = SHUTDOWN_MASK;
path = u->path;
u->path.dentry = NULL;
u->path.mnt = NULL;
state = sk->sk_state;
sk->sk_state = TCP_CLOSE;
Merge 4.9.274 into android-4.9-q Changes in 4.9.274 net: ieee802154: fix null deref in parse dev addr HID: hid-sensor-hub: Return error for hid_set_field() failure HID: Add BUS_VIRTUAL to hid_connect logging HID: usbhid: fix info leak in hid_submit_ctrl ARM: OMAP2+: Fix build warning when mmc_omap is not built HID: gt683r: add missing MODULE_DEVICE_TABLE gfs2: Fix use-after-free in gfs2_glock_shrink_scan scsi: target: core: Fix warning on realtime kernels ethernet: myri10ge: Fix missing error code in myri10ge_probe() net: ipconfig: Don't override command-line hostnames or domains rtnetlink: Fix missing error code in rtnl_bridge_notify() net/x25: Return the correct errno code net: Return the correct errno code fib: Return the correct errno code dmaengine: QCOM_HIDMA_MGMT depends on HAS_IOMEM dmaengine: stedma40: add missing iounmap() on error in d40_probe() mm: hwpoison: change PageHWPoison behavior on hugetlb pages batman-adv: Avoid WARN_ON timing related checks net: ipv4: fix memory leak in netlbl_cipsov4_add_std net: rds: fix memory leak in rds_recvmsg udp: fix race between close() and udp_abort() rtnetlink: Fix regression in bridge VLAN configuration netfilter: synproxy: Fix out of bounds when parsing TCP options alx: Fix an error handling path in 'alx_probe()' net: stmmac: dwmac1000: Fix extended MAC address registers definition qlcnic: Fix an error handling path in 'qlcnic_probe()' netxen_nic: Fix an error handling path in 'netxen_nic_probe()' net: cdc_ncm: switch to eth%d interface naming net: usb: fix possible use-after-free in smsc75xx_bind net: ipv4: fix memory leak in ip_mc_add1_src net/af_unix: fix a data-race in unix_dgram_sendmsg / unix_release_sock be2net: Fix an error handling path in 'be_probe()' net: hamradio: fix memory leak in mkiss_close net: cdc_eem: fix tx fixup skb leak net: ethernet: fix potential use-after-free in ec_bhf_remove scsi: core: Put .shost_dev in failure path if host state changes to RUNNING radeon: use memcpy_to/fromio for UVD fw upload can: bcm: fix infoleak in struct bcm_msg_head tracing: Do no increment trace_clock_global() by one PCI: Mark TI C667X to avoid bus reset PCI: Mark some NVIDIA GPUs to avoid bus reset dmaengine: pl330: fix wrong usage of spinlock flags in dma_cyclc net: fec_ptp: add clock rate zero check can: bcm/raw/isotp: use per module netdevice notifier usb: dwc3: core: fix kernel panic when do reboot tracing: Do not stop recording cmdlines when tracing is off tracing: Do not stop recording comms if the trace file is being read x86/fpu: Reset state for all signal restore failures inet: use bigger hash table for IP ID generation i40e: Be much more verbose about what we can and cannot offload ARM: 9081/1: fix gcc-10 thumb2-kernel regression Makefile: Move -Wno-unused-but-set-variable out of GCC only block arm64: perf: Disable PMU while processing counter overflows Revert "PCI: PM: Do not read power state in pci_enable_device_flags()" mac80211: remove warning in ieee80211_get_sband() cfg80211: call cfg80211_leave_ocb when switching away from OCB mac80211: drop multicast fragments ping: Check return value of function 'ping_queue_rcv_skb' inet: annotate date races around sk->sk_txhash net: caif: fix memory leak in ldisc_open net/packet: annotate accesses to po->bind net/packet: annotate accesses to po->ifindex r8152: Avoid memcpy() over-reading of ETH_SS_STATS sh_eth: Avoid memcpy() over-reading of ETH_SS_STATS r8169: Avoid memcpy() over-reading of ETH_SS_STATS net: qed: Fix memcpy() overflow of qed_dcbx_params() net: ll_temac: Avoid ndo_start_xmit returning NETDEV_TX_BUSY nilfs2: fix memory leak in nilfs_sysfs_delete_device_group i2c: robotfuzz-osif: fix control-request directions Linux 4.9.274 Signed-off-by: Greg Kroah-Hartman <gregkh@google.com> Change-Id: I31d1bfc426326657ecc9db939474f25961471552
2021-06-30 19:09:19 +02:00
skpair = unix_peer(sk);
unix_peer(sk) = NULL;
unix_state_unlock(sk);
wake_up_interruptible_all(&u->peer_wait);
if (skpair != NULL) {
if (sk->sk_type == SOCK_STREAM || sk->sk_type == SOCK_SEQPACKET) {
unix_state_lock(skpair);
/* No more writes */
skpair->sk_shutdown = SHUTDOWN_MASK;
if (!skb_queue_empty(&sk->sk_receive_queue) || embrion)
skpair->sk_err = ECONNRESET;
unix_state_unlock(skpair);
skpair->sk_state_change(skpair);
sk_wake_async(skpair, SOCK_WAKE_WAITD, POLL_HUP);
}
unix_dgram_peer_wake_disconnect(sk, skpair);
sock_put(skpair); /* It may now die */
}
/* Try to flush out this socket. Throw out buffers at least */
while ((skb = skb_dequeue(&sk->sk_receive_queue)) != NULL) {
if (state == TCP_LISTEN)
unix_release_sock(skb->sk, 1);
/* passed fds are erased in the kfree_skb hook */
UNIXCB(skb).consumed = skb->len;
kfree_skb(skb);
}
if (path.dentry)
path_put(&path);
sock_put(sk);
/* ---- Socket is dead now and most probably destroyed ---- */
/*
* Fixme: BSD difference: In BSD all sockets connected to us get
* ECONNRESET and we die on the spot. In Linux we behave
* like files and pipes do and wait for the last
* dereference.
*
* Can't we simply set sock->err?
*
* What the above comment does talk about? --ANK(980817)
*/
if (unix_tot_inflight)
unix_gc(); /* Garbage collect fds */
}
static void init_peercred(struct sock *sk)
{
const struct cred *old_cred;
struct pid *old_pid;
spin_lock(&sk->sk_peer_lock);
old_pid = sk->sk_peer_pid;
old_cred = sk->sk_peer_cred;
sk->sk_peer_pid = get_pid(task_tgid(current));
sk->sk_peer_cred = get_current_cred();
spin_unlock(&sk->sk_peer_lock);
put_pid(old_pid);
put_cred(old_cred);
}
static void copy_peercred(struct sock *sk, struct sock *peersk)
{
const struct cred *old_cred;
struct pid *old_pid;
if (sk < peersk) {
spin_lock(&sk->sk_peer_lock);
spin_lock_nested(&peersk->sk_peer_lock, SINGLE_DEPTH_NESTING);
} else {
spin_lock(&peersk->sk_peer_lock);
spin_lock_nested(&sk->sk_peer_lock, SINGLE_DEPTH_NESTING);
}
old_pid = sk->sk_peer_pid;
old_cred = sk->sk_peer_cred;
sk->sk_peer_pid = get_pid(peersk->sk_peer_pid);
sk->sk_peer_cred = get_cred(peersk->sk_peer_cred);
spin_unlock(&sk->sk_peer_lock);
spin_unlock(&peersk->sk_peer_lock);
put_pid(old_pid);
put_cred(old_cred);
}
static int unix_listen(struct socket *sock, int backlog)
{
int err;
struct sock *sk = sock->sk;
struct unix_sock *u = unix_sk(sk);
struct pid *old_pid = NULL;
err = -EOPNOTSUPP;
if (sock->type != SOCK_STREAM && sock->type != SOCK_SEQPACKET)
goto out; /* Only stream/seqpacket sockets accept */
err = -EINVAL;
if (!u->addr)
goto out; /* No listens on an unbound socket */
unix_state_lock(sk);
if (sk->sk_state != TCP_CLOSE && sk->sk_state != TCP_LISTEN)
goto out_unlock;
if (backlog > sk->sk_max_ack_backlog)
wake_up_interruptible_all(&u->peer_wait);
sk->sk_max_ack_backlog = backlog;
sk->sk_state = TCP_LISTEN;
/* set credentials so connect can copy them */
init_peercred(sk);
err = 0;
out_unlock:
unix_state_unlock(sk);
put_pid(old_pid);
out:
return err;
}
static int unix_release(struct socket *);
static int unix_bind(struct socket *, struct sockaddr *, int);
static int unix_stream_connect(struct socket *, struct sockaddr *,
int addr_len, int flags);
static int unix_socketpair(struct socket *, struct socket *);
static int unix_accept(struct socket *, struct socket *, int);
static int unix_getname(struct socket *, struct sockaddr *, int *, int);
static unsigned int unix_poll(struct file *, struct socket *, poll_table *);
static unsigned int unix_dgram_poll(struct file *, struct socket *,
poll_table *);
static int unix_ioctl(struct socket *, unsigned int, unsigned long);
static int unix_shutdown(struct socket *, int);
static int unix_stream_sendmsg(struct socket *, struct msghdr *, size_t);
static int unix_stream_recvmsg(struct socket *, struct msghdr *, size_t, int);
static ssize_t unix_stream_sendpage(struct socket *, struct page *, int offset,
size_t size, int flags);
static ssize_t unix_stream_splice_read(struct socket *, loff_t *ppos,
struct pipe_inode_info *, size_t size,
unsigned int flags);
static int unix_dgram_sendmsg(struct socket *, struct msghdr *, size_t);
static int unix_dgram_recvmsg(struct socket *, struct msghdr *, size_t, int);
static int unix_dgram_connect(struct socket *, struct sockaddr *,
int, int);
static int unix_seqpacket_sendmsg(struct socket *, struct msghdr *, size_t);
static int unix_seqpacket_recvmsg(struct socket *, struct msghdr *, size_t,
int);
static int unix_set_peek_off(struct sock *sk, int val)
{
struct unix_sock *u = unix_sk(sk);
if (mutex_lock_interruptible(&u->iolock))
return -EINTR;
sk->sk_peek_off = val;
mutex_unlock(&u->iolock);
return 0;
}
static const struct proto_ops unix_stream_ops = {
.family = PF_UNIX,
.owner = THIS_MODULE,
.release = unix_release,
.bind = unix_bind,
.connect = unix_stream_connect,
.socketpair = unix_socketpair,
.accept = unix_accept,
.getname = unix_getname,
.poll = unix_poll,
.ioctl = unix_ioctl,
.listen = unix_listen,
.shutdown = unix_shutdown,
.setsockopt = sock_no_setsockopt,
.getsockopt = sock_no_getsockopt,
.sendmsg = unix_stream_sendmsg,
.recvmsg = unix_stream_recvmsg,
.mmap = sock_no_mmap,
.sendpage = unix_stream_sendpage,
.splice_read = unix_stream_splice_read,
.set_peek_off = unix_set_peek_off,
};
static const struct proto_ops unix_dgram_ops = {
.family = PF_UNIX,
.owner = THIS_MODULE,
.release = unix_release,
.bind = unix_bind,
.connect = unix_dgram_connect,
.socketpair = unix_socketpair,
.accept = sock_no_accept,
.getname = unix_getname,
.poll = unix_dgram_poll,
.ioctl = unix_ioctl,
.listen = sock_no_listen,
.shutdown = unix_shutdown,
.setsockopt = sock_no_setsockopt,
.getsockopt = sock_no_getsockopt,
.sendmsg = unix_dgram_sendmsg,
.recvmsg = unix_dgram_recvmsg,
.mmap = sock_no_mmap,
.sendpage = sock_no_sendpage,
.set_peek_off = unix_set_peek_off,
};
static const struct proto_ops unix_seqpacket_ops = {
.family = PF_UNIX,
.owner = THIS_MODULE,
.release = unix_release,
.bind = unix_bind,
.connect = unix_stream_connect,
.socketpair = unix_socketpair,
.accept = unix_accept,
.getname = unix_getname,
.poll = unix_dgram_poll,
.ioctl = unix_ioctl,
.listen = unix_listen,
.shutdown = unix_shutdown,
.setsockopt = sock_no_setsockopt,
.getsockopt = sock_no_getsockopt,
.sendmsg = unix_seqpacket_sendmsg,
.recvmsg = unix_seqpacket_recvmsg,
.mmap = sock_no_mmap,
.sendpage = sock_no_sendpage,
.set_peek_off = unix_set_peek_off,
};
static struct proto unix_proto = {
.name = "UNIX",
.owner = THIS_MODULE,
.obj_size = sizeof(struct unix_sock),
};
/*
* AF_UNIX sockets do not interact with hardware, hence they
* dont trigger interrupts - so it's safe for them to have
* bh-unsafe locking for their sk_receive_queue.lock. Split off
* this special lock-class by reinitializing the spinlock key:
*/
static struct lock_class_key af_unix_sk_receive_queue_lock_key;
static struct sock *unix_create1(struct net *net, struct socket *sock, int kern)
{
struct sock *sk = NULL;
struct unix_sock *u;
atomic_long_inc(&unix_nr_socks);
if (atomic_long_read(&unix_nr_socks) > 2 * get_max_files())
goto out;
sk = sk_alloc(net, PF_UNIX, GFP_KERNEL, &unix_proto, kern);
if (!sk)
goto out;
sock_init_data(sock, sk);
lockdep_set_class(&sk->sk_receive_queue.lock,
&af_unix_sk_receive_queue_lock_key);
sk->sk_allocation = GFP_KERNEL_ACCOUNT;
sk->sk_write_space = unix_write_space;
sk->sk_max_ack_backlog = net->unx.sysctl_max_dgram_qlen;
sk->sk_destruct = unix_sock_destructor;
u = unix_sk(sk);
u->path.dentry = NULL;
u->path.mnt = NULL;
spin_lock_init(&u->lock);
atomic_long_set(&u->inflight, 0);
INIT_LIST_HEAD(&u->link);
mutex_init(&u->iolock); /* single task reading lock */
mutex_init(&u->bindlock); /* single task binding lock */
init_waitqueue_head(&u->peer_wait);
init_waitqueue_func_entry(&u->peer_wake, unix_dgram_peer_wake_relay);
unix_insert_socket(unix_sockets_unbound(sk), sk);
out:
if (sk == NULL)
atomic_long_dec(&unix_nr_socks);
else {
local_bh_disable();
sock_prot_inuse_add(sock_net(sk), sk->sk_prot, 1);
local_bh_enable();
}
return sk;
}
static int unix_create(struct net *net, struct socket *sock, int protocol,
int kern)
{
if (protocol && protocol != PF_UNIX)
return -EPROTONOSUPPORT;
sock->state = SS_UNCONNECTED;
switch (sock->type) {
case SOCK_STREAM:
sock->ops = &unix_stream_ops;
break;
/*
* Believe it or not BSD has AF_UNIX, SOCK_RAW though
* nothing uses it.
*/
case SOCK_RAW:
sock->type = SOCK_DGRAM;
case SOCK_DGRAM:
sock->ops = &unix_dgram_ops;
break;
case SOCK_SEQPACKET:
sock->ops = &unix_seqpacket_ops;
break;
default:
return -ESOCKTNOSUPPORT;
}
return unix_create1(net, sock, kern) ? 0 : -ENOMEM;
}
static int unix_release(struct socket *sock)
{
struct sock *sk = sock->sk;
if (!sk)
return 0;
unix_release_sock(sk, 0);
sock->sk = NULL;
return 0;
}
static int unix_autobind(struct socket *sock)
{
struct sock *sk = sock->sk;
struct net *net = sock_net(sk);
struct unix_sock *u = unix_sk(sk);
static u32 ordernum = 1;
struct unix_address *addr;
int err;
unsigned int retries = 0;
err = mutex_lock_interruptible(&u->bindlock);
if (err)
return err;
err = 0;
if (u->addr)
goto out;
err = -ENOMEM;
addr = kzalloc(sizeof(*addr) + sizeof(short) + 16, GFP_KERNEL);
if (!addr)
goto out;
addr->name->sun_family = AF_UNIX;
atomic_set(&addr->refcnt, 1);
retry:
addr->len = sprintf(addr->name->sun_path+1, "%05x", ordernum) + 1 + sizeof(short);
addr->hash = unix_hash_fold(csum_partial(addr->name, addr->len, 0));
spin_lock(&unix_table_lock);
ordernum = (ordernum+1)&0xFFFFF;
if (__unix_find_socket_byname(net, addr->name, addr->len, sock->type,
addr->hash)) {
spin_unlock(&unix_table_lock);
/*
* __unix_find_socket_byname() may take long time if many names
* are already in use.
*/
cond_resched();
/* Give up if all names seems to be in use. */
if (retries++ == 0xFFFFF) {
err = -ENOSPC;
kfree(addr);
goto out;
}
goto retry;
}
addr->hash ^= sk->sk_type;
__unix_remove_socket(sk);
Merge 4.9.164 into android-4.9 Changes in 4.9.164 ACPICA: Reference Counts: increase max to 0x4000 for large servers KEYS: restrict /proc/keys by credentials at open time l2tp: fix infoleak in l2tp_ip6_recvmsg() net: hsr: fix memory leak in hsr_dev_finalize() net/hsr: fix possible crash in add_timer() net: sit: fix UBSAN Undefined behaviour in check_6rd net/x25: fix use-after-free in x25_device_event() net/x25: reset state in x25_connect() pptp: dst_release sk_dst_cache in pptp_sock_destruct ravb: Decrease TxFIFO depth of Q3 and Q2 to one route: set the deleted fnhe fnhe_daddr to 0 in ip_del_fnhe to fix a race tcp: handle inet_csk_reqsk_queue_add() failures vxlan: test dev->flags & IFF_UP before calling gro_cells_receive() net/mlx4_core: Fix reset flow when in command polling mode net/mlx4_core: Fix locking in SRIOV mode when switching between events and polling net/mlx4_core: Fix qp mtt size calculation net/x25: fix a race in x25_bind() mdio_bus: Fix use-after-free on device_register fails net: Set rtm_table to RT_TABLE_COMPAT for ipv6 for tables > 255 missing barriers in some of unix_sock ->addr and ->path accesses ipvlan: disallow userns cap_net_admin to change global mode/flags vxlan: Fix GRO cells race condition between receive and link delete rxrpc: Fix client call queueing, waiting for channel gro_cells: make sure device is up in gro_cells_receive() tcp/dccp: remove reqsk_put() from inet_child_forget() perf/x86: Fixup typo in stub functions ALSA: bebob: use more identical mod_alias for Saffire Pro 10 I/O against Liquid Saffire 56 It's wrong to add len to sector_nr in raid10 reshape twice mmc: tmio_mmc_core: don't claim spurious interrupts of: Support const and non-const use for to_of_node() vhost/vsock: fix vhost vsock cid hashing inconsistent Linux 4.9.164 Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
2019-03-19 13:27:42 +01:00
smp_store_release(&u->addr, addr);
__unix_insert_socket(&unix_socket_table[addr->hash], sk);
spin_unlock(&unix_table_lock);
err = 0;
out: mutex_unlock(&u->bindlock);
return err;
}
static struct sock *unix_find_other(struct net *net,
struct sockaddr_un *sunname, int len,
int type, unsigned int hash, int *error)
{
struct sock *u;
struct path path;
int err = 0;
if (sunname->sun_path[0]) {
struct inode *inode;
err = kern_path(sunname->sun_path, LOOKUP_FOLLOW, &path);
if (err)
goto fail;
inode = d_real_inode(path.dentry);
err = inode_permission(inode, MAY_WRITE);
if (err)
goto put_fail;
err = -ECONNREFUSED;
if (!S_ISSOCK(inode->i_mode))
goto put_fail;
u = unix_find_socket_byinode(inode);
if (!u)
goto put_fail;
if (u->sk_type == type)
touch_atime(&path);
path_put(&path);
err = -EPROTOTYPE;
if (u->sk_type != type) {
sock_put(u);
goto fail;
}
} else {
err = -ECONNREFUSED;
u = unix_find_socket_byname(net, sunname, len, type, hash);
if (u) {
struct dentry *dentry;
dentry = unix_sk(u)->path.dentry;
if (dentry)
touch_atime(&unix_sk(u)->path);
} else
goto fail;
}
return u;
put_fail:
path_put(&path);
fail:
*error = err;
return NULL;
}
static int unix_mknod(const char *sun_path, umode_t mode, struct path *res)
{
struct dentry *dentry;
struct path path;
int err = 0;
/*
* Get the parent directory, calculate the hash for last
* component.
*/
dentry = kern_path_create(AT_FDCWD, sun_path, &path, 0);
err = PTR_ERR(dentry);
if (IS_ERR(dentry))
return err;
/*
* All right, let's create it.
*/
err = security_path_mknod(&path, dentry, mode, 0);
if (!err) {
err = vfs_mknod(d_inode(path.dentry), dentry, mode, 0);
if (!err) {
res->mnt = mntget(path.mnt);
res->dentry = dget(dentry);
}
}
done_path_create(&path, dentry);
return err;
}
static int unix_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
{
struct sock *sk = sock->sk;
struct net *net = sock_net(sk);
struct unix_sock *u = unix_sk(sk);
struct sockaddr_un *sunaddr = (struct sockaddr_un *)uaddr;
char *sun_path = sunaddr->sun_path;
int err;
unsigned int hash;
struct unix_address *addr;
struct hlist_head *list;
struct path path = { NULL, NULL };
err = -EINVAL;
if (addr_len < offsetofend(struct sockaddr_un, sun_family) ||
sunaddr->sun_family != AF_UNIX)
goto out;
if (addr_len == sizeof(short)) {
err = unix_autobind(sock);
goto out;
}
err = unix_mkname(sunaddr, addr_len, &hash);
if (err < 0)
goto out;
addr_len = err;
if (sun_path[0]) {
umode_t mode = S_IFSOCK |
(SOCK_INODE(sock)->i_mode & ~current_umask());
err = unix_mknod(sun_path, mode, &path);
if (err) {
if (err == -EEXIST)
err = -EADDRINUSE;
goto out;
}
}
err = mutex_lock_interruptible(&u->bindlock);
if (err)
goto out_put;
err = -EINVAL;
if (u->addr)
goto out_up;
err = -ENOMEM;
addr = kmalloc(sizeof(*addr)+addr_len, GFP_KERNEL);
if (!addr)
goto out_up;
memcpy(addr->name, sunaddr, addr_len);
addr->len = addr_len;
addr->hash = hash ^ sk->sk_type;
atomic_set(&addr->refcnt, 1);
if (sun_path[0]) {
addr->hash = UNIX_HASH_SIZE;
hash = d_real_inode(path.dentry)->i_ino & (UNIX_HASH_SIZE - 1);
spin_lock(&unix_table_lock);
u->path = path;
list = &unix_socket_table[hash];
} else {
spin_lock(&unix_table_lock);
err = -EADDRINUSE;
if (__unix_find_socket_byname(net, sunaddr, addr_len,
sk->sk_type, hash)) {
unix_release_addr(addr);
goto out_unlock;
}
list = &unix_socket_table[addr->hash];
}
err = 0;
__unix_remove_socket(sk);
Merge 4.9.164 into android-4.9 Changes in 4.9.164 ACPICA: Reference Counts: increase max to 0x4000 for large servers KEYS: restrict /proc/keys by credentials at open time l2tp: fix infoleak in l2tp_ip6_recvmsg() net: hsr: fix memory leak in hsr_dev_finalize() net/hsr: fix possible crash in add_timer() net: sit: fix UBSAN Undefined behaviour in check_6rd net/x25: fix use-after-free in x25_device_event() net/x25: reset state in x25_connect() pptp: dst_release sk_dst_cache in pptp_sock_destruct ravb: Decrease TxFIFO depth of Q3 and Q2 to one route: set the deleted fnhe fnhe_daddr to 0 in ip_del_fnhe to fix a race tcp: handle inet_csk_reqsk_queue_add() failures vxlan: test dev->flags & IFF_UP before calling gro_cells_receive() net/mlx4_core: Fix reset flow when in command polling mode net/mlx4_core: Fix locking in SRIOV mode when switching between events and polling net/mlx4_core: Fix qp mtt size calculation net/x25: fix a race in x25_bind() mdio_bus: Fix use-after-free on device_register fails net: Set rtm_table to RT_TABLE_COMPAT for ipv6 for tables > 255 missing barriers in some of unix_sock ->addr and ->path accesses ipvlan: disallow userns cap_net_admin to change global mode/flags vxlan: Fix GRO cells race condition between receive and link delete rxrpc: Fix client call queueing, waiting for channel gro_cells: make sure device is up in gro_cells_receive() tcp/dccp: remove reqsk_put() from inet_child_forget() perf/x86: Fixup typo in stub functions ALSA: bebob: use more identical mod_alias for Saffire Pro 10 I/O against Liquid Saffire 56 It's wrong to add len to sector_nr in raid10 reshape twice mmc: tmio_mmc_core: don't claim spurious interrupts of: Support const and non-const use for to_of_node() vhost/vsock: fix vhost vsock cid hashing inconsistent Linux 4.9.164 Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
2019-03-19 13:27:42 +01:00
smp_store_release(&u->addr, addr);
__unix_insert_socket(list, sk);
out_unlock:
spin_unlock(&unix_table_lock);
out_up:
mutex_unlock(&u->bindlock);
out_put:
if (err)
path_put(&path);
out:
return err;
}
static void unix_state_double_lock(struct sock *sk1, struct sock *sk2)
{
if (unlikely(sk1 == sk2) || !sk2) {
unix_state_lock(sk1);
return;
}
if (sk1 < sk2) {
unix_state_lock(sk1);
unix_state_lock_nested(sk2);
} else {
unix_state_lock(sk2);
unix_state_lock_nested(sk1);
}
}
static void unix_state_double_unlock(struct sock *sk1, struct sock *sk2)
{
if (unlikely(sk1 == sk2) || !sk2) {
unix_state_unlock(sk1);
return;
}
unix_state_unlock(sk1);
unix_state_unlock(sk2);
}
static int unix_dgram_connect(struct socket *sock, struct sockaddr *addr,
int alen, int flags)
{
struct sock *sk = sock->sk;
struct net *net = sock_net(sk);
struct sockaddr_un *sunaddr = (struct sockaddr_un *)addr;
struct sock *other;
unsigned int hash;
int err;
err = -EINVAL;
if (alen < offsetofend(struct sockaddr, sa_family))
goto out;
if (addr->sa_family != AF_UNSPEC) {
err = unix_mkname(sunaddr, alen, &hash);
if (err < 0)
goto out;
alen = err;
if (test_bit(SOCK_PASSCRED, &sock->flags) &&
!unix_sk(sk)->addr && (err = unix_autobind(sock)) != 0)
goto out;
restart:
other = unix_find_other(net, sunaddr, alen, sock->type, hash, &err);
if (!other)
goto out;
unix_state_double_lock(sk, other);
/* Apparently VFS overslept socket death. Retry. */
if (sock_flag(other, SOCK_DEAD)) {
unix_state_double_unlock(sk, other);
sock_put(other);
goto restart;
}
err = -EPERM;
if (!unix_may_send(sk, other))
goto out_unlock;
err = security_unix_may_send(sk->sk_socket, other->sk_socket);
if (err)
goto out_unlock;
} else {
/*
* 1003.1g breaking connected state with AF_UNSPEC
*/
other = NULL;
unix_state_double_lock(sk, other);
}
/*
* If it was connected, reconnect.
*/
if (unix_peer(sk)) {
struct sock *old_peer = unix_peer(sk);
unix_peer(sk) = other;
unix_dgram_peer_wake_disconnect_wakeup(sk, old_peer);
unix_state_double_unlock(sk, other);
if (other != old_peer)
unix_dgram_disconnected(sk, old_peer);
sock_put(old_peer);
} else {
unix_peer(sk) = other;
unix_state_double_unlock(sk, other);
}
return 0;
out_unlock:
unix_state_double_unlock(sk, other);
sock_put(other);
out:
return err;
}
static long unix_wait_for_peer(struct sock *other, long timeo)
{
struct unix_sock *u = unix_sk(other);
int sched;
DEFINE_WAIT(wait);
prepare_to_wait_exclusive(&u->peer_wait, &wait, TASK_INTERRUPTIBLE);
sched = !sock_flag(other, SOCK_DEAD) &&
!(other->sk_shutdown & RCV_SHUTDOWN) &&
unix_recvq_full(other);
unix_state_unlock(other);
if (sched)
timeo = schedule_timeout(timeo);
finish_wait(&u->peer_wait, &wait);
return timeo;
}
static int unix_stream_connect(struct socket *sock, struct sockaddr *uaddr,
int addr_len, int flags)
{
struct sockaddr_un *sunaddr = (struct sockaddr_un *)uaddr;
struct sock *sk = sock->sk;
struct net *net = sock_net(sk);
struct unix_sock *u = unix_sk(sk), *newu, *otheru;
struct sock *newsk = NULL;
struct sock *other = NULL;
struct sk_buff *skb = NULL;
unsigned int hash;
int st;
int err;
long timeo;
err = unix_mkname(sunaddr, addr_len, &hash);
if (err < 0)
goto out;
addr_len = err;
if (test_bit(SOCK_PASSCRED, &sock->flags) && !u->addr &&
(err = unix_autobind(sock)) != 0)
goto out;
timeo = sock_sndtimeo(sk, flags & O_NONBLOCK);
/* First of all allocate resources.
If we will make it after state is locked,
we will have to recheck all again in any case.
*/
err = -ENOMEM;
/* create new sock for complete connection */
newsk = unix_create1(sock_net(sk), NULL, 0);
if (newsk == NULL)
goto out;
/* Allocate skb for sending to listening sock */
skb = sock_wmalloc(newsk, 1, 0, GFP_KERNEL);
if (skb == NULL)
goto out;
restart:
/* Find listening sock. */
other = unix_find_other(net, sunaddr, addr_len, sk->sk_type, hash, &err);
if (!other)
goto out;
/* Latch state of peer */
unix_state_lock(other);
/* Apparently VFS overslept socket death. Retry. */
if (sock_flag(other, SOCK_DEAD)) {
unix_state_unlock(other);
sock_put(other);
goto restart;
}
err = -ECONNREFUSED;
if (other->sk_state != TCP_LISTEN)
goto out_unlock;
if (other->sk_shutdown & RCV_SHUTDOWN)
goto out_unlock;
if (unix_recvq_full(other)) {
err = -EAGAIN;
if (!timeo)
goto out_unlock;
timeo = unix_wait_for_peer(other, timeo);
err = sock_intr_errno(timeo);
if (signal_pending(current))
goto out;
sock_put(other);
goto restart;
}
/* Latch our state.
It is tricky place. We need to grab our state lock and cannot
drop lock on peer. It is dangerous because deadlock is
possible. Connect to self case and simultaneous
attempt to connect are eliminated by checking socket
state. other is TCP_LISTEN, if sk is TCP_LISTEN we
check this before attempt to grab lock.
Well, and we have to recheck the state after socket locked.
*/
st = sk->sk_state;
switch (st) {
case TCP_CLOSE:
/* This is ok... continue with connect */
break;
case TCP_ESTABLISHED:
/* Socket is already connected */
err = -EISCONN;
goto out_unlock;
default:
err = -EINVAL;
goto out_unlock;
}
unix_state_lock_nested(sk);
if (sk->sk_state != st) {
unix_state_unlock(sk);
unix_state_unlock(other);
sock_put(other);
goto restart;
}
err = security_unix_stream_connect(sk, other, newsk);
if (err) {
unix_state_unlock(sk);
goto out_unlock;
}
/* The way is open! Fastly set all the necessary fields... */
sock_hold(sk);
unix_peer(newsk) = sk;
newsk->sk_state = TCP_ESTABLISHED;
newsk->sk_type = sk->sk_type;
init_peercred(newsk);
newu = unix_sk(newsk);
RCU_INIT_POINTER(newsk->sk_wq, &newu->peer_wq);
otheru = unix_sk(other);
Merge 4.9.164 into android-4.9 Changes in 4.9.164 ACPICA: Reference Counts: increase max to 0x4000 for large servers KEYS: restrict /proc/keys by credentials at open time l2tp: fix infoleak in l2tp_ip6_recvmsg() net: hsr: fix memory leak in hsr_dev_finalize() net/hsr: fix possible crash in add_timer() net: sit: fix UBSAN Undefined behaviour in check_6rd net/x25: fix use-after-free in x25_device_event() net/x25: reset state in x25_connect() pptp: dst_release sk_dst_cache in pptp_sock_destruct ravb: Decrease TxFIFO depth of Q3 and Q2 to one route: set the deleted fnhe fnhe_daddr to 0 in ip_del_fnhe to fix a race tcp: handle inet_csk_reqsk_queue_add() failures vxlan: test dev->flags & IFF_UP before calling gro_cells_receive() net/mlx4_core: Fix reset flow when in command polling mode net/mlx4_core: Fix locking in SRIOV mode when switching between events and polling net/mlx4_core: Fix qp mtt size calculation net/x25: fix a race in x25_bind() mdio_bus: Fix use-after-free on device_register fails net: Set rtm_table to RT_TABLE_COMPAT for ipv6 for tables > 255 missing barriers in some of unix_sock ->addr and ->path accesses ipvlan: disallow userns cap_net_admin to change global mode/flags vxlan: Fix GRO cells race condition between receive and link delete rxrpc: Fix client call queueing, waiting for channel gro_cells: make sure device is up in gro_cells_receive() tcp/dccp: remove reqsk_put() from inet_child_forget() perf/x86: Fixup typo in stub functions ALSA: bebob: use more identical mod_alias for Saffire Pro 10 I/O against Liquid Saffire 56 It's wrong to add len to sector_nr in raid10 reshape twice mmc: tmio_mmc_core: don't claim spurious interrupts of: Support const and non-const use for to_of_node() vhost/vsock: fix vhost vsock cid hashing inconsistent Linux 4.9.164 Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
2019-03-19 13:27:42 +01:00
/* copy address information from listening to new sock
*
* The contents of *(otheru->addr) and otheru->path
* are seen fully set up here, since we have found
* otheru in hash under unix_table_lock. Insertion
* into the hash chain we'd found it in had been done
* in an earlier critical area protected by unix_table_lock,
* the same one where we'd set *(otheru->addr) contents,
* as well as otheru->path and otheru->addr itself.
*
* Using smp_store_release() here to set newu->addr
* is enough to make those stores, as well as stores
* to newu->path visible to anyone who gets newu->addr
* by smp_load_acquire(). IOW, the same warranties
* as for unix_sock instances bound in unix_bind() or
* in unix_autobind().
*/
if (otheru->path.dentry) {
path_get(&otheru->path);
newu->path = otheru->path;
}
Merge 4.9.164 into android-4.9 Changes in 4.9.164 ACPICA: Reference Counts: increase max to 0x4000 for large servers KEYS: restrict /proc/keys by credentials at open time l2tp: fix infoleak in l2tp_ip6_recvmsg() net: hsr: fix memory leak in hsr_dev_finalize() net/hsr: fix possible crash in add_timer() net: sit: fix UBSAN Undefined behaviour in check_6rd net/x25: fix use-after-free in x25_device_event() net/x25: reset state in x25_connect() pptp: dst_release sk_dst_cache in pptp_sock_destruct ravb: Decrease TxFIFO depth of Q3 and Q2 to one route: set the deleted fnhe fnhe_daddr to 0 in ip_del_fnhe to fix a race tcp: handle inet_csk_reqsk_queue_add() failures vxlan: test dev->flags & IFF_UP before calling gro_cells_receive() net/mlx4_core: Fix reset flow when in command polling mode net/mlx4_core: Fix locking in SRIOV mode when switching between events and polling net/mlx4_core: Fix qp mtt size calculation net/x25: fix a race in x25_bind() mdio_bus: Fix use-after-free on device_register fails net: Set rtm_table to RT_TABLE_COMPAT for ipv6 for tables > 255 missing barriers in some of unix_sock ->addr and ->path accesses ipvlan: disallow userns cap_net_admin to change global mode/flags vxlan: Fix GRO cells race condition between receive and link delete rxrpc: Fix client call queueing, waiting for channel gro_cells: make sure device is up in gro_cells_receive() tcp/dccp: remove reqsk_put() from inet_child_forget() perf/x86: Fixup typo in stub functions ALSA: bebob: use more identical mod_alias for Saffire Pro 10 I/O against Liquid Saffire 56 It's wrong to add len to sector_nr in raid10 reshape twice mmc: tmio_mmc_core: don't claim spurious interrupts of: Support const and non-const use for to_of_node() vhost/vsock: fix vhost vsock cid hashing inconsistent Linux 4.9.164 Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
2019-03-19 13:27:42 +01:00
atomic_inc(&otheru->addr->refcnt);
smp_store_release(&newu->addr, otheru->addr);
/* Set credentials */
copy_peercred(sk, other);
sock->state = SS_CONNECTED;
sk->sk_state = TCP_ESTABLISHED;
sock_hold(newsk);
smp_mb__after_atomic(); /* sock_hold() does an atomic_inc() */
unix_peer(sk) = newsk;
unix_state_unlock(sk);
/* take ten and and send info to listening sock */
spin_lock(&other->sk_receive_queue.lock);
__skb_queue_tail(&other->sk_receive_queue, skb);
spin_unlock(&other->sk_receive_queue.lock);
unix_state_unlock(other);
other->sk_data_ready(other);
sock_put(other);
return 0;
out_unlock:
if (other)
unix_state_unlock(other);
out:
kfree_skb(skb);
if (newsk)
unix_release_sock(newsk, 0);
if (other)
sock_put(other);
return err;
}
static int unix_socketpair(struct socket *socka, struct socket *sockb)
{
struct sock *ska = socka->sk, *skb = sockb->sk;
/* Join our sockets back to back */
sock_hold(ska);
sock_hold(skb);
unix_peer(ska) = skb;
unix_peer(skb) = ska;
init_peercred(ska);
init_peercred(skb);
if (ska->sk_type != SOCK_DGRAM) {
ska->sk_state = TCP_ESTABLISHED;
skb->sk_state = TCP_ESTABLISHED;
socka->state = SS_CONNECTED;
sockb->state = SS_CONNECTED;
}
return 0;
}
static void unix_sock_inherit_flags(const struct socket *old,
struct socket *new)
{
if (test_bit(SOCK_PASSCRED, &old->flags))
set_bit(SOCK_PASSCRED, &new->flags);
if (test_bit(SOCK_PASSSEC, &old->flags))
set_bit(SOCK_PASSSEC, &new->flags);
}
static int unix_accept(struct socket *sock, struct socket *newsock, int flags)
{
struct sock *sk = sock->sk;
struct sock *tsk;
struct sk_buff *skb;
int err;
err = -EOPNOTSUPP;
if (sock->type != SOCK_STREAM && sock->type != SOCK_SEQPACKET)
goto out;
err = -EINVAL;
if (sk->sk_state != TCP_LISTEN)
goto out;
/* If socket state is TCP_LISTEN it cannot change (for now...),
* so that no locks are necessary.
*/
skb = skb_recv_datagram(sk, 0, flags&O_NONBLOCK, &err);
if (!skb) {
/* This means receive shutdown. */
if (err == 0)
err = -EINVAL;
goto out;
}
tsk = skb->sk;
skb_free_datagram(sk, skb);
wake_up_interruptible(&unix_sk(sk)->peer_wait);
/* attach accepted sock to socket */
unix_state_lock(tsk);
newsock->state = SS_CONNECTED;
unix_sock_inherit_flags(sock, newsock);
sock_graft(tsk, newsock);
unix_state_unlock(tsk);
return 0;
out:
return err;
}
static int unix_getname(struct socket *sock, struct sockaddr *uaddr, int *uaddr_len, int peer)
{
struct sock *sk = sock->sk;
Merge 4.9.164 into android-4.9 Changes in 4.9.164 ACPICA: Reference Counts: increase max to 0x4000 for large servers KEYS: restrict /proc/keys by credentials at open time l2tp: fix infoleak in l2tp_ip6_recvmsg() net: hsr: fix memory leak in hsr_dev_finalize() net/hsr: fix possible crash in add_timer() net: sit: fix UBSAN Undefined behaviour in check_6rd net/x25: fix use-after-free in x25_device_event() net/x25: reset state in x25_connect() pptp: dst_release sk_dst_cache in pptp_sock_destruct ravb: Decrease TxFIFO depth of Q3 and Q2 to one route: set the deleted fnhe fnhe_daddr to 0 in ip_del_fnhe to fix a race tcp: handle inet_csk_reqsk_queue_add() failures vxlan: test dev->flags & IFF_UP before calling gro_cells_receive() net/mlx4_core: Fix reset flow when in command polling mode net/mlx4_core: Fix locking in SRIOV mode when switching between events and polling net/mlx4_core: Fix qp mtt size calculation net/x25: fix a race in x25_bind() mdio_bus: Fix use-after-free on device_register fails net: Set rtm_table to RT_TABLE_COMPAT for ipv6 for tables > 255 missing barriers in some of unix_sock ->addr and ->path accesses ipvlan: disallow userns cap_net_admin to change global mode/flags vxlan: Fix GRO cells race condition between receive and link delete rxrpc: Fix client call queueing, waiting for channel gro_cells: make sure device is up in gro_cells_receive() tcp/dccp: remove reqsk_put() from inet_child_forget() perf/x86: Fixup typo in stub functions ALSA: bebob: use more identical mod_alias for Saffire Pro 10 I/O against Liquid Saffire 56 It's wrong to add len to sector_nr in raid10 reshape twice mmc: tmio_mmc_core: don't claim spurious interrupts of: Support const and non-const use for to_of_node() vhost/vsock: fix vhost vsock cid hashing inconsistent Linux 4.9.164 Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
2019-03-19 13:27:42 +01:00
struct unix_address *addr;
DECLARE_SOCKADDR(struct sockaddr_un *, sunaddr, uaddr);
int err = 0;
if (peer) {
sk = unix_peer_get(sk);
err = -ENOTCONN;
if (!sk)
goto out;
err = 0;
} else {
sock_hold(sk);
}
Merge 4.9.164 into android-4.9 Changes in 4.9.164 ACPICA: Reference Counts: increase max to 0x4000 for large servers KEYS: restrict /proc/keys by credentials at open time l2tp: fix infoleak in l2tp_ip6_recvmsg() net: hsr: fix memory leak in hsr_dev_finalize() net/hsr: fix possible crash in add_timer() net: sit: fix UBSAN Undefined behaviour in check_6rd net/x25: fix use-after-free in x25_device_event() net/x25: reset state in x25_connect() pptp: dst_release sk_dst_cache in pptp_sock_destruct ravb: Decrease TxFIFO depth of Q3 and Q2 to one route: set the deleted fnhe fnhe_daddr to 0 in ip_del_fnhe to fix a race tcp: handle inet_csk_reqsk_queue_add() failures vxlan: test dev->flags & IFF_UP before calling gro_cells_receive() net/mlx4_core: Fix reset flow when in command polling mode net/mlx4_core: Fix locking in SRIOV mode when switching between events and polling net/mlx4_core: Fix qp mtt size calculation net/x25: fix a race in x25_bind() mdio_bus: Fix use-after-free on device_register fails net: Set rtm_table to RT_TABLE_COMPAT for ipv6 for tables > 255 missing barriers in some of unix_sock ->addr and ->path accesses ipvlan: disallow userns cap_net_admin to change global mode/flags vxlan: Fix GRO cells race condition between receive and link delete rxrpc: Fix client call queueing, waiting for channel gro_cells: make sure device is up in gro_cells_receive() tcp/dccp: remove reqsk_put() from inet_child_forget() perf/x86: Fixup typo in stub functions ALSA: bebob: use more identical mod_alias for Saffire Pro 10 I/O against Liquid Saffire 56 It's wrong to add len to sector_nr in raid10 reshape twice mmc: tmio_mmc_core: don't claim spurious interrupts of: Support const and non-const use for to_of_node() vhost/vsock: fix vhost vsock cid hashing inconsistent Linux 4.9.164 Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
2019-03-19 13:27:42 +01:00
addr = smp_load_acquire(&unix_sk(sk)->addr);
if (!addr) {
sunaddr->sun_family = AF_UNIX;
sunaddr->sun_path[0] = 0;
*uaddr_len = sizeof(short);
} else {
*uaddr_len = addr->len;
memcpy(sunaddr, addr->name, *uaddr_len);
}
sock_put(sk);
out:
return err;
}
Merge 4.9.278 into android-4.9-q Changes in 4.9.278 iommu/amd: Fix backport of 140456f994195b568ecd7fc2287a34eadffef3ca tipc: Fix backport of b77413446408fdd256599daf00d5be72b5f3e7c6 net: split out functions related to registering inflight socket files af_unix: fix garbage collect vs MSG_PEEK workqueue: fix UAF in pwq_unbound_release_workfn() net/802/mrp: fix memleak in mrp_request_join() net/802/garp: fix memleak in garp_request_join() sctp: move 198 addresses from unusable to private scope hfs: add missing clean-up in hfs_fill_super hfs: fix high memory mapping in hfs_bnode_read hfs: add lock nesting notation to hfs_find_init ARM: dts: versatile: Fix up interrupt controller node names lib/string.c: add multibyte memset functions ARM: ensure the signal page contains defined contents x86/kvm: fix vcpu-id indexed array sizes ocfs2: fix zero out valid data ocfs2: issue zeroout to EOF blocks can: usb_8dev: fix memory leak can: ems_usb: fix memory leak can: esd_usb2: fix memory leak NIU: fix incorrect error return, missed in previous revert nfc: nfcsim: fix use after free during module unload x86/asm: Ensure asm/proto.h can be included stand-alone cfg80211: Fix possible memory leak in function cfg80211_bss_update netfilter: conntrack: adjust stop timestamp to real expiry value netfilter: nft_nat: allow to specify layer 4 protocol NAT only tipc: fix sleeping in tipc accept routine mlx4: Fix missing error code in mlx4_load_one() net: llc: fix skb_over_panic net/mlx5: Fix flow table chaining tulip: windbond-840: Fix missing pci_disable_device() in probe and remove sis900: Fix missing pci_disable_device() in probe and remove Linux 4.9.278 Signed-off-by: Greg Kroah-Hartman <gregkh@google.com> Change-Id: Ib4a913f4321ead750bc71245e283aae9cb02681b
2021-08-04 12:49:31 +02:00
static void unix_peek_fds(struct scm_cookie *scm, struct sk_buff *skb)
{
Merge 4.9.278 into android-4.9-q Changes in 4.9.278 iommu/amd: Fix backport of 140456f994195b568ecd7fc2287a34eadffef3ca tipc: Fix backport of b77413446408fdd256599daf00d5be72b5f3e7c6 net: split out functions related to registering inflight socket files af_unix: fix garbage collect vs MSG_PEEK workqueue: fix UAF in pwq_unbound_release_workfn() net/802/mrp: fix memleak in mrp_request_join() net/802/garp: fix memleak in garp_request_join() sctp: move 198 addresses from unusable to private scope hfs: add missing clean-up in hfs_fill_super hfs: fix high memory mapping in hfs_bnode_read hfs: add lock nesting notation to hfs_find_init ARM: dts: versatile: Fix up interrupt controller node names lib/string.c: add multibyte memset functions ARM: ensure the signal page contains defined contents x86/kvm: fix vcpu-id indexed array sizes ocfs2: fix zero out valid data ocfs2: issue zeroout to EOF blocks can: usb_8dev: fix memory leak can: ems_usb: fix memory leak can: esd_usb2: fix memory leak NIU: fix incorrect error return, missed in previous revert nfc: nfcsim: fix use after free during module unload x86/asm: Ensure asm/proto.h can be included stand-alone cfg80211: Fix possible memory leak in function cfg80211_bss_update netfilter: conntrack: adjust stop timestamp to real expiry value netfilter: nft_nat: allow to specify layer 4 protocol NAT only tipc: fix sleeping in tipc accept routine mlx4: Fix missing error code in mlx4_load_one() net: llc: fix skb_over_panic net/mlx5: Fix flow table chaining tulip: windbond-840: Fix missing pci_disable_device() in probe and remove sis900: Fix missing pci_disable_device() in probe and remove Linux 4.9.278 Signed-off-by: Greg Kroah-Hartman <gregkh@google.com> Change-Id: Ib4a913f4321ead750bc71245e283aae9cb02681b
2021-08-04 12:49:31 +02:00
scm->fp = scm_fp_dup(UNIXCB(skb).fp);
/*
Merge 4.9.278 into android-4.9-q Changes in 4.9.278 iommu/amd: Fix backport of 140456f994195b568ecd7fc2287a34eadffef3ca tipc: Fix backport of b77413446408fdd256599daf00d5be72b5f3e7c6 net: split out functions related to registering inflight socket files af_unix: fix garbage collect vs MSG_PEEK workqueue: fix UAF in pwq_unbound_release_workfn() net/802/mrp: fix memleak in mrp_request_join() net/802/garp: fix memleak in garp_request_join() sctp: move 198 addresses from unusable to private scope hfs: add missing clean-up in hfs_fill_super hfs: fix high memory mapping in hfs_bnode_read hfs: add lock nesting notation to hfs_find_init ARM: dts: versatile: Fix up interrupt controller node names lib/string.c: add multibyte memset functions ARM: ensure the signal page contains defined contents x86/kvm: fix vcpu-id indexed array sizes ocfs2: fix zero out valid data ocfs2: issue zeroout to EOF blocks can: usb_8dev: fix memory leak can: ems_usb: fix memory leak can: esd_usb2: fix memory leak NIU: fix incorrect error return, missed in previous revert nfc: nfcsim: fix use after free during module unload x86/asm: Ensure asm/proto.h can be included stand-alone cfg80211: Fix possible memory leak in function cfg80211_bss_update netfilter: conntrack: adjust stop timestamp to real expiry value netfilter: nft_nat: allow to specify layer 4 protocol NAT only tipc: fix sleeping in tipc accept routine mlx4: Fix missing error code in mlx4_load_one() net: llc: fix skb_over_panic net/mlx5: Fix flow table chaining tulip: windbond-840: Fix missing pci_disable_device() in probe and remove sis900: Fix missing pci_disable_device() in probe and remove Linux 4.9.278 Signed-off-by: Greg Kroah-Hartman <gregkh@google.com> Change-Id: Ib4a913f4321ead750bc71245e283aae9cb02681b
2021-08-04 12:49:31 +02:00
* Garbage collection of unix sockets starts by selecting a set of
* candidate sockets which have reference only from being in flight
* (total_refs == inflight_refs). This condition is checked once during
* the candidate collection phase, and candidates are marked as such, so
* that non-candidates can later be ignored. While inflight_refs is
* protected by unix_gc_lock, total_refs (file count) is not, hence this
* is an instantaneous decision.
*
* Once a candidate, however, the socket must not be reinstalled into a
* file descriptor while the garbage collection is in progress.
*
* If the above conditions are met, then the directed graph of
* candidates (*) does not change while unix_gc_lock is held.
*
* Any operations that changes the file count through file descriptors
* (dup, close, sendmsg) does not change the graph since candidates are
* not installed in fds.
*
* Dequeing a candidate via recvmsg would install it into an fd, but
* that takes unix_gc_lock to decrement the inflight count, so it's
* serialized with garbage collection.
*
* MSG_PEEK is special in that it does not change the inflight count,
* yet does install the socket into an fd. The following lock/unlock
* pair is to ensure serialization with garbage collection. It must be
* done between incrementing the file count and installing the file into
* an fd.
*
* If garbage collection starts after the barrier provided by the
* lock/unlock, then it will see the elevated refcount and not mark this
* as a candidate. If a garbage collection is already in progress
* before the file count was incremented, then the lock/unlock pair will
* ensure that garbage collection is finished before progressing to
* installing the fd.
*
* (*) A -> B where B is on the queue of A or B is on the queue of C
* which is on the queue of listening socket A.
*/
Merge 4.9.278 into android-4.9-q Changes in 4.9.278 iommu/amd: Fix backport of 140456f994195b568ecd7fc2287a34eadffef3ca tipc: Fix backport of b77413446408fdd256599daf00d5be72b5f3e7c6 net: split out functions related to registering inflight socket files af_unix: fix garbage collect vs MSG_PEEK workqueue: fix UAF in pwq_unbound_release_workfn() net/802/mrp: fix memleak in mrp_request_join() net/802/garp: fix memleak in garp_request_join() sctp: move 198 addresses from unusable to private scope hfs: add missing clean-up in hfs_fill_super hfs: fix high memory mapping in hfs_bnode_read hfs: add lock nesting notation to hfs_find_init ARM: dts: versatile: Fix up interrupt controller node names lib/string.c: add multibyte memset functions ARM: ensure the signal page contains defined contents x86/kvm: fix vcpu-id indexed array sizes ocfs2: fix zero out valid data ocfs2: issue zeroout to EOF blocks can: usb_8dev: fix memory leak can: ems_usb: fix memory leak can: esd_usb2: fix memory leak NIU: fix incorrect error return, missed in previous revert nfc: nfcsim: fix use after free during module unload x86/asm: Ensure asm/proto.h can be included stand-alone cfg80211: Fix possible memory leak in function cfg80211_bss_update netfilter: conntrack: adjust stop timestamp to real expiry value netfilter: nft_nat: allow to specify layer 4 protocol NAT only tipc: fix sleeping in tipc accept routine mlx4: Fix missing error code in mlx4_load_one() net: llc: fix skb_over_panic net/mlx5: Fix flow table chaining tulip: windbond-840: Fix missing pci_disable_device() in probe and remove sis900: Fix missing pci_disable_device() in probe and remove Linux 4.9.278 Signed-off-by: Greg Kroah-Hartman <gregkh@google.com> Change-Id: Ib4a913f4321ead750bc71245e283aae9cb02681b
2021-08-04 12:49:31 +02:00
spin_lock(&unix_gc_lock);
spin_unlock(&unix_gc_lock);
}
static int unix_scm_to_skb(struct scm_cookie *scm, struct sk_buff *skb, bool send_fds)
{
int err = 0;
UNIXCB(skb).pid = get_pid(scm->pid);
UNIXCB(skb).uid = scm->creds.uid;
UNIXCB(skb).gid = scm->creds.gid;
UNIXCB(skb).fp = NULL;
unix_get_secdata(scm, skb);
if (scm->fp && send_fds)
err = unix_attach_fds(scm, skb);
skb->destructor = unix_destruct_scm;
return err;
}
static bool unix_passcred_enabled(const struct socket *sock,
const struct sock *other)
{
return test_bit(SOCK_PASSCRED, &sock->flags) ||
!other->sk_socket ||
test_bit(SOCK_PASSCRED, &other->sk_socket->flags);
}
/*
* Some apps rely on write() giving SCM_CREDENTIALS
* We include credentials if source or destination socket
* asserted SOCK_PASSCRED.
*/
static void maybe_add_creds(struct sk_buff *skb, const struct socket *sock,
const struct sock *other)
{
if (UNIXCB(skb).pid)
return;
if (unix_passcred_enabled(sock, other)) {
UNIXCB(skb).pid = get_pid(task_tgid(current));
current_uid_gid(&UNIXCB(skb).uid, &UNIXCB(skb).gid);
}
}
static int maybe_init_creds(struct scm_cookie *scm,
struct socket *socket,
const struct sock *other)
{
int err;
struct msghdr msg = { .msg_controllen = 0 };
err = scm_send(socket, &msg, scm, false);
if (err)
return err;
if (unix_passcred_enabled(socket, other)) {
scm->pid = get_pid(task_tgid(current));
current_uid_gid(&scm->creds.uid, &scm->creds.gid);
}
return err;
}
static bool unix_skb_scm_eq(struct sk_buff *skb,
struct scm_cookie *scm)
{
const struct unix_skb_parms *u = &UNIXCB(skb);
return u->pid == scm->pid &&
uid_eq(u->uid, scm->creds.uid) &&
gid_eq(u->gid, scm->creds.gid) &&
unix_secdata_eq(scm, skb);
}
/*
* Send AF_UNIX data.
*/
static int unix_dgram_sendmsg(struct socket *sock, struct msghdr *msg,
size_t len)
{
struct sock *sk = sock->sk;
struct net *net = sock_net(sk);
struct unix_sock *u = unix_sk(sk);
DECLARE_SOCKADDR(struct sockaddr_un *, sunaddr, msg->msg_name);
struct sock *other = NULL;
int namelen = 0; /* fake GCC */
int err;
unsigned int hash;
struct sk_buff *skb;
long timeo;
struct scm_cookie scm;
int max_level;
int data_len = 0;
int sk_locked;
wait_for_unix_gc();
err = scm_send(sock, msg, &scm, false);
if (err < 0)
return err;
err = -EOPNOTSUPP;
if (msg->msg_flags&MSG_OOB)
goto out;
if (msg->msg_namelen) {
err = unix_mkname(sunaddr, msg->msg_namelen, &hash);
if (err < 0)
goto out;
namelen = err;
} else {
sunaddr = NULL;
err = -ENOTCONN;
other = unix_peer_get(sk);
if (!other)
goto out;
}
if (test_bit(SOCK_PASSCRED, &sock->flags) && !u->addr
&& (err = unix_autobind(sock)) != 0)
goto out;
err = -EMSGSIZE;
if (len > sk->sk_sndbuf - 32)
goto out;
if (len > SKB_MAX_ALLOC) {
data_len = min_t(size_t,
len - SKB_MAX_ALLOC,
MAX_SKB_FRAGS * PAGE_SIZE);
data_len = PAGE_ALIGN(data_len);
BUILD_BUG_ON(SKB_MAX_ALLOC < PAGE_SIZE);
}
skb = sock_alloc_send_pskb(sk, len - data_len, data_len,
msg->msg_flags & MSG_DONTWAIT, &err,
PAGE_ALLOC_COSTLY_ORDER);
if (skb == NULL)
goto out;
err = unix_scm_to_skb(&scm, skb, true);
if (err < 0)
goto out_free;
max_level = err + 1;
skb_put(skb, len - data_len);
skb->data_len = data_len;
skb->len = len;
err = skb_copy_datagram_from_iter(skb, 0, &msg->msg_iter, len);
if (err)
goto out_free;
timeo = sock_sndtimeo(sk, msg->msg_flags & MSG_DONTWAIT);
restart:
if (!other) {
err = -ECONNRESET;
if (sunaddr == NULL)
goto out_free;
other = unix_find_other(net, sunaddr, namelen, sk->sk_type,
hash, &err);
if (other == NULL)
goto out_free;
}
if (sk_filter(other, skb) < 0) {
/* Toss the packet but do not return any error to the sender */
err = len;
goto out_free;
}
sk_locked = 0;
unix_state_lock(other);
restart_locked:
err = -EPERM;
if (!unix_may_send(sk, other))
goto out_unlock;
if (unlikely(sock_flag(other, SOCK_DEAD))) {
/*
* Check with 1003.1g - what should
* datagram error
*/
unix_state_unlock(other);
sock_put(other);
if (!sk_locked)
unix_state_lock(sk);
err = 0;
if (unix_peer(sk) == other) {
unix_peer(sk) = NULL;
unix_dgram_peer_wake_disconnect_wakeup(sk, other);
unix_state_unlock(sk);
unix_dgram_disconnected(sk, other);
sock_put(other);
err = -ECONNREFUSED;
} else {
unix_state_unlock(sk);
}
other = NULL;
if (err)
goto out_free;
goto restart;
}
err = -EPIPE;
if (other->sk_shutdown & RCV_SHUTDOWN)
goto out_unlock;
if (sk->sk_type != SOCK_SEQPACKET) {
err = security_unix_may_send(sk->sk_socket, other->sk_socket);
if (err)
goto out_unlock;
}
/* other == sk && unix_peer(other) != sk if
* - unix_peer(sk) == NULL, destination address bound to sk
* - unix_peer(sk) == sk by time of get but disconnected before lock
*/
if (other != sk &&
Merge 4.9.238 into android-4.9-q Changes in 4.9.238 af_key: pfkey_dump needs parameter validation KVM: fix memory leak in kvm_io_bus_unregister_dev() kprobes: fix kill kprobe which has been marked as gone RDMA/ucma: ucma_context reference leak in error path mtd: Fix comparison in map_word_andequal() hdlc_ppp: add range checks in ppp_cp_parse_cr() ip: fix tos reflection in ack and reset packets tipc: use skb_unshare() instead in tipc_buf_append() bnxt_en: Protect bnxt_set_eee() and bnxt_set_pauseparam() with mutex. net: phy: Avoid NPD upon phy_detach() when driver is unbound net/hsr: Check skb_put_padto() return value net: add __must_check to skb_put_padto() serial: 8250: Avoid error message on reprobe scsi: aacraid: fix illegal IO beyond last LBA m68k: q40: Fix info-leak in rtc_ioctl gma/gma500: fix a memory disclosure bug due to uninitialized bytes ASoC: kirkwood: fix IRQ error handling ALSA: usb-audio: Add delay quirk for H570e USB headsets PM / devfreq: tegra30: Fix integer overflow on CPU's freq max out clk/ti/adpll: allocate room for terminating null mtd: cfi_cmdset_0002: don't free cfi->cfiq in error path of cfi_amdstd_setup() mfd: mfd-core: Protect against NULL call-back function pointer tracing: Adding NULL checks for trace_array descriptor pointer bcache: fix a lost wake-up problem caused by mca_cannibalize_lock RDMA/i40iw: Fix potential use after free xfs: fix attr leaf header freemap.size underflow RDMA/iw_cgxb4: Fix an error handling path in 'c4iw_connect()' debugfs: Fix !DEBUG_FS debugfs_create_automount CIFS: Properly process SMB3 lease breaks kernel/sys.c: avoid copying possible padding bytes in copy_to_user neigh_stat_seq_next() should increase position index rt_cpu_seq_next should increase position index seqlock: Require WRITE_ONCE surrounding raw_seqcount_barrier media: ti-vpe: cal: Restrict DMA to avoid memory corruption ACPI: EC: Reference count query handlers under lock dmaengine: zynqmp_dma: fix burst length configuration tracing: Set kernel_stack's caller size properly ar5523: Add USB ID of SMCWUSBT-G2 wireless adapter Bluetooth: Fix refcount use-after-free issue mm: pagewalk: fix termination condition in walk_pte_range() Bluetooth: prefetch channel before killing sock KVM: fix overflow of zero page refcount with ksm running ALSA: hda: Clear RIRB status before reading WP skbuff: fix a data race in skb_queue_len() audit: CONFIG_CHANGE don't log internal bookkeeping as an event selinux: sel_avc_get_stat_idx should increase position index scsi: lpfc: Fix RQ buffer leakage when no IOCBs available scsi: lpfc: Fix coverity errors in fmdi attribute handling drm/omap: fix possible object reference leak RDMA/rxe: Fix configuration of atomic queue pair attributes KVM: x86: fix incorrect comparison in trace event x86/pkeys: Add check for pkey "overflow" bpf: Remove recursion prevention from rcu free callback dmaengine: tegra-apb: Prevent race conditions on channel's freeing media: go7007: Fix URB type for interrupt handling Bluetooth: guard against controllers sending zero'd events timekeeping: Prevent 32bit truncation in scale64_check_overflow() drm/amdgpu: increase atombios cmd timeout Bluetooth: L2CAP: handle l2cap config request during open state media: tda10071: fix unsigned sign extension overflow xfs: don't ever return a stale pointer from __xfs_dir3_free_read tpm: ibmvtpm: Wait for buffer to be set before proceeding tracing: Use address-of operator on section symbols serial: 8250_port: Don't service RX FIFO if throttled serial: 8250_omap: Fix sleeping function called from invalid context during probe serial: 8250: 8250_omap: Terminate DMA before pushing data on RX timeout cpufreq: powernv: Fix frame-size-overflow in powernv_cpufreq_work_fn tools: gpio-hammer: Avoid potential overflow in main SUNRPC: Fix a potential buffer overflow in 'svc_print_xprts()' svcrdma: Fix leak of transport addresses ubifs: Fix out-of-bounds memory access caused by abnormal value of node_len ALSA: usb-audio: Fix case when USB MIDI interface has more than one extra endpoint descriptor mm/filemap.c: clear page error before actual read mm/mmap.c: initialize align_offset explicitly for vm_unmapped_area KVM: Remove CREATE_IRQCHIP/SET_PIT2 race bdev: Reduce time holding bd_mutex in sync in blkdev_close() drivers: char: tlclk.c: Avoid data race between init and interrupt handler dt-bindings: sound: wm8994: Correct required supplies based on actual implementaion atm: fix a memory leak of vcc->user_back phy: samsung: s5pv210-usb2: Add delay after reset Bluetooth: Handle Inquiry Cancel error after Inquiry Complete USB: EHCI: ehci-mv: fix error handling in mv_ehci_probe() tty: serial: samsung: Correct clock selection logic ALSA: hda: Fix potential race in unsol event handler fuse: don't check refcount after stealing page USB: EHCI: ehci-mv: fix less than zero comparison of an unsigned int e1000: Do not perform reset in reset_task if we are already down printk: handle blank console arguments passed in. btrfs: don't force read-only after error in drop snapshot vfio/pci: fix memory leaks of eventfd ctx perf util: Fix memory leak of prefix_if_not_in perf kcore_copy: Fix module map when there are no modules loaded mtd: rawnand: omap_elm: Fix runtime PM imbalance on error ceph: fix potential race in ceph_check_caps mtd: parser: cmdline: Support MTD names containing one or more colons x86/speculation/mds: Mark mds_user_clear_cpu_buffers() __always_inline vfio/pci: Clear error and request eventfd ctx after releasing cifs: Fix double add page to memcg when cifs_readpages selftests/x86/syscall_nt: Clear weird flags after each test vfio/pci: fix racy on error and request eventfd ctx s390/init: add missing __init annotations i2c: core: Call i2c_acpi_install_space_handler() before i2c_acpi_register_devices() objtool: Fix noreturn detection for ignored functions ieee802154/adf7242: check status of adf7242_read_reg clocksource/drivers/h8300_timer8: Fix wrong return value in h8300_8timer_init() mwifiex: Increase AES key storage size to 256 bits batman-adv: bla: fix type misuse for backbone_gw hash indexing atm: eni: fix the missed pci_disable_device() for eni_init_one() batman-adv: mcast/TT: fix wrongly dropped or rerouted packets mac802154: tx: fix use-after-free batman-adv: Add missing include for in_interrupt() batman-adv: mcast: fix duplicate mcast packets in BLA backbone from mesh ALSA: asihpi: fix iounmap in error handler MIPS: Add the missing 'CPU_1074K' into __get_cpu_type() kprobes: Fix to check probe enabled before disarm_kprobe_ftrace() lib/string.c: implement stpcpy ata: define AC_ERR_OK ata: make qc_prep return ata_completion_errors ata: sata_mv, avoid trigerrable BUG_ON Linux 4.9.238 Signed-off-by: Greg Kroah-Hartman <gregkh@google.com> Change-Id: I799877db3bc49e473bbc023ab948cd241755beff
2020-10-02 09:20:19 +02:00
unlikely(unix_peer(other) != sk &&
unix_recvq_full_lockless(other))) {
if (timeo) {
timeo = unix_wait_for_peer(other, timeo);
err = sock_intr_errno(timeo);
if (signal_pending(current))
goto out_free;
goto restart;
}
if (!sk_locked) {
unix_state_unlock(other);
unix_state_double_lock(sk, other);
}
if (unix_peer(sk) != other ||
unix_dgram_peer_wake_me(sk, other)) {
err = -EAGAIN;
sk_locked = 1;
goto out_unlock;
}
if (!sk_locked) {
sk_locked = 1;
goto restart_locked;
}
}
if (unlikely(sk_locked))
unix_state_unlock(sk);
if (sock_flag(other, SOCK_RCVTSTAMP))
__net_timestamp(skb);
maybe_add_creds(skb, sock, other);
skb_queue_tail(&other->sk_receive_queue, skb);
if (max_level > unix_sk(other)->recursion_level)
unix_sk(other)->recursion_level = max_level;
unix_state_unlock(other);
other->sk_data_ready(other);
sock_put(other);
scm_destroy(&scm);
return len;
out_unlock:
if (sk_locked)
unix_state_unlock(sk);
unix_state_unlock(other);
out_free:
kfree_skb(skb);
out:
if (other)
sock_put(other);
scm_destroy(&scm);
return err;
}
/* We use paged skbs for stream sockets, and limit occupancy to 32768
* bytes, and a minimun of a full page.
*/
#define UNIX_SKB_FRAGS_SZ (PAGE_SIZE << get_order(32768))
static int unix_stream_sendmsg(struct socket *sock, struct msghdr *msg,
size_t len)
{
struct sock *sk = sock->sk;
struct sock *other = NULL;
int err, size;
struct sk_buff *skb;
int sent = 0;
struct scm_cookie scm;
bool fds_sent = false;
int max_level;
int data_len;
wait_for_unix_gc();
err = scm_send(sock, msg, &scm, false);
if (err < 0)
return err;
err = -EOPNOTSUPP;
if (msg->msg_flags&MSG_OOB)
goto out_err;
if (msg->msg_namelen) {
err = sk->sk_state == TCP_ESTABLISHED ? -EISCONN : -EOPNOTSUPP;
goto out_err;
} else {
err = -ENOTCONN;
other = unix_peer(sk);
if (!other)
goto out_err;
}
if (sk->sk_shutdown & SEND_SHUTDOWN)
goto pipe_err;
while (sent < len) {
size = len - sent;
/* Keep two messages in the pipe so it schedules better */
size = min_t(int, size, (sk->sk_sndbuf >> 1) - 64);
/* allow fallback to order-0 allocations */
size = min_t(int, size, SKB_MAX_HEAD(0) + UNIX_SKB_FRAGS_SZ);
data_len = max_t(int, 0, size - SKB_MAX_HEAD(0));
data_len = min_t(size_t, size, PAGE_ALIGN(data_len));
skb = sock_alloc_send_pskb(sk, size - data_len, data_len,
msg->msg_flags & MSG_DONTWAIT, &err,
get_order(UNIX_SKB_FRAGS_SZ));
if (!skb)
goto out_err;
/* Only send the fds in the first buffer */
err = unix_scm_to_skb(&scm, skb, !fds_sent);
if (err < 0) {
kfree_skb(skb);
goto out_err;
}
max_level = err + 1;
fds_sent = true;
skb_put(skb, size - data_len);
skb->data_len = data_len;
skb->len = size;
err = skb_copy_datagram_from_iter(skb, 0, &msg->msg_iter, size);
if (err) {
kfree_skb(skb);
goto out_err;
}
unix_state_lock(other);
if (sock_flag(other, SOCK_DEAD) ||
(other->sk_shutdown & RCV_SHUTDOWN))
goto pipe_err_free;
maybe_add_creds(skb, sock, other);
skb_queue_tail(&other->sk_receive_queue, skb);
if (max_level > unix_sk(other)->recursion_level)
unix_sk(other)->recursion_level = max_level;
unix_state_unlock(other);
other->sk_data_ready(other);
sent += size;
}
scm_destroy(&scm);
return sent;
pipe_err_free:
unix_state_unlock(other);
kfree_skb(skb);
pipe_err:
if (sent == 0 && !(msg->msg_flags&MSG_NOSIGNAL))
send_sig(SIGPIPE, current, 0);
err = -EPIPE;
out_err:
scm_destroy(&scm);
return sent ? : err;
}
static ssize_t unix_stream_sendpage(struct socket *socket, struct page *page,
int offset, size_t size, int flags)
{
int err;
bool send_sigpipe = false;
bool init_scm = true;
struct scm_cookie scm;
struct sock *other, *sk = socket->sk;
struct sk_buff *skb, *newskb = NULL, *tail = NULL;
if (flags & MSG_OOB)
return -EOPNOTSUPP;
other = unix_peer(sk);
if (!other || sk->sk_state != TCP_ESTABLISHED)
return -ENOTCONN;
if (false) {
alloc_skb:
unix_state_unlock(other);
mutex_unlock(&unix_sk(other)->iolock);
newskb = sock_alloc_send_pskb(sk, 0, 0, flags & MSG_DONTWAIT,
&err, 0);
if (!newskb)
goto err;
}
/* we must acquire iolock as we modify already present
* skbs in the sk_receive_queue and mess with skb->len
*/
err = mutex_lock_interruptible(&unix_sk(other)->iolock);
if (err) {
err = flags & MSG_DONTWAIT ? -EAGAIN : -ERESTARTSYS;
goto err;
}
if (sk->sk_shutdown & SEND_SHUTDOWN) {
err = -EPIPE;
send_sigpipe = true;
goto err_unlock;
}
unix_state_lock(other);
if (sock_flag(other, SOCK_DEAD) ||
other->sk_shutdown & RCV_SHUTDOWN) {
err = -EPIPE;
send_sigpipe = true;
goto err_state_unlock;
}
if (init_scm) {
err = maybe_init_creds(&scm, socket, other);
if (err)
goto err_state_unlock;
init_scm = false;
}
skb = skb_peek_tail(&other->sk_receive_queue);
if (tail && tail == skb) {
skb = newskb;
} else if (!skb || !unix_skb_scm_eq(skb, &scm)) {
if (newskb) {
skb = newskb;
} else {
tail = skb;
goto alloc_skb;
}
} else if (newskb) {
/* this is fast path, we don't necessarily need to
* call to kfree_skb even though with newskb == NULL
* this - does no harm
*/
consume_skb(newskb);
newskb = NULL;
}
if (skb_append_pagefrags(skb, page, offset, size)) {
tail = skb;
goto alloc_skb;
}
skb->len += size;
skb->data_len += size;
skb->truesize += size;
atomic_add(size, &sk->sk_wmem_alloc);
if (newskb) {
err = unix_scm_to_skb(&scm, skb, false);
if (err)
goto err_state_unlock;
spin_lock(&other->sk_receive_queue.lock);
__skb_queue_tail(&other->sk_receive_queue, newskb);
spin_unlock(&other->sk_receive_queue.lock);
}
unix_state_unlock(other);
mutex_unlock(&unix_sk(other)->iolock);
other->sk_data_ready(other);
scm_destroy(&scm);
return size;
err_state_unlock:
unix_state_unlock(other);
err_unlock:
mutex_unlock(&unix_sk(other)->iolock);
err:
kfree_skb(newskb);
if (send_sigpipe && !(flags & MSG_NOSIGNAL))
send_sig(SIGPIPE, current, 0);
if (!init_scm)
scm_destroy(&scm);
return err;
}
static int unix_seqpacket_sendmsg(struct socket *sock, struct msghdr *msg,
size_t len)
{
int err;
struct sock *sk = sock->sk;
err = sock_error(sk);
if (err)
return err;
if (sk->sk_state != TCP_ESTABLISHED)
return -ENOTCONN;
if (msg->msg_namelen)
msg->msg_namelen = 0;
return unix_dgram_sendmsg(sock, msg, len);
}
static int unix_seqpacket_recvmsg(struct socket *sock, struct msghdr *msg,
size_t size, int flags)
{
struct sock *sk = sock->sk;
if (sk->sk_state != TCP_ESTABLISHED)
return -ENOTCONN;
return unix_dgram_recvmsg(sock, msg, size, flags);
}
static void unix_copy_addr(struct msghdr *msg, struct sock *sk)
{
Merge 4.9.164 into android-4.9 Changes in 4.9.164 ACPICA: Reference Counts: increase max to 0x4000 for large servers KEYS: restrict /proc/keys by credentials at open time l2tp: fix infoleak in l2tp_ip6_recvmsg() net: hsr: fix memory leak in hsr_dev_finalize() net/hsr: fix possible crash in add_timer() net: sit: fix UBSAN Undefined behaviour in check_6rd net/x25: fix use-after-free in x25_device_event() net/x25: reset state in x25_connect() pptp: dst_release sk_dst_cache in pptp_sock_destruct ravb: Decrease TxFIFO depth of Q3 and Q2 to one route: set the deleted fnhe fnhe_daddr to 0 in ip_del_fnhe to fix a race tcp: handle inet_csk_reqsk_queue_add() failures vxlan: test dev->flags & IFF_UP before calling gro_cells_receive() net/mlx4_core: Fix reset flow when in command polling mode net/mlx4_core: Fix locking in SRIOV mode when switching between events and polling net/mlx4_core: Fix qp mtt size calculation net/x25: fix a race in x25_bind() mdio_bus: Fix use-after-free on device_register fails net: Set rtm_table to RT_TABLE_COMPAT for ipv6 for tables > 255 missing barriers in some of unix_sock ->addr and ->path accesses ipvlan: disallow userns cap_net_admin to change global mode/flags vxlan: Fix GRO cells race condition between receive and link delete rxrpc: Fix client call queueing, waiting for channel gro_cells: make sure device is up in gro_cells_receive() tcp/dccp: remove reqsk_put() from inet_child_forget() perf/x86: Fixup typo in stub functions ALSA: bebob: use more identical mod_alias for Saffire Pro 10 I/O against Liquid Saffire 56 It's wrong to add len to sector_nr in raid10 reshape twice mmc: tmio_mmc_core: don't claim spurious interrupts of: Support const and non-const use for to_of_node() vhost/vsock: fix vhost vsock cid hashing inconsistent Linux 4.9.164 Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
2019-03-19 13:27:42 +01:00
struct unix_address *addr = smp_load_acquire(&unix_sk(sk)->addr);
Merge 4.9.164 into android-4.9 Changes in 4.9.164 ACPICA: Reference Counts: increase max to 0x4000 for large servers KEYS: restrict /proc/keys by credentials at open time l2tp: fix infoleak in l2tp_ip6_recvmsg() net: hsr: fix memory leak in hsr_dev_finalize() net/hsr: fix possible crash in add_timer() net: sit: fix UBSAN Undefined behaviour in check_6rd net/x25: fix use-after-free in x25_device_event() net/x25: reset state in x25_connect() pptp: dst_release sk_dst_cache in pptp_sock_destruct ravb: Decrease TxFIFO depth of Q3 and Q2 to one route: set the deleted fnhe fnhe_daddr to 0 in ip_del_fnhe to fix a race tcp: handle inet_csk_reqsk_queue_add() failures vxlan: test dev->flags & IFF_UP before calling gro_cells_receive() net/mlx4_core: Fix reset flow when in command polling mode net/mlx4_core: Fix locking in SRIOV mode when switching between events and polling net/mlx4_core: Fix qp mtt size calculation net/x25: fix a race in x25_bind() mdio_bus: Fix use-after-free on device_register fails net: Set rtm_table to RT_TABLE_COMPAT for ipv6 for tables > 255 missing barriers in some of unix_sock ->addr and ->path accesses ipvlan: disallow userns cap_net_admin to change global mode/flags vxlan: Fix GRO cells race condition between receive and link delete rxrpc: Fix client call queueing, waiting for channel gro_cells: make sure device is up in gro_cells_receive() tcp/dccp: remove reqsk_put() from inet_child_forget() perf/x86: Fixup typo in stub functions ALSA: bebob: use more identical mod_alias for Saffire Pro 10 I/O against Liquid Saffire 56 It's wrong to add len to sector_nr in raid10 reshape twice mmc: tmio_mmc_core: don't claim spurious interrupts of: Support const and non-const use for to_of_node() vhost/vsock: fix vhost vsock cid hashing inconsistent Linux 4.9.164 Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
2019-03-19 13:27:42 +01:00
if (addr) {
msg->msg_namelen = addr->len;
memcpy(msg->msg_name, addr->name, addr->len);
}
}
static int unix_dgram_recvmsg(struct socket *sock, struct msghdr *msg,
size_t size, int flags)
{
struct scm_cookie scm;
struct sock *sk = sock->sk;
struct unix_sock *u = unix_sk(sk);
struct sk_buff *skb, *last;
long timeo;
int err;
int peeked, skip;
err = -EOPNOTSUPP;
if (flags&MSG_OOB)
goto out;
timeo = sock_rcvtimeo(sk, flags & MSG_DONTWAIT);
do {
mutex_lock(&u->iolock);
skip = sk_peek_offset(sk, flags);
skb = __skb_try_recv_datagram(sk, flags, &peeked, &skip, &err,
&last);
if (skb)
break;
mutex_unlock(&u->iolock);
if (err != -EAGAIN)
break;
} while (timeo &&
!__skb_wait_for_more_packets(sk, &err, &timeo, last));
if (!skb) { /* implies iolock unlocked */
unix_state_lock(sk);
/* Signal EOF on disconnected non-blocking SEQPACKET socket. */
if (sk->sk_type == SOCK_SEQPACKET && err == -EAGAIN &&
(sk->sk_shutdown & RCV_SHUTDOWN))
err = 0;
unix_state_unlock(sk);
goto out;
}
if (wq_has_sleeper(&u->peer_wait))
wake_up_interruptible_sync_poll(&u->peer_wait,
POLLOUT | POLLWRNORM |
POLLWRBAND);
if (msg->msg_name)
unix_copy_addr(msg, skb->sk);
if (size > skb->len - skip)
size = skb->len - skip;
else if (size < skb->len - skip)
msg->msg_flags |= MSG_TRUNC;
err = skb_copy_datagram_msg(skb, skip, msg, size);
if (err)
goto out_free;
if (sock_flag(sk, SOCK_RCVTSTAMP))
__sock_recv_timestamp(msg, sk, skb);
memset(&scm, 0, sizeof(scm));
scm_set_cred(&scm, UNIXCB(skb).pid, UNIXCB(skb).uid, UNIXCB(skb).gid);
unix_set_secdata(&scm, skb);
if (!(flags & MSG_PEEK)) {
if (UNIXCB(skb).fp)
unix_detach_fds(&scm, skb);
sk_peek_offset_bwd(sk, skb->len);
} else {
/* It is questionable: on PEEK we could:
- do not return fds - good, but too simple 8)
- return fds, and do not return them on read (old strategy,
apparently wrong)
- clone fds (I chose it for now, it is the most universal
solution)
POSIX 1003.1g does not actually define this clearly
at all. POSIX 1003.1g doesn't define a lot of things
clearly however!
*/
sk_peek_offset_fwd(sk, size);
if (UNIXCB(skb).fp)
Merge 4.9.278 into android-4.9-q Changes in 4.9.278 iommu/amd: Fix backport of 140456f994195b568ecd7fc2287a34eadffef3ca tipc: Fix backport of b77413446408fdd256599daf00d5be72b5f3e7c6 net: split out functions related to registering inflight socket files af_unix: fix garbage collect vs MSG_PEEK workqueue: fix UAF in pwq_unbound_release_workfn() net/802/mrp: fix memleak in mrp_request_join() net/802/garp: fix memleak in garp_request_join() sctp: move 198 addresses from unusable to private scope hfs: add missing clean-up in hfs_fill_super hfs: fix high memory mapping in hfs_bnode_read hfs: add lock nesting notation to hfs_find_init ARM: dts: versatile: Fix up interrupt controller node names lib/string.c: add multibyte memset functions ARM: ensure the signal page contains defined contents x86/kvm: fix vcpu-id indexed array sizes ocfs2: fix zero out valid data ocfs2: issue zeroout to EOF blocks can: usb_8dev: fix memory leak can: ems_usb: fix memory leak can: esd_usb2: fix memory leak NIU: fix incorrect error return, missed in previous revert nfc: nfcsim: fix use after free during module unload x86/asm: Ensure asm/proto.h can be included stand-alone cfg80211: Fix possible memory leak in function cfg80211_bss_update netfilter: conntrack: adjust stop timestamp to real expiry value netfilter: nft_nat: allow to specify layer 4 protocol NAT only tipc: fix sleeping in tipc accept routine mlx4: Fix missing error code in mlx4_load_one() net: llc: fix skb_over_panic net/mlx5: Fix flow table chaining tulip: windbond-840: Fix missing pci_disable_device() in probe and remove sis900: Fix missing pci_disable_device() in probe and remove Linux 4.9.278 Signed-off-by: Greg Kroah-Hartman <gregkh@google.com> Change-Id: Ib4a913f4321ead750bc71245e283aae9cb02681b
2021-08-04 12:49:31 +02:00
unix_peek_fds(&scm, skb);
}
err = (flags & MSG_TRUNC) ? skb->len - skip : size;
scm_recv(sock, msg, &scm, flags);
out_free:
skb_free_datagram(sk, skb);
mutex_unlock(&u->iolock);
out:
return err;
}
/*
* Sleep until more data has arrived. But check for races..
*/
static long unix_stream_data_wait(struct sock *sk, long timeo,
struct sk_buff *last, unsigned int last_len,
bool freezable)
{
struct sk_buff *tail;
DEFINE_WAIT(wait);
unix_state_lock(sk);
for (;;) {
prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE);
tail = skb_peek_tail(&sk->sk_receive_queue);
if (tail != last ||
(tail && tail->len != last_len) ||
sk->sk_err ||
(sk->sk_shutdown & RCV_SHUTDOWN) ||
signal_pending(current) ||
!timeo)
break;
sk_set_bit(SOCKWQ_ASYNC_WAITDATA, sk);
unix_state_unlock(sk);
if (freezable)
timeo = freezable_schedule_timeout(timeo);
else
timeo = schedule_timeout(timeo);
unix_state_lock(sk);
if (sock_flag(sk, SOCK_DEAD))
break;
sk_clear_bit(SOCKWQ_ASYNC_WAITDATA, sk);
}
finish_wait(sk_sleep(sk), &wait);
unix_state_unlock(sk);
return timeo;
}
static unsigned int unix_skb_len(const struct sk_buff *skb)
{
return skb->len - UNIXCB(skb).consumed;
}
struct unix_stream_read_state {
int (*recv_actor)(struct sk_buff *, int, int,
struct unix_stream_read_state *);
struct socket *socket;
struct msghdr *msg;
struct pipe_inode_info *pipe;
size_t size;
int flags;
unsigned int splice_flags;
};
static int unix_stream_read_generic(struct unix_stream_read_state *state,
bool freezable)
{
struct scm_cookie scm;
struct socket *sock = state->socket;
struct sock *sk = sock->sk;
struct unix_sock *u = unix_sk(sk);
int copied = 0;
int flags = state->flags;
int noblock = flags & MSG_DONTWAIT;
bool check_creds = false;
int target;
int err = 0;
long timeo;
int skip;
size_t size = state->size;
unsigned int last_len;
if (unlikely(sk->sk_state != TCP_ESTABLISHED)) {
err = -EINVAL;
goto out;
}
if (unlikely(flags & MSG_OOB)) {
err = -EOPNOTSUPP;
goto out;
}
target = sock_rcvlowat(sk, flags & MSG_WAITALL, size);
timeo = sock_rcvtimeo(sk, noblock);
memset(&scm, 0, sizeof(scm));
/* Lock the socket to prevent queue disordering
* while sleeps in memcpy_tomsg
*/
mutex_lock(&u->iolock);
if (flags & MSG_PEEK)
skip = sk_peek_offset(sk, flags);
else
skip = 0;
do {
int chunk;
bool drop_skb;
struct sk_buff *skb, *last;
redo:
unix_state_lock(sk);
if (sock_flag(sk, SOCK_DEAD)) {
err = -ECONNRESET;
goto unlock;
}
last = skb = skb_peek(&sk->sk_receive_queue);
last_len = last ? last->len : 0;
again:
if (skb == NULL) {
unix_sk(sk)->recursion_level = 0;
if (copied >= target)
goto unlock;
/*
* POSIX 1003.1g mandates this order.
*/
err = sock_error(sk);
if (err)
goto unlock;
if (sk->sk_shutdown & RCV_SHUTDOWN)
goto unlock;
unix_state_unlock(sk);
if (!timeo) {
err = -EAGAIN;
break;
}
mutex_unlock(&u->iolock);
timeo = unix_stream_data_wait(sk, timeo, last,
last_len, freezable);
if (signal_pending(current)) {
err = sock_intr_errno(timeo);
scm_destroy(&scm);
goto out;
}
mutex_lock(&u->iolock);
goto redo;
unlock:
unix_state_unlock(sk);
break;
}
while (skip >= unix_skb_len(skb)) {
skip -= unix_skb_len(skb);
last = skb;
last_len = skb->len;
skb = skb_peek_next(skb, &sk->sk_receive_queue);
if (!skb)
goto again;
}
unix_state_unlock(sk);
if (check_creds) {
/* Never glue messages from different writers */
if (!unix_skb_scm_eq(skb, &scm))
break;
} else if (test_bit(SOCK_PASSCRED, &sock->flags)) {
/* Copy credentials */
scm_set_cred(&scm, UNIXCB(skb).pid, UNIXCB(skb).uid, UNIXCB(skb).gid);
unix_set_secdata(&scm, skb);
check_creds = true;
}
/* Copy address just once */
if (state->msg && state->msg->msg_name) {
DECLARE_SOCKADDR(struct sockaddr_un *, sunaddr,
state->msg->msg_name);
unix_copy_addr(state->msg, skb->sk);
sunaddr = NULL;
}
chunk = min_t(unsigned int, unix_skb_len(skb) - skip, size);
skb_get(skb);
chunk = state->recv_actor(skb, skip, chunk, state);
drop_skb = !unix_skb_len(skb);
/* skb is only safe to use if !drop_skb */
consume_skb(skb);
if (chunk < 0) {
if (copied == 0)
copied = -EFAULT;
break;
}
copied += chunk;
size -= chunk;
if (drop_skb) {
/* the skb was touched by a concurrent reader;
* we should not expect anything from this skb
* anymore and assume it invalid - we can be
* sure it was dropped from the socket queue
*
* let's report a short read
*/
err = 0;
break;
}
/* Mark read part of skb as used */
if (!(flags & MSG_PEEK)) {
UNIXCB(skb).consumed += chunk;
sk_peek_offset_bwd(sk, chunk);
if (UNIXCB(skb).fp)
unix_detach_fds(&scm, skb);
if (unix_skb_len(skb))
break;
skb_unlink(skb, &sk->sk_receive_queue);
consume_skb(skb);
if (scm.fp)
break;
} else {
/* It is questionable, see note in unix_dgram_recvmsg.
*/
if (UNIXCB(skb).fp)
Merge 4.9.278 into android-4.9-q Changes in 4.9.278 iommu/amd: Fix backport of 140456f994195b568ecd7fc2287a34eadffef3ca tipc: Fix backport of b77413446408fdd256599daf00d5be72b5f3e7c6 net: split out functions related to registering inflight socket files af_unix: fix garbage collect vs MSG_PEEK workqueue: fix UAF in pwq_unbound_release_workfn() net/802/mrp: fix memleak in mrp_request_join() net/802/garp: fix memleak in garp_request_join() sctp: move 198 addresses from unusable to private scope hfs: add missing clean-up in hfs_fill_super hfs: fix high memory mapping in hfs_bnode_read hfs: add lock nesting notation to hfs_find_init ARM: dts: versatile: Fix up interrupt controller node names lib/string.c: add multibyte memset functions ARM: ensure the signal page contains defined contents x86/kvm: fix vcpu-id indexed array sizes ocfs2: fix zero out valid data ocfs2: issue zeroout to EOF blocks can: usb_8dev: fix memory leak can: ems_usb: fix memory leak can: esd_usb2: fix memory leak NIU: fix incorrect error return, missed in previous revert nfc: nfcsim: fix use after free during module unload x86/asm: Ensure asm/proto.h can be included stand-alone cfg80211: Fix possible memory leak in function cfg80211_bss_update netfilter: conntrack: adjust stop timestamp to real expiry value netfilter: nft_nat: allow to specify layer 4 protocol NAT only tipc: fix sleeping in tipc accept routine mlx4: Fix missing error code in mlx4_load_one() net: llc: fix skb_over_panic net/mlx5: Fix flow table chaining tulip: windbond-840: Fix missing pci_disable_device() in probe and remove sis900: Fix missing pci_disable_device() in probe and remove Linux 4.9.278 Signed-off-by: Greg Kroah-Hartman <gregkh@google.com> Change-Id: Ib4a913f4321ead750bc71245e283aae9cb02681b
2021-08-04 12:49:31 +02:00
unix_peek_fds(&scm, skb);
sk_peek_offset_fwd(sk, chunk);
if (UNIXCB(skb).fp)
break;
skip = 0;
last = skb;
last_len = skb->len;
unix_state_lock(sk);
skb = skb_peek_next(skb, &sk->sk_receive_queue);
if (skb)
goto again;
unix_state_unlock(sk);
break;
}
} while (size);
mutex_unlock(&u->iolock);
if (state->msg)
scm_recv(sock, state->msg, &scm, flags);
else
scm_destroy(&scm);
out:
return copied ? : err;
}
static int unix_stream_read_actor(struct sk_buff *skb,
int skip, int chunk,
struct unix_stream_read_state *state)
{
int ret;
ret = skb_copy_datagram_msg(skb, UNIXCB(skb).consumed + skip,
state->msg, chunk);
return ret ?: chunk;
}
static int unix_stream_recvmsg(struct socket *sock, struct msghdr *msg,
size_t size, int flags)
{
struct unix_stream_read_state state = {
.recv_actor = unix_stream_read_actor,
.socket = sock,
.msg = msg,
.size = size,
.flags = flags
};
return unix_stream_read_generic(&state, true);
}
static int unix_stream_splice_actor(struct sk_buff *skb,
int skip, int chunk,
struct unix_stream_read_state *state)
{
return skb_splice_bits(skb, state->socket->sk,
UNIXCB(skb).consumed + skip,
state->pipe, chunk, state->splice_flags);
}
static ssize_t unix_stream_splice_read(struct socket *sock, loff_t *ppos,
struct pipe_inode_info *pipe,
size_t size, unsigned int flags)
{
struct unix_stream_read_state state = {
.recv_actor = unix_stream_splice_actor,
.socket = sock,
.pipe = pipe,
.size = size,
.splice_flags = flags,
};
if (unlikely(*ppos))
return -ESPIPE;
if (sock->file->f_flags & O_NONBLOCK ||
flags & SPLICE_F_NONBLOCK)
state.flags = MSG_DONTWAIT;
return unix_stream_read_generic(&state, false);
}
static int unix_shutdown(struct socket *sock, int mode)
{
struct sock *sk = sock->sk;
struct sock *other;
if (mode < SHUT_RD || mode > SHUT_RDWR)
return -EINVAL;
/* This maps:
* SHUT_RD (0) -> RCV_SHUTDOWN (1)
* SHUT_WR (1) -> SEND_SHUTDOWN (2)
* SHUT_RDWR (2) -> SHUTDOWN_MASK (3)
*/
++mode;
unix_state_lock(sk);
sk->sk_shutdown |= mode;
other = unix_peer(sk);
if (other)
sock_hold(other);
unix_state_unlock(sk);
sk->sk_state_change(sk);
if (other &&
(sk->sk_type == SOCK_STREAM || sk->sk_type == SOCK_SEQPACKET)) {
int peer_mode = 0;
if (mode&RCV_SHUTDOWN)
peer_mode |= SEND_SHUTDOWN;
if (mode&SEND_SHUTDOWN)
peer_mode |= RCV_SHUTDOWN;
unix_state_lock(other);
other->sk_shutdown |= peer_mode;
unix_state_unlock(other);
other->sk_state_change(other);
if (peer_mode == SHUTDOWN_MASK)
sk_wake_async(other, SOCK_WAKE_WAITD, POLL_HUP);
else if (peer_mode & RCV_SHUTDOWN)
sk_wake_async(other, SOCK_WAKE_WAITD, POLL_IN);
}
if (other)
sock_put(other);
return 0;
}
long unix_inq_len(struct sock *sk)
{
struct sk_buff *skb;
long amount = 0;
if (sk->sk_state == TCP_LISTEN)
return -EINVAL;
spin_lock(&sk->sk_receive_queue.lock);
if (sk->sk_type == SOCK_STREAM ||
sk->sk_type == SOCK_SEQPACKET) {
skb_queue_walk(&sk->sk_receive_queue, skb)
amount += unix_skb_len(skb);
} else {
skb = skb_peek(&sk->sk_receive_queue);
if (skb)
amount = skb->len;
}
spin_unlock(&sk->sk_receive_queue.lock);
return amount;
}
EXPORT_SYMBOL_GPL(unix_inq_len);
long unix_outq_len(struct sock *sk)
{
return sk_wmem_alloc_get(sk);
}
EXPORT_SYMBOL_GPL(unix_outq_len);
static int unix_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
{
struct sock *sk = sock->sk;
long amount = 0;
int err;
switch (cmd) {
case SIOCOUTQ:
amount = unix_outq_len(sk);
err = put_user(amount, (int __user *)arg);
break;
case SIOCINQ:
amount = unix_inq_len(sk);
if (amount < 0)
err = amount;
else
err = put_user(amount, (int __user *)arg);
break;
default:
err = -ENOIOCTLCMD;
break;
}
return err;
}
static unsigned int unix_poll(struct file *file, struct socket *sock, poll_table *wait)
{
struct sock *sk = sock->sk;
unsigned int mask;
sock_poll_wait(file, sk_sleep(sk), wait);
mask = 0;
/* exceptional events? */
if (sk->sk_err)
mask |= POLLERR;
if (sk->sk_shutdown == SHUTDOWN_MASK)
mask |= POLLHUP;
if (sk->sk_shutdown & RCV_SHUTDOWN)
mask |= POLLRDHUP | POLLIN | POLLRDNORM;
/* readable? */
if (!skb_queue_empty(&sk->sk_receive_queue))
mask |= POLLIN | POLLRDNORM;
/* Connection-based need to check for termination and startup */
if ((sk->sk_type == SOCK_STREAM || sk->sk_type == SOCK_SEQPACKET) &&
sk->sk_state == TCP_CLOSE)
mask |= POLLHUP;
/*
* we set writable also when the other side has shut down the
* connection. This prevents stuck sockets.
*/
if (unix_writable(sk))
mask |= POLLOUT | POLLWRNORM | POLLWRBAND;
return mask;
}
static unsigned int unix_dgram_poll(struct file *file, struct socket *sock,
poll_table *wait)
{
struct sock *sk = sock->sk, *other;
unsigned int mask, writable;
sock_poll_wait(file, sk_sleep(sk), wait);
mask = 0;
/* exceptional events? */
if (sk->sk_err || !skb_queue_empty(&sk->sk_error_queue))
mask |= POLLERR |
(sock_flag(sk, SOCK_SELECT_ERR_QUEUE) ? POLLPRI : 0);
if (sk->sk_shutdown & RCV_SHUTDOWN)
mask |= POLLRDHUP | POLLIN | POLLRDNORM;
if (sk->sk_shutdown == SHUTDOWN_MASK)
mask |= POLLHUP;
/* readable? */
if (!skb_queue_empty(&sk->sk_receive_queue))
mask |= POLLIN | POLLRDNORM;
/* Connection-based need to check for termination and startup */
if (sk->sk_type == SOCK_SEQPACKET) {
if (sk->sk_state == TCP_CLOSE)
mask |= POLLHUP;
/* connection hasn't started yet? */
if (sk->sk_state == TCP_SYN_SENT)
return mask;
}
/* No write status requested, avoid expensive OUT tests. */
if (!(poll_requested_events(wait) & (POLLWRBAND|POLLWRNORM|POLLOUT)))
return mask;
writable = unix_writable(sk);
if (writable) {
unix_state_lock(sk);
other = unix_peer(sk);
if (other && unix_peer(other) != sk &&
Merge 4.9.283 into android-4.9-q Changes in 4.9.283 ext4: fix race writing to an inline_data file while its xattrs are changing mtd: nand: atmel_nand: remove build warning in atmel_nand_remove() xtensa: fix kconfig unmet dependency warning for HAVE_FUTEX_CMPXCHG qed: Fix the VF msix vectors flow qede: Fix memset corruption perf/x86/amd/ibs: Work around erratum #1197 cryptoloop: add a deprecation warning ARM: 8918/2: only build return_address() if needed ALSA: pcm: fix divide error in snd_pcm_lib_ioctl ath: Use safer key clearing with key cache entries ath9k: Clear key cache explicitly on disabling hardware ath: Export ath_hw_keysetmac() ath: Modify ath_key_delete() to not need full key entry ath9k: Postpone key cache entry deletion for TXQ frames reference it media: stkwebcam: fix memory leak in stk_camera_probe igmp: Add ip_mc_list lock in ip_check_mc_rcu usb: phy: isp1301: Fix build warning when CONFIG_OF is disabled USB: serial: mos7720: improve OOM-handling in read_mos_reg() net/sched: cls_flower: Use mask for addr_type PM / wakeirq: Enable dedicated wakeirq for suspend tc358743: fix register i2c_rd/wr function fix nvme-pci: Fix an error handling path in 'nvme_probe()' gfs2: Don't clear SGID when inheriting ACLs ipv4/icmp: l3mdev: Perform icmp error route lookup on source device routing table (v2) s390/disassembler: correct disassembly lines alignment mm/kmemleak.c: make cond_resched() rate-limiting more efficient crypto: talitos - reduce max key size for SEC1 powerpc/module64: Fix comment in R_PPC64_ENTRY handling powerpc/boot: Delete unneeded .globl _zimage_start net: ll_temac: Remove left-over debug message mm/page_alloc: speed up the iteration of max_order Revert "btrfs: compression: don't try to compress if we don't have enough pages" x86/reboot: Limit Dell Optiplex 990 quirk to early BIOS versions PCI: Call Max Payload Size-related fixup quirks early regmap: fix the offset of register error log crypto: mxs-dcp - Check for DMA mapping errors power: supply: axp288_fuel_gauge: Report register-address on readb / writeb errors crypto: omap-sham - clear dma flags only after omap_sham_update_dma_stop() udf: Check LVID earlier power: supply: max17042_battery: fix typo in MAx17042_TOFF libata: fix ata_host_start() crypto: qat - do not ignore errors from enable_vf2pf_comms() crypto: qat - handle both source of interrupt in VF ISR crypto: qat - fix reuse of completion variable crypto: qat - fix naming for init/shutdown VF to PF notifications crypto: qat - do not export adf_iov_putmsg() udf_get_extendedattr() had no boundary checks. m68k: emu: Fix invalid free in nfeth_cleanup() spi: spi-pic32: Fix issue with uninitialized dma_slave_config crypto: qat - use proper type for vf_mask certs: Trigger creation of RSA module signing key if it's not an RSA key media: dvb-usb: fix uninit-value in dvb_usb_adapter_dvb_init media: dvb-usb: fix uninit-value in vp702x_read_mac_addr media: go7007: remove redundant initialization Bluetooth: sco: prevent information leak in sco_conn_defer_accept() tcp: seq_file: Avoid skipping sk during tcp_seek_last_pos net: cipso: fix warnings in netlbl_cipsov4_add_std i2c: highlander: add IRQ check PCI: PM: Enable PME if it can be signaled from D3cold soc: qcom: smsm: Fix missed interrupts if state changes while masked Bluetooth: increase BTNAMSIZ to 21 chars to fix potential buffer overflow arm64: dts: exynos: correct GIC CPU interfaces address range on Exynos7 Bluetooth: fix repeated calls to sco_sock_kill drm/msm/dsi: Fix some reference counted resource leaks usb: gadget: udc: at91: add IRQ check usb: phy: fsl-usb: add IRQ check usb: phy: twl6030: add IRQ checks Bluetooth: Move shutdown callback before flushing tx and rx queue usb: host: ohci-tmio: add IRQ check usb: phy: tahvo: add IRQ check usb: gadget: mv_u3d: request_irq() after initializing UDC Bluetooth: add timeout sanity check to hci_inquiry i2c: iop3xx: fix deferred probing i2c: s3c2410: fix IRQ check mmc: dw_mmc: Fix issue with uninitialized dma_slave_config mmc: moxart: Fix issue with uninitialized dma_slave_config CIFS: Fix a potencially linear read overflow i2c: mt65xx: fix IRQ check usb: ehci-orion: Handle errors of clk_prepare_enable() in probe ath6kl: wmi: fix an error code in ath6kl_wmi_sync_point() bcma: Fix memory leak for internally-handled cores ipv4: make exception cache less predictible tty: Fix data race between tiocsti() and flush_to_ldisc() KVM: x86: Update vCPU's hv_clock before back to guest when tsc_offset is adjusted IMA: remove -Wmissing-prototypes warning clk: kirkwood: Fix a clocking boot regression fbmem: don't allow too huge resolutions rtc: tps65910: Correct driver module alias PCI/MSI: Skip masking MSI-X on Xen PV powerpc/perf/hv-gpci: Fix counter value parsing xen: fix setting of max_pfn in shared_info crypto: public_key: fix overflow during implicit conversion power: supply: max17042: handle fails of reading status register VMCI: fix NULL pointer dereference when unmapping queue pair media: uvc: don't do DMA on stack media: rc-loopback: return number of emitters rather than error libata: add ATA_HORKAGE_NO_NCQ_TRIM for Samsung 860 and 870 SSDs ARM: 9105/1: atags_to_fdt: don't warn about stack size PCI: Restrict ASMedia ASM1062 SATA Max Payload Size Supported PCI: Return ~0 data on pciconfig_read() CAP_SYS_ADMIN failure vfio: Use config not menuconfig for VFIO_NOIOMMU openrisc: don't printk() unconditionally pinctrl: single: Fix error return code in pcs_parse_bits_in_pinctrl_entry() MIPS: Malta: fix alignment of the devicetree buffer crypto: mxs-dcp - Use sg_mapping_iter to copy data PCI: Use pci_update_current_state() in pci_enable_device_flags() iio: dac: ad5624r: Fix incorrect handling of an optional regulator. video: fbdev: kyro: fix a DoS bug by restricting user input netlink: Deal with ESRCH error in nlmsg_notify() Smack: Fix wrong semantics in smk_access_entry() usb: host: fotg210: fix the endpoint's transactional opportunities calculation usb: host: fotg210: fix the actual_length of an iso packet usb: gadget: u_ether: fix a potential null pointer dereference usb: gadget: composite: Allow bMaxPower=0 if self-powered staging: board: Fix uninitialized spinlock when attaching genpd tty: serial: jsm: hold port lock when reporting modem line changes bpf/tests: Fix copy-and-paste error in double word test bpf/tests: Do not PASS tests without actually testing the result video: fbdev: asiliantfb: Error out if 'pixclock' equals zero video: fbdev: kyro: Error out if 'pixclock' equals zero video: fbdev: riva: Error out if 'pixclock' equals zero ipv4: ip_output.c: Fix out-of-bounds warning in ip_copy_addrs() flow_dissector: Fix out-of-bounds warnings s390/jump_label: print real address in a case of a jump label bug serial: 8250: Define RX trigger levels for OxSemi 950 devices xtensa: ISS: don't panic in rs_init hvsi: don't panic on tty_register_driver failure serial: 8250_pci: make setup_port() parameters explicitly unsigned staging: ks7010: Fix the initialization of the 'sleep_status' structure ata: sata_dwc_460ex: No need to call phy_exit() befre phy_init() Bluetooth: skip invalid hci_sync_conn_complete_evt ASoC: Intel: bytcr_rt5640: Move "Platform Clock" routes to the maps for the matching in-/output net: ethernet: stmmac: Do not use unreachable() in ipq806x_gmac_probe() Bluetooth: avoid circular locks in sco_sock_connect gpu: drm: amd: amdgpu: amdgpu_i2c: fix possible uninitialized-variable access in amdgpu_i2c_router_select_ddc_port() ARM: tegra: tamonten: Fix UART pad setting rpc: fix gss_svc_init cleanup on failure gfs2: Don't call dlm after protocol is unmounted mmc: rtsx_pci: Fix long reads when clock is prescaled cifs: fix wrong release in sess_alloc_buffer() failed path Revert "USB: xhci: fix U1/U2 handling for hardware with XHCI_INTEL_HOST quirk set" usbip: give back URBs for unsent unlink requests during cleanup parport: remove non-zero check on count ath9k: fix OOB read ar9300_eeprom_restore_internal ath9k: fix sleeping in atomic context net: fix NULL pointer reference in cipso_v4_doi_free net: w5100: check return value after calling platform_get_resource() parisc: fix crash with signals and alloca scsi: BusLogic: Fix missing pr_cont() use mm/hugetlb: initialize hugetlb_usage in mm_init memcg: enable accounting for pids in nested pid namespaces platform/chrome: cros_ec_proto: Send command again when timeout occurs xen: reset legacy rtc flag for PV domU bnx2x: Fix enabling network interfaces without VFs net-caif: avoid user-triggerable WARN_ON(1) ptp: dp83640: don't define PAGE0 dccp: don't duplicate ccid when cloning dccp sock net/l2tp: Fix reference count leak in l2tp_udp_recv_core r6040: Restore MDIO clock frequency after MAC reset tipc: increase timeout in tipc_sk_enqueue() events: Reuse value read using READ_ONCE instead of re-reading it net/af_unix: fix a data-race in unix_dgram_poll tcp: fix tp->undo_retrans accounting in tcp_sacktag_one() x86/mm: Fix kern_addr_valid() to cope with existing but not present entries dt-bindings: mtd: gpmc: Fix the ECC bytes vs. OOB bytes equation mfd: Don't use irq_create_mapping() to resolve a mapping net: usb: cdc_mbim: avoid altsetting toggling for Telit LN920 ethtool: Fix an error code in cxgb2.c PCI: Sync __pci_register_driver() stub for CONFIG_PCI=n mtd: rawnand: cafe: Fix a resource leak in the error handling path of 'cafe_nand_probe()' ARC: export clear_user_page() for modules net: dsa: b53: Fix calculating number of switch ports qlcnic: Remove redundant unlock in qlcnic_pinit_from_rom net: renesas: sh_eth: Fix freeing wrong tx descriptor s390/bpf: Fix 64-bit subtraction of the -0x80000000 constant Linux 4.9.283 Signed-off-by: Greg Kroah-Hartman <gregkh@google.com> Change-Id: I9e2017cce36805d71566ea1f265974a43bae33d1
2021-09-22 12:18:14 +02:00
unix_recvq_full_lockless(other) &&
unix_dgram_peer_wake_me(sk, other))
writable = 0;
unix_state_unlock(sk);
}
if (writable)
mask |= POLLOUT | POLLWRNORM | POLLWRBAND;
else
sk_set_bit(SOCKWQ_ASYNC_NOSPACE, sk);
return mask;
}
#ifdef CONFIG_PROC_FS
#define BUCKET_SPACE (BITS_PER_LONG - (UNIX_HASH_BITS + 1) - 1)
#define get_bucket(x) ((x) >> BUCKET_SPACE)
#define get_offset(x) ((x) & ((1L << BUCKET_SPACE) - 1))
#define set_bucket_offset(b, o) ((b) << BUCKET_SPACE | (o))
static struct sock *unix_from_bucket(struct seq_file *seq, loff_t *pos)
{
unsigned long offset = get_offset(*pos);
unsigned long bucket = get_bucket(*pos);
struct sock *sk;
unsigned long count = 0;
for (sk = sk_head(&unix_socket_table[bucket]); sk; sk = sk_next(sk)) {
if (sock_net(sk) != seq_file_net(seq))
continue;
if (++count == offset)
break;
}
return sk;
}
static struct sock *unix_next_socket(struct seq_file *seq,
struct sock *sk,
loff_t *pos)
{
unsigned long bucket;
while (sk > (struct sock *)SEQ_START_TOKEN) {
sk = sk_next(sk);
if (!sk)
goto next_bucket;
if (sock_net(sk) == seq_file_net(seq))
return sk;
}
do {
sk = unix_from_bucket(seq, pos);
if (sk)
return sk;
next_bucket:
bucket = get_bucket(*pos) + 1;
*pos = set_bucket_offset(bucket, 1);
} while (bucket < ARRAY_SIZE(unix_socket_table));
return NULL;
}
static void *unix_seq_start(struct seq_file *seq, loff_t *pos)
__acquires(unix_table_lock)
{
spin_lock(&unix_table_lock);
if (!*pos)
return SEQ_START_TOKEN;
if (get_bucket(*pos) >= ARRAY_SIZE(unix_socket_table))
return NULL;
return unix_next_socket(seq, NULL, pos);
}
static void *unix_seq_next(struct seq_file *seq, void *v, loff_t *pos)
{
++*pos;
return unix_next_socket(seq, v, pos);
}
static void unix_seq_stop(struct seq_file *seq, void *v)
__releases(unix_table_lock)
{
spin_unlock(&unix_table_lock);
}
static int unix_seq_show(struct seq_file *seq, void *v)
{
if (v == SEQ_START_TOKEN)
seq_puts(seq, "Num RefCount Protocol Flags Type St "
"Inode Path\n");
else {
struct sock *s = v;
struct unix_sock *u = unix_sk(s);
unix_state_lock(s);
seq_printf(seq, "%pK: %08X %08X %08X %04X %02X %5lu",
s,
atomic_read(&s->sk_refcnt),
0,
s->sk_state == TCP_LISTEN ? __SO_ACCEPTCON : 0,
s->sk_type,
s->sk_socket ?
(s->sk_state == TCP_ESTABLISHED ? SS_CONNECTED : SS_UNCONNECTED) :
(s->sk_state == TCP_ESTABLISHED ? SS_CONNECTING : SS_DISCONNECTING),
sock_i_ino(s));
Merge 4.9.164 into android-4.9 Changes in 4.9.164 ACPICA: Reference Counts: increase max to 0x4000 for large servers KEYS: restrict /proc/keys by credentials at open time l2tp: fix infoleak in l2tp_ip6_recvmsg() net: hsr: fix memory leak in hsr_dev_finalize() net/hsr: fix possible crash in add_timer() net: sit: fix UBSAN Undefined behaviour in check_6rd net/x25: fix use-after-free in x25_device_event() net/x25: reset state in x25_connect() pptp: dst_release sk_dst_cache in pptp_sock_destruct ravb: Decrease TxFIFO depth of Q3 and Q2 to one route: set the deleted fnhe fnhe_daddr to 0 in ip_del_fnhe to fix a race tcp: handle inet_csk_reqsk_queue_add() failures vxlan: test dev->flags & IFF_UP before calling gro_cells_receive() net/mlx4_core: Fix reset flow when in command polling mode net/mlx4_core: Fix locking in SRIOV mode when switching between events and polling net/mlx4_core: Fix qp mtt size calculation net/x25: fix a race in x25_bind() mdio_bus: Fix use-after-free on device_register fails net: Set rtm_table to RT_TABLE_COMPAT for ipv6 for tables > 255 missing barriers in some of unix_sock ->addr and ->path accesses ipvlan: disallow userns cap_net_admin to change global mode/flags vxlan: Fix GRO cells race condition between receive and link delete rxrpc: Fix client call queueing, waiting for channel gro_cells: make sure device is up in gro_cells_receive() tcp/dccp: remove reqsk_put() from inet_child_forget() perf/x86: Fixup typo in stub functions ALSA: bebob: use more identical mod_alias for Saffire Pro 10 I/O against Liquid Saffire 56 It's wrong to add len to sector_nr in raid10 reshape twice mmc: tmio_mmc_core: don't claim spurious interrupts of: Support const and non-const use for to_of_node() vhost/vsock: fix vhost vsock cid hashing inconsistent Linux 4.9.164 Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
2019-03-19 13:27:42 +01:00
if (u->addr) { // under unix_table_lock here
int i, len;
seq_putc(seq, ' ');
i = 0;
len = u->addr->len - sizeof(short);
if (!UNIX_ABSTRACT(s))
len--;
else {
seq_putc(seq, '@');
i++;
}
for ( ; i < len; i++)
seq_putc(seq, u->addr->name->sun_path[i] ?:
'@');
}
unix_state_unlock(s);
seq_putc(seq, '\n');
}
return 0;
}
static const struct seq_operations unix_seq_ops = {
.start = unix_seq_start,
.next = unix_seq_next,
.stop = unix_seq_stop,
.show = unix_seq_show,
};
static int unix_seq_open(struct inode *inode, struct file *file)
{
return seq_open_net(inode, file, &unix_seq_ops,
sizeof(struct seq_net_private));
}
static const struct file_operations unix_seq_fops = {
.owner = THIS_MODULE,
.open = unix_seq_open,
.read = seq_read,
.llseek = seq_lseek,
.release = seq_release_net,
};
#endif
static const struct net_proto_family unix_family_ops = {
.family = PF_UNIX,
.create = unix_create,
.owner = THIS_MODULE,
};
static int __net_init unix_net_init(struct net *net)
{
int error = -ENOMEM;
net->unx.sysctl_max_dgram_qlen = 10;
if (unix_sysctl_register(net))
goto out;
#ifdef CONFIG_PROC_FS
if (!proc_create("unix", 0, net->proc_net, &unix_seq_fops)) {
unix_sysctl_unregister(net);
goto out;
}
#endif
error = 0;
out:
return error;
}
static void __net_exit unix_net_exit(struct net *net)
{
unix_sysctl_unregister(net);
remove_proc_entry("unix", net->proc_net);
}
static struct pernet_operations unix_net_ops = {
.init = unix_net_init,
.exit = unix_net_exit,
};
static int __init af_unix_init(void)
{
int rc = -1;
BUILD_BUG_ON(sizeof(struct unix_skb_parms) > FIELD_SIZEOF(struct sk_buff, cb));
rc = proto_register(&unix_proto, 1);
if (rc != 0) {
pr_crit("%s: Cannot create unix_sock SLAB cache!\n", __func__);
goto out;
}
sock_register(&unix_family_ops);
register_pernet_subsys(&unix_net_ops);
out:
return rc;
}
static void __exit af_unix_exit(void)
{
sock_unregister(PF_UNIX);
proto_unregister(&unix_proto);
unregister_pernet_subsys(&unix_net_ops);
}
/* Earlier than device_initcall() so that other drivers invoking
request_module() don't end up in a loop when modprobe tries
to use a UNIX socket. But later than subsys_initcall() because
we depend on stuff initialised there */
fs_initcall(af_unix_init);
module_exit(af_unix_exit);
MODULE_LICENSE("GPL");
MODULE_ALIAS_NETPROTO(PF_UNIX);