mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-06 19:08:57 +09:00
Merge 4.9.25 into android-4.9
Changes in 4.9.25: KEYS: Disallow keyrings beginning with '.' to be joined as session keyrings KEYS: Change the name of the dead type to ".dead" to prevent user access KEYS: fix keyctl_set_reqkey_keyring() to not leak thread keyrings tracing: Allocate the snapshot buffer before enabling probe ring-buffer: Have ring_buffer_iter_empty() return true when empty mm: prevent NR_ISOLATE_* stats from going negative cifs: Do not send echoes before Negotiate is complete CIFS: remove bad_network_name flag s390/mm: fix CMMA vs KSM vs others Input: elantech - add Fujitsu Lifebook E547 to force crc_enabled ACPI / power: Avoid maybe-uninitialized warning mmc: sdhci-esdhc-imx: increase the pad I/O drive strength for DDR50 card ubifs: Fix RENAME_WHITEOUT support ubifs: Fix O_TMPFILE corner case in ubifs_link() mac80211: reject ToDS broadcast data frames mac80211: fix MU-MIMO follow-MAC mode ubi/upd: Always flush after prepared for an update powerpc/kprobe: Fix oops when kprobed on 'stdu' instruction x86/mce/AMD: Give a name to MCA bank 3 when accessed with legacy MSRs x86/mce: Make the MCE notifier a blocking one device-dax: switch to srcu, fix rcu_read_lock() vs pte allocation Linux 4.9.25 Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
This commit is contained in:
2
Makefile
2
Makefile
@@ -1,6 +1,6 @@
|
||||
VERSION = 4
|
||||
PATCHLEVEL = 9
|
||||
SUBLEVEL = 24
|
||||
SUBLEVEL = 25
|
||||
EXTRAVERSION =
|
||||
NAME = Roaring Lionus
|
||||
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
|
||||
|
||||
@@ -59,7 +59,7 @@ static const char * const th_names[] = {
|
||||
"load_store",
|
||||
"insn_fetch",
|
||||
"combined_unit",
|
||||
"",
|
||||
"decode_unit",
|
||||
"northbridge",
|
||||
"execution_unit",
|
||||
};
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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 (**)
|
||||
@@ -1523,6 +1524,13 @@ static const struct dmi_system_id elantech_dmi_force_crc_enabled[] = {
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK E544"),
|
||||
},
|
||||
},
|
||||
{
|
||||
/* 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 = {
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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 @@ tcon_exit:
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -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 @@ out_cancel:
|
||||
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.
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -6571,11 +6571,13 @@ ftrace_trace_snapshot_callback(struct ftrace_hash *hash,
|
||||
return ret;
|
||||
|
||||
out_reg:
|
||||
ret = alloc_snapshot(&global_trace);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
|
||||
ret = register_ftrace_function_probe(glob, ops, count);
|
||||
|
||||
if (ret >= 0)
|
||||
alloc_snapshot(&global_trace);
|
||||
|
||||
out:
|
||||
return ret < 0 ? ret : 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -46,7 +46,7 @@ static unsigned long key_gc_flags;
|
||||
* immediately unlinked.
|
||||
*/
|
||||
struct key_type key_type_dead = {
|
||||
.name = "dead",
|
||||
.name = ".dead",
|
||||
};
|
||||
|
||||
/*
|
||||
|
||||
@@ -271,7 +271,8 @@ error:
|
||||
* 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 @@ 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:
|
||||
|
||||
@@ -127,13 +127,18 @@ error:
|
||||
}
|
||||
|
||||
/*
|
||||
* 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)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user