--- /dev/null
+From 36960e440ccf94349c09fb944930d3bfe4bc473f Mon Sep 17 00:00:00 2001
+From: Jeff Layton <jlayton@redhat.com>
+Date: Sat, 3 Nov 2012 09:37:28 -0400
+Subject: cifs: fix potential buffer overrun in cifs.idmap handling code
+
+From: Jeff Layton <jlayton@redhat.com>
+
+commit 36960e440ccf94349c09fb944930d3bfe4bc473f upstream.
+
+The userspace cifs.idmap program generally works with the wbclient libs
+to generate binary SIDs in userspace. That program defines the struct
+that holds these values as having a max of 15 subauthorities. The kernel
+idmapping code however limits that value to 5.
+
+When the kernel copies those values around though, it doesn't sanity
+check the num_subauths value handed back from userspace or from the
+server. It's possible therefore for userspace to hand us back a bogus
+num_subauths value (or one that's valid, but greater than 5) that could
+cause the kernel to walk off the end of the cifs_sid->sub_auths array.
+
+Fix this by defining a new routine for copying sids and using that in
+all of the places that copy it. If we end up with a sid that's longer
+than expected then this approach will just lop off the "extra" subauths,
+but that's basically what the code does today already. Better approaches
+might be to fix this code to reject SIDs with >5 subauths, or fix it
+to handle the subauths array dynamically.
+
+At the same time, change the kernel to check the length of the data
+returned by userspace. If it's shorter than struct cifs_sid, reject it
+and return -EIO. If that happens we'll end up with fields that are
+basically uninitialized.
+
+Long term, it might make sense to redefine cifs_sid using a flexarray at
+the end, to allow for variable-length subauth lists, and teach the code
+to handle the case where the subauths array being passed in from
+userspace is shorter than 5 elements.
+
+Note too, that I don't consider this a security issue since you'd need
+a compromised cifs.idmap program. If you have that, you can do all sorts
+of nefarious stuff. Still, this is probably reasonable for stable.
+
+Reviewed-by: Shirish Pargaonkar <shirishpargaonkar@gmail.com>
+Signed-off-by: Jeff Layton <jlayton@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/cifs/cifsacl.c | 49 ++++++++++++++++++++-----------------------------
+ 1 file changed, 20 insertions(+), 29 deletions(-)
+
+--- a/fs/cifs/cifsacl.c
++++ b/fs/cifs/cifsacl.c
+@@ -225,6 +225,13 @@ sid_to_str(struct cifs_sid *sidptr, char
+ }
+
+ static void
++cifs_copy_sid(struct cifs_sid *dst, const struct cifs_sid *src)
++{
++ memcpy(dst, src, sizeof(*dst));
++ dst->num_subauth = min_t(u8, src->num_subauth, NUM_SUBAUTHS);
++}
++
++static void
+ id_rb_insert(struct rb_root *root, struct cifs_sid *sidptr,
+ struct cifs_sid_id **psidid, char *typestr)
+ {
+@@ -248,7 +255,7 @@ id_rb_insert(struct rb_root *root, struc
+ }
+ }
+
+- memcpy(&(*psidid)->sid, sidptr, sizeof(struct cifs_sid));
++ cifs_copy_sid(&(*psidid)->sid, sidptr);
+ (*psidid)->time = jiffies - (SID_MAP_RETRY + 1);
+ (*psidid)->refcount = 0;
+
+@@ -354,7 +361,7 @@ id_to_sid(unsigned long cid, uint sidtyp
+ * any fields of the node after a reference is put .
+ */
+ if (test_bit(SID_ID_MAPPED, &psidid->state)) {
+- memcpy(ssid, &psidid->sid, sizeof(struct cifs_sid));
++ cifs_copy_sid(ssid, &psidid->sid);
+ psidid->time = jiffies; /* update ts for accessing */
+ goto id_sid_out;
+ }
+@@ -370,14 +377,14 @@ id_to_sid(unsigned long cid, uint sidtyp
+ if (IS_ERR(sidkey)) {
+ rc = -EINVAL;
+ cFYI(1, "%s: Can't map and id to a SID", __func__);
++ } else if (sidkey->datalen < sizeof(struct cifs_sid)) {
++ rc = -EIO;
++ cFYI(1, "%s: Downcall contained malformed key "
++ "(datalen=%hu)", __func__, sidkey->datalen);
+ } else {
+ lsid = (struct cifs_sid *)sidkey->payload.data;
+- memcpy(&psidid->sid, lsid,
+- sidkey->datalen < sizeof(struct cifs_sid) ?
+- sidkey->datalen : sizeof(struct cifs_sid));
+- memcpy(ssid, &psidid->sid,
+- sidkey->datalen < sizeof(struct cifs_sid) ?
+- sidkey->datalen : sizeof(struct cifs_sid));
++ cifs_copy_sid(&psidid->sid, lsid);
++ cifs_copy_sid(ssid, &psidid->sid);
+ set_bit(SID_ID_MAPPED, &psidid->state);
+ key_put(sidkey);
+ kfree(psidid->sidstr);
+@@ -396,7 +403,7 @@ id_to_sid(unsigned long cid, uint sidtyp
+ return rc;
+ }
+ if (test_bit(SID_ID_MAPPED, &psidid->state))
+- memcpy(ssid, &psidid->sid, sizeof(struct cifs_sid));
++ cifs_copy_sid(ssid, &psidid->sid);
+ else
+ rc = -EINVAL;
+ }
+@@ -675,8 +682,6 @@ int compare_sids(const struct cifs_sid *
+ static void copy_sec_desc(const struct cifs_ntsd *pntsd,
+ struct cifs_ntsd *pnntsd, __u32 sidsoffset)
+ {
+- int i;
+-
+ struct cifs_sid *owner_sid_ptr, *group_sid_ptr;
+ struct cifs_sid *nowner_sid_ptr, *ngroup_sid_ptr;
+
+@@ -692,26 +697,14 @@ static void copy_sec_desc(const struct c
+ owner_sid_ptr = (struct cifs_sid *)((char *)pntsd +
+ le32_to_cpu(pntsd->osidoffset));
+ nowner_sid_ptr = (struct cifs_sid *)((char *)pnntsd + sidsoffset);
+-
+- nowner_sid_ptr->revision = owner_sid_ptr->revision;
+- nowner_sid_ptr->num_subauth = owner_sid_ptr->num_subauth;
+- for (i = 0; i < 6; i++)
+- nowner_sid_ptr->authority[i] = owner_sid_ptr->authority[i];
+- for (i = 0; i < 5; i++)
+- nowner_sid_ptr->sub_auth[i] = owner_sid_ptr->sub_auth[i];
++ cifs_copy_sid(nowner_sid_ptr, owner_sid_ptr);
+
+ /* copy group sid */
+ group_sid_ptr = (struct cifs_sid *)((char *)pntsd +
+ le32_to_cpu(pntsd->gsidoffset));
+ ngroup_sid_ptr = (struct cifs_sid *)((char *)pnntsd + sidsoffset +
+ sizeof(struct cifs_sid));
+-
+- ngroup_sid_ptr->revision = group_sid_ptr->revision;
+- ngroup_sid_ptr->num_subauth = group_sid_ptr->num_subauth;
+- for (i = 0; i < 6; i++)
+- ngroup_sid_ptr->authority[i] = group_sid_ptr->authority[i];
+- for (i = 0; i < 5; i++)
+- ngroup_sid_ptr->sub_auth[i] = group_sid_ptr->sub_auth[i];
++ cifs_copy_sid(ngroup_sid_ptr, group_sid_ptr);
+
+ return;
+ }
+@@ -1120,8 +1113,7 @@ static int build_sec_desc(struct cifs_nt
+ kfree(nowner_sid_ptr);
+ return rc;
+ }
+- memcpy(owner_sid_ptr, nowner_sid_ptr,
+- sizeof(struct cifs_sid));
++ cifs_copy_sid(owner_sid_ptr, nowner_sid_ptr);
+ kfree(nowner_sid_ptr);
+ *aclflag = CIFS_ACL_OWNER;
+ }
+@@ -1139,8 +1131,7 @@ static int build_sec_desc(struct cifs_nt
+ kfree(ngroup_sid_ptr);
+ return rc;
+ }
+- memcpy(group_sid_ptr, ngroup_sid_ptr,
+- sizeof(struct cifs_sid));
++ cifs_copy_sid(group_sid_ptr, ngroup_sid_ptr);
+ kfree(ngroup_sid_ptr);
+ *aclflag = CIFS_ACL_GROUP;
+ }
--- /dev/null
+From 9efade1b3e981f5064f9db9ca971b4dc7557ae42 Mon Sep 17 00:00:00 2001
+From: Jussi Kivilinna <jussi.kivilinna@mbnet.fi>
+Date: Sun, 21 Oct 2012 20:42:28 +0300
+Subject: crypto: cryptd - disable softirqs in cryptd_queue_worker to prevent data corruption
+
+From: Jussi Kivilinna <jussi.kivilinna@mbnet.fi>
+
+commit 9efade1b3e981f5064f9db9ca971b4dc7557ae42 upstream.
+
+cryptd_queue_worker attempts to prevent simultaneous accesses to crypto
+workqueue by cryptd_enqueue_request using preempt_disable/preempt_enable.
+However cryptd_enqueue_request might be called from softirq context,
+so add local_bh_disable/local_bh_enable to prevent data corruption and
+panics.
+
+Bug report at http://marc.info/?l=linux-crypto-vger&m=134858649616319&w=2
+
+v2:
+ - Disable software interrupts instead of hardware interrupts
+
+Reported-by: Gurucharan Shetty <gurucharan.shetty@gmail.com>
+Signed-off-by: Jussi Kivilinna <jussi.kivilinna@mbnet.fi>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ crypto/cryptd.c | 11 ++++++++---
+ 1 file changed, 8 insertions(+), 3 deletions(-)
+
+--- a/crypto/cryptd.c
++++ b/crypto/cryptd.c
+@@ -137,13 +137,18 @@ static void cryptd_queue_worker(struct w
+ struct crypto_async_request *req, *backlog;
+
+ cpu_queue = container_of(work, struct cryptd_cpu_queue, work);
+- /* Only handle one request at a time to avoid hogging crypto
+- * workqueue. preempt_disable/enable is used to prevent
+- * being preempted by cryptd_enqueue_request() */
++ /*
++ * Only handle one request at a time to avoid hogging crypto workqueue.
++ * preempt_disable/enable is used to prevent being preempted by
++ * cryptd_enqueue_request(). local_bh_disable/enable is used to prevent
++ * cryptd_enqueue_request() being accessed from software interrupts.
++ */
++ local_bh_disable();
+ preempt_disable();
+ backlog = crypto_get_backlog(&cpu_queue->queue);
+ req = crypto_dequeue_request(&cpu_queue->queue);
+ preempt_enable();
++ local_bh_enable();
+
+ if (!req)
+ return;
--- /dev/null
+From 848561d368751a1c0f679b9f045a02944506a801 Mon Sep 17 00:00:00 2001
+From: Eric Paris <eparis@redhat.com>
+Date: Thu, 8 Nov 2012 15:53:37 -0800
+Subject: fanotify: fix missing break
+
+From: Eric Paris <eparis@redhat.com>
+
+commit 848561d368751a1c0f679b9f045a02944506a801 upstream.
+
+Anders Blomdell noted in 2010 that Fanotify lost events and provided a
+test case. Eric Paris confirmed it was a bug and posted a fix to the
+list
+
+ https://groups.google.com/forum/?fromgroups=#!topic/linux.kernel/RrJfTfyW2BE
+
+but never applied it. Repeated attempts over time to actually get him
+to apply it have never had a reply from anyone who has raised it
+
+So apply it anyway
+
+Signed-off-by: Alan Cox <alan@linux.intel.com>
+Reported-by: Anders Blomdell <anders.blomdell@control.lth.se>
+Cc: Eric Paris <eparis@redhat.com>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/notify/fanotify/fanotify.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/fs/notify/fanotify/fanotify.c
++++ b/fs/notify/fanotify/fanotify.c
+@@ -21,6 +21,7 @@ static bool should_merge(struct fsnotify
+ if ((old->path.mnt == new->path.mnt) &&
+ (old->path.dentry == new->path.dentry))
+ return true;
++ break;
+ case (FSNOTIFY_EVENT_NONE):
+ return true;
+ default:
--- /dev/null
+From 1f98ab7fef48a2968f37f422c256c9fbd978c3f0 Mon Sep 17 00:00:00 2001
+From: Felix Fietkau <nbd@openwrt.org>
+Date: Sat, 10 Nov 2012 03:44:14 +0100
+Subject: mac80211: call skb_dequeue/ieee80211_free_txskb instead of __skb_queue_purge
+
+From: Felix Fietkau <nbd@openwrt.org>
+
+commit 1f98ab7fef48a2968f37f422c256c9fbd978c3f0 upstream.
+
+Fixes more wifi status skb leaks, leading to hostapd/wpa_supplicant hangs.
+
+Signed-off-by: Felix Fietkau <nbd@openwrt.org>
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ net/mac80211/ieee80211_i.h | 2 ++
+ net/mac80211/sta_info.c | 6 +++---
+ net/mac80211/status.c | 9 +++++++++
+ net/mac80211/tx.c | 9 ++++++---
+ 4 files changed, 20 insertions(+), 6 deletions(-)
+
+--- a/net/mac80211/ieee80211_i.h
++++ b/net/mac80211/ieee80211_i.h
+@@ -1297,6 +1297,8 @@ netdev_tx_t ieee80211_monitor_start_xmit
+ struct net_device *dev);
+ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb,
+ struct net_device *dev);
++void ieee80211_purge_tx_queue(struct ieee80211_hw *hw,
++ struct sk_buff_head *skbs);
+
+ /* HT */
+ bool ieee80111_cfg_override_disables_ht40(struct ieee80211_sub_if_data *sdata);
+--- a/net/mac80211/sta_info.c
++++ b/net/mac80211/sta_info.c
+@@ -738,8 +738,8 @@ int __must_check __sta_info_destroy(stru
+
+ for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) {
+ local->total_ps_buffered -= skb_queue_len(&sta->ps_tx_buf[ac]);
+- __skb_queue_purge(&sta->ps_tx_buf[ac]);
+- __skb_queue_purge(&sta->tx_filtered[ac]);
++ ieee80211_purge_tx_queue(&local->hw, &sta->ps_tx_buf[ac]);
++ ieee80211_purge_tx_queue(&local->hw, &sta->tx_filtered[ac]);
+ }
+
+ #ifdef CONFIG_MAC80211_MESH
+@@ -774,7 +774,7 @@ int __must_check __sta_info_destroy(stru
+ tid_tx = rcu_dereference_raw(sta->ampdu_mlme.tid_tx[i]);
+ if (!tid_tx)
+ continue;
+- __skb_queue_purge(&tid_tx->pending);
++ ieee80211_purge_tx_queue(&local->hw, &tid_tx->pending);
+ kfree(tid_tx);
+ }
+
+--- a/net/mac80211/status.c
++++ b/net/mac80211/status.c
+@@ -660,3 +660,12 @@ void ieee80211_free_txskb(struct ieee802
+ dev_kfree_skb_any(skb);
+ }
+ EXPORT_SYMBOL(ieee80211_free_txskb);
++
++void ieee80211_purge_tx_queue(struct ieee80211_hw *hw,
++ struct sk_buff_head *skbs)
++{
++ struct sk_buff *skb;
++
++ while ((skb = __skb_dequeue(skbs)))
++ ieee80211_free_txskb(hw, skb);
++}
+--- a/net/mac80211/tx.c
++++ b/net/mac80211/tx.c
+@@ -1357,7 +1357,7 @@ static int invoke_tx_handlers(struct iee
+ if (tx->skb)
+ dev_kfree_skb(tx->skb);
+ else
+- __skb_queue_purge(&tx->skbs);
++ ieee80211_purge_tx_queue(&tx->local->hw, &tx->skbs);
+ return -1;
+ } else if (unlikely(res == TX_QUEUED)) {
+ I802_DEBUG_INC(tx->local->tx_handlers_queued);
+@@ -2126,10 +2126,13 @@ netdev_tx_t ieee80211_subif_start_xmit(s
+ */
+ void ieee80211_clear_tx_pending(struct ieee80211_local *local)
+ {
++ struct sk_buff *skb;
+ int i;
+
+- for (i = 0; i < local->hw.queues; i++)
+- skb_queue_purge(&local->pending[i]);
++ for (i = 0; i < local->hw.queues; i++) {
++ while ((skb = skb_dequeue(&local->pending[i])) != NULL)
++ ieee80211_free_txskb(&local->hw, skb);
++ }
+ }
+
+ /*
--- /dev/null
+From 20f544eea03db4b498942558b882d463ce575c3e Mon Sep 17 00:00:00 2001
+From: Johannes Berg <johannes.berg@intel.com>
+Date: Thu, 8 Nov 2012 14:06:28 +0100
+Subject: mac80211: don't send null data packet when not associated
+
+From: Johannes Berg <johannes.berg@intel.com>
+
+commit 20f544eea03db4b498942558b882d463ce575c3e upstream.
+
+On resume or firmware recovery, mac80211 sends a null
+data packet to see if the AP is still around and hasn't
+disconnected us. However, it always does this even if
+it wasn't even connected before, leading to a warning
+in the new channel context code. Fix this by checking
+that it's associated.
+
+Reviewed-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ net/mac80211/util.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/net/mac80211/util.c
++++ b/net/mac80211/util.c
+@@ -1341,6 +1341,8 @@ int ieee80211_reconfig(struct ieee80211_
+ list_for_each_entry(sdata, &local->interfaces, list) {
+ if (sdata->vif.type != NL80211_IFTYPE_STATION)
+ continue;
++ if (!sdata->u.mgd.associated)
++ continue;
+
+ ieee80211_send_nullfunc(local, sdata, 0);
+ }
--- /dev/null
+From 987c285c2ae2e4e32aca3a9b3252d28171c75711 Mon Sep 17 00:00:00 2001
+From: Arik Nemtsov <arik@wizery.com>
+Date: Mon, 5 Nov 2012 10:27:52 +0200
+Subject: mac80211: sync acccess to tx_filtered/ps_tx_buf queues
+
+From: Arik Nemtsov <arik@wizery.com>
+
+commit 987c285c2ae2e4e32aca3a9b3252d28171c75711 upstream.
+
+These are accessed without a lock when ending STA PSM. If the
+sta_cleanup timer accesses these lists at the same time, we might crash.
+
+This may fix some mysterious crashes we had during
+ieee80211_sta_ps_deliver_wakeup.
+
+Signed-off-by: Arik Nemtsov <arik@wizery.com>
+Signed-off-by: Ido Yariv <ido@wizery.com>
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ net/mac80211/sta_info.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+--- a/net/mac80211/sta_info.c
++++ b/net/mac80211/sta_info.c
+@@ -959,6 +959,7 @@ void ieee80211_sta_ps_deliver_wakeup(str
+ struct ieee80211_local *local = sdata->local;
+ struct sk_buff_head pending;
+ int filtered = 0, buffered = 0, ac;
++ unsigned long flags;
+
+ clear_sta_flag(sta, WLAN_STA_SP);
+
+@@ -974,12 +975,16 @@ void ieee80211_sta_ps_deliver_wakeup(str
+ for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) {
+ int count = skb_queue_len(&pending), tmp;
+
++ spin_lock_irqsave(&sta->tx_filtered[ac].lock, flags);
+ skb_queue_splice_tail_init(&sta->tx_filtered[ac], &pending);
++ spin_unlock_irqrestore(&sta->tx_filtered[ac].lock, flags);
+ tmp = skb_queue_len(&pending);
+ filtered += tmp - count;
+ count = tmp;
+
++ spin_lock_irqsave(&sta->ps_tx_buf[ac].lock, flags);
+ skb_queue_splice_tail_init(&sta->ps_tx_buf[ac], &pending);
++ spin_unlock_irqrestore(&sta->ps_tx_buf[ac].lock, flags);
+ tmp = skb_queue_len(&pending);
+ buffered += tmp - count;
+ }
--- /dev/null
+From 59ef28b1f14899b10d6b2682c7057ca00a9a3f47 Mon Sep 17 00:00:00 2001
+From: Rusty Russell <rusty@rustcorp.com.au>
+Date: Thu, 25 Oct 2012 10:49:25 +1030
+Subject: module: fix out-by-one error in kallsyms
+
+From: Rusty Russell <rusty@rustcorp.com.au>
+
+commit 59ef28b1f14899b10d6b2682c7057ca00a9a3f47 upstream.
+
+Masaki found and patched a kallsyms issue: the last symbol in a
+module's symtab wasn't transferred. This is because we manually copy
+the zero'th entry (which is always empty) then copy the rest in a loop
+starting at 1, though from src[0]. His fix was minimal, I prefer to
+rewrite the loops in more standard form.
+
+There are two loops: one to get the size, and one to copy. Make these
+identical: always count entry 0 and any defined symbol in an allocated
+non-init section.
+
+This bug exists since the following commit was introduced.
+ module: reduce symbol table for loaded modules (v2)
+ commit: 4a4962263f07d14660849ec134ee42b63e95ea9a
+
+LKML: http://lkml.org/lkml/2012/10/24/27
+Reported-by: Masaki Kimura <masaki.kimura.kz@hitachi.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ kernel/module.c | 27 ++++++++++++++++-----------
+ 1 file changed, 16 insertions(+), 11 deletions(-)
+
+--- a/kernel/module.c
++++ b/kernel/module.c
+@@ -2273,12 +2273,17 @@ static void layout_symtab(struct module
+ src = (void *)info->hdr + symsect->sh_offset;
+ nsrc = symsect->sh_size / sizeof(*src);
+
++ /* strtab always starts with a nul, so offset 0 is the empty string. */
++ strtab_size = 1;
++
+ /* Compute total space required for the core symbols' strtab. */
+- for (ndst = i = strtab_size = 1; i < nsrc; ++i, ++src)
+- if (is_core_symbol(src, info->sechdrs, info->hdr->e_shnum)) {
+- strtab_size += strlen(&info->strtab[src->st_name]) + 1;
++ for (ndst = i = 0; i < nsrc; i++) {
++ if (i == 0 ||
++ is_core_symbol(src+i, info->sechdrs, info->hdr->e_shnum)) {
++ strtab_size += strlen(&info->strtab[src[i].st_name])+1;
+ ndst++;
+ }
++ }
+
+ /* Append room for core symbols at end of core part. */
+ info->symoffs = ALIGN(mod->core_size, symsect->sh_addralign ?: 1);
+@@ -2312,15 +2317,15 @@ static void add_kallsyms(struct module *
+ mod->core_symtab = dst = mod->module_core + info->symoffs;
+ mod->core_strtab = s = mod->module_core + info->stroffs;
+ src = mod->symtab;
+- *dst = *src;
+ *s++ = 0;
+- for (ndst = i = 1; i < mod->num_symtab; ++i, ++src) {
+- if (!is_core_symbol(src, info->sechdrs, info->hdr->e_shnum))
+- continue;
+-
+- dst[ndst] = *src;
+- dst[ndst++].st_name = s - mod->core_strtab;
+- s += strlcpy(s, &mod->strtab[src->st_name], KSYM_NAME_LEN) + 1;
++ for (ndst = i = 0; i < mod->num_symtab; i++) {
++ if (i == 0 ||
++ is_core_symbol(src+i, info->sechdrs, info->hdr->e_shnum)) {
++ dst[ndst] = src[i];
++ dst[ndst++].st_name = s - mod->core_strtab;
++ s += strlcpy(s, &mod->strtab[src[i].st_name],
++ KSYM_NAME_LEN) + 1;
++ }
+ }
+ mod->core_num_syms = ndst;
+ }
--- /dev/null
+From 90b5c1d7c45eeb622302680ff96ed30c1a2b6f0e Mon Sep 17 00:00:00 2001
+From: Huang Ying <ying.huang@intel.com>
+Date: Wed, 24 Oct 2012 14:54:13 +0800
+Subject: PCI/PM: Fix deadlock when unbinding device if parent in D3cold
+
+From: Huang Ying <ying.huang@intel.com>
+
+commit 90b5c1d7c45eeb622302680ff96ed30c1a2b6f0e upstream.
+
+If a PCI device and its parents are put into D3cold, unbinding the
+device will trigger deadlock as follow:
+
+- driver_unbind
+ - device_release_driver
+ - device_lock(dev) <--- previous lock here
+ - __device_release_driver
+ - pm_runtime_get_sync
+ ...
+ - rpm_resume(dev)
+ - rpm_resume(dev->parent)
+ ...
+ - pci_pm_runtime_resume
+ ...
+ - pci_set_power_state
+ - __pci_start_power_transition
+ - pci_wakeup_bus(dev->parent->subordinate)
+ - pci_walk_bus
+ - device_lock(dev) <--- deadlock here
+
+
+If we do not do device_lock in pci_walk_bus, we can avoid deadlock.
+Device_lock in pci_walk_bus is introduced in commit:
+d71374dafbba7ec3f67371d3b7e9f6310a588808, corresponding email thread
+is: https://lkml.org/lkml/2006/5/26/38. The patch author Zhang Yanmin
+said device_lock is added to pci_walk_bus because:
+
+ Some error handling functions call pci_walk_bus. For example, PCIe
+ aer. Here we lock the device, so the driver wouldn't detach from the
+ device, as the cb might call driver's callback function.
+
+So I fixed the deadlock as follows:
+
+- remove device_lock from pci_walk_bus
+- add device_lock into callback if callback will call driver's callback
+
+I checked pci_walk_bus users one by one, and found only PCIe aer needs
+device lock.
+
+Signed-off-by: Huang Ying <ying.huang@intel.com>
+Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
+Acked-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+CC: Zhang Yanmin <yanmin.zhang@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/pci/bus.c | 3 ---
+ drivers/pci/pcie/aer/aerdrv_core.c | 20 ++++++++++++++++----
+ 2 files changed, 16 insertions(+), 7 deletions(-)
+
+--- a/drivers/pci/bus.c
++++ b/drivers/pci/bus.c
+@@ -314,10 +314,7 @@ void pci_walk_bus(struct pci_bus *top, i
+ } else
+ next = dev->bus_list.next;
+
+- /* Run device routines with the device locked */
+- device_lock(&dev->dev);
+ retval = cb(dev, userdata);
+- device_unlock(&dev->dev);
+ if (retval)
+ break;
+ }
+--- a/drivers/pci/pcie/aer/aerdrv_core.c
++++ b/drivers/pci/pcie/aer/aerdrv_core.c
+@@ -244,6 +244,7 @@ static int report_error_detected(struct
+ struct aer_broadcast_data *result_data;
+ result_data = (struct aer_broadcast_data *) data;
+
++ device_lock(&dev->dev);
+ dev->error_state = result_data->state;
+
+ if (!dev->driver ||
+@@ -262,12 +263,14 @@ static int report_error_detected(struct
+ dev->driver ?
+ "no AER-aware driver" : "no driver");
+ }
+- return 0;
++ goto out;
+ }
+
+ err_handler = dev->driver->err_handler;
+ vote = err_handler->error_detected(dev, result_data->state);
+ result_data->result = merge_result(result_data->result, vote);
++out:
++ device_unlock(&dev->dev);
+ return 0;
+ }
+
+@@ -278,14 +281,17 @@ static int report_mmio_enabled(struct pc
+ struct aer_broadcast_data *result_data;
+ result_data = (struct aer_broadcast_data *) data;
+
++ device_lock(&dev->dev);
+ if (!dev->driver ||
+ !dev->driver->err_handler ||
+ !dev->driver->err_handler->mmio_enabled)
+- return 0;
++ goto out;
+
+ err_handler = dev->driver->err_handler;
+ vote = err_handler->mmio_enabled(dev);
+ result_data->result = merge_result(result_data->result, vote);
++out:
++ device_unlock(&dev->dev);
+ return 0;
+ }
+
+@@ -296,14 +302,17 @@ static int report_slot_reset(struct pci_
+ struct aer_broadcast_data *result_data;
+ result_data = (struct aer_broadcast_data *) data;
+
++ device_lock(&dev->dev);
+ if (!dev->driver ||
+ !dev->driver->err_handler ||
+ !dev->driver->err_handler->slot_reset)
+- return 0;
++ goto out;
+
+ err_handler = dev->driver->err_handler;
+ vote = err_handler->slot_reset(dev);
+ result_data->result = merge_result(result_data->result, vote);
++out:
++ device_unlock(&dev->dev);
+ return 0;
+ }
+
+@@ -311,15 +320,18 @@ static int report_resume(struct pci_dev
+ {
+ struct pci_error_handlers *err_handler;
+
++ device_lock(&dev->dev);
+ dev->error_state = pci_channel_io_normal;
+
+ if (!dev->driver ||
+ !dev->driver->err_handler ||
+ !dev->driver->err_handler->resume)
+- return 0;
++ goto out;
+
+ err_handler = dev->driver->err_handler;
+ err_handler->resume(dev);
++out:
++ device_unlock(&dev->dev);
+ return 0;
+ }
+
mm-bugfix-set-current-reclaim_state-to-null-while-returning-from-kswapd.patch
+xfs-drop-buffer-io-reference-when-a-bad-bio-is-built.patch
+mac80211-sync-acccess-to-tx_filtered-ps_tx_buf-queues.patch
+mac80211-don-t-send-null-data-packet-when-not-associated.patch
+mac80211-call-skb_dequeue-ieee80211_free_txskb-instead-of-__skb_queue_purge.patch
+pci-pm-fix-deadlock-when-unbinding-device-if-parent-in-d3cold.patch
+fanotify-fix-missing-break.patch
+module-fix-out-by-one-error-in-kallsyms.patch
+cifs-fix-potential-buffer-overrun-in-cifs.idmap-handling-code.patch
+crypto-cryptd-disable-softirqs-in-cryptd_queue_worker-to-prevent-data-corruption.patch
--- /dev/null
+From d69043c42d8c6414fa28ad18d99973aa6c1c2e24 Mon Sep 17 00:00:00 2001
+From: Dave Chinner <dchinner@redhat.com>
+Date: Mon, 12 Nov 2012 22:09:46 +1100
+Subject: xfs: drop buffer io reference when a bad bio is built
+
+From: Dave Chinner <dchinner@redhat.com>
+
+commit d69043c42d8c6414fa28ad18d99973aa6c1c2e24 upstream.
+
+Error handling in xfs_buf_ioapply_map() does not handle IO reference
+counts correctly. We increment the b_io_remaining count before
+building the bio, but then fail to decrement it in the failure case.
+This leads to the buffer never running IO completion and releasing
+the reference that the IO holds, so at unmount we can leak the
+buffer. This leak is captured by this assert failure during unmount:
+
+XFS: Assertion failed: atomic_read(&pag->pag_ref) == 0, file: fs/xfs/xfs_mount.c, line: 273
+
+This is not a new bug - the b_io_remaining accounting has had this
+problem for a long, long time - it's just very hard to get a
+zero length bio being built by this code...
+
+Further, the buffer IO error can be overwritten on a multi-segment
+buffer by subsequent bio completions for partial sections of the
+buffer. Hence we should only set the buffer error status if the
+buffer is not already carrying an error status. This ensures that a
+partial IO error on a multi-segment buffer will not be lost. This
+part of the problem is a regression, however.
+
+Signed-off-by: Dave Chinner <dchinner@redhat.com>
+Reviewed-by: Mark Tinguely <tinguely@sgi.com>
+Signed-off-by: Ben Myers <bpm@sgi.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/xfs/xfs_buf.c | 14 ++++++++++++--
+ 1 file changed, 12 insertions(+), 2 deletions(-)
+
+--- a/fs/xfs/xfs_buf.c
++++ b/fs/xfs/xfs_buf.c
+@@ -1165,9 +1165,14 @@ xfs_buf_bio_end_io(
+ {
+ xfs_buf_t *bp = (xfs_buf_t *)bio->bi_private;
+
+- xfs_buf_ioerror(bp, -error);
++ /*
++ * don't overwrite existing errors - otherwise we can lose errors on
++ * buffers that require multiple bios to complete.
++ */
++ if (!bp->b_error)
++ xfs_buf_ioerror(bp, -error);
+
+- if (!error && xfs_buf_is_vmapped(bp) && (bp->b_flags & XBF_READ))
++ if (!bp->b_error && xfs_buf_is_vmapped(bp) && (bp->b_flags & XBF_READ))
+ invalidate_kernel_vmap_range(bp->b_addr, xfs_buf_vmap_len(bp));
+
+ _xfs_buf_ioend(bp, 1);
+@@ -1243,6 +1248,11 @@ next_chunk:
+ if (size)
+ goto next_chunk;
+ } else {
++ /*
++ * This is guaranteed not to be the last io reference count
++ * because the caller (xfs_buf_iorequest) holds a count itself.
++ */
++ atomic_dec(&bp->b_io_remaining);
+ xfs_buf_ioerror(bp, EIO);
+ bio_put(bio);
+ }