From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from lists.gentoo.org (pigeon.gentoo.org [208.92.234.80]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by finch.gentoo.org (Postfix) with ESMTPS id C063C139694 for ; Thu, 27 Apr 2017 09:05:37 +0000 (UTC) Received: from pigeon.gentoo.org (localhost [127.0.0.1]) by pigeon.gentoo.org (Postfix) with SMTP id 8920BE085E; Thu, 27 Apr 2017 09:05:35 +0000 (UTC) Received: from smtp.gentoo.org (dev.gentoo.org [IPv6:2001:470:ea4a:1:5054:ff:fec7:86e4]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by pigeon.gentoo.org (Postfix) with ESMTPS id 4E7B4E085E for ; Thu, 27 Apr 2017 09:05:35 +0000 (UTC) Received: from oystercatcher.gentoo.org (unknown [IPv6:2a01:4f8:202:4333:225:90ff:fed9:fc84]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.gentoo.org (Postfix) with ESMTPS id B50023416A0 for ; Thu, 27 Apr 2017 09:05:33 +0000 (UTC) Received: from localhost.localdomain (localhost [IPv6:::1]) by oystercatcher.gentoo.org (Postfix) with ESMTP id 284887438 for ; Thu, 27 Apr 2017 09:05:32 +0000 (UTC) From: "Alice Ferrazzi" To: gentoo-commits@lists.gentoo.org Content-Transfer-Encoding: 8bit Content-type: text/plain; charset=UTF-8 Reply-To: gentoo-dev@lists.gentoo.org, "Alice Ferrazzi" Message-ID: <1493283875.4f4d1ac05d21ec33cf9aea7bfdabb1202fbea0c8.alicef@gentoo> Subject: [gentoo-commits] proj/linux-patches:4.9 commit in: / X-VCS-Repository: proj/linux-patches X-VCS-Files: 0000_README 1024_linux-4.9.25.patch X-VCS-Directories: / X-VCS-Committer: alicef X-VCS-Committer-Name: Alice Ferrazzi X-VCS-Revision: 4f4d1ac05d21ec33cf9aea7bfdabb1202fbea0c8 X-VCS-Branch: 4.9 Date: Thu, 27 Apr 2017 09:05:32 +0000 (UTC) Precedence: bulk List-Post: List-Help: List-Unsubscribe: List-Subscribe: List-Id: Gentoo Linux mail X-BeenThere: gentoo-commits@lists.gentoo.org X-Archives-Salt: 6f87f12c-5499-42e5-9a84-ea1a01b429c1 X-Archives-Hash: cc4f89b6b8bff279f1b928fa626b6985 commit: 4f4d1ac05d21ec33cf9aea7bfdabb1202fbea0c8 Author: Alice Ferrazzi gentoo org> AuthorDate: Thu Apr 27 09:04:35 2017 +0000 Commit: Alice Ferrazzi gentoo org> CommitDate: Thu Apr 27 09:04:35 2017 +0000 URL: https://gitweb.gentoo.org/proj/linux-patches.git/commit/?id=4f4d1ac0 Linux patch 4.9.25 0000_README | 4 + 1024_linux-4.9.25.patch | 754 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 758 insertions(+) diff --git a/0000_README b/0000_README index 83039dd..6d83bcd 100644 --- a/0000_README +++ b/0000_README @@ -139,6 +139,10 @@ Patch: 1023_linux-4.9.24.patch From: http://www.kernel.org Desc: Linux 4.9.24 +Patch: 1024_linux-4.9.25.patch +From: http://www.kernel.org +Desc: Linux 4.9.25 + Patch: 1500_XATTR_USER_PREFIX.patch From: https://bugs.gentoo.org/show_bug.cgi?id=470644 Desc: Support for namespace user.pax.* on tmpfs. diff --git a/1024_linux-4.9.25.patch b/1024_linux-4.9.25.patch new file mode 100644 index 0000000..33e6419 --- /dev/null +++ b/1024_linux-4.9.25.patch @@ -0,0 +1,754 @@ +diff --git a/Makefile b/Makefile +index 50436f502d81..8e18c63388c4 100644 +--- a/Makefile ++++ b/Makefile +@@ -1,6 +1,6 @@ + VERSION = 4 + PATCHLEVEL = 9 +-SUBLEVEL = 24 ++SUBLEVEL = 25 + EXTRAVERSION = + NAME = Roaring Lionus + +diff --git a/arch/powerpc/kernel/entry_64.S b/arch/powerpc/kernel/entry_64.S +index 6432d4bf08c8..767ef6d68c9e 100644 +--- a/arch/powerpc/kernel/entry_64.S ++++ b/arch/powerpc/kernel/entry_64.S +@@ -689,7 +689,7 @@ resume_kernel: + + addi r8,r1,INT_FRAME_SIZE /* Get the kprobed function entry */ + +- lwz r3,GPR1(r1) ++ ld r3,GPR1(r1) + subi r3,r3,INT_FRAME_SIZE /* dst: Allocate a trampoline exception frame */ + mr r4,r1 /* src: current exception frame */ + mr r1,r3 /* Reroute the trampoline frame to r1 */ +@@ -703,8 +703,8 @@ resume_kernel: + addi r6,r6,8 + bdnz 2b + +- /* Do real store operation to complete stwu */ +- lwz r5,GPR1(r1) ++ /* Do real store operation to complete stdu */ ++ ld r5,GPR1(r1) + std r8,0(r5) + + /* Clear _TIF_EMULATE_STACK_STORE flag */ +diff --git a/arch/s390/include/asm/pgtable.h b/arch/s390/include/asm/pgtable.h +index 0362cd5fa187..0cea7026e4ff 100644 +--- a/arch/s390/include/asm/pgtable.h ++++ b/arch/s390/include/asm/pgtable.h +@@ -1029,6 +1029,8 @@ int get_guest_storage_key(struct mm_struct *mm, unsigned long addr, + static inline void set_pte_at(struct mm_struct *mm, unsigned long addr, + pte_t *ptep, pte_t entry) + { ++ if (pte_present(entry)) ++ pte_val(entry) &= ~_PAGE_UNUSED; + if (mm_has_pgste(mm)) + ptep_set_pte_at(mm, addr, ptep, entry); + else +diff --git a/arch/x86/kernel/cpu/mcheck/mce-genpool.c b/arch/x86/kernel/cpu/mcheck/mce-genpool.c +index 93d824ec3120..040af1939460 100644 +--- a/arch/x86/kernel/cpu/mcheck/mce-genpool.c ++++ b/arch/x86/kernel/cpu/mcheck/mce-genpool.c +@@ -85,7 +85,7 @@ void mce_gen_pool_process(void) + head = llist_reverse_order(head); + llist_for_each_entry_safe(node, tmp, head, llnode) { + mce = &node->mce; +- atomic_notifier_call_chain(&x86_mce_decoder_chain, 0, mce); ++ blocking_notifier_call_chain(&x86_mce_decoder_chain, 0, mce); + gen_pool_free(mce_evt_pool, (unsigned long)node, sizeof(*node)); + } + } +diff --git a/arch/x86/kernel/cpu/mcheck/mce-internal.h b/arch/x86/kernel/cpu/mcheck/mce-internal.h +index cd74a3f00aea..de20902ecf23 100644 +--- a/arch/x86/kernel/cpu/mcheck/mce-internal.h ++++ b/arch/x86/kernel/cpu/mcheck/mce-internal.h +@@ -13,7 +13,7 @@ enum severity_level { + MCE_PANIC_SEVERITY, + }; + +-extern struct atomic_notifier_head x86_mce_decoder_chain; ++extern struct blocking_notifier_head x86_mce_decoder_chain; + + #define ATTR_LEN 16 + #define INITIAL_CHECK_INTERVAL 5 * 60 /* 5 minutes */ +diff --git a/arch/x86/kernel/cpu/mcheck/mce.c b/arch/x86/kernel/cpu/mcheck/mce.c +index a7fdf453d895..22cda29d654e 100644 +--- a/arch/x86/kernel/cpu/mcheck/mce.c ++++ b/arch/x86/kernel/cpu/mcheck/mce.c +@@ -120,7 +120,7 @@ static void (*quirk_no_way_out)(int bank, struct mce *m, struct pt_regs *regs); + * CPU/chipset specific EDAC code can register a notifier call here to print + * MCE errors in a human-readable form. + */ +-ATOMIC_NOTIFIER_HEAD(x86_mce_decoder_chain); ++BLOCKING_NOTIFIER_HEAD(x86_mce_decoder_chain); + + /* Do initial initialization of a struct mce */ + void mce_setup(struct mce *m) +@@ -213,13 +213,13 @@ void mce_register_decode_chain(struct notifier_block *nb) + if (nb != &mce_srao_nb && nb->priority == INT_MAX) + nb->priority -= 1; + +- atomic_notifier_chain_register(&x86_mce_decoder_chain, nb); ++ blocking_notifier_chain_register(&x86_mce_decoder_chain, nb); + } + EXPORT_SYMBOL_GPL(mce_register_decode_chain); + + void mce_unregister_decode_chain(struct notifier_block *nb) + { +- atomic_notifier_chain_unregister(&x86_mce_decoder_chain, nb); ++ blocking_notifier_chain_unregister(&x86_mce_decoder_chain, nb); + } + EXPORT_SYMBOL_GPL(mce_unregister_decode_chain); + +@@ -272,8 +272,6 @@ struct mca_msr_regs msr_ops = { + + static void print_mce(struct mce *m) + { +- int ret = 0; +- + pr_emerg(HW_ERR "CPU %d: Machine Check Exception: %Lx Bank %d: %016Lx\n", + m->extcpu, m->mcgstatus, m->bank, m->status); + +@@ -309,14 +307,6 @@ static void print_mce(struct mce *m) + m->cpuvendor, m->cpuid, m->time, m->socketid, m->apicid, + cpu_data(m->extcpu).microcode); + +- /* +- * Print out human-readable details about the MCE error, +- * (if the CPU has an implementation for that) +- */ +- ret = atomic_notifier_call_chain(&x86_mce_decoder_chain, 0, m); +- if (ret == NOTIFY_STOP) +- return; +- + pr_emerg_ratelimited(HW_ERR "Run the above through 'mcelog --ascii'\n"); + } + +diff --git a/arch/x86/kernel/cpu/mcheck/mce_amd.c b/arch/x86/kernel/cpu/mcheck/mce_amd.c +index 9b5403462936..3dfca7b302dc 100644 +--- a/arch/x86/kernel/cpu/mcheck/mce_amd.c ++++ b/arch/x86/kernel/cpu/mcheck/mce_amd.c +@@ -59,7 +59,7 @@ static const char * const th_names[] = { + "load_store", + "insn_fetch", + "combined_unit", +- "", ++ "decode_unit", + "northbridge", + "execution_unit", + }; +diff --git a/drivers/acpi/power.c b/drivers/acpi/power.c +index fcd4ce6f78d5..1c2b846c5776 100644 +--- a/drivers/acpi/power.c ++++ b/drivers/acpi/power.c +@@ -200,6 +200,7 @@ static int acpi_power_get_list_state(struct list_head *list, int *state) + return -EINVAL; + + /* The state of the list is 'on' IFF all resources are 'on'. */ ++ cur_state = 0; + list_for_each_entry(entry, list, node) { + struct acpi_power_resource *resource = entry->resource; + acpi_handle handle = resource->device.handle; +diff --git a/drivers/dax/Kconfig b/drivers/dax/Kconfig +index 3e2ab3b14eea..9e95bf94eb13 100644 +--- a/drivers/dax/Kconfig ++++ b/drivers/dax/Kconfig +@@ -2,6 +2,7 @@ menuconfig DEV_DAX + tristate "DAX: direct access to differentiated memory" + default m if NVDIMM_DAX + depends on TRANSPARENT_HUGEPAGE ++ select SRCU + help + Support raw access to differentiated (persistence, bandwidth, + latency...) memory via an mmap(2) capable character +diff --git a/drivers/dax/dax.c b/drivers/dax/dax.c +index 152552d2c306..193224889e41 100644 +--- a/drivers/dax/dax.c ++++ b/drivers/dax/dax.c +@@ -24,6 +24,7 @@ + #include "dax.h" + + static dev_t dax_devt; ++DEFINE_STATIC_SRCU(dax_srcu); + static struct class *dax_class; + static DEFINE_IDA(dax_minor_ida); + static int nr_dax = CONFIG_NR_DEV_DAX; +@@ -59,7 +60,7 @@ struct dax_region { + * @region - parent region + * @dev - device backing the character device + * @cdev - core chardev data +- * @alive - !alive + rcu grace period == no new mappings can be established ++ * @alive - !alive + srcu grace period == no new mappings can be established + * @id - child id in the region + * @num_resources - number of physical address extents in this device + * @res - array of physical address ranges +@@ -437,7 +438,7 @@ static int __dax_dev_pmd_fault(struct dax_dev *dax_dev, + static int dax_dev_pmd_fault(struct vm_area_struct *vma, unsigned long addr, + pmd_t *pmd, unsigned int flags) + { +- int rc; ++ int rc, id; + struct file *filp = vma->vm_file; + struct dax_dev *dax_dev = filp->private_data; + +@@ -445,9 +446,9 @@ static int dax_dev_pmd_fault(struct vm_area_struct *vma, unsigned long addr, + current->comm, (flags & FAULT_FLAG_WRITE) + ? "write" : "read", vma->vm_start, vma->vm_end); + +- rcu_read_lock(); ++ id = srcu_read_lock(&dax_srcu); + rc = __dax_dev_pmd_fault(dax_dev, vma, addr, pmd, flags); +- rcu_read_unlock(); ++ srcu_read_unlock(&dax_srcu, id); + + return rc; + } +@@ -563,11 +564,11 @@ static void unregister_dax_dev(void *dev) + * Note, rcu is not protecting the liveness of dax_dev, rcu is + * ensuring that any fault handlers that might have seen + * dax_dev->alive == true, have completed. Any fault handlers +- * that start after synchronize_rcu() has started will abort ++ * that start after synchronize_srcu() has started will abort + * upon seeing dax_dev->alive == false. + */ + dax_dev->alive = false; +- synchronize_rcu(); ++ synchronize_srcu(&dax_srcu); + unmap_mapping_range(dax_dev->inode->i_mapping, 0, 0, 1); + cdev_del(cdev); + device_unregister(dev); +diff --git a/drivers/input/mouse/elantech.c b/drivers/input/mouse/elantech.c +index db7d1d666ac1..7826994c45bf 100644 +--- a/drivers/input/mouse/elantech.c ++++ b/drivers/input/mouse/elantech.c +@@ -1118,6 +1118,7 @@ static int elantech_get_resolution_v4(struct psmouse *psmouse, + * Asus UX32VD 0x361f02 00, 15, 0e clickpad + * Avatar AVIU-145A2 0x361f00 ? clickpad + * Fujitsu LIFEBOOK E544 0x470f00 d0, 12, 09 2 hw buttons ++ * Fujitsu LIFEBOOK E547 0x470f00 50, 12, 09 2 hw buttons + * Fujitsu LIFEBOOK E554 0x570f01 40, 14, 0c 2 hw buttons + * Fujitsu T725 0x470f01 05, 12, 09 2 hw buttons + * Fujitsu H730 0x570f00 c0, 14, 0c 3 hw buttons (**) +@@ -1524,6 +1525,13 @@ static const struct dmi_system_id elantech_dmi_force_crc_enabled[] = { + }, + }, + { ++ /* Fujitsu LIFEBOOK E547 does not work with crc_enabled == 0 */ ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"), ++ DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK E547"), ++ }, ++ }, ++ { + /* Fujitsu LIFEBOOK E554 does not work with crc_enabled == 0 */ + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"), +diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c +index 7123ef96ed18..445fc47dc3e7 100644 +--- a/drivers/mmc/host/sdhci-esdhc-imx.c ++++ b/drivers/mmc/host/sdhci-esdhc-imx.c +@@ -830,6 +830,7 @@ static int esdhc_change_pinstate(struct sdhci_host *host, + + switch (uhs) { + case MMC_TIMING_UHS_SDR50: ++ case MMC_TIMING_UHS_DDR50: + pinctrl = imx_data->pins_100mhz; + break; + case MMC_TIMING_UHS_SDR104: +diff --git a/drivers/mtd/ubi/upd.c b/drivers/mtd/ubi/upd.c +index 0134ba32a057..39712560b4c1 100644 +--- a/drivers/mtd/ubi/upd.c ++++ b/drivers/mtd/ubi/upd.c +@@ -148,11 +148,11 @@ int ubi_start_update(struct ubi_device *ubi, struct ubi_volume *vol, + return err; + } + +- if (bytes == 0) { +- err = ubi_wl_flush(ubi, UBI_ALL, UBI_ALL); +- if (err) +- return err; ++ err = ubi_wl_flush(ubi, UBI_ALL, UBI_ALL); ++ if (err) ++ return err; + ++ if (bytes == 0) { + err = clear_update_marker(ubi, vol, 0); + if (err) + return err; +diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h +index 203287f86525..94661cf77ae8 100644 +--- a/fs/cifs/cifsglob.h ++++ b/fs/cifs/cifsglob.h +@@ -930,7 +930,6 @@ struct cifs_tcon { + bool use_persistent:1; /* use persistent instead of durable handles */ + #ifdef CONFIG_CIFS_SMB2 + bool print:1; /* set if connection to printer share */ +- bool bad_network_name:1; /* set if ret status STATUS_BAD_NETWORK_NAME */ + __le32 capabilities; + __u32 share_flags; + __u32 maximal_access; +diff --git a/fs/cifs/smb1ops.c b/fs/cifs/smb1ops.c +index fc537c29044e..87b87e091e8e 100644 +--- a/fs/cifs/smb1ops.c ++++ b/fs/cifs/smb1ops.c +@@ -1015,6 +1015,15 @@ cifs_dir_needs_close(struct cifsFileInfo *cfile) + return !cfile->srch_inf.endOfSearch && !cfile->invalidHandle; + } + ++static bool ++cifs_can_echo(struct TCP_Server_Info *server) ++{ ++ if (server->tcpStatus == CifsGood) ++ return true; ++ ++ return false; ++} ++ + struct smb_version_operations smb1_operations = { + .send_cancel = send_nt_cancel, + .compare_fids = cifs_compare_fids, +@@ -1049,6 +1058,7 @@ struct smb_version_operations smb1_operations = { + .get_dfs_refer = CIFSGetDFSRefer, + .qfs_tcon = cifs_qfs_tcon, + .is_path_accessible = cifs_is_path_accessible, ++ .can_echo = cifs_can_echo, + .query_path_info = cifs_query_path_info, + .query_file_info = cifs_query_file_info, + .get_srv_inum = cifs_get_srv_inum, +diff --git a/fs/cifs/smb2pdu.c b/fs/cifs/smb2pdu.c +index 7080dac3592c..802185386851 100644 +--- a/fs/cifs/smb2pdu.c ++++ b/fs/cifs/smb2pdu.c +@@ -1084,9 +1084,6 @@ SMB2_tcon(const unsigned int xid, struct cifs_ses *ses, const char *tree, + else + return -EIO; + +- if (tcon && tcon->bad_network_name) +- return -ENOENT; +- + if ((tcon && tcon->seal) && + ((ses->server->capabilities & SMB2_GLOBAL_CAP_ENCRYPTION) == 0)) { + cifs_dbg(VFS, "encryption requested but no server support"); +@@ -1188,8 +1185,6 @@ SMB2_tcon(const unsigned int xid, struct cifs_ses *ses, const char *tree, + tcon_error_exit: + if (rsp->hdr.Status == STATUS_BAD_NETWORK_NAME) { + cifs_dbg(VFS, "BAD_NETWORK_NAME: %s\n", tree); +- if (tcon) +- tcon->bad_network_name = true; + } + goto tcon_exit; + } +diff --git a/fs/ubifs/dir.c b/fs/ubifs/dir.c +index ca16c5d7bab1..87ab02e2d666 100644 +--- a/fs/ubifs/dir.c ++++ b/fs/ubifs/dir.c +@@ -622,6 +622,11 @@ static int ubifs_link(struct dentry *old_dentry, struct inode *dir, + return err; + + lock_2_inodes(dir, inode); ++ ++ /* Handle O_TMPFILE corner case, it is allowed to link a O_TMPFILE. */ ++ if (inode->i_nlink == 0) ++ ubifs_delete_orphan(c, inode->i_ino); ++ + inc_nlink(inode); + ihold(inode); + inode->i_ctime = ubifs_current_time(inode); +@@ -641,6 +646,8 @@ static int ubifs_link(struct dentry *old_dentry, struct inode *dir, + dir->i_size -= sz_change; + dir_ui->ui_size = dir->i_size; + drop_nlink(inode); ++ if (inode->i_nlink == 0) ++ ubifs_add_orphan(c, inode->i_ino); + unlock_2_inodes(dir, inode); + ubifs_release_budget(c, &req); + iput(inode); +@@ -1088,9 +1095,6 @@ static int do_rename(struct inode *old_dir, struct dentry *old_dentry, + struct timespec time; + unsigned int uninitialized_var(saved_nlink); + +- if (flags & ~RENAME_NOREPLACE) +- return -EINVAL; +- + /* + * Budget request settings: deletion direntry, new direntry, removing + * the old inode, and changing old and new parent directory inodes. +diff --git a/kernel/trace/ring_buffer.c b/kernel/trace/ring_buffer.c +index f30847af7310..f5c016e8fc88 100644 +--- a/kernel/trace/ring_buffer.c ++++ b/kernel/trace/ring_buffer.c +@@ -3435,11 +3435,23 @@ EXPORT_SYMBOL_GPL(ring_buffer_iter_reset); + int ring_buffer_iter_empty(struct ring_buffer_iter *iter) + { + struct ring_buffer_per_cpu *cpu_buffer; ++ struct buffer_page *reader; ++ struct buffer_page *head_page; ++ struct buffer_page *commit_page; ++ unsigned commit; + + cpu_buffer = iter->cpu_buffer; + +- return iter->head_page == cpu_buffer->commit_page && +- iter->head == rb_commit_index(cpu_buffer); ++ /* Remember, trace recording is off when iterator is in use */ ++ reader = cpu_buffer->reader_page; ++ head_page = cpu_buffer->head_page; ++ commit_page = cpu_buffer->commit_page; ++ commit = rb_page_commit(commit_page); ++ ++ return ((iter->head_page == commit_page && iter->head == commit) || ++ (iter->head_page == reader && commit_page == head_page && ++ head_page->read == commit && ++ iter->head == rb_page_commit(cpu_buffer->reader_page))); + } + EXPORT_SYMBOL_GPL(ring_buffer_iter_empty); + +diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c +index 862bc8805d97..83c60f9013cb 100644 +--- a/kernel/trace/trace.c ++++ b/kernel/trace/trace.c +@@ -6481,11 +6481,13 @@ ftrace_trace_snapshot_callback(struct ftrace_hash *hash, + return ret; + + out_reg: +- ret = register_ftrace_function_probe(glob, ops, count); ++ ret = alloc_snapshot(&global_trace); ++ if (ret < 0) ++ goto out; + +- if (ret >= 0) +- alloc_snapshot(&global_trace); ++ ret = register_ftrace_function_probe(glob, ops, count); + ++ out: + return ret < 0 ? ret : 0; + } + +diff --git a/mm/migrate.c b/mm/migrate.c +index 66ce6b490b13..6850f62998cd 100644 +--- a/mm/migrate.c ++++ b/mm/migrate.c +@@ -183,9 +183,9 @@ void putback_movable_pages(struct list_head *l) + unlock_page(page); + put_page(page); + } else { +- putback_lru_page(page); + dec_node_page_state(page, NR_ISOLATED_ANON + + page_is_file_cache(page)); ++ putback_lru_page(page); + } + } + } +diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c +index a697ddf56334..acaaf616da71 100644 +--- a/net/mac80211/rx.c ++++ b/net/mac80211/rx.c +@@ -208,6 +208,51 @@ ieee80211_rx_radiotap_hdrlen(struct ieee80211_local *local, + return len; + } + ++static void ieee80211_handle_mu_mimo_mon(struct ieee80211_sub_if_data *sdata, ++ struct sk_buff *skb, ++ int rtap_vendor_space) ++{ ++ struct { ++ struct ieee80211_hdr_3addr hdr; ++ u8 category; ++ u8 action_code; ++ } __packed action; ++ ++ if (!sdata) ++ return; ++ ++ BUILD_BUG_ON(sizeof(action) != IEEE80211_MIN_ACTION_SIZE + 1); ++ ++ if (skb->len < rtap_vendor_space + sizeof(action) + ++ VHT_MUMIMO_GROUPS_DATA_LEN) ++ return; ++ ++ if (!is_valid_ether_addr(sdata->u.mntr.mu_follow_addr)) ++ return; ++ ++ skb_copy_bits(skb, rtap_vendor_space, &action, sizeof(action)); ++ ++ if (!ieee80211_is_action(action.hdr.frame_control)) ++ return; ++ ++ if (action.category != WLAN_CATEGORY_VHT) ++ return; ++ ++ if (action.action_code != WLAN_VHT_ACTION_GROUPID_MGMT) ++ return; ++ ++ if (!ether_addr_equal(action.hdr.addr1, sdata->u.mntr.mu_follow_addr)) ++ return; ++ ++ skb = skb_copy(skb, GFP_ATOMIC); ++ if (!skb) ++ return; ++ ++ skb->pkt_type = IEEE80211_SDATA_QUEUE_TYPE_FRAME; ++ skb_queue_tail(&sdata->skb_queue, skb); ++ ieee80211_queue_work(&sdata->local->hw, &sdata->work); ++} ++ + /* + * ieee80211_add_rx_radiotap_header - add radiotap header + * +@@ -515,7 +560,6 @@ ieee80211_rx_monitor(struct ieee80211_local *local, struct sk_buff *origskb, + struct net_device *prev_dev = NULL; + int present_fcs_len = 0; + unsigned int rtap_vendor_space = 0; +- struct ieee80211_mgmt *mgmt; + struct ieee80211_sub_if_data *monitor_sdata = + rcu_dereference(local->monitor_sdata); + +@@ -553,6 +597,8 @@ ieee80211_rx_monitor(struct ieee80211_local *local, struct sk_buff *origskb, + return remove_monitor_info(local, origskb, rtap_vendor_space); + } + ++ ieee80211_handle_mu_mimo_mon(monitor_sdata, origskb, rtap_vendor_space); ++ + /* room for the radiotap header based on driver features */ + rt_hdrlen = ieee80211_rx_radiotap_hdrlen(local, status, origskb); + needed_headroom = rt_hdrlen - rtap_vendor_space; +@@ -618,23 +664,6 @@ ieee80211_rx_monitor(struct ieee80211_local *local, struct sk_buff *origskb, + ieee80211_rx_stats(sdata->dev, skb->len); + } + +- mgmt = (void *)skb->data; +- if (monitor_sdata && +- skb->len >= IEEE80211_MIN_ACTION_SIZE + 1 + VHT_MUMIMO_GROUPS_DATA_LEN && +- ieee80211_is_action(mgmt->frame_control) && +- mgmt->u.action.category == WLAN_CATEGORY_VHT && +- mgmt->u.action.u.vht_group_notif.action_code == WLAN_VHT_ACTION_GROUPID_MGMT && +- is_valid_ether_addr(monitor_sdata->u.mntr.mu_follow_addr) && +- ether_addr_equal(mgmt->da, monitor_sdata->u.mntr.mu_follow_addr)) { +- struct sk_buff *mu_skb = skb_copy(skb, GFP_ATOMIC); +- +- if (mu_skb) { +- mu_skb->pkt_type = IEEE80211_SDATA_QUEUE_TYPE_FRAME; +- skb_queue_tail(&monitor_sdata->skb_queue, mu_skb); +- ieee80211_queue_work(&local->hw, &monitor_sdata->work); +- } +- } +- + if (prev_dev) { + skb->dev = prev_dev; + netif_receive_skb(skb); +@@ -3617,6 +3646,27 @@ static bool ieee80211_accept_frame(struct ieee80211_rx_data *rx) + !ether_addr_equal(bssid, hdr->addr1)) + return false; + } ++ ++ /* ++ * 802.11-2016 Table 9-26 says that for data frames, A1 must be ++ * the BSSID - we've checked that already but may have accepted ++ * the wildcard (ff:ff:ff:ff:ff:ff). ++ * ++ * It also says: ++ * The BSSID of the Data frame is determined as follows: ++ * a) If the STA is contained within an AP or is associated ++ * with an AP, the BSSID is the address currently in use ++ * by the STA contained in the AP. ++ * ++ * So we should not accept data frames with an address that's ++ * multicast. ++ * ++ * Accepting it also opens a security problem because stations ++ * could encrypt it with the GTK and inject traffic that way. ++ */ ++ if (ieee80211_is_data(hdr->frame_control) && multicast) ++ return false; ++ + return true; + case NL80211_IFTYPE_WDS: + if (bssid || !ieee80211_is_data(hdr->frame_control)) +diff --git a/security/keys/gc.c b/security/keys/gc.c +index addf060399e0..9cb4fe4478a1 100644 +--- a/security/keys/gc.c ++++ b/security/keys/gc.c +@@ -46,7 +46,7 @@ static unsigned long key_gc_flags; + * immediately unlinked. + */ + struct key_type key_type_dead = { +- .name = "dead", ++ .name = ".dead", + }; + + /* +diff --git a/security/keys/keyctl.c b/security/keys/keyctl.c +index d580ad06b792..dbbfd7735ce5 100644 +--- a/security/keys/keyctl.c ++++ b/security/keys/keyctl.c +@@ -271,7 +271,8 @@ long keyctl_get_keyring_ID(key_serial_t id, int create) + * Create and join an anonymous session keyring or join a named session + * keyring, creating it if necessary. A named session keyring must have Search + * permission for it to be joined. Session keyrings without this permit will +- * be skipped over. ++ * be skipped over. It is not permitted for userspace to create or join ++ * keyrings whose name begin with a dot. + * + * If successful, the ID of the joined session keyring will be returned. + */ +@@ -288,12 +289,16 @@ long keyctl_join_session_keyring(const char __user *_name) + ret = PTR_ERR(name); + goto error; + } ++ ++ ret = -EPERM; ++ if (name[0] == '.') ++ goto error_name; + } + + /* join the session */ + ret = join_session_keyring(name); ++error_name: + kfree(name); +- + error: + return ret; + } +@@ -1251,8 +1256,8 @@ long keyctl_reject_key(key_serial_t id, unsigned timeout, unsigned error, + * Read or set the default keyring in which request_key() will cache keys and + * return the old setting. + * +- * If a process keyring is specified then this will be created if it doesn't +- * yet exist. The old setting will be returned if successful. ++ * If a thread or process keyring is specified then it will be created if it ++ * doesn't yet exist. The old setting will be returned if successful. + */ + long keyctl_set_reqkey_keyring(int reqkey_defl) + { +@@ -1277,11 +1282,8 @@ long keyctl_set_reqkey_keyring(int reqkey_defl) + + case KEY_REQKEY_DEFL_PROCESS_KEYRING: + ret = install_process_keyring_to_cred(new); +- if (ret < 0) { +- if (ret != -EEXIST) +- goto error; +- ret = 0; +- } ++ if (ret < 0) ++ goto error; + goto set; + + case KEY_REQKEY_DEFL_DEFAULT: +diff --git a/security/keys/process_keys.c b/security/keys/process_keys.c +index 40a885239782..45536c677b05 100644 +--- a/security/keys/process_keys.c ++++ b/security/keys/process_keys.c +@@ -127,13 +127,18 @@ int install_user_keyrings(void) + } + + /* +- * Install a fresh thread keyring directly to new credentials. This keyring is +- * allowed to overrun the quota. ++ * Install a thread keyring to the given credentials struct if it didn't have ++ * one already. This is allowed to overrun the quota. ++ * ++ * Return: 0 if a thread keyring is now present; -errno on failure. + */ + int install_thread_keyring_to_cred(struct cred *new) + { + struct key *keyring; + ++ if (new->thread_keyring) ++ return 0; ++ + keyring = keyring_alloc("_tid", new->uid, new->gid, new, + KEY_POS_ALL | KEY_USR_VIEW, + KEY_ALLOC_QUOTA_OVERRUN, +@@ -146,7 +151,9 @@ int install_thread_keyring_to_cred(struct cred *new) + } + + /* +- * Install a fresh thread keyring, discarding the old one. ++ * Install a thread keyring to the current task if it didn't have one already. ++ * ++ * Return: 0 if a thread keyring is now present; -errno on failure. + */ + static int install_thread_keyring(void) + { +@@ -157,8 +164,6 @@ static int install_thread_keyring(void) + if (!new) + return -ENOMEM; + +- BUG_ON(new->thread_keyring); +- + ret = install_thread_keyring_to_cred(new); + if (ret < 0) { + abort_creds(new); +@@ -169,17 +174,17 @@ static int install_thread_keyring(void) + } + + /* +- * Install a process keyring directly to a credentials struct. ++ * Install a process keyring to the given credentials struct if it didn't have ++ * one already. This is allowed to overrun the quota. + * +- * Returns -EEXIST if there was already a process keyring, 0 if one installed, +- * and other value on any other error ++ * Return: 0 if a process keyring is now present; -errno on failure. + */ + int install_process_keyring_to_cred(struct cred *new) + { + struct key *keyring; + + if (new->process_keyring) +- return -EEXIST; ++ return 0; + + keyring = keyring_alloc("_pid", new->uid, new->gid, new, + KEY_POS_ALL | KEY_USR_VIEW, +@@ -193,11 +198,9 @@ int install_process_keyring_to_cred(struct cred *new) + } + + /* +- * Make sure a process keyring is installed for the current process. The +- * existing process keyring is not replaced. ++ * Install a process keyring to the current task if it didn't have one already. + * +- * Returns 0 if there is a process keyring by the end of this function, some +- * error otherwise. ++ * Return: 0 if a process keyring is now present; -errno on failure. + */ + static int install_process_keyring(void) + { +@@ -211,14 +214,18 @@ static int install_process_keyring(void) + ret = install_process_keyring_to_cred(new); + if (ret < 0) { + abort_creds(new); +- return ret != -EEXIST ? ret : 0; ++ return ret; + } + + return commit_creds(new); + } + + /* +- * Install a session keyring directly to a credentials struct. ++ * Install the given keyring as the session keyring of the given credentials ++ * struct, replacing the existing one if any. If the given keyring is NULL, ++ * then install a new anonymous session keyring. ++ * ++ * Return: 0 on success; -errno on failure. + */ + int install_session_keyring_to_cred(struct cred *cred, struct key *keyring) + { +@@ -253,8 +260,11 @@ int install_session_keyring_to_cred(struct cred *cred, struct key *keyring) + } + + /* +- * Install a session keyring, discarding the old one. If a keyring is not +- * supplied, an empty one is invented. ++ * Install the given keyring as the session keyring of the current task, ++ * replacing the existing one if any. If the given keyring is NULL, then ++ * install a new anonymous session keyring. ++ * ++ * Return: 0 on success; -errno on failure. + */ + static int install_session_keyring(struct key *keyring) + {