* [PATCH 3.2 71/77] sh_eth: fix kernel oops in skb_put()
2015-12-24 15:37 [PATCH 3.2 00/77] 3.2.75-rc1 review Ben Hutchings
` (3 preceding siblings ...)
2015-12-24 15:37 ` [PATCH 3.2 23/77] can: sja1000: clear interrupts on start Ben Hutchings
@ 2015-12-24 15:37 ` Ben Hutchings
2015-12-24 15:37 ` [PATCH 3.2 27/77] unix: avoid use-after-free in ep_remove_wait_queue Ben Hutchings
` (73 subsequent siblings)
78 siblings, 0 replies; 84+ messages in thread
From: Ben Hutchings @ 2015-12-24 15:37 UTC (permalink / raw)
To: linux-kernel, stable
Cc: akpm, David S. Miller, Yasushi SHOJI, Sergei Shtylyov
3.2.75-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
[ Upstream commit 248be83dcb3feb3f6332eb3d010a016402138484 ]
In a low memory situation the following kernel oops occurs:
Unable to handle kernel NULL pointer dereference at virtual address 00000050
pgd = 8490c000
[00000050] *pgd=4651e831, *pte=00000000, *ppte=00000000
Internal error: Oops: 17 [#1] PREEMPT ARM
Modules linked in:
CPU: 0 Not tainted (3.4-at16 #9)
PC is at skb_put+0x10/0x98
LR is at sh_eth_poll+0x2c8/0xa10
pc : [<8035f780>] lr : [<8028bf50>] psr: 60000113
sp : 84eb1a90 ip : 84eb1ac8 fp : 84eb1ac4
r10: 0000003f r9 : 000005ea r8 : 00000000
r7 : 00000000 r6 : 940453b0 r5 : 00030000 r4 : 9381b180
r3 : 00000000 r2 : 00000000 r1 : 000005ea r0 : 00000000
Flags: nZCv IRQs on FIQs on Mode SVC_32 ISA ARM Segment user
Control: 10c53c7d Table: 4248c059 DAC: 00000015
Process klogd (pid: 2046, stack limit = 0x84eb02e8)
[...]
This is because netdev_alloc_skb() fails and 'mdp->rx_skbuff[entry]' is left
NULL but sh_eth_rx() later uses it without checking. Add such check...
Reported-by: Yasushi SHOJI <yashi@atmark-techno.com>
Signed-off-by: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
[bwh: Backported to 3.2: adjust context]
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
---
drivers/net/ethernet/renesas/sh_eth.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
--- a/drivers/net/ethernet/renesas/sh_eth.c
+++ b/drivers/net/ethernet/renesas/sh_eth.c
@@ -911,6 +911,7 @@ static int sh_eth_rx(struct net_device *
if (!(desc_status & RDFEND))
mdp->stats.rx_length_errors++;
+ skb = mdp->rx_skbuff[entry];
if (desc_status & (RD_RFS1 | RD_RFS2 | RD_RFS3 | RD_RFS4 |
RD_RFS5 | RD_RFS6 | RD_RFS10)) {
mdp->stats.rx_errors++;
@@ -926,12 +927,11 @@ static int sh_eth_rx(struct net_device *
mdp->stats.rx_missed_errors++;
if (desc_status & RD_RFS10)
mdp->stats.rx_over_errors++;
- } else {
+ } else if (skb) {
if (!mdp->cd->hw_swap)
sh_eth_soft_swap(
phys_to_virt(ALIGN(rxdesc->addr, 4)),
pkt_len + 2);
- skb = mdp->rx_skbuff[entry];
mdp->rx_skbuff[entry] = NULL;
if (mdp->cd->rpadir)
skb_reserve(skb, NET_IP_ALIGN);
^ permalink raw reply [flat|nested] 84+ messages in thread
* [PATCH 3.2 05/77] ALSA: usb-audio: work around CH345 input SysEx corruption
2015-12-24 15:37 [PATCH 3.2 00/77] 3.2.75-rc1 review Ben Hutchings
` (48 preceding siblings ...)
2015-12-24 15:37 ` [PATCH 3.2 46/77] drm: Fix an unwanted master inheritance v2 Ben Hutchings
@ 2015-12-24 15:37 ` Ben Hutchings
2015-12-24 15:37 ` [PATCH 3.2 55/77] parisc iommu: fix panic due to trying to allocate too large region Ben Hutchings
` (28 subsequent siblings)
78 siblings, 0 replies; 84+ messages in thread
From: Ben Hutchings @ 2015-12-24 15:37 UTC (permalink / raw)
To: linux-kernel, stable; +Cc: akpm, Takashi Iwai, Clemens Ladisch
3.2.75-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Clemens Ladisch <clemens@ladisch.de>
commit a91e627e3f0ed820b11d86cdc04df38f65f33a70 upstream.
One of the many faults of the QinHeng CH345 USB MIDI interface chip is
that it does not handle received SysEx messages correctly -- every second
event packet has a wrong code index number, which is the one from the last
seen message, instead of 4. For example, the two messages "FE F0 01 02 03
04 05 06 07 08 09 0A 0B 0C 0D 0E F7" result in the following event
packets:
correct: CH345:
0F FE 00 00 0F FE 00 00
04 F0 01 02 04 F0 01 02
04 03 04 05 0F 03 04 05
04 06 07 08 04 06 07 08
04 09 0A 0B 0F 09 0A 0B
04 0C 0D 0E 04 0C 0D 0E
05 F7 00 00 05 F7 00 00
A class-compliant driver must interpret an event packet with CIN 15 as
having a single data byte, so the other two bytes would be ignored. The
message received by the host would then be missing two bytes out of six;
in this example, "F0 01 02 03 06 07 08 09 0C 0D 0E F7".
These corrupted SysEx event packages contain only data bytes, while the
CH345 uses event packets with a correct CIN value only for messages with
a status byte, so it is possible to distinguish between these two cases by
checking for the presence of this status byte.
(Other bugs in the CH345's input handling, such as the corruption resulting
from running status, cannot be worked around.)
Signed-off-by: Clemens Ladisch <clemens@ladisch.de>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
---
sound/usb/midi.c | 42 ++++++++++++++++++++++++++++++++++++++++++
1 file changed, 42 insertions(+)
--- a/sound/usb/midi.c
+++ b/sound/usb/midi.c
@@ -174,6 +174,8 @@ struct snd_usb_midi_in_endpoint {
u8 running_status_length;
} ports[0x10];
u8 seen_f5;
+ bool in_sysex;
+ u8 last_cin;
u8 error_resubmit;
int current_port;
};
@@ -465,6 +467,39 @@ static void snd_usbmidi_maudio_broken_ru
}
/*
+ * QinHeng CH345 is buggy: every second packet inside a SysEx has not CIN 4
+ * but the previously seen CIN, but still with three data bytes.
+ */
+static void ch345_broken_sysex_input(struct snd_usb_midi_in_endpoint *ep,
+ uint8_t *buffer, int buffer_length)
+{
+ unsigned int i, cin, length;
+
+ for (i = 0; i + 3 < buffer_length; i += 4) {
+ if (buffer[i] == 0 && i > 0)
+ break;
+ cin = buffer[i] & 0x0f;
+ if (ep->in_sysex &&
+ cin == ep->last_cin &&
+ (buffer[i + 1 + (cin == 0x6)] & 0x80) == 0)
+ cin = 0x4;
+#if 0
+ if (buffer[i + 1] == 0x90) {
+ /*
+ * Either a corrupted running status or a real note-on
+ * message; impossible to detect reliably.
+ */
+ }
+#endif
+ length = snd_usbmidi_cin_length[cin];
+ snd_usbmidi_input_data(ep, 0, &buffer[i + 1], length);
+ ep->in_sysex = cin == 0x4;
+ if (!ep->in_sysex)
+ ep->last_cin = cin;
+ }
+}
+
+/*
* CME protocol: like the standard protocol, but SysEx commands are sent as a
* single USB packet preceded by a 0x0F byte.
*/
@@ -650,6 +685,12 @@ static struct usb_protocol_ops snd_usbmi
.output_packet = snd_usbmidi_output_standard_packet,
};
+static struct usb_protocol_ops snd_usbmidi_ch345_broken_sysex_ops = {
+ .input = ch345_broken_sysex_input,
+ .output = snd_usbmidi_standard_output,
+ .output_packet = snd_usbmidi_output_standard_packet,
+};
+
/*
* AKAI MPD16 protocol:
*
@@ -2216,6 +2257,7 @@ int snd_usbmidi_create(struct snd_card *
err = snd_usbmidi_detect_per_port_endpoints(umidi, endpoints);
break;
case QUIRK_MIDI_CH345:
+ umidi->usb_protocol_ops = &snd_usbmidi_ch345_broken_sysex_ops;
err = snd_usbmidi_detect_per_port_endpoints(umidi, endpoints);
break;
default:
^ permalink raw reply [flat|nested] 84+ messages in thread
* [PATCH 3.2 25/77] USB: cdc-acm - Add IGNORE_DEVICE quirk
2015-12-24 15:37 [PATCH 3.2 00/77] 3.2.75-rc1 review Ben Hutchings
` (5 preceding siblings ...)
2015-12-24 15:37 ` [PATCH 3.2 27/77] unix: avoid use-after-free in ep_remove_wait_queue Ben Hutchings
@ 2015-12-24 15:37 ` Ben Hutchings
2015-12-24 15:37 ` [PATCH 3.2 40/77] wan/x25: Fix use-after-free in x25_asy_open_tty() Ben Hutchings
` (71 subsequent siblings)
78 siblings, 0 replies; 84+ messages in thread
From: Ben Hutchings @ 2015-12-24 15:37 UTC (permalink / raw)
To: linux-kernel, stable; +Cc: akpm
3.2.75-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Ben Hutchings <ben@decadent.org.uk>
Extracted from commit 16142655269a ("USB: cdc-acm - blacklist IMS PCU
device").
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
---
--- a/drivers/usb/class/cdc-acm.c
+++ b/drivers/usb/class/cdc-acm.c
@@ -916,6 +916,10 @@ static int acm_probe(struct usb_interfac
/* normal quirks */
quirks = (unsigned long)id->driver_info;
+
+ if (quirks == IGNORE_DEVICE)
+ return -ENODEV;
+
num_rx_buf = (quirks == SINGLE_RX_URB) ? 1 : ACM_NR;
/* handle quirks deadly to normal probing*/
--- a/drivers/usb/class/cdc-acm.h
+++ b/drivers/usb/class/cdc-acm.h
@@ -127,4 +127,5 @@ struct acm {
#define NO_CAP_LINE 4
#define NOT_A_MODEM 8
#define NO_DATA_INTERFACE 16
+#define IGNORE_DEVICE 32
#define CLEAR_HALT_CONDITIONS BIT(7)
^ permalink raw reply [flat|nested] 84+ messages in thread
* [PATCH 3.2 58/77] sh64: fix __NR_fgetxattr
2015-12-24 15:37 [PATCH 3.2 00/77] 3.2.75-rc1 review Ben Hutchings
` (52 preceding siblings ...)
2015-12-24 15:37 ` [PATCH 3.2 20/77] mac: validate mac_partition is within sector Ben Hutchings
@ 2015-12-24 15:37 ` Ben Hutchings
2015-12-24 15:37 ` [PATCH 3.2 04/77] ALSA: usb-audio: prevent CH345 multiport output SysEx corruption Ben Hutchings
` (24 subsequent siblings)
78 siblings, 0 replies; 84+ messages in thread
From: Ben Hutchings @ 2015-12-24 15:37 UTC (permalink / raw)
To: linux-kernel, stable
Cc: akpm, Geert Uytterhoeven, Linus Torvalds, Dmitry V. Levin
3.2.75-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: "Dmitry V. Levin" <ldv@altlinux.org>
commit 2d33fa1059da4c8e816627a688d950b613ec0474 upstream.
According to arch/sh/kernel/syscalls_64.S and common sense, __NR_fgetxattr
has to be defined to 259, but it doesn't. Instead, it's defined to 269,
which is of course used by another syscall, __NR_sched_setaffinity in this
case.
This bug was found by strace test suite.
Signed-off-by: Dmitry V. Levin <ldv@altlinux.org>
Acked-by: Geert Uytterhoeven <geert+renesas@glider.be>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
[bwh: Backported to 3.2: adjust filename]
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
---
arch/sh/include/asm/unistd_64.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
--- a/arch/sh/include/asm/unistd_64.h
+++ b/arch/sh/include/asm/unistd_64.h
@@ -279,7 +279,7 @@
#define __NR_fsetxattr 256
#define __NR_getxattr 257
#define __NR_lgetxattr 258
-#define __NR_fgetxattr 269
+#define __NR_fgetxattr 259
#define __NR_listxattr 260
#define __NR_llistxattr 261
#define __NR_flistxattr 262
^ permalink raw reply [flat|nested] 84+ messages in thread
* [PATCH 3.2 57/77] mm: hugetlb: call huge_pte_alloc() only if ptep is null
2015-12-24 15:37 [PATCH 3.2 00/77] 3.2.75-rc1 review Ben Hutchings
` (24 preceding siblings ...)
2015-12-24 15:37 ` [PATCH 3.2 75/77] af_unix: fix a fatal race with bit fields Ben Hutchings
@ 2015-12-24 15:37 ` Ben Hutchings
2015-12-24 15:37 ` [PATCH 3.2 22/77] net: ip6mr: fix static mfc/dev leaks on table destruction Ben Hutchings
` (52 subsequent siblings)
78 siblings, 0 replies; 84+ messages in thread
From: Ben Hutchings @ 2015-12-24 15:37 UTC (permalink / raw)
To: linux-kernel, stable
Cc: akpm, Dave Hansen, Joonsoo Kim, David Rientjes, Naoya Horiguchi,
Hugh Dickins, Mel Gorman, Hillf Danton, Linus Torvalds,
Mike Kravetz
3.2.75-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Naoya Horiguchi <n-horiguchi@ah.jp.nec.com>
commit 0d777df5d8953293be090d9ab5a355db893e8357 upstream.
Currently at the beginning of hugetlb_fault(), we call huge_pte_offset()
and check whether the obtained *ptep is a migration/hwpoison entry or
not. And if not, then we get to call huge_pte_alloc(). This is racy
because the *ptep could turn into migration/hwpoison entry after the
huge_pte_offset() check. This race results in BUG_ON in
huge_pte_alloc().
We don't have to call huge_pte_alloc() when the huge_pte_offset()
returns non-NULL, so let's fix this bug with moving the code into else
block.
Note that the *ptep could turn into a migration/hwpoison entry after
this block, but that's not a problem because we have another
!pte_present check later (we never go into hugetlb_no_page() in that
case.)
Fixes: 290408d4a250 ("hugetlb: hugepage migration core")
Signed-off-by: Naoya Horiguchi <n-horiguchi@ah.jp.nec.com>
Acked-by: Hillf Danton <hillf.zj@alibaba-inc.com>
Acked-by: David Rientjes <rientjes@google.com>
Cc: Hugh Dickins <hughd@google.com>
Cc: Dave Hansen <dave.hansen@intel.com>
Cc: Mel Gorman <mgorman@suse.de>
Cc: Joonsoo Kim <iamjoonsoo.kim@lge.com>
Cc: Mike Kravetz <mike.kravetz@oracle.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
[bwh: Backported to 3.2: adjust context]
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
---
mm/hugetlb.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
--- a/mm/hugetlb.c
+++ b/mm/hugetlb.c
@@ -2818,12 +2818,12 @@ int hugetlb_fault(struct mm_struct *mm,
} else if (unlikely(is_hugetlb_entry_hwpoisoned(entry)))
return VM_FAULT_HWPOISON_LARGE |
VM_FAULT_SET_HINDEX(h - hstates);
+ } else {
+ ptep = huge_pte_alloc(mm, address, huge_page_size(h));
+ if (!ptep)
+ return VM_FAULT_OOM;
}
- ptep = huge_pte_alloc(mm, address, huge_page_size(h));
- if (!ptep)
- return VM_FAULT_OOM;
-
/*
* Serialize hugepage allocation and instantiation, so that we don't
* get spurious allocation failures if two CPUs race to instantiate
^ permalink raw reply [flat|nested] 84+ messages in thread
* [PATCH 3.2 56/77] mm, vmstat: allow WQ concurrency to discover memory reclaim doesn't make any progress
2015-12-24 15:37 [PATCH 3.2 00/77] 3.2.75-rc1 review Ben Hutchings
` (13 preceding siblings ...)
2015-12-24 15:37 ` [PATCH 3.2 47/77] sched/core: Remove false-positive warning from wake_up_process() Ben Hutchings
@ 2015-12-24 15:37 ` Ben Hutchings
2015-12-24 15:37 ` [PATCH 3.2 45/77] locking: Add WARN_ON_ONCE lock assertion Ben Hutchings
` (63 subsequent siblings)
78 siblings, 0 replies; 84+ messages in thread
From: Ben Hutchings @ 2015-12-24 15:37 UTC (permalink / raw)
To: linux-kernel, stable
Cc: akpm, Tejun Heo, Linus Torvalds, Tetsuo Handa, Joonsoo Kim,
Cristopher Lameter, Arkadiusz Miskiewicz, Michal Hocko
3.2.75-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Michal Hocko <mhocko@suse.com>
commit 373ccbe5927034b55bdc80b0f8b54d6e13fe8d12 upstream.
Tetsuo Handa has reported that the system might basically livelock in
OOM condition without triggering the OOM killer.
The issue is caused by internal dependency of the direct reclaim on
vmstat counter updates (via zone_reclaimable) which are performed from
the workqueue context. If all the current workers get assigned to an
allocation request, though, they will be looping inside the allocator
trying to reclaim memory but zone_reclaimable can see stalled numbers so
it will consider a zone reclaimable even though it has been scanned way
too much. WQ concurrency logic will not consider this situation as a
congested workqueue because it relies that worker would have to sleep in
such a situation. This also means that it doesn't try to spawn new
workers or invoke the rescuer thread if the one is assigned to the
queue.
In order to fix this issue we need to do two things. First we have to
let wq concurrency code know that we are in trouble so we have to do a
short sleep. In order to prevent from issues handled by 0e093d99763e
("writeback: do not sleep on the congestion queue if there are no
congested BDIs or if significant congestion is not being encountered in
the current zone") we limit the sleep only to worker threads which are
the ones of the interest anyway.
The second thing to do is to create a dedicated workqueue for vmstat and
mark it WQ_MEM_RECLAIM to note it participates in the reclaim and to
have a spare worker thread for it.
Signed-off-by: Michal Hocko <mhocko@suse.com>
Reported-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
Cc: Tejun Heo <tj@kernel.org>
Cc: Cristopher Lameter <clameter@sgi.com>
Cc: Joonsoo Kim <js1304@gmail.com>
Cc: Arkadiusz Miskiewicz <arekm@maven.pl>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
[bwh: Backported to 3.2: adjust context]
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
---
mm/backing-dev.c | 19 ++++++++++++++++---
mm/vmstat.c | 6 ++++--
2 files changed, 20 insertions(+), 5 deletions(-)
--- a/mm/backing-dev.c
+++ b/mm/backing-dev.c
@@ -847,8 +847,9 @@ EXPORT_SYMBOL(congestion_wait);
* jiffies for either a BDI to exit congestion of the given @sync queue
* or a write to complete.
*
- * In the absence of zone congestion, cond_resched() is called to yield
- * the processor if necessary but otherwise does not sleep.
+ * In the absence of zone congestion, a short sleep or a cond_resched is
+ * performed to yield the processor and to allow other subsystems to make
+ * a forward progress.
*
* The return value is 0 if the sleep is for the full timeout. Otherwise,
* it is the number of jiffies that were still remaining when the function
@@ -868,7 +869,19 @@ long wait_iff_congested(struct zone *zon
*/
if (atomic_read(&nr_bdi_congested[sync]) == 0 ||
!zone_is_reclaim_congested(zone)) {
- cond_resched();
+
+ /*
+ * Memory allocation/reclaim might be called from a WQ
+ * context and the current implementation of the WQ
+ * concurrency control doesn't recognize that a particular
+ * WQ is congested if the worker thread is looping without
+ * ever sleeping. Therefore we have to do a short sleep
+ * here rather than calling cond_resched().
+ */
+ if (current->flags & PF_WQ_WORKER)
+ schedule_timeout(1);
+ else
+ cond_resched();
/* In case we scheduled, work out time remaining */
ret = timeout - (jiffies - start);
--- a/mm/vmstat.c
+++ b/mm/vmstat.c
@@ -1139,13 +1139,14 @@ static const struct file_operations proc
#endif /* CONFIG_PROC_FS */
#ifdef CONFIG_SMP
+static struct workqueue_struct *vmstat_wq;
static DEFINE_PER_CPU(struct delayed_work, vmstat_work);
int sysctl_stat_interval __read_mostly = HZ;
static void vmstat_update(struct work_struct *w)
{
refresh_cpu_vm_stats(smp_processor_id());
- schedule_delayed_work(&__get_cpu_var(vmstat_work),
+ queue_delayed_work(vmstat_wq, &__get_cpu_var(vmstat_work),
round_jiffies_relative(sysctl_stat_interval));
}
@@ -1154,7 +1155,7 @@ static void __cpuinit start_cpu_timer(in
struct delayed_work *work = &per_cpu(vmstat_work, cpu);
INIT_DELAYED_WORK_DEFERRABLE(work, vmstat_update);
- schedule_delayed_work_on(cpu, work, __round_jiffies_relative(HZ, cpu));
+ queue_delayed_work_on(cpu, vmstat_wq, work, __round_jiffies_relative(HZ, cpu));
}
/*
@@ -1204,6 +1205,7 @@ static int __init setup_vmstat(void)
register_cpu_notifier(&vmstat_notifier);
+ vmstat_wq = alloc_workqueue("vmstat", WQ_FREEZABLE|WQ_MEM_RECLAIM, 0);
for_each_online_cpu(cpu)
start_cpu_timer(cpu);
#endif
^ permalink raw reply [flat|nested] 84+ messages in thread
* [PATCH 3.2 75/77] af_unix: fix a fatal race with bit fields
2015-12-24 15:37 [PATCH 3.2 00/77] 3.2.75-rc1 review Ben Hutchings
` (23 preceding siblings ...)
2015-12-24 15:37 ` [PATCH 3.2 52/77] ipmi: move timer init to before irq is setup Ben Hutchings
@ 2015-12-24 15:37 ` Ben Hutchings
2015-12-24 15:37 ` [PATCH 3.2 57/77] mm: hugetlb: call huge_pte_alloc() only if ptep is null Ben Hutchings
` (53 subsequent siblings)
78 siblings, 0 replies; 84+ messages in thread
From: Ben Hutchings @ 2015-12-24 15:37 UTC (permalink / raw)
To: linux-kernel, stable
Cc: akpm, Eric Dumazet, Paul Mackerras, Eric Dumazet,
Benjamin Herrenschmidt, Ambrose Feinstein, David S. Miller
3.2.75-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Eric Dumazet <eric.dumazet@gmail.com>
commit 60bc851ae59bfe99be6ee89d6bc50008c85ec75d upstream.
Using bit fields is dangerous on ppc64/sparc64, as the compiler [1]
uses 64bit instructions to manipulate them.
If the 64bit word includes any atomic_t or spinlock_t, we can lose
critical concurrent changes.
This is happening in af_unix, where unix_sk(sk)->gc_candidate/
gc_maybe_cycle/lock share the same 64bit word.
This leads to fatal deadlock, as one/several cpus spin forever
on a spinlock that will never be available again.
A safer way would be to use a long to store flags.
This way we are sure compiler/arch wont do bad things.
As we own unix_gc_lock spinlock when clearing or setting bits,
we can use the non atomic __set_bit()/__clear_bit().
recursion_level can share the same 64bit location with the spinlock,
as it is set only with this spinlock held.
[1] bug fixed in gcc-4.8.0 :
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=52080
Reported-by: Ambrose Feinstein <ambrose@google.com>
Signed-off-by: Eric Dumazet <edumazet@google.com>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Paul Mackerras <paulus@samba.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
---
include/net/af_unix.h | 5 +++--
net/unix/garbage.c | 12 ++++++------
2 files changed, 9 insertions(+), 8 deletions(-)
--- a/include/net/af_unix.h
+++ b/include/net/af_unix.h
@@ -54,9 +54,10 @@ struct unix_sock {
struct list_head link;
atomic_long_t inflight;
spinlock_t lock;
- unsigned int gc_candidate : 1;
- unsigned int gc_maybe_cycle : 1;
unsigned char recursion_level;
+ unsigned long gc_flags;
+#define UNIX_GC_CANDIDATE 0
+#define UNIX_GC_MAYBE_CYCLE 1
struct socket_wq peer_wq;
wait_queue_t peer_wake;
};
--- a/net/unix/garbage.c
+++ b/net/unix/garbage.c
@@ -185,7 +185,7 @@ static void scan_inflight(struct sock *x
* have been added to the queues after
* starting the garbage collection
*/
- if (u->gc_candidate) {
+ if (test_bit(UNIX_GC_CANDIDATE, &u->gc_flags)) {
hit = true;
func(u);
}
@@ -254,7 +254,7 @@ static void inc_inflight_move_tail(struc
* of the list, so that it's checked even if it was already
* passed over
*/
- if (u->gc_maybe_cycle)
+ if (test_bit(UNIX_GC_MAYBE_CYCLE, &u->gc_flags))
list_move_tail(&u->link, &gc_candidates);
}
@@ -315,8 +315,8 @@ void unix_gc(void)
BUG_ON(total_refs < inflight_refs);
if (total_refs == inflight_refs) {
list_move_tail(&u->link, &gc_candidates);
- u->gc_candidate = 1;
- u->gc_maybe_cycle = 1;
+ __set_bit(UNIX_GC_CANDIDATE, &u->gc_flags);
+ __set_bit(UNIX_GC_MAYBE_CYCLE, &u->gc_flags);
}
}
@@ -344,7 +344,7 @@ void unix_gc(void)
if (atomic_long_read(&u->inflight) > 0) {
list_move_tail(&u->link, ¬_cycle_list);
- u->gc_maybe_cycle = 0;
+ __clear_bit(UNIX_GC_MAYBE_CYCLE, &u->gc_flags);
scan_children(&u->sk, inc_inflight_move_tail, NULL);
}
}
@@ -356,7 +356,7 @@ void unix_gc(void)
*/
while (!list_empty(¬_cycle_list)) {
u = list_entry(not_cycle_list.next, struct unix_sock, link);
- u->gc_candidate = 0;
+ __clear_bit(UNIX_GC_CANDIDATE, &u->gc_flags);
list_move_tail(&u->link, &gc_inflight_list);
}
^ permalink raw reply [flat|nested] 84+ messages in thread
* [PATCH 3.2 36/77] nfs: if we have no valid attrs, then don't declare the attribute cache valid
2015-12-24 15:37 [PATCH 3.2 00/77] 3.2.75-rc1 review Ben Hutchings
` (28 preceding siblings ...)
2015-12-24 15:37 ` [PATCH 3.2 12/77] net: fix __netdev_update_features return on ndo_set_features failure Ben Hutchings
@ 2015-12-24 15:37 ` Ben Hutchings
2015-12-24 15:37 ` [PATCH 3.2 13/77] FS-Cache: Add missing initialization of ret in cachefiles_write_page() Ben Hutchings
` (48 subsequent siblings)
78 siblings, 0 replies; 84+ messages in thread
From: Ben Hutchings @ 2015-12-24 15:37 UTC (permalink / raw)
To: linux-kernel, stable
Cc: akpm, Jeff Layton, Trond Myklebust, Steve French, Jeff Layton
3.2.75-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Jeff Layton <jlayton@poochiereds.net>
commit c812012f9ca7cf89c9e1a1cd512e6c3b5be04b85 upstream.
If we pass in an empty nfs_fattr struct to nfs_update_inode, it will
(correctly) not update any of the attributes, but it then clears the
NFS_INO_INVALID_ATTR flag, which indicates that the attributes are
up to date. Don't clear the flag if the fattr struct has no valid
attrs to apply.
Reviewed-by: Steve French <steve.french@primarydata.com>
Signed-off-by: Jeff Layton <jeff.layton@primarydata.com>
Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
---
fs/nfs/inode.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
--- a/fs/nfs/inode.c
+++ b/fs/nfs/inode.c
@@ -1389,7 +1389,11 @@ static int nfs_update_inode(struct inode
nfsi->attrtimeo_timestamp = now;
}
}
- invalid &= ~NFS_INO_INVALID_ATTR;
+
+ /* Don't declare attrcache up to date if there were no attrs! */
+ if (fattr->valid != 0)
+ invalid &= ~NFS_INO_INVALID_ATTR;
+
/* Don't invalidate the data if we were to blame */
if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode)
|| S_ISLNK(inode->i_mode)))
^ permalink raw reply [flat|nested] 84+ messages in thread
* [PATCH 3.2 39/77] sata_sil: disable trim
2015-12-24 15:37 [PATCH 3.2 00/77] 3.2.75-rc1 review Ben Hutchings
` (39 preceding siblings ...)
2015-12-24 15:37 ` [PATCH 3.2 72/77] pptp: verify sockaddr_len in pptp_bind() and pptp_connect() Ben Hutchings
@ 2015-12-24 15:37 ` Ben Hutchings
2015-12-24 15:37 ` [PATCH 3.2 70/77] net: add validation for the socket syscall protocol argument Ben Hutchings
` (37 subsequent siblings)
78 siblings, 0 replies; 84+ messages in thread
From: Ben Hutchings @ 2015-12-24 15:37 UTC (permalink / raw)
To: linux-kernel, stable; +Cc: akpm, Tejun Heo, Mikulas Patocka
3.2.75-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Mikulas Patocka <mpatocka@redhat.com>
commit d98f1cd0a3b70ea91f1dfda3ac36c3b2e1a4d5e2 upstream.
When I connect an Intel SSD to SATA SIL controller (PCI ID 1095:3114), any
TRIM command results in I/O errors being reported in the log. There is
other similar error reported with TRIM and the SIL controller:
https://bugs.centos.org/view.php?id=5880
Apparently the controller doesn't support TRIM commands. This patch
disables TRIM support on the SATA SIL controller.
ata7.00: exception Emask 0x0 SAct 0x0 SErr 0x0 action 0x0
ata7.00: BMDMA2 stat 0x50001
ata7.00: failed command: DATA SET MANAGEMENT
ata7.00: cmd 06/01:01:00:00:00/00:00:00:00:00/a0 tag 0 dma 512 out
res 51/04:01:00:00:00/00:00:00:00:00/a0 Emask 0x1 (device error)
ata7.00: status: { DRDY ERR }
ata7.00: error: { ABRT }
ata7.00: device reported invalid CHS sector 0
sd 8:0:0:0: [sdb] tag#0 FAILED Result: hostbyte=DID_OK driverbyte=DRIVER_SENSE
sd 8:0:0:0: [sdb] tag#0 Sense Key : Illegal Request [current] [descriptor]
sd 8:0:0:0: [sdb] tag#0 Add. Sense: Unaligned write command
sd 8:0:0:0: [sdb] tag#0 CDB: Write same(16) 93 08 00 00 00 00 00 21 95 88 00 20 00 00 00 00
blk_update_request: I/O error, dev sdb, sector 2200968
Signed-off-by: Mikulas Patocka <mpatocka@redhat.com>
Signed-off-by: Tejun Heo <tj@kernel.org>
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
---
drivers/ata/sata_sil.c | 3 +++
1 file changed, 3 insertions(+)
--- a/drivers/ata/sata_sil.c
+++ b/drivers/ata/sata_sil.c
@@ -631,6 +631,9 @@ static void sil_dev_config(struct ata_de
unsigned int n, quirks = 0;
unsigned char model_num[ATA_ID_PROD_LEN + 1];
+ /* This controller doesn't support trim */
+ dev->horkage |= ATA_HORKAGE_NOTRIM;
+
ata_id_c_string(dev->id, model_num, ATA_ID_PROD, sizeof(model_num));
for (n = 0; sil_blacklist[n].product; n++)
^ permalink raw reply [flat|nested] 84+ messages in thread
* [PATCH 3.2 28/77] fix sysvfs symlinks
2015-12-24 15:37 [PATCH 3.2 00/77] 3.2.75-rc1 review Ben Hutchings
` (74 preceding siblings ...)
2015-12-24 15:37 ` [PATCH 3.2 18/77] USB: option: add XS Stick W100-2 from 4G Systems Ben Hutchings
@ 2015-12-24 15:37 ` Ben Hutchings
2015-12-24 15:37 ` [PATCH 3.2 16/77] xhci: Add XHCI_INTEL_HOST quirk Ben Hutchings
` (2 subsequent siblings)
78 siblings, 0 replies; 84+ messages in thread
From: Ben Hutchings @ 2015-12-24 15:37 UTC (permalink / raw)
To: linux-kernel, stable; +Cc: akpm, Al Viro
3.2.75-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Al Viro <viro@zeniv.linux.org.uk>
commit 0ebf7f10d67a70e120f365018f1c5fce9ddc567d upstream.
The thing got broken back in 2002 - sysvfs does *not* have inline
symlinks; even short ones have bodies stored in the first block
of file. sysv_symlink() handles that correctly; unfortunately,
attempting to look an existing symlink up will end up confusing
them for inline symlinks, and interpret the block number containing
the body as the body itself.
Nobody has noticed until now, which says something about the level
of testing sysvfs gets ;-/
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
[bwh: Backported to 3.2:
- Adjust context
- Also delete unused sysv_fast_symlink_inode_operations]
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
---
fs/sysv/inode.c | 11 ++---------
1 file changed, 2 insertions(+), 9 deletions(-)
--- a/fs/sysv/inode.c
+++ b/fs/sysv/inode.c
@@ -176,14 +176,8 @@ void sysv_set_inode(struct inode *inode,
inode->i_fop = &sysv_dir_operations;
inode->i_mapping->a_ops = &sysv_aops;
} else if (S_ISLNK(inode->i_mode)) {
- if (inode->i_blocks) {
- inode->i_op = &sysv_symlink_inode_operations;
- inode->i_mapping->a_ops = &sysv_aops;
- } else {
- inode->i_op = &sysv_fast_symlink_inode_operations;
- nd_terminate_link(SYSV_I(inode)->i_data, inode->i_size,
- sizeof(SYSV_I(inode)->i_data) - 1);
- }
+ inode->i_op = &sysv_symlink_inode_operations;
+ inode->i_mapping->a_ops = &sysv_aops;
} else
init_special_inode(inode, inode->i_mode, rdev);
}
--- a/fs/sysv/Makefile
+++ b/fs/sysv/Makefile
@@ -5,4 +5,4 @@
obj-$(CONFIG_SYSV_FS) += sysv.o
sysv-objs := ialloc.o balloc.o inode.o itree.o file.o dir.o \
- namei.o super.o symlink.o
+ namei.o super.o
--- a/fs/sysv/symlink.c
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- * linux/fs/sysv/symlink.c
- *
- * Handling of System V filesystem fast symlinks extensions.
- * Aug 2001, Christoph Hellwig (hch@infradead.org)
- */
-
-#include "sysv.h"
-#include <linux/namei.h>
-
-static void *sysv_follow_link(struct dentry *dentry, struct nameidata *nd)
-{
- nd_set_link(nd, (char *)SYSV_I(dentry->d_inode)->i_data);
- return NULL;
-}
-
-const struct inode_operations sysv_fast_symlink_inode_operations = {
- .readlink = generic_readlink,
- .follow_link = sysv_follow_link,
-};
^ permalink raw reply [flat|nested] 84+ messages in thread
* [PATCH 3.2 40/77] wan/x25: Fix use-after-free in x25_asy_open_tty()
2015-12-24 15:37 [PATCH 3.2 00/77] 3.2.75-rc1 review Ben Hutchings
` (6 preceding siblings ...)
2015-12-24 15:37 ` [PATCH 3.2 25/77] USB: cdc-acm - Add IGNORE_DEVICE quirk Ben Hutchings
@ 2015-12-24 15:37 ` Ben Hutchings
2015-12-24 15:37 ` [PATCH 3.2 02/77] sctp: translate host order to network order when setting a hmacid Ben Hutchings
` (70 subsequent siblings)
78 siblings, 0 replies; 84+ messages in thread
From: Ben Hutchings @ 2015-12-24 15:37 UTC (permalink / raw)
To: linux-kernel, stable; +Cc: akpm, Peter Hurley, David S. Miller
3.2.75-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Peter Hurley <peter@hurleysoftware.com>
commit ee9159ddce14bc1dec9435ae4e3bd3153e783706 upstream.
The N_X25 line discipline may access the previous line discipline's closed
and already-freed private data on open [1].
The tty->disc_data field _never_ refers to valid data on entry to the
line discipline's open() method. Rather, the ldisc is expected to
initialize that field for its own use for the lifetime of the instance
(ie. from open() to close() only).
[1]
[ 634.336761] ==================================================================
[ 634.338226] BUG: KASAN: use-after-free in x25_asy_open_tty+0x13d/0x490 at addr ffff8800a743efd0
[ 634.339558] Read of size 4 by task syzkaller_execu/8981
[ 634.340359] =============================================================================
[ 634.341598] BUG kmalloc-512 (Not tainted): kasan: bad access detected
...
[ 634.405018] Call Trace:
[ 634.405277] dump_stack (lib/dump_stack.c:52)
[ 634.405775] print_trailer (mm/slub.c:655)
[ 634.406361] object_err (mm/slub.c:662)
[ 634.406824] kasan_report_error (mm/kasan/report.c:138 mm/kasan/report.c:236)
[ 634.409581] __asan_report_load4_noabort (mm/kasan/report.c:279)
[ 634.411355] x25_asy_open_tty (drivers/net/wan/x25_asy.c:559 (discriminator 1))
[ 634.413997] tty_ldisc_open.isra.2 (drivers/tty/tty_ldisc.c:447)
[ 634.414549] tty_set_ldisc (drivers/tty/tty_ldisc.c:567)
[ 634.415057] tty_ioctl (drivers/tty/tty_io.c:2646 drivers/tty/tty_io.c:2879)
[ 634.423524] do_vfs_ioctl (fs/ioctl.c:43 fs/ioctl.c:607)
[ 634.427491] SyS_ioctl (fs/ioctl.c:622 fs/ioctl.c:613)
[ 634.427945] entry_SYSCALL_64_fastpath (arch/x86/entry/entry_64.S:188)
Reported-and-tested-by: Sasha Levin <sasha.levin@oracle.com>
Signed-off-by: Peter Hurley <peter@hurleysoftware.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
---
drivers/net/wan/x25_asy.c | 6 +-----
1 file changed, 1 insertion(+), 5 deletions(-)
--- a/drivers/net/wan/x25_asy.c
+++ b/drivers/net/wan/x25_asy.c
@@ -547,16 +547,12 @@ static void x25_asy_receive_buf(struct t
static int x25_asy_open_tty(struct tty_struct *tty)
{
- struct x25_asy *sl = tty->disc_data;
+ struct x25_asy *sl;
int err;
if (tty->ops->write == NULL)
return -EOPNOTSUPP;
- /* First make sure we're not already connected. */
- if (sl && sl->magic == X25_ASY_MAGIC)
- return -EEXIST;
-
/* OK. Find a free X.25 channel to use. */
sl = x25_asy_alloc();
if (sl == NULL)
^ permalink raw reply [flat|nested] 84+ messages in thread
* [PATCH 3.2 29/77] vfs: Make sendfile(2) killable even better
2015-12-24 15:37 [PATCH 3.2 00/77] 3.2.75-rc1 review Ben Hutchings
` (50 preceding siblings ...)
2015-12-24 15:37 ` [PATCH 3.2 55/77] parisc iommu: fix panic due to trying to allocate too large region Ben Hutchings
@ 2015-12-24 15:37 ` Ben Hutchings
2015-12-24 15:37 ` [PATCH 3.2 20/77] mac: validate mac_partition is within sector Ben Hutchings
` (26 subsequent siblings)
78 siblings, 0 replies; 84+ messages in thread
From: Ben Hutchings @ 2015-12-24 15:37 UTC (permalink / raw)
To: linux-kernel, stable; +Cc: akpm, Al Viro, Dmitry Vyukov, Jan Kara
3.2.75-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Jan Kara <jack@suse.cz>
commit c725bfce7968009756ed2836a8cd7ba4dc163011 upstream.
Commit 296291cdd162 (mm: make sendfile(2) killable) fixed an issue where
sendfile(2) was doing a lot of tiny writes into a filesystem and thus
was unkillable for a long time. However sendfile(2) can be (mis)used to
issue lots of writes into arbitrary file descriptor such as evenfd or
similar special file descriptors which never hit the standard filesystem
write path and thus are still unkillable. E.g. the following example
from Dmitry burns CPU for ~16s on my test system without possibility to
be killed:
int r1 = eventfd(0, 0);
int r2 = memfd_create("", 0);
unsigned long n = 1<<30;
fallocate(r2, 0, 0, n);
sendfile(r1, r2, 0, n);
There are actually quite a few tests for pending signals in sendfile
code however we data to write is always available none of them seems to
trigger. So fix the problem by adding a test for pending signal into
splice_from_pipe_next() also before the loop waiting for pipe buffers to
be available. This should fix all the lockup issues with sendfile of the
do-ton-of-tiny-writes nature.
Reported-by: Dmitry Vyukov <dvyukov@google.com>
Signed-off-by: Jan Kara <jack@suse.cz>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
---
fs/splice.c | 7 +++++++
1 file changed, 7 insertions(+)
--- a/fs/splice.c
+++ b/fs/splice.c
@@ -872,6 +872,13 @@ EXPORT_SYMBOL(splice_from_pipe_feed);
*/
int splice_from_pipe_next(struct pipe_inode_info *pipe, struct splice_desc *sd)
{
+ /*
+ * Check for signal early to make process killable when there are
+ * always buffers available
+ */
+ if (signal_pending(current))
+ return -ERESTARTSYS;
+
while (!pipe->nrbufs) {
if (!pipe->writers)
return 0;
^ permalink raw reply [flat|nested] 84+ messages in thread
* [PATCH 3.2 19/77] usblp: do not set TASK_INTERRUPTIBLE before lock
2015-12-24 15:37 [PATCH 3.2 00/77] 3.2.75-rc1 review Ben Hutchings
` (21 preceding siblings ...)
2015-12-24 15:37 ` [PATCH 3.2 31/77] broadcom: fix PHY_ID_BCM5481 entry in the id table Ben Hutchings
@ 2015-12-24 15:37 ` Ben Hutchings
2015-12-24 15:37 ` [PATCH 3.2 52/77] ipmi: move timer init to before irq is setup Ben Hutchings
` (55 subsequent siblings)
78 siblings, 0 replies; 84+ messages in thread
From: Ben Hutchings @ 2015-12-24 15:37 UTC (permalink / raw)
To: linux-kernel, stable; +Cc: akpm, Jiri Slaby, Greg Kroah-Hartman, Pete Zaitcev
3.2.75-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Jiri Slaby <jslaby@suse.cz>
commit 19cd80a214821f4b558560ebd76bfb2c38b4f3d8 upstream.
It is not permitted to set task state before lock. usblp_wwait sets
the state to TASK_INTERRUPTIBLE and calls mutex_lock_interruptible.
Upon return from that function, the state will be TASK_RUNNING again.
This is clearly a bug and a warning is generated with LOCKDEP too:
WARNING: CPU: 1 PID: 5109 at kernel/sched/core.c:7404 __might_sleep+0x7d/0x90()
do not call blocking ops when !TASK_RUNNING; state=1 set at [<ffffffffa0c588d0>] usblp_wwait+0xa0/0x310 [usblp]
Modules linked in: ...
CPU: 1 PID: 5109 Comm: captmon Tainted: G W 4.2.5-0.gef2823b-default #1
Hardware name: LENOVO 23252SG/23252SG, BIOS G2ET33WW (1.13 ) 07/24/2012
ffffffff81a4edce ffff880236ec7ba8 ffffffff81716651 0000000000000000
ffff880236ec7bf8 ffff880236ec7be8 ffffffff8106e146 0000000000000282
ffffffff81a50119 000000000000028b 0000000000000000 ffff8802dab7c508
Call Trace:
...
[<ffffffff8106e1c6>] warn_slowpath_fmt+0x46/0x50
[<ffffffff8109a8bd>] __might_sleep+0x7d/0x90
[<ffffffff8171b20f>] mutex_lock_interruptible_nested+0x2f/0x4b0
[<ffffffffa0c588fc>] usblp_wwait+0xcc/0x310 [usblp]
[<ffffffffa0c58bb2>] usblp_write+0x72/0x350 [usblp]
[<ffffffff8121ed98>] __vfs_write+0x28/0xf0
...
Commit 7f477358e2384c54b190cc3b6ce28277050a041b (usblp: Implement the
ENOSPC convention) moved the set prior locking. So move it back after
the lock.
Signed-off-by: Jiri Slaby <jslaby@suse.cz>
Fixes: 7f477358e2 ("usblp: Implement the ENOSPC convention")
Acked-By: Pete Zaitcev <zaitcev@yahoo.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
---
drivers/usb/class/usblp.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/usb/class/usblp.c
+++ b/drivers/usb/class/usblp.c
@@ -861,11 +861,11 @@ static int usblp_wwait(struct usblp *usb
add_wait_queue(&usblp->wwait, &waita);
for (;;) {
- set_current_state(TASK_INTERRUPTIBLE);
if (mutex_lock_interruptible(&usblp->mut)) {
rc = -EINTR;
break;
}
+ set_current_state(TASK_INTERRUPTIBLE);
rc = usblp_wtest(usblp, nonblock);
mutex_unlock(&usblp->mut);
if (rc <= 0)
^ permalink raw reply [flat|nested] 84+ messages in thread
* [PATCH 3.2 48/77] sched/core: Clear the root_domain cpumasks in init_rootdomain()
2015-12-24 15:37 [PATCH 3.2 00/77] 3.2.75-rc1 review Ben Hutchings
` (61 preceding siblings ...)
2015-12-24 15:37 ` [PATCH 3.2 01/77] fuse: break infinite loop in fuse_fill_write_pages() Ben Hutchings
@ 2015-12-24 15:37 ` Ben Hutchings
2015-12-24 15:37 ` [PATCH 3.2 08/77] USB: ti_usb_3410_502: Fix ID table size Ben Hutchings
` (15 subsequent siblings)
78 siblings, 0 replies; 84+ messages in thread
From: Ben Hutchings @ 2015-12-24 15:37 UTC (permalink / raw)
To: linux-kernel, stable
Cc: akpm, Xunlei Pang, Linus Torvalds, Steven Rostedt, Ingo Molnar,
Mike Galbraith, Peter Zijlstra (Intel), Thomas Gleixner
3.2.75-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Xunlei Pang <xlpang@redhat.com>
commit 8295c69925ad53ec32ca54ac9fc194ff21bc40e2 upstream.
root_domain::rto_mask allocated through alloc_cpumask_var()
contains garbage data, this may cause problems. For instance,
When doing pull_rt_task(), it may do useless iterations if
rto_mask retains some extra garbage bits. Worse still, this
violates the isolated domain rule for clustered scheduling
using cpuset, because the tasks(with all the cpus allowed)
belongs to one root domain can be pulled away into another
root domain.
The patch cleans the garbage by using zalloc_cpumask_var()
instead of alloc_cpumask_var() for root_domain::rto_mask
allocation, thereby addressing the issues.
Do the same thing for root_domain's other cpumask memembers:
dlo_mask, span, and online.
Signed-off-by: Xunlei Pang <xlpang@redhat.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Steven Rostedt <rostedt@goodmis.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Link: http://lkml.kernel.org/r/1449057179-29321-1-git-send-email-xlpang@redhat.com
Signed-off-by: Ingo Molnar <mingo@kernel.org>
[bwh: Backported to 3.2:
- There's no dlo_mask to initialise
- Adjust filename]
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
---
kernel/sched.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
--- a/kernel/sched.c
+++ b/kernel/sched.c
@@ -7170,11 +7170,11 @@ static int init_rootdomain(struct root_d
{
memset(rd, 0, sizeof(*rd));
- if (!alloc_cpumask_var(&rd->span, GFP_KERNEL))
+ if (!zalloc_cpumask_var(&rd->span, GFP_KERNEL))
goto out;
- if (!alloc_cpumask_var(&rd->online, GFP_KERNEL))
+ if (!zalloc_cpumask_var(&rd->online, GFP_KERNEL))
goto free_span;
- if (!alloc_cpumask_var(&rd->rto_mask, GFP_KERNEL))
+ if (!zalloc_cpumask_var(&rd->rto_mask, GFP_KERNEL))
goto free_online;
if (cpupri_init(&rd->cpupri) != 0)
^ permalink raw reply [flat|nested] 84+ messages in thread
* [PATCH 3.2 32/77] ring-buffer: Update read stamp with first real commit on page
2015-12-24 15:37 [PATCH 3.2 00/77] 3.2.75-rc1 review Ben Hutchings
` (36 preceding siblings ...)
2015-12-24 15:37 ` [PATCH 3.2 77/77] ppp, slip: Validate VJ compression slot parameters completely Ben Hutchings
@ 2015-12-24 15:37 ` Ben Hutchings
2015-12-24 15:37 ` [PATCH 3.2 33/77] ext4: Fix handling of extended tv_sec Ben Hutchings
` (40 subsequent siblings)
78 siblings, 0 replies; 84+ messages in thread
From: Ben Hutchings @ 2015-12-24 15:37 UTC (permalink / raw)
To: linux-kernel, stable; +Cc: akpm, Steven Rostedt (Red Hat)
3.2.75-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: "Steven Rostedt (Red Hat)" <rostedt@goodmis.org>
commit b81f472a208d3e2b4392faa6d17037a89442f4ce upstream.
Do not update the read stamp after swapping out the reader page from the
write buffer. If the reader page is swapped out of the buffer before an
event is written to it, then the read_stamp may get an out of date
timestamp, as the page timestamp is updated on the first commit to that
page.
rb_get_reader_page() only returns a page if it has an event on it, otherwise
it will return NULL. At that point, check if the page being returned has
events and has not been read yet. Then at that point update the read_stamp
to match the time stamp of the reader page.
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
---
kernel/trace/ring_buffer.c | 12 +++++-------
1 file changed, 5 insertions(+), 7 deletions(-)
--- a/kernel/trace/ring_buffer.c
+++ b/kernel/trace/ring_buffer.c
@@ -1581,12 +1581,6 @@ rb_set_commit_to_write(struct ring_buffe
goto again;
}
-static void rb_reset_reader_page(struct ring_buffer_per_cpu *cpu_buffer)
-{
- cpu_buffer->read_stamp = cpu_buffer->reader_page->page->time_stamp;
- cpu_buffer->reader_page->read = 0;
-}
-
static void rb_inc_iter(struct ring_buffer_iter *iter)
{
struct ring_buffer_per_cpu *cpu_buffer = iter->cpu_buffer;
@@ -3064,7 +3058,7 @@ rb_get_reader_page(struct ring_buffer_pe
/* Finally update the reader page to the new head */
cpu_buffer->reader_page = reader;
- rb_reset_reader_page(cpu_buffer);
+ cpu_buffer->reader_page->read = 0;
if (overwrite != cpu_buffer->last_overrun) {
cpu_buffer->lost_events = overwrite - cpu_buffer->last_overrun;
@@ -3074,6 +3068,10 @@ rb_get_reader_page(struct ring_buffer_pe
goto again;
out:
+ /* Update the read_stamp on the first event */
+ if (reader && reader->read == 0)
+ cpu_buffer->read_stamp = reader->page->time_stamp;
+
arch_spin_unlock(&cpu_buffer->lock);
local_irq_restore(flags);
^ permalink raw reply [flat|nested] 84+ messages in thread
* [PATCH 3.2 13/77] FS-Cache: Add missing initialization of ret in cachefiles_write_page()
2015-12-24 15:37 [PATCH 3.2 00/77] 3.2.75-rc1 review Ben Hutchings
` (29 preceding siblings ...)
2015-12-24 15:37 ` [PATCH 3.2 36/77] nfs: if we have no valid attrs, then don't declare the attribute cache valid Ben Hutchings
@ 2015-12-24 15:37 ` Ben Hutchings
2015-12-24 15:37 ` [PATCH 3.2 03/77] ALSA: usb-audio: add packet size quirk for the Medeli DD305 Ben Hutchings
` (47 subsequent siblings)
78 siblings, 0 replies; 84+ messages in thread
From: Ben Hutchings @ 2015-12-24 15:37 UTC (permalink / raw)
To: linux-kernel, stable; +Cc: akpm, David Howells, Geert Uytterhoeven, Al Viro
3.2.75-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Geert Uytterhoeven <geert@linux-m68k.org>
commit cf89752645e47d86ba8a4157f4b121fcb33434c5 upstream.
fs/cachefiles/rdwr.c: In function ‘cachefiles_write_page’:
fs/cachefiles/rdwr.c:882: warning: ‘ret’ may be used uninitialized in
this function
If the jump to label "error" is taken, "ret" will indeed be
uninitialized, and random stack data may be printed by the debug code.
Fixes: 102f4d900c9c8f5e ("FS-Cache: Handle a write to the page immediately beyond the EOF marker")
Signed-off-by: Geert Uytterhoeven <geert@linux-m68k.org>
Signed-off-by: David Howells <dhowells@redhat.com>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
---
fs/cachefiles/rdwr.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
--- a/fs/cachefiles/rdwr.c
+++ b/fs/cachefiles/rdwr.c
@@ -894,7 +894,7 @@ int cachefiles_write_page(struct fscache
loff_t pos, eof;
size_t len;
void *data;
- int ret;
+ int ret = -ENOBUFS;
ASSERT(op != NULL);
ASSERT(page != NULL);
^ permalink raw reply [flat|nested] 84+ messages in thread
* [PATCH 3.2 31/77] broadcom: fix PHY_ID_BCM5481 entry in the id table
2015-12-24 15:37 [PATCH 3.2 00/77] 3.2.75-rc1 review Ben Hutchings
` (20 preceding siblings ...)
2015-12-24 15:37 ` [PATCH 3.2 10/77] usb: musb: core: fix order of arguments to ulpi write callback Ben Hutchings
@ 2015-12-24 15:37 ` Ben Hutchings
2015-12-24 15:37 ` [PATCH 3.2 19/77] usblp: do not set TASK_INTERRUPTIBLE before lock Ben Hutchings
` (56 subsequent siblings)
78 siblings, 0 replies; 84+ messages in thread
From: Ben Hutchings @ 2015-12-24 15:37 UTC (permalink / raw)
To: linux-kernel, stable; +Cc: akpm, David S. Miller, Aaro Koskinen
3.2.75-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Aaro Koskinen <aaro.koskinen@iki.fi>
commit 3c25a860d17b7378822f35d8c9141db9507e3beb upstream.
Commit fcb26ec5b18d ("broadcom: move all PHY_ID's to header")
updated broadcom_tbl to use PHY_IDs, but incorrectly replaced 0x0143bca0
with PHY_ID_BCM5482 (making a duplicate entry, and completely omitting
the original). Fix that.
Fixes: fcb26ec5b18d ("broadcom: move all PHY_ID's to header")
Signed-off-by: Aaro Koskinen <aaro.koskinen@iki.fi>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
---
drivers/net/phy/broadcom.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/net/phy/broadcom.c
+++ b/drivers/net/phy/broadcom.c
@@ -935,7 +935,7 @@ static struct mdio_device_id __maybe_unu
{ PHY_ID_BCM5421, 0xfffffff0 },
{ PHY_ID_BCM5461, 0xfffffff0 },
{ PHY_ID_BCM5464, 0xfffffff0 },
- { PHY_ID_BCM5482, 0xfffffff0 },
+ { PHY_ID_BCM5481, 0xfffffff0 },
{ PHY_ID_BCM5482, 0xfffffff0 },
{ PHY_ID_BCM50610, 0xfffffff0 },
{ PHY_ID_BCM50610M, 0xfffffff0 },
^ permalink raw reply [flat|nested] 84+ messages in thread
* [PATCH 3.2 04/77] ALSA: usb-audio: prevent CH345 multiport output SysEx corruption
2015-12-24 15:37 [PATCH 3.2 00/77] 3.2.75-rc1 review Ben Hutchings
` (53 preceding siblings ...)
2015-12-24 15:37 ` [PATCH 3.2 58/77] sh64: fix __NR_fgetxattr Ben Hutchings
@ 2015-12-24 15:37 ` Ben Hutchings
2015-12-24 15:37 ` [PATCH 3.2 67/77] atl1c: Improve driver not to do order 4 GFP_ATOMIC allocation Ben Hutchings
` (23 subsequent siblings)
78 siblings, 0 replies; 84+ messages in thread
From: Ben Hutchings @ 2015-12-24 15:37 UTC (permalink / raw)
To: linux-kernel, stable; +Cc: akpm, Takashi Iwai, Clemens Ladisch
3.2.75-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Clemens Ladisch <clemens@ladisch.de>
commit 1ca8b201309d842642f221db7f02f71c0af5be2d upstream.
The CH345 USB MIDI chip has two output ports. However, they are
multiplexed through one pin, and the number of ports cannot be reduced
even for hardware that implements only one connector, so for those
devices, data sent to either port ends up on the same hardware output.
This becomes a problem when both ports are used at the same time, as
longer MIDI commands (such as SysEx messages) are likely to be
interrupted by messages from the other port, and thus to get lost.
It would not be possible for the driver to detect how many ports the
device actually has, except that in practice, _all_ devices built with
the CH345 have only one port. So we can just ignore the device's
descriptors, and hardcode one output port.
Signed-off-by: Clemens Ladisch <clemens@ladisch.de>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
---
sound/usb/midi.c | 3 +++
sound/usb/quirks-table.h | 11 +++++++++++
sound/usb/quirks.c | 1 +
sound/usb/usbaudio.h | 1 +
4 files changed, 16 insertions(+)
--- a/sound/usb/midi.c
+++ b/sound/usb/midi.c
@@ -2215,6 +2215,9 @@ int snd_usbmidi_create(struct snd_card *
err = snd_usbmidi_detect_per_port_endpoints(umidi, endpoints);
break;
+ case QUIRK_MIDI_CH345:
+ err = snd_usbmidi_detect_per_port_endpoints(umidi, endpoints);
+ break;
default:
snd_printd(KERN_ERR "invalid quirk type %d\n", quirk->type);
err = -ENXIO;
--- a/sound/usb/quirks-table.h
+++ b/sound/usb/quirks-table.h
@@ -2611,6 +2611,17 @@ YAMAHA_DEVICE(0x7010, "UB99"),
.idProduct = 0x1020,
},
+/* QinHeng devices */
+{
+ USB_DEVICE(0x1a86, 0x752d),
+ .driver_info = (unsigned long) &(const struct snd_usb_audio_quirk) {
+ .vendor_name = "QinHeng",
+ .product_name = "CH345",
+ .ifnum = 1,
+ .type = QUIRK_MIDI_CH345
+ }
+},
+
/* KeithMcMillen Stringport */
{
USB_DEVICE(0x1f38, 0x0001),
--- a/sound/usb/quirks.c
+++ b/sound/usb/quirks.c
@@ -311,6 +311,7 @@ int snd_usb_create_quirk(struct snd_usb_
[QUIRK_MIDI_CME] = create_any_midi_quirk,
[QUIRK_MIDI_AKAI] = create_any_midi_quirk,
[QUIRK_MIDI_FTDI] = create_any_midi_quirk,
+ [QUIRK_MIDI_CH345] = create_any_midi_quirk,
[QUIRK_AUDIO_STANDARD_INTERFACE] = create_standard_audio_quirk,
[QUIRK_AUDIO_FIXED_ENDPOINT] = create_fixed_stream_quirk,
[QUIRK_AUDIO_EDIROL_UAXX] = create_uaxx_quirk,
--- a/sound/usb/usbaudio.h
+++ b/sound/usb/usbaudio.h
@@ -81,6 +81,7 @@ enum quirk_type {
QUIRK_MIDI_AKAI,
QUIRK_MIDI_US122L,
QUIRK_MIDI_FTDI,
+ QUIRK_MIDI_CH345,
QUIRK_AUDIO_STANDARD_INTERFACE,
QUIRK_AUDIO_FIXED_ENDPOINT,
QUIRK_AUDIO_EDIROL_UAXX,
^ permalink raw reply [flat|nested] 84+ messages in thread
* [PATCH 3.2 20/77] mac: validate mac_partition is within sector
2015-12-24 15:37 [PATCH 3.2 00/77] 3.2.75-rc1 review Ben Hutchings
` (51 preceding siblings ...)
2015-12-24 15:37 ` [PATCH 3.2 29/77] vfs: Make sendfile(2) killable even better Ben Hutchings
@ 2015-12-24 15:37 ` Ben Hutchings
2015-12-24 15:37 ` [PATCH 3.2 58/77] sh64: fix __NR_fgetxattr Ben Hutchings
` (25 subsequent siblings)
78 siblings, 0 replies; 84+ messages in thread
From: Ben Hutchings @ 2015-12-24 15:37 UTC (permalink / raw)
To: linux-kernel, stable; +Cc: akpm, Jens Axboe, Kees Cook
3.2.75-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Kees Cook <keescook@chromium.org>
commit 02e2a5bfebe99edcf9d694575a75032d53fe1b73 upstream.
If md->signature == MAC_DRIVER_MAGIC and md->block_size == 1023, a single
512 byte sector would be read (secsize / 512). However the partition
structure would be located past the end of the buffer (secsize % 512).
Signed-off-by: Kees Cook <keescook@chromium.org>
Signed-off-by: Jens Axboe <axboe@fb.com>
[bwh: Backported to 3.2: adjust filename]
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
---
fs/partitions/mac.c | 10 +++++++---
1 file changed, 7 insertions(+), 3 deletions(-)
--- a/fs/partitions/mac.c
+++ b/fs/partitions/mac.c
@@ -32,7 +32,7 @@ int mac_partition(struct parsed_partitio
Sector sect;
unsigned char *data;
int slot, blocks_in_map;
- unsigned secsize;
+ unsigned secsize, datasize, partoffset;
#ifdef CONFIG_PPC_PMAC
int found_root = 0;
int found_root_goodness = 0;
@@ -50,10 +50,14 @@ int mac_partition(struct parsed_partitio
}
secsize = be16_to_cpu(md->block_size);
put_dev_sector(sect);
- data = read_part_sector(state, secsize/512, §);
+ datasize = round_down(secsize, 512);
+ data = read_part_sector(state, datasize / 512, §);
if (!data)
return -1;
- part = (struct mac_partition *) (data + secsize%512);
+ partoffset = secsize % 512;
+ if (partoffset + sizeof(*part) > datasize)
+ return -1;
+ part = (struct mac_partition *) (data + partoffset);
if (be16_to_cpu(part->signature) != MAC_PARTITION_MAGIC) {
put_dev_sector(sect);
return 0; /* not a MacOS disk */
^ permalink raw reply [flat|nested] 84+ messages in thread
* [PATCH 3.2 34/77] jbd2: Fix unreclaimed pages after truncate in data=journal mode
2015-12-24 15:37 [PATCH 3.2 00/77] 3.2.75-rc1 review Ben Hutchings
` (63 preceding siblings ...)
2015-12-24 15:37 ` [PATCH 3.2 08/77] USB: ti_usb_3410_502: Fix ID table size Ben Hutchings
@ 2015-12-24 15:37 ` Ben Hutchings
2015-12-24 15:37 ` [PATCH 3.2 74/77] af_unix: Revert 'lock_interruptible' in stream receive code Ben Hutchings
` (13 subsequent siblings)
78 siblings, 0 replies; 84+ messages in thread
From: Ben Hutchings @ 2015-12-24 15:37 UTC (permalink / raw)
To: linux-kernel, stable; +Cc: akpm, Jan Kara, Theodore Ts'o
3.2.75-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Jan Kara <jack@suse.cz>
commit bc23f0c8d7ccd8d924c4e70ce311288cb3e61ea8 upstream.
Ted and Namjae have reported that truncated pages don't get timely
reclaimed after being truncated in data=journal mode. The following test
triggers the issue easily:
for (i = 0; i < 1000; i++) {
pwrite(fd, buf, 1024*1024, 0);
fsync(fd);
fsync(fd);
ftruncate(fd, 0);
}
The reason is that journal_unmap_buffer() finds that truncated buffers
are not journalled (jh->b_transaction == NULL), they are part of
checkpoint list of a transaction (jh->b_cp_transaction != NULL) and have
been already written out (!buffer_dirty(bh)). We clean such buffers but
we leave them in the checkpoint list. Since checkpoint transaction holds
a reference to the journal head, these buffers cannot be released until
the checkpoint transaction is cleaned up. And at that point we don't
call release_buffer_page() anymore so pages detached from mapping are
lingering in the system waiting for reclaim to find them and free them.
Fix the problem by removing buffers from transaction checkpoint lists
when journal_unmap_buffer() finds out they don't have to be there
anymore.
Reported-and-tested-by: Namjae Jeon <namjae.jeon@samsung.com>
Fixes: de1b794130b130e77ffa975bb58cb843744f9ae5
Signed-off-by: Jan Kara <jack@suse.cz>
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
---
fs/jbd2/transaction.c | 2 ++
1 file changed, 2 insertions(+)
--- a/fs/jbd2/transaction.c
+++ b/fs/jbd2/transaction.c
@@ -1876,6 +1876,7 @@ static int journal_unmap_buffer(journal_
if (!buffer_dirty(bh)) {
/* bdflush has written it. We can drop it now */
+ __jbd2_journal_remove_checkpoint(jh);
goto zap_buffer;
}
@@ -1913,6 +1914,7 @@ static int journal_unmap_buffer(journal_
/* The orphan record's transaction has
* committed. We can cleanse this buffer */
clear_buffer_jbddirty(bh);
+ __jbd2_journal_remove_checkpoint(jh);
goto zap_buffer;
}
}
^ permalink raw reply [flat|nested] 84+ messages in thread
* [PATCH 3.2 01/77] fuse: break infinite loop in fuse_fill_write_pages()
2015-12-24 15:37 [PATCH 3.2 00/77] 3.2.75-rc1 review Ben Hutchings
` (60 preceding siblings ...)
2015-12-24 15:37 ` [PATCH 3.2 76/77] isdn_ppp: Add checks for allocation failure in isdn_ppp_open() Ben Hutchings
@ 2015-12-24 15:37 ` Ben Hutchings
2015-12-24 15:37 ` [PATCH 3.2 48/77] sched/core: Clear the root_domain cpumasks in init_rootdomain() Ben Hutchings
` (16 subsequent siblings)
78 siblings, 0 replies; 84+ messages in thread
From: Ben Hutchings @ 2015-12-24 15:37 UTC (permalink / raw)
To: linux-kernel, stable
Cc: akpm, Maxim Patlasov, Konstantin Khlebnikov, Roman Gushchin,
Miklos Szeredi
3.2.75-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Roman Gushchin <klamm@yandex-team.ru>
commit 3ca8138f014a913f98e6ef40e939868e1e9ea876 upstream.
I got a report about unkillable task eating CPU. Further
investigation shows, that the problem is in the fuse_fill_write_pages()
function. If iov's first segment has zero length, we get an infinite
loop, because we never reach iov_iter_advance() call.
Fix this by calling iov_iter_advance() before repeating an attempt to
copy data from userspace.
A similar problem is described in 124d3b7041f ("fix writev regression:
pan hanging unkillable and un-straceable"). If zero-length segmend
is followed by segment with invalid address,
iov_iter_fault_in_readable() checks only first segment (zero-length),
iov_iter_copy_from_user_atomic() skips it, fails at second and
returns zero -> goto again without skipping zero-length segment.
Patch calls iov_iter_advance() before goto again: we'll skip zero-length
segment at second iteraction and iov_iter_fault_in_readable() will detect
invalid address.
Special thanks to Konstantin Khlebnikov, who helped a lot with the commit
description.
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Maxim Patlasov <mpatlasov@parallels.com>
Cc: Konstantin Khlebnikov <khlebnikov@yandex-team.ru>
Signed-off-by: Roman Gushchin <klamm@yandex-team.ru>
Signed-off-by: Miklos Szeredi <miklos@szeredi.hu>
Fixes: ea9b9907b82a ("fuse: implement perform_write")
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
---
fs/fuse/file.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
--- a/fs/fuse/file.c
+++ b/fs/fuse/file.c
@@ -850,6 +850,7 @@ static ssize_t fuse_fill_write_pages(str
mark_page_accessed(page);
+ iov_iter_advance(ii, tmp);
if (!tmp) {
unlock_page(page);
page_cache_release(page);
@@ -861,7 +862,6 @@ static ssize_t fuse_fill_write_pages(str
req->pages[req->num_pages] = page;
req->num_pages++;
- iov_iter_advance(ii, tmp);
count += tmp;
pos += tmp;
offset += tmp;
^ permalink raw reply [flat|nested] 84+ messages in thread
* [PATCH 3.2 07/77] USB: serial: ti_usb_3410_5052: add Abbott strip port ID to combined table as well.
2015-12-24 15:37 [PATCH 3.2 00/77] 3.2.75-rc1 review Ben Hutchings
2015-12-24 15:37 ` [PATCH 3.2 42/77] usb: Use the USB_SS_MULT() macro to decode burst multiplier for log message Ben Hutchings
2015-12-24 15:37 ` [PATCH 3.2 50/77] ALSA: rme96: Fix unexpected volume reset after rate changes Ben Hutchings
@ 2015-12-24 15:37 ` Ben Hutchings
2015-12-24 15:37 ` [PATCH 3.2 23/77] can: sja1000: clear interrupts on start Ben Hutchings
` (75 subsequent siblings)
78 siblings, 0 replies; 84+ messages in thread
From: Ben Hutchings @ 2015-12-24 15:37 UTC (permalink / raw)
To: linux-kernel, stable; +Cc: akpm, Greg Kroah-Hartman, Diego Elio Pettenò
3.2.75-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Diego Elio Pettenò <flameeyes@flameeyes.eu>
commit c9d09dc7ad106492c17c587b6eeb99fe3f43e522 upstream.
Without this change, the USB cable for Freestyle Option and compatible
glucometers will not be detected by the driver.
Signed-off-by: Diego Elio Pettenò <flameeyes@flameeyes.eu>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
---
drivers/usb/serial/ti_usb_3410_5052.c | 1 +
1 file changed, 1 insertion(+)
--- a/drivers/usb/serial/ti_usb_3410_5052.c
+++ b/drivers/usb/serial/ti_usb_3410_5052.c
@@ -209,6 +209,7 @@ static struct usb_device_id ti_id_table_
{ USB_DEVICE(IBM_VENDOR_ID, IBM_454B_PRODUCT_ID) },
{ USB_DEVICE(IBM_VENDOR_ID, IBM_454C_PRODUCT_ID) },
{ USB_DEVICE(ABBOTT_VENDOR_ID, ABBOTT_PRODUCT_ID) },
+ { USB_DEVICE(ABBOTT_VENDOR_ID, ABBOTT_STRIP_PORT_ID) },
{ USB_DEVICE(TI_VENDOR_ID, FRI2_PRODUCT_ID) },
{ }
};
^ permalink raw reply [flat|nested] 84+ messages in thread
* [PATCH 3.2 38/77] AHCI: Fix softreset failed issue of Port Multiplier
2015-12-24 15:37 [PATCH 3.2 00/77] 3.2.75-rc1 review Ben Hutchings
` (16 preceding siblings ...)
2015-12-24 15:37 ` [PATCH 3.2 61/77] net, scm: fix PaX detected msg_controllen overflow in scm_detach_fds Ben Hutchings
@ 2015-12-24 15:37 ` Ben Hutchings
2015-12-24 15:37 ` [PATCH 3.2 15/77] macvlan: fix leak in macvlan_handle_frame Ben Hutchings
` (60 subsequent siblings)
78 siblings, 0 replies; 84+ messages in thread
From: Ben Hutchings @ 2015-12-24 15:37 UTC (permalink / raw)
To: linux-kernel, stable; +Cc: akpm, Xiangliang Yu, Tejun Heo
3.2.75-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Xiangliang Yu <Xiangliang.Yu@amd.com>
commit 023113d24ef9e1d2b44cb2446872b17e2b01d8b1 upstream.
Current code doesn't update port value of Port Multiplier(PM) when
sending FIS of softreset to device, command will fail if FBS is
enabled.
There are two ways to fix the issue: the first is to disable FBS
before sending softreset command to PM device and the second is
to update port value of PM when sending command.
For the first way, i can't find any related rule in AHCI Spec. The
second way can avoid disabling FBS and has better performance.
Signed-off-by: Xiangliang Yu <Xiangliang.Yu@amd.com>
Signed-off-by: Tejun Heo <tj@kernel.org>
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
---
drivers/ata/libahci.c | 9 +++++++++
1 file changed, 9 insertions(+)
--- a/drivers/ata/libahci.c
+++ b/drivers/ata/libahci.c
@@ -1226,6 +1226,15 @@ static int ahci_exec_polled_cmd(struct a
ata_tf_to_fis(tf, pmp, is_cmd, fis);
ahci_fill_cmd_slot(pp, 0, cmd_fis_len | flags | (pmp << 12));
+ /* set port value for softreset of Port Multiplier */
+ if (pp->fbs_enabled && pp->fbs_last_dev != pmp) {
+ tmp = readl(port_mmio + PORT_FBS);
+ tmp &= ~(PORT_FBS_DEV_MASK | PORT_FBS_DEC);
+ tmp |= pmp << PORT_FBS_DEV_OFFSET;
+ writel(tmp, port_mmio + PORT_FBS);
+ pp->fbs_last_dev = pmp;
+ }
+
/* issue & wait */
writel(1, port_mmio + PORT_CMD_ISSUE);
^ permalink raw reply [flat|nested] 84+ messages in thread
* [PATCH 3.2 22/77] net: ip6mr: fix static mfc/dev leaks on table destruction
2015-12-24 15:37 [PATCH 3.2 00/77] 3.2.75-rc1 review Ben Hutchings
` (25 preceding siblings ...)
2015-12-24 15:37 ` [PATCH 3.2 57/77] mm: hugetlb: call huge_pte_alloc() only if ptep is null Ben Hutchings
@ 2015-12-24 15:37 ` Ben Hutchings
2015-12-24 15:37 ` [PATCH 3.2 60/77] tcp: initialize tp->copied_seq in case of cross SYN connection Ben Hutchings
` (51 subsequent siblings)
78 siblings, 0 replies; 84+ messages in thread
From: Ben Hutchings @ 2015-12-24 15:37 UTC (permalink / raw)
To: linux-kernel, stable
Cc: akpm, Benjamin Thery, Cong Wang, Nikolay Aleksandrov,
David S. Miller
3.2.75-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Nikolay Aleksandrov <nikolay@cumulusnetworks.com>
commit 4c6980462f32b4f282c5d8e5f7ea8070e2937725 upstream.
Similar to ipv4, when destroying an mrt table the static mfc entries and
the static devices are kept, which leads to devices that can never be
destroyed (because of refcnt taken) and leaked memory. Make sure that
everything is cleaned up on netns destruction.
Fixes: 8229efdaef1e ("netns: ip6mr: enable namespace support in ipv6 multicast forwarding code")
CC: Benjamin Thery <benjamin.thery@bull.net>
Signed-off-by: Nikolay Aleksandrov <nikolay@cumulusnetworks.com>
Reviewed-by: Cong Wang <cwang@twopensource.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
---
net/ipv6/ip6mr.c | 15 ++++++++-------
1 file changed, 8 insertions(+), 7 deletions(-)
--- a/net/ipv6/ip6mr.c
+++ b/net/ipv6/ip6mr.c
@@ -118,7 +118,7 @@ static int __ip6mr_fill_mroute(struct mr
struct mfc6_cache *c, struct rtmsg *rtm);
static int ip6mr_rtm_dumproute(struct sk_buff *skb,
struct netlink_callback *cb);
-static void mroute_clean_tables(struct mr6_table *mrt);
+static void mroute_clean_tables(struct mr6_table *mrt, bool all);
static void ipmr_expire_process(unsigned long arg);
#ifdef CONFIG_IPV6_MROUTE_MULTIPLE_TABLES
@@ -335,7 +335,7 @@ static struct mr6_table *ip6mr_new_table
static void ip6mr_free_table(struct mr6_table *mrt)
{
del_timer_sync(&mrt->ipmr_expire_timer);
- mroute_clean_tables(mrt);
+ mroute_clean_tables(mrt, true);
kfree(mrt);
}
@@ -1473,7 +1473,7 @@ static int ip6mr_mfc_add(struct net *net
* Close the multicast socket, and clear the vif tables etc
*/
-static void mroute_clean_tables(struct mr6_table *mrt)
+static void mroute_clean_tables(struct mr6_table *mrt, bool all)
{
int i;
LIST_HEAD(list);
@@ -1483,8 +1483,9 @@ static void mroute_clean_tables(struct m
* Shut down all active vif entries
*/
for (i = 0; i < mrt->maxvif; i++) {
- if (!(mrt->vif6_table[i].flags & VIFF_STATIC))
- mif6_delete(mrt, i, &list);
+ if (!all && (mrt->vif6_table[i].flags & VIFF_STATIC))
+ continue;
+ mif6_delete(mrt, i, &list);
}
unregister_netdevice_many(&list);
@@ -1493,7 +1494,7 @@ static void mroute_clean_tables(struct m
*/
for (i = 0; i < MFC6_LINES; i++) {
list_for_each_entry_safe(c, next, &mrt->mfc6_cache_array[i], list) {
- if (c->mfc_flags & MFC_STATIC)
+ if (!all && (c->mfc_flags & MFC_STATIC))
continue;
write_lock_bh(&mrt_lock);
list_del(&c->list);
@@ -1547,7 +1548,7 @@ int ip6mr_sk_done(struct sock *sk)
net->ipv6.devconf_all->mc_forwarding--;
write_unlock_bh(&mrt_lock);
- mroute_clean_tables(mrt);
+ mroute_clean_tables(mrt, false);
err = 0;
break;
}
^ permalink raw reply [flat|nested] 84+ messages in thread
* [PATCH 3.2 73/77] bluetooth: Validate socket address length in sco_sock_bind().
2015-12-24 15:37 [PATCH 3.2 00/77] 3.2.75-rc1 review Ben Hutchings
` (65 preceding siblings ...)
2015-12-24 15:37 ` [PATCH 3.2 74/77] af_unix: Revert 'lock_interruptible' in stream receive code Ben Hutchings
@ 2015-12-24 15:37 ` Ben Hutchings
2015-12-24 15:37 ` [PATCH 3.2 09/77] USB: ti_usb_3410_5052: Add Honeywell HGI80 ID Ben Hutchings
` (11 subsequent siblings)
78 siblings, 0 replies; 84+ messages in thread
From: Ben Hutchings @ 2015-12-24 15:37 UTC (permalink / raw)
To: linux-kernel, stable; +Cc: akpm, David S. Miller
3.2.75-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: "David S. Miller" <davem@davemloft.net>
[ Upstream commit 5233252fce714053f0151680933571a2da9cbfb4 ]
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
---
net/bluetooth/sco.c | 3 +++
1 file changed, 3 insertions(+)
--- a/net/bluetooth/sco.c
+++ b/net/bluetooth/sco.c
@@ -475,6 +475,9 @@ static int sco_sock_bind(struct socket *
if (!addr || addr->sa_family != AF_BLUETOOTH)
return -EINVAL;
+ if (addr_len < sizeof(struct sockaddr_sco))
+ return -EINVAL;
+
lock_sock(sk);
if (sk->sk_state != BT_OPEN) {
^ permalink raw reply [flat|nested] 84+ messages in thread
* [PATCH 3.2 12/77] net: fix __netdev_update_features return on ndo_set_features failure
2015-12-24 15:37 [PATCH 3.2 00/77] 3.2.75-rc1 review Ben Hutchings
` (27 preceding siblings ...)
2015-12-24 15:37 ` [PATCH 3.2 60/77] tcp: initialize tp->copied_seq in case of cross SYN connection Ben Hutchings
@ 2015-12-24 15:37 ` Ben Hutchings
2015-12-24 15:37 ` [PATCH 3.2 36/77] nfs: if we have no valid attrs, then don't declare the attribute cache valid Ben Hutchings
` (49 subsequent siblings)
78 siblings, 0 replies; 84+ messages in thread
From: Ben Hutchings @ 2015-12-24 15:37 UTC (permalink / raw)
To: linux-kernel, stable
Cc: akpm, Nikolay Aleksandrov, David S. Miller,
Michał Mirosław
3.2.75-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Nikolay Aleksandrov <nikolay@cumulusnetworks.com>
commit 00ee5927177792a6e139d50b6b7564d35705556a upstream.
If ndo_set_features fails __netdev_update_features() will return -1 but
this is wrong because it is expected to return 0 if no features were
changed (see netdev_update_features()), which will cause a netdev
notifier to be called without any actual changes. Fix this by returning
0 if ndo_set_features fails.
Fixes: 6cb6a27c45ce ("net: Call netdev_features_change() from netdev_update_features()")
CC: Michał Mirosław <mirq-linux@rere.qmqm.pl>
Signed-off-by: Nikolay Aleksandrov <nikolay@cumulusnetworks.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
[bwh: Backported to 3.2: adjust context]
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
---
net/core/dev.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -5446,7 +5446,7 @@ int __netdev_update_features(struct net_
netdev_err(dev,
"set_features() failed (%d); wanted 0x%08x, left 0x%08x\n",
err, features, dev->features);
- return -1;
+ return 0;
}
if (!err)
^ permalink raw reply [flat|nested] 84+ messages in thread
* [PATCH 3.2 42/77] usb: Use the USB_SS_MULT() macro to decode burst multiplier for log message
2015-12-24 15:37 [PATCH 3.2 00/77] 3.2.75-rc1 review Ben Hutchings
@ 2015-12-24 15:37 ` Ben Hutchings
2015-12-24 15:37 ` [PATCH 3.2 50/77] ALSA: rme96: Fix unexpected volume reset after rate changes Ben Hutchings
` (77 subsequent siblings)
78 siblings, 0 replies; 84+ messages in thread
From: Ben Hutchings @ 2015-12-24 15:37 UTC (permalink / raw)
To: linux-kernel, stable; +Cc: akpm, Greg Kroah-Hartman
3.2.75-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Ben Hutchings <ben@decadent.org.uk>
commit 5377adb092664d336ac212499961cac5e8728794 upstream.
usb_parse_ss_endpoint_companion() now decodes the burst multiplier
correctly in order to check that it's <= 3, but still uses the wrong
expression if warning that it's > 3.
Fixes: ff30cbc8da42 ("usb: Use the USB_SS_MULT() macro to get the ...")
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/usb/core/config.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
--- a/drivers/usb/core/config.c
+++ b/drivers/usb/core/config.c
@@ -117,7 +117,8 @@ static void usb_parse_ss_endpoint_compan
USB_SS_MULT(desc->bmAttributes) > 3) {
dev_warn(ddev, "Isoc endpoint has Mult of %d in "
"config %d interface %d altsetting %d ep %d: "
- "setting to 3\n", desc->bmAttributes + 1,
+ "setting to 3\n",
+ USB_SS_MULT(desc->bmAttributes),
cfgno, inum, asnum, ep->desc.bEndpointAddress);
ep->ss_ep_comp.bmAttributes = 2;
}
^ permalink raw reply [flat|nested] 84+ messages in thread
* [PATCH 3.2 14/77] mac80211: mesh: fix call_rcu() usage
2015-12-24 15:37 [PATCH 3.2 00/77] 3.2.75-rc1 review Ben Hutchings
` (72 preceding siblings ...)
2015-12-24 15:37 ` [PATCH 3.2 49/77] usb: xhci: fix config fail of FS hub behind a HS hub with MTT Ben Hutchings
@ 2015-12-24 15:37 ` Ben Hutchings
2015-12-24 15:37 ` [PATCH 3.2 18/77] USB: option: add XS Stick W100-2 from 4G Systems Ben Hutchings
` (4 subsequent siblings)
78 siblings, 0 replies; 84+ messages in thread
From: Ben Hutchings @ 2015-12-24 15:37 UTC (permalink / raw)
To: linux-kernel, stable; +Cc: akpm, Jouni Malinen, Johannes Berg
3.2.75-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Johannes Berg <johannes.berg@intel.com>
commit c2e703a55245bfff3db53b1f7cbe59f1ee8a4339 upstream.
When using call_rcu(), the called function may be delayed quite
significantly, and without a matching rcu_barrier() there's no
way to be sure it has finished.
Therefore, global state that could be gone/freed/reused should
never be touched in the callback.
Fix this in mesh by moving the atomic_dec() into the caller;
that's not really a problem since we already unlinked the path
and it will be destroyed anyway.
This fixes a crash Jouni observed when running certain tests in
a certain order, in which the mesh interface was torn down, the
memory reused for a function pointer (work struct) and running
that then crashed since the pointer had been decremented by 1,
resulting in an invalid instruction byte stream.
Fixes: eb2b9311fd00 ("mac80211: mesh path table implementation")
Reported-by: Jouni Malinen <j@w1.fi>
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
---
net/mac80211/mesh_pathtbl.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
--- a/net/mac80211/mesh_pathtbl.c
+++ b/net/mac80211/mesh_pathtbl.c
@@ -779,10 +779,8 @@ void mesh_plink_broken(struct sta_info *
static void mesh_path_node_reclaim(struct rcu_head *rp)
{
struct mpath_node *node = container_of(rp, struct mpath_node, rcu);
- struct ieee80211_sub_if_data *sdata = node->mpath->sdata;
del_timer_sync(&node->mpath->timer);
- atomic_dec(&sdata->u.mesh.mpaths);
kfree(node->mpath);
kfree(node);
}
@@ -790,8 +788,9 @@ static void mesh_path_node_reclaim(struc
/* needs to be called with the corresponding hashwlock taken */
static void __mesh_path_del(struct mesh_table *tbl, struct mpath_node *node)
{
- struct mesh_path *mpath;
- mpath = node->mpath;
+ struct mesh_path *mpath = node->mpath;
+ struct ieee80211_sub_if_data *sdata = node->mpath->sdata;
+
spin_lock(&mpath->state_lock);
mpath->flags |= MESH_PATH_RESOLVING;
if (mpath->is_gate)
@@ -799,6 +798,7 @@ static void __mesh_path_del(struct mesh_
hlist_del_rcu(&node->list);
call_rcu(&node->rcu, mesh_path_node_reclaim);
spin_unlock(&mpath->state_lock);
+ atomic_dec(&sdata->u.mesh.mpaths);
atomic_dec(&tbl->entries);
}
^ permalink raw reply [flat|nested] 84+ messages in thread
* [PATCH 3.2 63/77] ipv6: distinguish frag queues by device for multicast and link-local packets
2015-12-24 15:37 [PATCH 3.2 00/77] 3.2.75-rc1 review Ben Hutchings
` (42 preceding siblings ...)
2015-12-24 15:37 ` [PATCH 3.2 65/77] ipv6: add complete rcu protection around np->opt Ben Hutchings
@ 2015-12-24 15:37 ` Ben Hutchings
2015-12-24 15:37 ` [PATCH 3.2 64/77] dccp: remove unnecessary codes in ipv6.c Ben Hutchings
` (34 subsequent siblings)
78 siblings, 0 replies; 84+ messages in thread
From: Ben Hutchings @ 2015-12-24 15:37 UTC (permalink / raw)
To: linux-kernel, stable; +Cc: akpm, David S. Miller, Michal Kubeček
3.2.75-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Michal Kubeček <mkubecek@suse.cz>
[ Upstream commit 264640fc2c5f4f913db5c73fa3eb1ead2c45e9d7 ]
If a fragmented multicast packet is received on an ethernet device which
has an active macvlan on top of it, each fragment is duplicated and
received both on the underlying device and the macvlan. If some
fragments for macvlan are processed before the whole packet for the
underlying device is reassembled, the "overlapping fragments" test in
ip6_frag_queue() discards the whole fragment queue.
To resolve this, add device ifindex to the search key and require it to
match reassembling multicast packets and packets to link-local
addresses.
Note: similar patch has been already submitted by Yoshifuji Hideaki in
http://patchwork.ozlabs.org/patch/220979/
but got lost and forgotten for some reason.
Signed-off-by: Michal Kubecek <mkubecek@suse.cz>
Signed-off-by: David S. Miller <davem@davemloft.net>
[bwh: Backported to 3.2: adjust context]
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
---
--- a/include/net/ipv6.h
+++ b/include/net/ipv6.h
@@ -382,6 +382,7 @@ struct ip6_create_arg {
u32 user;
const struct in6_addr *src;
const struct in6_addr *dst;
+ int iif;
};
void ip6_frag_init(struct inet_frag_queue *q, void *a);
--- a/net/ipv6/netfilter/nf_conntrack_reasm.c
+++ b/net/ipv6/netfilter/nf_conntrack_reasm.c
@@ -162,7 +162,7 @@ out:
/* Creation primitives. */
static __inline__ struct nf_ct_frag6_queue *
-fq_find(__be32 id, u32 user, struct in6_addr *src, struct in6_addr *dst)
+fq_find(__be32 id, u32 user, struct in6_addr *src, struct in6_addr *dst, int iif)
{
struct inet_frag_queue *q;
struct ip6_create_arg arg;
@@ -172,6 +172,7 @@ fq_find(__be32 id, u32 user, struct in6_
arg.user = user;
arg.src = src;
arg.dst = dst;
+ arg.iif = iif;
read_lock_bh(&nf_frags.lock);
hash = inet6_hash_frag(id, src, dst, nf_frags.rnd);
@@ -558,7 +559,8 @@ struct sk_buff *nf_ct_frag6_gather(struc
if (atomic_read(&nf_init_frags.mem) > nf_init_frags.high_thresh)
nf_ct_frag6_evictor();
- fq = fq_find(fhdr->identification, user, &hdr->saddr, &hdr->daddr);
+ fq = fq_find(fhdr->identification, user, &hdr->saddr, &hdr->daddr,
+ skb->dev ? skb->dev->ifindex : 0);
if (fq == NULL) {
pr_debug("Can't find and can't create new queue\n");
goto ret_orig;
--- a/net/ipv6/reassembly.c
+++ b/net/ipv6/reassembly.c
@@ -144,8 +144,11 @@ int ip6_frag_match(struct inet_frag_queu
fq = container_of(q, struct frag_queue, q);
return (fq->id == arg->id && fq->user == arg->user &&
- ipv6_addr_equal(&fq->saddr, arg->src) &&
- ipv6_addr_equal(&fq->daddr, arg->dst));
+ ipv6_addr_equal(&fq->saddr, arg->src) &&
+ ipv6_addr_equal(&fq->daddr, arg->dst) &&
+ (arg->iif == fq->iif ||
+ !(ipv6_addr_type(arg->dst) & (IPV6_ADDR_MULTICAST |
+ IPV6_ADDR_LINKLOCAL))));
}
EXPORT_SYMBOL(ip6_frag_match);
@@ -228,7 +231,8 @@ out:
}
static __inline__ struct frag_queue *
-fq_find(struct net *net, __be32 id, const struct in6_addr *src, const struct in6_addr *dst)
+fq_find(struct net *net, __be32 id, const struct in6_addr *src,
+ const struct in6_addr *dst, int iif)
{
struct inet_frag_queue *q;
struct ip6_create_arg arg;
@@ -238,6 +242,7 @@ fq_find(struct net *net, __be32 id, cons
arg.user = IP6_DEFRAG_LOCAL_DELIVER;
arg.src = src;
arg.dst = dst;
+ arg.iif = iif;
read_lock(&ip6_frags.lock);
hash = inet6_hash_frag(id, src, dst, ip6_frags.rnd);
@@ -583,7 +588,8 @@ static int ipv6_frag_rcv(struct sk_buff
if (atomic_read(&net->ipv6.frags.mem) > net->ipv6.frags.high_thresh)
ip6_evictor(net, ip6_dst_idev(skb_dst(skb)));
- fq = fq_find(net, fhdr->identification, &hdr->saddr, &hdr->daddr);
+ fq = fq_find(net, fhdr->identification, &hdr->saddr, &hdr->daddr,
+ skb->dev ? skb->dev->ifindex : 0);
if (fq != NULL) {
int ret;
^ permalink raw reply [flat|nested] 84+ messages in thread
* [PATCH 3.2 47/77] sched/core: Remove false-positive warning from wake_up_process()
2015-12-24 15:37 [PATCH 3.2 00/77] 3.2.75-rc1 review Ben Hutchings
` (12 preceding siblings ...)
2015-12-24 15:37 ` [PATCH 3.2 43/77] dm btree: fix leak of bufio-backed block in btree_split_sibling error path Ben Hutchings
@ 2015-12-24 15:37 ` Ben Hutchings
2015-12-24 15:37 ` [PATCH 3.2 56/77] mm, vmstat: allow WQ concurrency to discover memory reclaim doesn't make any progress Ben Hutchings
` (64 subsequent siblings)
78 siblings, 0 replies; 84+ messages in thread
From: Ben Hutchings @ 2015-12-24 15:37 UTC (permalink / raw)
To: linux-kernel, stable
Cc: akpm, Mike Galbraith, oleg, Peter Zijlstra (Intel),
Thomas Gleixner, Sasha Levin, Linus Torvalds, Ingo Molnar
3.2.75-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Sasha Levin <sasha.levin@oracle.com>
commit 119d6f6a3be8b424b200dcee56e74484d5445f7e upstream.
Because wakeups can (fundamentally) be late, a task might not be in
the expected state. Therefore testing against a task's state is racy,
and can yield false positives.
Signed-off-by: Sasha Levin <sasha.levin@oracle.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Acked-by: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: oleg@redhat.com
Fixes: 9067ac85d533 ("wake_up_process() should be never used to wakeup a TASK_STOPPED/TRACED task")
Link: http://lkml.kernel.org/r/1448933660-23082-1-git-send-email-sasha.levin@oracle.com
Signed-off-by: Ingo Molnar <mingo@kernel.org>
[bwh: Backported to 3.2: adjust filename]
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
---
kernel/sched.c | 1 -
1 file changed, 1 deletion(-)
--- a/kernel/sched.c
+++ b/kernel/sched.c
@@ -2932,7 +2932,6 @@ out:
*/
int wake_up_process(struct task_struct *p)
{
- WARN_ON(task_is_stopped_or_traced(p));
return try_to_wake_up(p, TASK_NORMAL, 0);
}
EXPORT_SYMBOL(wake_up_process);
^ permalink raw reply [flat|nested] 84+ messages in thread
* [PATCH 3.2 15/77] macvlan: fix leak in macvlan_handle_frame
2015-12-24 15:37 [PATCH 3.2 00/77] 3.2.75-rc1 review Ben Hutchings
` (17 preceding siblings ...)
2015-12-24 15:37 ` [PATCH 3.2 38/77] AHCI: Fix softreset failed issue of Port Multiplier Ben Hutchings
@ 2015-12-24 15:37 ` Ben Hutchings
2015-12-24 15:37 ` [PATCH 3.2 66/77] ipv6: sctp: implement sctp_v6_destroy_sock() Ben Hutchings
` (59 subsequent siblings)
78 siblings, 0 replies; 84+ messages in thread
From: Ben Hutchings @ 2015-12-24 15:37 UTC (permalink / raw)
To: linux-kernel, stable; +Cc: akpm, Sabrina Dubroca, David S. Miller
3.2.75-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Sabrina Dubroca <sd@queasysnail.net>
commit e639b8d8a7a728f0b05ef2df6cb6b45dc3d4e556 upstream.
Reset pskb in macvlan_handle_frame in case skb_share_check returned a
clone.
Fixes: 8a4eb5734e8d ("net: introduce rx_handler results and logic around that")
Signed-off-by: Sabrina Dubroca <sd@queasysnail.net>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
---
drivers/net/macvlan.c | 2 ++
1 file changed, 2 insertions(+)
--- a/drivers/net/macvlan.c
+++ b/drivers/net/macvlan.c
@@ -172,6 +172,7 @@ static rx_handler_result_t macvlan_handl
skb = ip_check_defrag(skb, IP_DEFRAG_MACVLAN);
if (!skb)
return RX_HANDLER_CONSUMED;
+ *pskb = skb;
eth = eth_hdr(skb);
src = macvlan_hash_lookup(port, eth->h_source);
if (!src)
@@ -221,6 +222,7 @@ static rx_handler_result_t macvlan_handl
if (!skb)
goto out;
+ *pskb = skb;
skb->dev = dev;
skb->pkt_type = PACKET_HOST;
^ permalink raw reply [flat|nested] 84+ messages in thread
* [PATCH 3.2 26/77] USB: cdc_acm: Ignore Infineon Flash Loader utility
2015-12-24 15:37 [PATCH 3.2 00/77] 3.2.75-rc1 review Ben Hutchings
` (31 preceding siblings ...)
2015-12-24 15:37 ` [PATCH 3.2 03/77] ALSA: usb-audio: add packet size quirk for the Medeli DD305 Ben Hutchings
@ 2015-12-24 15:37 ` Ben Hutchings
2015-12-24 15:37 ` [PATCH 3.2 06/77] USB: serial: option: add support for Novatel MiFi USB620L Ben Hutchings
` (45 subsequent siblings)
78 siblings, 0 replies; 84+ messages in thread
From: Ben Hutchings @ 2015-12-24 15:37 UTC (permalink / raw)
To: linux-kernel, stable; +Cc: akpm, Jonas Jonsson, Johan Hovold, Daniele Palmas
3.2.75-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Jonas Jonsson <jonas@ludd.ltu.se>
commit f33a7f72e5fc033daccbb8d4753d7c5c41a4d67b upstream.
Some modems, such as the Telit UE910, are using an Infineon Flash Loader
utility. It has two interfaces, 2/2/0 (Abstract Modem) and 10/0/0 (CDC
Data). The latter can be used as a serial interface to upgrade the
firmware of the modem. However, that isn't possible when the cdc-acm
driver takes control of the device.
The following is an explanation of the behaviour by Daniele Palmas during
discussion on linux-usb.
"This is what happens when the device is turned on (without modifying
the drivers):
[155492.352031] usb 1-3: new high-speed USB device number 27 using ehci-pci
[155492.485429] usb 1-3: config 1 interface 0 altsetting 0 endpoint 0x81 has an invalid bInterval 255, changing to 11
[155492.485436] usb 1-3: New USB device found, idVendor=058b, idProduct=0041
[155492.485439] usb 1-3: New USB device strings: Mfr=0, Product=0, SerialNumber=0
[155492.485952] cdc_acm 1-3:1.0: ttyACM0: USB ACM device
This is the flashing device that is caught by the cdc-acm driver. Once
the ttyACM appears, the application starts sending a magic string
(simple write on the file descriptor) to keep the device in flashing
mode. If this magic string is not properly received in a certain time
interval, the modem goes on in normal operative mode:
[155493.748094] usb 1-3: USB disconnect, device number 27
[155494.916025] usb 1-3: new high-speed USB device number 28 using ehci-pci
[155495.059978] usb 1-3: New USB device found, idVendor=1bc7, idProduct=0021
[155495.059983] usb 1-3: New USB device strings: Mfr=1, Product=2, SerialNumber=3
[155495.059986] usb 1-3: Product: 6 CDC-ACM + 1 CDC-ECM
[155495.059989] usb 1-3: Manufacturer: Telit
[155495.059992] usb 1-3: SerialNumber: 359658044004697
[155495.138958] cdc_acm 1-3:1.0: ttyACM0: USB ACM device
[155495.140832] cdc_acm 1-3:1.2: ttyACM1: USB ACM device
[155495.142827] cdc_acm 1-3:1.4: ttyACM2: USB ACM device
[155495.144462] cdc_acm 1-3:1.6: ttyACM3: USB ACM device
[155495.145967] cdc_acm 1-3:1.8: ttyACM4: USB ACM device
[155495.147588] cdc_acm 1-3:1.10: ttyACM5: USB ACM device
[155495.154322] cdc_ether 1-3:1.12 wwan0: register 'cdc_ether' at usb-0000:00:1a.7-3, Mobile Broadband Network Device, 00:00:11:12:13:14
Using the cdc-acm driver, the string, though being sent in the same way
than using the usb-serial-simple driver (I can confirm that the data is
passing properly since I used an hw usb sniffer), does not make the
device to stay in flashing mode."
Signed-off-by: Jonas Jonsson <jonas@ludd.ltu.se>
Tested-by: Daniele Palmas <dnlplm@gmail.com>
Signed-off-by: Johan Hovold <johan@kernel.org>
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
---
drivers/usb/class/cdc-acm.c | 5 +++++
1 file changed, 5 insertions(+)
--- a/drivers/usb/class/cdc-acm.c
+++ b/drivers/usb/class/cdc-acm.c
@@ -1666,6 +1666,11 @@ static const struct usb_device_id acm_id
.driver_info = NO_DATA_INTERFACE,
},
+ /* Exclude Infineon Flash Loader utility */
+ { USB_DEVICE(0x058b, 0x0041),
+ .driver_info = IGNORE_DEVICE,
+ },
+
/* control interfaces without any protocol set */
{ USB_INTERFACE_INFO(USB_CLASS_COMM, USB_CDC_SUBCLASS_ACM,
USB_CDC_PROTO_NONE) },
^ permalink raw reply [flat|nested] 84+ messages in thread
* [PATCH 3.2 10/77] usb: musb: core: fix order of arguments to ulpi write callback
2015-12-24 15:37 [PATCH 3.2 00/77] 3.2.75-rc1 review Ben Hutchings
` (19 preceding siblings ...)
2015-12-24 15:37 ` [PATCH 3.2 66/77] ipv6: sctp: implement sctp_v6_destroy_sock() Ben Hutchings
@ 2015-12-24 15:37 ` Ben Hutchings
2015-12-24 15:37 ` [PATCH 3.2 31/77] broadcom: fix PHY_ID_BCM5481 entry in the id table Ben Hutchings
` (57 subsequent siblings)
78 siblings, 0 replies; 84+ messages in thread
From: Ben Hutchings @ 2015-12-24 15:37 UTC (permalink / raw)
To: linux-kernel, stable; +Cc: akpm, Uwe Kleine-König, Felipe Balbi
3.2.75-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
commit 705e63d2b29c8bbf091119084544d353bda70393 upstream.
There is a bit of a mess in the order of arguments to the ulpi write
callback. There is
int ulpi_write(struct ulpi *ulpi, u8 addr, u8 val)
in drivers/usb/common/ulpi.c;
struct usb_phy_io_ops {
...
int (*write)(struct usb_phy *x, u32 val, u32 reg);
}
in include/linux/usb/phy.h.
The callback registered by the musb driver has to comply to the latter,
but up to now had "offset" first which effectively made the function
broken for correct users. So flip the order and while at it also
switch to the parameter names of struct usb_phy_io_ops's write.
Fixes: ffb865b1e460 ("usb: musb: add ulpi access operations")
Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
Signed-off-by: Felipe Balbi <balbi@ti.com>
[bwh: Backported to 3.2: adjust context]
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
---
--- a/drivers/usb/musb/musb_core.c
+++ b/drivers/usb/musb/musb_core.c
@@ -131,7 +131,7 @@ static inline struct musb *dev_to_musb(s
/*-------------------------------------------------------------------------*/
#ifndef CONFIG_BLACKFIN
-static int musb_ulpi_read(struct otg_transceiver *otg, u32 offset)
+static int musb_ulpi_read(struct otg_transceiver *otg, u32 reg)
{
void __iomem *addr = otg->io_priv;
int i = 0;
@@ -147,7 +147,7 @@ static int musb_ulpi_read(struct otg_tra
* ULPICarKitControlDisableUTMI after clearing POWER_SUSPENDM.
*/
- musb_writeb(addr, MUSB_ULPI_REG_ADDR, (u8)offset);
+ musb_writeb(addr, MUSB_ULPI_REG_ADDR, (u8)reg);
musb_writeb(addr, MUSB_ULPI_REG_CONTROL,
MUSB_ULPI_REG_REQ | MUSB_ULPI_RDN_WR);
@@ -165,8 +165,7 @@ static int musb_ulpi_read(struct otg_tra
return musb_readb(addr, MUSB_ULPI_REG_DATA);
}
-static int musb_ulpi_write(struct otg_transceiver *otg,
- u32 offset, u32 data)
+static int musb_ulpi_write(struct otg_transceiver *otg, u32 val, u32 reg)
{
void __iomem *addr = otg->io_priv;
int i = 0;
@@ -178,8 +177,8 @@ static int musb_ulpi_write(struct otg_tr
power &= ~MUSB_POWER_SUSPENDM;
musb_writeb(addr, MUSB_POWER, power);
- musb_writeb(addr, MUSB_ULPI_REG_ADDR, (u8)offset);
- musb_writeb(addr, MUSB_ULPI_REG_DATA, (u8)data);
+ musb_writeb(addr, MUSB_ULPI_REG_ADDR, (u8)reg);
+ musb_writeb(addr, MUSB_ULPI_REG_DATA, (u8)val);
musb_writeb(addr, MUSB_ULPI_REG_CONTROL, MUSB_ULPI_REG_REQ);
while (!(musb_readb(addr, MUSB_ULPI_REG_CONTROL)
^ permalink raw reply [flat|nested] 84+ messages in thread
* [PATCH 3.2 09/77] USB: ti_usb_3410_5052: Add Honeywell HGI80 ID
2015-12-24 15:37 [PATCH 3.2 00/77] 3.2.75-rc1 review Ben Hutchings
` (66 preceding siblings ...)
2015-12-24 15:37 ` [PATCH 3.2 73/77] bluetooth: Validate socket address length in sco_sock_bind() Ben Hutchings
@ 2015-12-24 15:37 ` Ben Hutchings
2015-12-24 15:37 ` [PATCH 3.2 69/77] ipv6: sctp: clone options to avoid use after free Ben Hutchings
` (10 subsequent siblings)
78 siblings, 0 replies; 84+ messages in thread
From: Ben Hutchings @ 2015-12-24 15:37 UTC (permalink / raw)
To: linux-kernel, stable; +Cc: akpm, David Woodhouse, Johan Hovold, David Woodhouse
3.2.75-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: David Woodhouse <dwmw2@infradead.org>
commit 1bcb49e663f88bccee35b8688e6a3da2bea31fd4 upstream.
The Honeywell HGI80 is a wireless interface to the evohome connected
thermostat. It uses a TI 3410 USB-serial port.
Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
Signed-off-by: Johan Hovold <johan@kernel.org>
[bwh: Backported to 3.2: adjust context; update array sizes]
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
---
--- a/drivers/usb/serial/ti_usb_3410_5052.c
+++ b/drivers/usb/serial/ti_usb_3410_5052.c
@@ -164,7 +164,7 @@ static unsigned int product_5052_count;
/* the array dimension is the number of default entries plus */
/* TI_EXTRA_VID_PID_COUNT user defined entries plus 1 terminating */
/* null entry */
-static struct usb_device_id ti_id_table_3410[16+TI_EXTRA_VID_PID_COUNT+1] = {
+static struct usb_device_id ti_id_table_3410[17+TI_EXTRA_VID_PID_COUNT+1] = {
{ USB_DEVICE(TI_VENDOR_ID, TI_3410_PRODUCT_ID) },
{ USB_DEVICE(TI_VENDOR_ID, TI_3410_EZ430_ID) },
{ USB_DEVICE(MTS_VENDOR_ID, MTS_GSM_NO_FW_PRODUCT_ID) },
@@ -181,6 +181,7 @@ static struct usb_device_id ti_id_table_
{ USB_DEVICE(ABBOTT_VENDOR_ID, ABBOTT_STEREO_PLUG_ID) },
{ USB_DEVICE(ABBOTT_VENDOR_ID, ABBOTT_STRIP_PORT_ID) },
{ USB_DEVICE(TI_VENDOR_ID, FRI2_PRODUCT_ID) },
+ { USB_DEVICE(HONEYWELL_VENDOR_ID, HONEYWELL_HGI80_PRODUCT_ID) },
};
static struct usb_device_id ti_id_table_5052[5+TI_EXTRA_VID_PID_COUNT+1] = {
@@ -190,7 +191,7 @@ static struct usb_device_id ti_id_table_
{ USB_DEVICE(TI_VENDOR_ID, TI_5052_FIRMWARE_PRODUCT_ID) },
};
-static struct usb_device_id ti_id_table_combined[20+2*TI_EXTRA_VID_PID_COUNT+1] = {
+static struct usb_device_id ti_id_table_combined[21+2*TI_EXTRA_VID_PID_COUNT+1] = {
{ USB_DEVICE(TI_VENDOR_ID, TI_3410_PRODUCT_ID) },
{ USB_DEVICE(TI_VENDOR_ID, TI_3410_EZ430_ID) },
{ USB_DEVICE(MTS_VENDOR_ID, MTS_GSM_NO_FW_PRODUCT_ID) },
@@ -211,6 +212,7 @@ static struct usb_device_id ti_id_table_
{ USB_DEVICE(ABBOTT_VENDOR_ID, ABBOTT_PRODUCT_ID) },
{ USB_DEVICE(ABBOTT_VENDOR_ID, ABBOTT_STRIP_PORT_ID) },
{ USB_DEVICE(TI_VENDOR_ID, FRI2_PRODUCT_ID) },
+ { USB_DEVICE(HONEYWELL_VENDOR_ID, HONEYWELL_HGI80_PRODUCT_ID) },
{ }
};
--- a/drivers/usb/serial/ti_usb_3410_5052.h
+++ b/drivers/usb/serial/ti_usb_3410_5052.h
@@ -56,6 +56,10 @@
#define ABBOTT_PRODUCT_ID ABBOTT_STEREO_PLUG_ID
#define ABBOTT_STRIP_PORT_ID 0x3420
+/* Honeywell vendor and product IDs */
+#define HONEYWELL_VENDOR_ID 0x10ac
+#define HONEYWELL_HGI80_PRODUCT_ID 0x0102 /* Honeywell HGI80 */
+
/* Commands */
#define TI_GET_VERSION 0x01
#define TI_GET_PORT_STATUS 0x02
^ permalink raw reply [flat|nested] 84+ messages in thread
* [PATCH 3.2 46/77] drm: Fix an unwanted master inheritance v2
2015-12-24 15:37 [PATCH 3.2 00/77] 3.2.75-rc1 review Ben Hutchings
` (47 preceding siblings ...)
2015-12-24 15:37 ` [PATCH 3.2 54/77] vgaarb: fix signal handling in vga_get() Ben Hutchings
@ 2015-12-24 15:37 ` Ben Hutchings
2015-12-25 14:13 ` Thomas Hellstrom
2015-12-24 15:37 ` [PATCH 3.2 05/77] ALSA: usb-audio: work around CH345 input SysEx corruption Ben Hutchings
` (29 subsequent siblings)
78 siblings, 1 reply; 84+ messages in thread
From: Ben Hutchings @ 2015-12-24 15:37 UTC (permalink / raw)
To: linux-kernel, stable; +Cc: akpm, Thomas Hellstrom, Dave Airlie
3.2.75-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Thomas Hellstrom <thellstrom@vmware.com>
commit a0af2e538c80f3e47f1d6ddf120a153ad909e8ad upstream.
A client calling drmSetMaster() using a file descriptor that was opened
when another client was master would inherit the latter client's master
object and all its authenticated clients.
This is unwanted behaviour, and when this happens, instead allocate a
brand new master object for the client calling drmSetMaster().
Fixes a BUG() throw in vmw_master_set().
Signed-off-by: Thomas Hellstrom <thellstrom@vmware.com>
Signed-off-by: Dave Airlie <airlied@redhat.com>
[bwh: Backported to 3.2:
- s/master_mutex/struct_mutex/
- drm_new_set_master() must drop struct_mutex while calling
drm_driver::master_create
- Adjust filename, context, indentation]
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
---
--- a/drivers/gpu/drm/drm_stub.c
+++ b/drivers/gpu/drm/drm_stub.c
@@ -225,6 +225,10 @@ int drm_setmaster_ioctl(struct drm_devic
if (!file_priv->minor->master &&
file_priv->minor->master != file_priv->master) {
mutex_lock(&dev->struct_mutex);
+ if (!file_priv->allowed_master) {
+ ret = drm_new_set_master(dev, file_priv);
+ goto out_unlock;
+ }
file_priv->minor->master = drm_master_get(file_priv->master);
file_priv->is_master = 1;
if (dev->driver->master_set) {
@@ -234,10 +238,11 @@ int drm_setmaster_ioctl(struct drm_devic
drm_master_put(&file_priv->minor->master);
}
}
+ out_unlock:
mutex_unlock(&dev->struct_mutex);
}
- return 0;
+ return ret;
}
int drm_dropmaster_ioctl(struct drm_device *dev, void *data,
--- a/drivers/gpu/drm/drm_fops.c
+++ b/drivers/gpu/drm/drm_fops.c
@@ -219,6 +219,62 @@ static int drm_cpu_valid(void)
}
/**
+ * drm_new_set_master - Allocate a new master object and become master for the
+ * associated master realm.
+ *
+ * @dev: The associated device.
+ * @fpriv: File private identifying the client.
+ *
+ * This function must be called with dev::struct_mutex held.
+ * Returns negative error code on failure. Zero on success.
+ */
+int drm_new_set_master(struct drm_device *dev, struct drm_file *fpriv)
+{
+ struct drm_master *old_master;
+ int ret;
+
+ lockdep_assert_held_once(&dev->struct_mutex);
+
+ /* create a new master */
+ fpriv->minor->master = drm_master_create(fpriv->minor);
+ if (!fpriv->minor->master)
+ return -ENOMEM;
+
+ /* take another reference for the copy in the local file priv */
+ old_master = fpriv->master;
+ fpriv->master = drm_master_get(fpriv->minor->master);
+
+ if (dev->driver->master_create) {
+ mutex_unlock(&dev->struct_mutex);
+ ret = dev->driver->master_create(dev, fpriv->master);
+ mutex_lock(&dev->struct_mutex);
+ if (ret)
+ goto out_err;
+ }
+ if (dev->driver->master_set) {
+ ret = dev->driver->master_set(dev, fpriv, true);
+ if (ret)
+ goto out_err;
+ }
+
+ fpriv->is_master = 1;
+ fpriv->allowed_master = 1;
+ fpriv->authenticated = 1;
+ if (old_master)
+ drm_master_put(&old_master);
+
+ return 0;
+
+out_err:
+ /* drop both references and restore old master on failure */
+ drm_master_put(&fpriv->minor->master);
+ drm_master_put(&fpriv->master);
+ fpriv->master = old_master;
+
+ return ret;
+}
+
+/**
* Called whenever a process opens /dev/drm.
*
* \param inode device inode.
@@ -279,43 +335,10 @@ static int drm_open_helper(struct inode
mutex_lock(&dev->struct_mutex);
if (!priv->minor->master) {
/* create a new master */
- priv->minor->master = drm_master_create(priv->minor);
- if (!priv->minor->master) {
- mutex_unlock(&dev->struct_mutex);
- ret = -ENOMEM;
- goto out_free;
- }
-
- priv->is_master = 1;
- /* take another reference for the copy in the local file priv */
- priv->master = drm_master_get(priv->minor->master);
-
- priv->authenticated = 1;
-
- mutex_unlock(&dev->struct_mutex);
- if (dev->driver->master_create) {
- ret = dev->driver->master_create(dev, priv->master);
- if (ret) {
- mutex_lock(&dev->struct_mutex);
- /* drop both references if this fails */
- drm_master_put(&priv->minor->master);
- drm_master_put(&priv->master);
- mutex_unlock(&dev->struct_mutex);
- goto out_free;
- }
- }
- mutex_lock(&dev->struct_mutex);
- if (dev->driver->master_set) {
- ret = dev->driver->master_set(dev, priv, true);
- if (ret) {
- /* drop both references if this fails */
- drm_master_put(&priv->minor->master);
- drm_master_put(&priv->master);
- mutex_unlock(&dev->struct_mutex);
- goto out_free;
- }
- }
+ ret = drm_new_set_master(dev, priv);
mutex_unlock(&dev->struct_mutex);
+ if (ret)
+ goto out_free;
} else {
/* get a reference to the master */
priv->master = drm_master_get(priv->minor->master);
--- a/include/drm/drmP.h
+++ b/include/drm/drmP.h
@@ -430,6 +430,11 @@ struct drm_file {
void *driver_priv;
int is_master; /* this file private is a master for a minor */
+ /*
+ * This client is allowed to gain master privileges for @master.
+ * Protected by struct drm_device::struct_mutex.
+ */
+ unsigned allowed_master:1;
struct drm_master *master; /* master this node is currently associated with
N.B. not always minor->master */
struct list_head fbs;
@@ -1254,6 +1259,7 @@ extern int drm_fasync(int fd, struct fil
extern ssize_t drm_read(struct file *filp, char __user *buffer,
size_t count, loff_t *offset);
extern int drm_release(struct inode *inode, struct file *filp);
+extern int drm_new_set_master(struct drm_device *dev, struct drm_file *fpriv);
/* Mapping support (drm_vm.h) */
extern int drm_mmap(struct file *filp, struct vm_area_struct *vma);
^ permalink raw reply [flat|nested] 84+ messages in thread
* [PATCH 3.2 23/77] can: sja1000: clear interrupts on start
2015-12-24 15:37 [PATCH 3.2 00/77] 3.2.75-rc1 review Ben Hutchings
` (2 preceding siblings ...)
2015-12-24 15:37 ` [PATCH 3.2 07/77] USB: serial: ti_usb_3410_5052: add Abbott strip port ID to combined table as well Ben Hutchings
@ 2015-12-24 15:37 ` Ben Hutchings
2015-12-24 15:37 ` [PATCH 3.2 71/77] sh_eth: fix kernel oops in skb_put() Ben Hutchings
` (74 subsequent siblings)
78 siblings, 0 replies; 84+ messages in thread
From: Ben Hutchings @ 2015-12-24 15:37 UTC (permalink / raw)
To: linux-kernel, stable
Cc: akpm, Marc Kleine-Budde, Mirza Krak, Christian Magnusson
3.2.75-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Mirza Krak <mirza.krak@hostmobility.com>
commit 7cecd9ab80f43972c056dc068338f7bcc407b71c upstream.
According to SJA1000 data sheet error-warning (EI) interrupt is not
cleared by setting the controller in to reset-mode.
Then if we have the following case:
- system is suspended (echo mem > /sys/power/state) and SJA1000 is left
in operating state
- A bus error condition occurs which activates EI interrupt, system is
still suspended which means EI interrupt will be not be handled nor
cleared.
If the above two events occur, on resume there is no way to return the
SJA1000 to operating state, except to cycle power to it.
By simply reading the IR register on start we will clear any previous
conditions that could be present.
Signed-off-by: Mirza Krak <mirza.krak@hostmobility.com>
Reported-by: Christian Magnusson <Christian.Magnusson@semcon.com>
Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
[bwh: Backported to 3.2: s/SJA1000_IR/REG_IR/]
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
---
drivers/net/can/sja1000/sja1000.c | 3 +++
1 file changed, 3 insertions(+)
--- a/drivers/net/can/sja1000/sja1000.c
+++ b/drivers/net/can/sja1000/sja1000.c
@@ -177,6 +177,9 @@ static void sja1000_start(struct net_dev
priv->write_reg(priv, REG_RXERR, 0x0);
priv->read_reg(priv, REG_ECC);
+ /* clear interrupt flags */
+ priv->read_reg(priv, REG_IR);
+
/* leave reset mode */
set_normal_mode(dev);
}
^ permalink raw reply [flat|nested] 84+ messages in thread
* [PATCH 3.2 02/77] sctp: translate host order to network order when setting a hmacid
2015-12-24 15:37 [PATCH 3.2 00/77] 3.2.75-rc1 review Ben Hutchings
` (7 preceding siblings ...)
2015-12-24 15:37 ` [PATCH 3.2 40/77] wan/x25: Fix use-after-free in x25_asy_open_tty() Ben Hutchings
@ 2015-12-24 15:37 ` Ben Hutchings
2015-12-24 15:37 ` [PATCH 3.2 17/77] xhci: Workaround to get Intel xHCI reset working more reliably Ben Hutchings
` (69 subsequent siblings)
78 siblings, 0 replies; 84+ messages in thread
From: Ben Hutchings @ 2015-12-24 15:37 UTC (permalink / raw)
To: linux-kernel, stable
Cc: akpm, Marcelo Ricardo Leitner, David S. Miller, Vlad Yasevich,
Neil Horman, lucien
3.2.75-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: lucien <lucien.xin@gmail.com>
commit ed5a377d87dc4c87fb3e1f7f698cba38cd893103 upstream.
now sctp auth cannot work well when setting a hmacid manually, which
is caused by that we didn't use the network order for hmacid, so fix
it by adding the transformation in sctp_auth_ep_set_hmacs.
even we set hmacid with the network order in userspace, it still
can't work, because of this condition in sctp_auth_ep_set_hmacs():
if (id > SCTP_AUTH_HMAC_ID_MAX)
return -EOPNOTSUPP;
so this wasn't working before and thus it won't break compatibility.
Fixes: 65b07e5d0d09 ("[SCTP]: API updates to suport SCTP-AUTH extensions.")
Signed-off-by: Xin Long <lucien.xin@gmail.com>
Signed-off-by: Marcelo Ricardo Leitner <marcelo.leitner@gmail.com>
Acked-by: Neil Horman <nhorman@tuxdriver.com>
Acked-by: Vlad Yasevich <vyasevich@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
---
net/sctp/auth.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
--- a/net/sctp/auth.c
+++ b/net/sctp/auth.c
@@ -804,8 +804,8 @@ int sctp_auth_ep_set_hmacs(struct sctp_e
if (!has_sha1)
return -EINVAL;
- memcpy(ep->auth_hmacs_list->hmac_ids, &hmacs->shmac_idents[0],
- hmacs->shmac_num_idents * sizeof(__u16));
+ for (i = 0; i < hmacs->shmac_num_idents; i++)
+ ep->auth_hmacs_list->hmac_ids[i] = htons(hmacs->shmac_idents[i]);
ep->auth_hmacs_list->param_hdr.length = htons(sizeof(sctp_paramhdr_t) +
hmacs->shmac_num_idents * sizeof(__u16));
return 0;
^ permalink raw reply [flat|nested] 84+ messages in thread
* [PATCH 3.2 49/77] usb: xhci: fix config fail of FS hub behind a HS hub with MTT
2015-12-24 15:37 [PATCH 3.2 00/77] 3.2.75-rc1 review Ben Hutchings
` (71 preceding siblings ...)
2015-12-24 15:37 ` [PATCH 3.2 53/77] dm btree: fix bufio buffer leaks in dm_btree_del() error path Ben Hutchings
@ 2015-12-24 15:37 ` Ben Hutchings
2015-12-24 15:37 ` [PATCH 3.2 14/77] mac80211: mesh: fix call_rcu() usage Ben Hutchings
` (5 subsequent siblings)
78 siblings, 0 replies; 84+ messages in thread
From: Ben Hutchings @ 2015-12-24 15:37 UTC (permalink / raw)
To: linux-kernel, stable
Cc: akpm, Mathias Nyman, Greg Kroah-Hartman, Chunfeng Yun
3.2.75-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Chunfeng Yun <chunfeng.yun@mediatek.com>
commit 096b110a3dd3c868e4610937c80d2e3f3357c1a9 upstream.
if a full speed hub connects to a high speed hub which
supports MTT, the MTT field of its slot context will be set
to 1 when xHCI driver setups an xHCI virtual device in
xhci_setup_addressable_virt_dev(); once usb core fetch its
hub descriptor, and need to update the xHC's internal data
structures for the device, the HUB field of its slot context
will be set to 1 too, meanwhile MTT is also set before,
this will cause configure endpoint command fail, so in the
case, we should clear MTT to 0 for full speed hub according
to section 6.2.2
Signed-off-by: Chunfeng Yun <chunfeng.yun@mediatek.com>
Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
---
drivers/usb/host/xhci.c | 8 ++++++++
1 file changed, 8 insertions(+)
--- a/drivers/usb/host/xhci.c
+++ b/drivers/usb/host/xhci.c
@@ -4130,8 +4130,16 @@ int xhci_update_hub_device(struct usb_hc
ctrl_ctx->add_flags |= cpu_to_le32(SLOT_FLAG);
slot_ctx = xhci_get_slot_ctx(xhci, config_cmd->in_ctx);
slot_ctx->dev_info |= cpu_to_le32(DEV_HUB);
+ /*
+ * refer to section 6.2.2: MTT should be 0 for full speed hub,
+ * but it may be already set to 1 when setup an xHCI virtual
+ * device, so clear it anyway.
+ */
if (tt->multi)
slot_ctx->dev_info |= cpu_to_le32(DEV_MTT);
+ else if (hdev->speed == USB_SPEED_FULL)
+ slot_ctx->dev_info &= cpu_to_le32(~DEV_MTT);
+
if (xhci->hci_version > 0x95) {
xhci_dbg(xhci, "xHCI version %x needs hub "
"TT think time and number of ports\n",
^ permalink raw reply [flat|nested] 84+ messages in thread
* [PATCH 3.2 62/77] net: ipmr: fix static mfc/dev leaks on table destruction
2015-12-24 15:37 [PATCH 3.2 00/77] 3.2.75-rc1 review Ben Hutchings
` (57 preceding siblings ...)
2015-12-24 15:37 ` [PATCH 3.2 11/77] ASoC: wm8962: correct addresses for HPF_C_0/1 Ben Hutchings
@ 2015-12-24 15:37 ` Ben Hutchings
2015-12-24 15:37 ` [PATCH 3.2 37/77] drm/ttm: Fixed a read/write lock imbalance Ben Hutchings
` (19 subsequent siblings)
78 siblings, 0 replies; 84+ messages in thread
From: Ben Hutchings @ 2015-12-24 15:37 UTC (permalink / raw)
To: linux-kernel, stable
Cc: akpm, Cong Wang, Nikolay Aleksandrov, David S. Miller
3.2.75-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Nikolay Aleksandrov <nikolay@cumulusnetworks.com>
[ Upstream commit 0e615e9601a15efeeb8942cf7cd4dadba0c8c5a7 ]
When destroying an mrt table the static mfc entries and the static
devices are kept, which leads to devices that can never be destroyed
(because of refcnt taken) and leaked memory, for example:
unreferenced object 0xffff880034c144c0 (size 192):
comm "mfc-broken", pid 4777, jiffies 4320349055 (age 46001.964s)
hex dump (first 32 bytes):
98 53 f0 34 00 88 ff ff 98 53 f0 34 00 88 ff ff .S.4.....S.4....
ef 0a 0a 14 01 02 03 04 00 00 00 00 01 00 00 00 ................
backtrace:
[<ffffffff815c1b9e>] kmemleak_alloc+0x4e/0xb0
[<ffffffff811ea6e0>] kmem_cache_alloc+0x190/0x300
[<ffffffff815931cb>] ip_mroute_setsockopt+0x5cb/0x910
[<ffffffff8153d575>] do_ip_setsockopt.isra.11+0x105/0xff0
[<ffffffff8153e490>] ip_setsockopt+0x30/0xa0
[<ffffffff81564e13>] raw_setsockopt+0x33/0x90
[<ffffffff814d1e14>] sock_common_setsockopt+0x14/0x20
[<ffffffff814d0b51>] SyS_setsockopt+0x71/0xc0
[<ffffffff815cdbf6>] entry_SYSCALL_64_fastpath+0x16/0x7a
[<ffffffffffffffff>] 0xffffffffffffffff
Make sure that everything is cleaned on netns destruction.
Signed-off-by: Nikolay Aleksandrov <nikolay@cumulusnetworks.com>
Reviewed-by: Cong Wang <cwang@twopensource.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
[bwh: Backported to 3.2: adjust context]
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
---
net/ipv4/ipmr.c | 15 ++++++++-------
1 file changed, 8 insertions(+), 7 deletions(-)
--- a/net/ipv4/ipmr.c
+++ b/net/ipv4/ipmr.c
@@ -134,7 +134,7 @@ static int ipmr_cache_report(struct mr_t
struct sk_buff *pkt, vifi_t vifi, int assert);
static int __ipmr_fill_mroute(struct mr_table *mrt, struct sk_buff *skb,
struct mfc_cache *c, struct rtmsg *rtm);
-static void mroute_clean_tables(struct mr_table *mrt);
+static void mroute_clean_tables(struct mr_table *mrt, bool all);
static void ipmr_expire_process(unsigned long arg);
#ifdef CONFIG_IP_MROUTE_MULTIPLE_TABLES
@@ -346,7 +346,7 @@ static struct mr_table *ipmr_new_table(s
static void ipmr_free_table(struct mr_table *mrt)
{
del_timer_sync(&mrt->ipmr_expire_timer);
- mroute_clean_tables(mrt);
+ mroute_clean_tables(mrt, true);
kfree(mrt);
}
@@ -1143,7 +1143,7 @@ static int ipmr_mfc_add(struct net *net,
* Close the multicast socket, and clear the vif tables etc
*/
-static void mroute_clean_tables(struct mr_table *mrt)
+static void mroute_clean_tables(struct mr_table *mrt, bool all)
{
int i;
LIST_HEAD(list);
@@ -1152,8 +1152,9 @@ static void mroute_clean_tables(struct m
/* Shut down all active vif entries */
for (i = 0; i < mrt->maxvif; i++) {
- if (!(mrt->vif_table[i].flags & VIFF_STATIC))
- vif_delete(mrt, i, 0, &list);
+ if (!all && (mrt->vif_table[i].flags & VIFF_STATIC))
+ continue;
+ vif_delete(mrt, i, 0, &list);
}
unregister_netdevice_many(&list);
@@ -1161,7 +1162,7 @@ static void mroute_clean_tables(struct m
for (i = 0; i < MFC_LINES; i++) {
list_for_each_entry_safe(c, next, &mrt->mfc_cache_array[i], list) {
- if (c->mfc_flags & MFC_STATIC)
+ if (!all && (c->mfc_flags & MFC_STATIC))
continue;
list_del_rcu(&c->list);
ipmr_cache_free(c);
@@ -1191,7 +1192,7 @@ static void mrtsock_destruct(struct sock
if (sk == rtnl_dereference(mrt->mroute_sk)) {
IPV4_DEVCONF_ALL(net, MC_FORWARDING)--;
RCU_INIT_POINTER(mrt->mroute_sk, NULL);
- mroute_clean_tables(mrt);
+ mroute_clean_tables(mrt, false);
}
}
rtnl_unlock();
^ permalink raw reply [flat|nested] 84+ messages in thread
* [PATCH 3.2 66/77] ipv6: sctp: implement sctp_v6_destroy_sock()
2015-12-24 15:37 [PATCH 3.2 00/77] 3.2.75-rc1 review Ben Hutchings
` (18 preceding siblings ...)
2015-12-24 15:37 ` [PATCH 3.2 15/77] macvlan: fix leak in macvlan_handle_frame Ben Hutchings
@ 2015-12-24 15:37 ` Ben Hutchings
2015-12-24 15:37 ` [PATCH 3.2 10/77] usb: musb: core: fix order of arguments to ulpi write callback Ben Hutchings
` (58 subsequent siblings)
78 siblings, 0 replies; 84+ messages in thread
From: Ben Hutchings @ 2015-12-24 15:37 UTC (permalink / raw)
To: linux-kernel, stable
Cc: akpm, Dmitry Vyukov, Eric Dumazet, Daniel Borkmann,
David S. Miller
3.2.75-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Eric Dumazet <edumazet@google.com>
[ Upstream commit 602dd62dfbda3e63a2d6a3cbde953ebe82bf5087 ]
Dmitry Vyukov reported a memory leak using IPV6 SCTP sockets.
We need to call inet6_destroy_sock() to properly release
inet6 specific fields.
Reported-by: Dmitry Vyukov <dvyukov@google.com>
Signed-off-by: Eric Dumazet <edumazet@google.com>
Acked-by: Daniel Borkmann <daniel@iogearbox.net>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
---
net/sctp/socket.c | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -6910,6 +6910,13 @@ struct proto sctp_prot = {
#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
+#include <net/transp_v6.h>
+static void sctp_v6_destroy_sock(struct sock *sk)
+{
+ sctp_destroy_sock(sk);
+ inet6_destroy_sock(sk);
+}
+
struct proto sctpv6_prot = {
.name = "SCTPv6",
.owner = THIS_MODULE,
@@ -6919,7 +6926,7 @@ struct proto sctpv6_prot = {
.accept = sctp_accept,
.ioctl = sctp_ioctl,
.init = sctp_init_sock,
- .destroy = sctp_destroy_sock,
+ .destroy = sctp_v6_destroy_sock,
.shutdown = sctp_shutdown,
.setsockopt = sctp_setsockopt,
.getsockopt = sctp_getsockopt,
^ permalink raw reply [flat|nested] 84+ messages in thread
* [PATCH 3.2 77/77] ppp, slip: Validate VJ compression slot parameters completely
2015-12-24 15:37 [PATCH 3.2 00/77] 3.2.75-rc1 review Ben Hutchings
` (35 preceding siblings ...)
2015-12-24 15:37 ` [PATCH 3.2 24/77] USB: cp210x: Remove CP2110 ID from compatibility list Ben Hutchings
@ 2015-12-24 15:37 ` Ben Hutchings
2015-12-24 15:37 ` [PATCH 3.2 32/77] ring-buffer: Update read stamp with first real commit on page Ben Hutchings
` (41 subsequent siblings)
78 siblings, 0 replies; 84+ messages in thread
From: Ben Hutchings @ 2015-12-24 15:37 UTC (permalink / raw)
To: linux-kernel, stable; +Cc: akpm, 郭永刚, David S. Miller
3.2.75-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Ben Hutchings <ben@decadent.org.uk>
commit 4ab42d78e37a294ac7bc56901d563c642e03c4ae upstream.
Currently slhc_init() treats out-of-range values of rslots and tslots
as equivalent to 0, except that if tslots is too large it will
dereference a null pointer (CVE-2015-7799).
Add a range-check at the top of the function and make it return an
ERR_PTR() on error instead of NULL. Change the callers accordingly.
Compile-tested only.
Reported-by: 郭永刚 <guoyonggang@360.cn>
References: http://article.gmane.org/gmane.comp.security.oss.general/17908
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
Signed-off-by: David S. Miller <davem@davemloft.net>
[bwh: Backported to 3.2: adjust indentation]
---
drivers/isdn/i4l/isdn_ppp.c | 10 ++++------
drivers/net/ppp/ppp_generic.c | 6 ++----
drivers/net/slip/slhc.c | 12 ++++++++----
drivers/net/slip/slip.c | 2 +-
4 files changed, 15 insertions(+), 15 deletions(-)
--- a/drivers/isdn/i4l/isdn_ppp.c
+++ b/drivers/isdn/i4l/isdn_ppp.c
@@ -322,9 +322,9 @@ isdn_ppp_open(int min, struct file *file
* VJ header compression init
*/
is->slcomp = slhc_init(16, 16); /* not necessary for 2. link in bundle */
- if (!is->slcomp) {
+ if (IS_ERR(is->slcomp)) {
isdn_ppp_ccp_reset_free(is);
- return -ENOMEM;
+ return PTR_ERR(is->slcomp);
}
#endif
#ifdef CONFIG_IPPP_FILTER
@@ -574,10 +574,8 @@ isdn_ppp_ioctl(int min, struct file *fil
is->maxcid = val;
#ifdef CONFIG_ISDN_PPP_VJ
sltmp = slhc_init(16, val);
- if (!sltmp) {
- printk(KERN_ERR "ippp, can't realloc slhc struct\n");
- return -ENOMEM;
- }
+ if (IS_ERR(sltmp))
+ return PTR_ERR(sltmp);
if (is->slcomp)
slhc_free(is->slcomp);
is->slcomp = sltmp;
--- a/drivers/net/ppp/ppp_generic.c
+++ b/drivers/net/ppp/ppp_generic.c
@@ -703,10 +703,8 @@ static long ppp_ioctl(struct file *file,
val &= 0xffff;
}
vj = slhc_init(val2+1, val+1);
- if (!vj) {
- netdev_err(ppp->dev,
- "PPP: no memory (VJ compressor)\n");
- err = -ENOMEM;
+ if (IS_ERR(vj)) {
+ err = PTR_ERR(vj);
break;
}
ppp_lock(ppp);
--- a/drivers/net/slip/slhc.c
+++ b/drivers/net/slip/slhc.c
@@ -85,8 +85,9 @@ static long decode(unsigned char **cpp);
static unsigned char * put16(unsigned char *cp, unsigned short x);
static unsigned short pull16(unsigned char **cpp);
-/* Initialize compression data structure
+/* Allocate compression data structure
* slots must be in range 0 to 255 (zero meaning no compression)
+ * Returns pointer to structure or ERR_PTR() on error.
*/
struct slcompress *
slhc_init(int rslots, int tslots)
@@ -95,11 +96,14 @@ slhc_init(int rslots, int tslots)
register struct cstate *ts;
struct slcompress *comp;
+ if (rslots < 0 || rslots > 255 || tslots < 0 || tslots > 255)
+ return ERR_PTR(-EINVAL);
+
comp = kzalloc(sizeof(struct slcompress), GFP_KERNEL);
if (! comp)
goto out_fail;
- if ( rslots > 0 && rslots < 256 ) {
+ if (rslots > 0) {
size_t rsize = rslots * sizeof(struct cstate);
comp->rstate = kzalloc(rsize, GFP_KERNEL);
if (! comp->rstate)
@@ -107,7 +111,7 @@ slhc_init(int rslots, int tslots)
comp->rslot_limit = rslots - 1;
}
- if ( tslots > 0 && tslots < 256 ) {
+ if (tslots > 0) {
size_t tsize = tslots * sizeof(struct cstate);
comp->tstate = kzalloc(tsize, GFP_KERNEL);
if (! comp->tstate)
@@ -142,7 +146,7 @@ out_free2:
out_free:
kfree(comp);
out_fail:
- return NULL;
+ return ERR_PTR(-ENOMEM);
}
--- a/drivers/net/slip/slip.c
+++ b/drivers/net/slip/slip.c
@@ -164,7 +164,7 @@ static int sl_alloc_bufs(struct slip *sl
if (cbuff == NULL)
goto err_exit;
slcomp = slhc_init(16, 16);
- if (slcomp == NULL)
+ if (IS_ERR(slcomp))
goto err_exit;
#endif
spin_lock_bh(&sl->lock);
^ permalink raw reply [flat|nested] 84+ messages in thread
* [PATCH 3.2 08/77] USB: ti_usb_3410_502: Fix ID table size
2015-12-24 15:37 [PATCH 3.2 00/77] 3.2.75-rc1 review Ben Hutchings
` (62 preceding siblings ...)
2015-12-24 15:37 ` [PATCH 3.2 48/77] sched/core: Clear the root_domain cpumasks in init_rootdomain() Ben Hutchings
@ 2015-12-24 15:37 ` Ben Hutchings
2015-12-24 15:37 ` [PATCH 3.2 34/77] jbd2: Fix unreclaimed pages after truncate in data=journal mode Ben Hutchings
` (14 subsequent siblings)
78 siblings, 0 replies; 84+ messages in thread
From: Ben Hutchings @ 2015-12-24 15:37 UTC (permalink / raw)
To: linux-kernel, stable; +Cc: akpm
3.2.75-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Ben Hutchings <ben@decadent.org.uk>
Commit 35a2fbc941ac ("USB: serial: ti_usb_3410_5052: new device id for
Abbot strip port cable") failed to update the size of the
ti_id_table_3410 array. This doesn't need to be fixed upstream
following commit d7ece6515e12 ("USB: ti_usb_3410_5052: remove
vendor/product module parameters") but should be fixed in stable
branches older than 3.12.
Backports of commit c9d09dc7ad10 ("USB: serial: ti_usb_3410_5052: add
Abbott strip port ID to combined table as well.") similarly failed to
update the size of the ti_id_table_combined array.
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
---
--- a/drivers/usb/serial/ti_usb_3410_5052.c
+++ b/drivers/usb/serial/ti_usb_3410_5052.c
@@ -164,7 +164,7 @@ static unsigned int product_5052_count;
/* the array dimension is the number of default entries plus */
/* TI_EXTRA_VID_PID_COUNT user defined entries plus 1 terminating */
/* null entry */
-static struct usb_device_id ti_id_table_3410[15+TI_EXTRA_VID_PID_COUNT+1] = {
+static struct usb_device_id ti_id_table_3410[16+TI_EXTRA_VID_PID_COUNT+1] = {
{ USB_DEVICE(TI_VENDOR_ID, TI_3410_PRODUCT_ID) },
{ USB_DEVICE(TI_VENDOR_ID, TI_3410_EZ430_ID) },
{ USB_DEVICE(MTS_VENDOR_ID, MTS_GSM_NO_FW_PRODUCT_ID) },
@@ -190,7 +190,7 @@ static struct usb_device_id ti_id_table_
{ USB_DEVICE(TI_VENDOR_ID, TI_5052_FIRMWARE_PRODUCT_ID) },
};
-static struct usb_device_id ti_id_table_combined[19+2*TI_EXTRA_VID_PID_COUNT+1] = {
+static struct usb_device_id ti_id_table_combined[20+2*TI_EXTRA_VID_PID_COUNT+1] = {
{ USB_DEVICE(TI_VENDOR_ID, TI_3410_PRODUCT_ID) },
{ USB_DEVICE(TI_VENDOR_ID, TI_3410_EZ430_ID) },
{ USB_DEVICE(MTS_VENDOR_ID, MTS_GSM_NO_FW_PRODUCT_ID) },
^ permalink raw reply [flat|nested] 84+ messages in thread
* [PATCH 3.2 69/77] ipv6: sctp: clone options to avoid use after free
2015-12-24 15:37 [PATCH 3.2 00/77] 3.2.75-rc1 review Ben Hutchings
` (67 preceding siblings ...)
2015-12-24 15:37 ` [PATCH 3.2 09/77] USB: ti_usb_3410_5052: Add Honeywell HGI80 ID Ben Hutchings
@ 2015-12-24 15:37 ` Ben Hutchings
2015-12-24 15:37 ` [PATCH 3.2 30/77] vfs: Avoid softlockups with sendfile(2) Ben Hutchings
` (9 subsequent siblings)
78 siblings, 0 replies; 84+ messages in thread
From: Ben Hutchings @ 2015-12-24 15:37 UTC (permalink / raw)
To: linux-kernel, stable
Cc: akpm, Vlad Yasevich, David S. Miller, Eric Dumazet, Dmitry Vyukov
3.2.75-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Eric Dumazet <edumazet@google.com>
[ Upstream commit 9470e24f35ab81574da54e69df90c1eb4a96b43f ]
SCTP is lacking proper np->opt cloning at accept() time.
TCP and DCCP use ipv6_dup_options() helper, do the same
in SCTP.
We might later factorize this code in a common helper to avoid
future mistakes.
Reported-by: Dmitry Vyukov <dvyukov@google.com>
Signed-off-by: Eric Dumazet <edumazet@google.com>
Acked-by: Vlad Yasevich <vyasevich@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
---
net/sctp/ipv6.c | 8 ++++++++
1 file changed, 8 insertions(+)
--- a/net/sctp/ipv6.c
+++ b/net/sctp/ipv6.c
@@ -635,6 +635,7 @@ static struct sock *sctp_v6_create_accep
struct sock *newsk;
struct ipv6_pinfo *newnp, *np = inet6_sk(sk);
struct sctp6_sock *newsctp6sk;
+ struct ipv6_txoptions *opt;
newsk = sk_alloc(sock_net(sk), PF_INET6, GFP_KERNEL, sk->sk_prot);
if (!newsk)
@@ -654,6 +655,13 @@ static struct sock *sctp_v6_create_accep
memcpy(newnp, np, sizeof(struct ipv6_pinfo));
+ rcu_read_lock();
+ opt = rcu_dereference(np->opt);
+ if (opt)
+ opt = ipv6_dup_options(newsk, opt);
+ RCU_INIT_POINTER(newnp->opt, opt);
+ rcu_read_unlock();
+
/* Initialize sk's sport, dport, rcv_saddr and daddr for getsockname()
* and getpeername().
*/
^ permalink raw reply [flat|nested] 84+ messages in thread
* [PATCH 3.2 41/77] USB: whci-hcd: add check for dma mapping error
2015-12-24 15:37 [PATCH 3.2 00/77] 3.2.75-rc1 review Ben Hutchings
` (44 preceding siblings ...)
2015-12-24 15:37 ` [PATCH 3.2 64/77] dccp: remove unnecessary codes in ipv6.c Ben Hutchings
@ 2015-12-24 15:37 ` Ben Hutchings
2015-12-24 15:37 ` [PATCH 3.2 21/77] ip6mr: call del_timer_sync() in ip6mr_free_table() Ben Hutchings
` (32 subsequent siblings)
78 siblings, 0 replies; 84+ messages in thread
From: Ben Hutchings @ 2015-12-24 15:37 UTC (permalink / raw)
To: linux-kernel, stable; +Cc: akpm, Greg Kroah-Hartman, Alexey Khoroshilov
3.2.75-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Alexey Khoroshilov <khoroshilov@ispras.ru>
commit f9fa1887dcf26bd346665a6ae3d3f53dec54cba1 upstream.
qset_fill_page_list() do not check for dma mapping errors.
Found by Linux Driver Verification project (linuxtesting.org).
Signed-off-by: Alexey Khoroshilov <khoroshilov@ispras.ru>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
---
drivers/usb/host/whci/qset.c | 4 ++++
1 file changed, 4 insertions(+)
--- a/drivers/usb/host/whci/qset.c
+++ b/drivers/usb/host/whci/qset.c
@@ -377,6 +377,10 @@ static int qset_fill_page_list(struct wh
if (std->pl_virt == NULL)
return -ENOMEM;
std->dma_addr = dma_map_single(whc->wusbhc.dev, std->pl_virt, pl_len, DMA_TO_DEVICE);
+ if (dma_mapping_error(whc->wusbhc.dev, std->dma_addr)) {
+ kfree(std->pl_virt);
+ return -EFAULT;
+ }
for (p = 0; p < std->num_pointers; p++) {
std->pl_virt[p].buf_ptr = cpu_to_le64(dma_addr);
^ permalink raw reply [flat|nested] 84+ messages in thread
* [PATCH 3.2 30/77] vfs: Avoid softlockups with sendfile(2)
2015-12-24 15:37 [PATCH 3.2 00/77] 3.2.75-rc1 review Ben Hutchings
` (68 preceding siblings ...)
2015-12-24 15:37 ` [PATCH 3.2 69/77] ipv6: sctp: clone options to avoid use after free Ben Hutchings
@ 2015-12-24 15:37 ` Ben Hutchings
2015-12-24 15:37 ` [PATCH 3.2 35/77] RDS: fix race condition when sending a message on unbound socket Ben Hutchings
` (8 subsequent siblings)
78 siblings, 0 replies; 84+ messages in thread
From: Ben Hutchings @ 2015-12-24 15:37 UTC (permalink / raw)
To: linux-kernel, stable; +Cc: akpm, Dmitry Vyukov, Jan Kara, Al Viro
3.2.75-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Jan Kara <jack@suse.cz>
commit c2489e07c0a71a56fb2c84bc0ee66cddfca7d068 upstream.
The following test program from Dmitry can cause softlockups or RCU
stalls as it copies 1GB from tmpfs into eventfd and we don't have any
scheduling point at that path in sendfile(2) implementation:
int r1 = eventfd(0, 0);
int r2 = memfd_create("", 0);
unsigned long n = 1<<30;
fallocate(r2, 0, 0, n);
sendfile(r1, r2, 0, n);
Add cond_resched() into __splice_from_pipe() to fix the problem.
CC: Dmitry Vyukov <dvyukov@google.com>
Signed-off-by: Jan Kara <jack@suse.cz>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
---
fs/splice.c | 1 +
1 file changed, 1 insertion(+)
--- a/fs/splice.c
+++ b/fs/splice.c
@@ -957,6 +957,7 @@ ssize_t __splice_from_pipe(struct pipe_i
splice_from_pipe_begin(sd);
do {
+ cond_resched();
ret = splice_from_pipe_next(pipe, sd);
if (ret > 0)
ret = splice_from_pipe_feed(pipe, sd, actor);
^ permalink raw reply [flat|nested] 84+ messages in thread
* [PATCH 3.2 50/77] ALSA: rme96: Fix unexpected volume reset after rate changes
2015-12-24 15:37 [PATCH 3.2 00/77] 3.2.75-rc1 review Ben Hutchings
2015-12-24 15:37 ` [PATCH 3.2 42/77] usb: Use the USB_SS_MULT() macro to decode burst multiplier for log message Ben Hutchings
@ 2015-12-24 15:37 ` Ben Hutchings
2015-12-24 15:37 ` [PATCH 3.2 07/77] USB: serial: ti_usb_3410_5052: add Abbott strip port ID to combined table as well Ben Hutchings
` (76 subsequent siblings)
78 siblings, 0 replies; 84+ messages in thread
From: Ben Hutchings @ 2015-12-24 15:37 UTC (permalink / raw)
To: linux-kernel, stable; +Cc: akpm, Takashi Iwai
3.2.75-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Takashi Iwai <tiwai@suse.de>
commit a74a821624c0c75388a193337babd17a8c02c740 upstream.
rme96 driver needs to reset DAC depending on the sample rate, and this
results in resetting to the max volume suddenly. It's because of the
missing call of snd_rme96_apply_dac_volume().
However, calling this function right after the DAC reset still may not
work, and we need some delay before this call. Since the DAC reset
and the procedure after that are performed in the spinlock, we delay
the DAC volume restore at the end after the spinlock.
Reported-and-tested-by: Sylvain LABOISNE <maeda1@free.fr>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
---
sound/pci/rme96.c | 41 ++++++++++++++++++++++++++---------------
1 file changed, 26 insertions(+), 15 deletions(-)
--- a/sound/pci/rme96.c
+++ b/sound/pci/rme96.c
@@ -704,10 +704,11 @@ snd_rme96_playback_setrate(struct rme96
{
/* change to/from double-speed: reset the DAC (if available) */
snd_rme96_reset_dac(rme96);
+ return 1; /* need to restore volume */
} else {
writel(rme96->wcreg, rme96->iobase + RME96_IO_CONTROL_REGISTER);
+ return 0;
}
- return 0;
}
static int
@@ -945,6 +946,7 @@ snd_rme96_playback_hw_params(struct snd_
struct rme96 *rme96 = snd_pcm_substream_chip(substream);
struct snd_pcm_runtime *runtime = substream->runtime;
int err, rate, dummy;
+ bool apply_dac_volume = false;
runtime->dma_area = (void __force *)(rme96->iobase +
RME96_IO_PLAY_BUFFER);
@@ -958,24 +960,26 @@ snd_rme96_playback_hw_params(struct snd_
{
/* slave clock */
if ((int)params_rate(params) != rate) {
- spin_unlock_irq(&rme96->lock);
- return -EIO;
- }
- } else if ((err = snd_rme96_playback_setrate(rme96, params_rate(params))) < 0) {
- spin_unlock_irq(&rme96->lock);
- return err;
- }
- if ((err = snd_rme96_playback_setformat(rme96, params_format(params))) < 0) {
- spin_unlock_irq(&rme96->lock);
- return err;
+ err = -EIO;
+ goto error;
+ }
+ } else {
+ err = snd_rme96_playback_setrate(rme96, params_rate(params));
+ if (err < 0)
+ goto error;
+ apply_dac_volume = err > 0; /* need to restore volume later? */
}
+
+ err = snd_rme96_playback_setformat(rme96, params_format(params));
+ if (err < 0)
+ goto error;
snd_rme96_setframelog(rme96, params_channels(params), 1);
if (rme96->capture_periodsize != 0) {
if (params_period_size(params) << rme96->playback_frlog !=
rme96->capture_periodsize)
{
- spin_unlock_irq(&rme96->lock);
- return -EBUSY;
+ err = -EBUSY;
+ goto error;
}
}
rme96->playback_periodsize =
@@ -986,9 +990,16 @@ snd_rme96_playback_hw_params(struct snd_
rme96->wcreg &= ~(RME96_WCR_PRO | RME96_WCR_DOLBY | RME96_WCR_EMP);
writel(rme96->wcreg |= rme96->wcreg_spdif_stream, rme96->iobase + RME96_IO_CONTROL_REGISTER);
}
+
+ err = 0;
+ error:
spin_unlock_irq(&rme96->lock);
-
- return 0;
+ if (apply_dac_volume) {
+ usleep_range(3000, 10000);
+ snd_rme96_apply_dac_volume(rme96);
+ }
+
+ return err;
}
static int
^ permalink raw reply [flat|nested] 84+ messages in thread
* [PATCH 3.2 11/77] ASoC: wm8962: correct addresses for HPF_C_0/1
2015-12-24 15:37 [PATCH 3.2 00/77] 3.2.75-rc1 review Ben Hutchings
` (56 preceding siblings ...)
2015-12-24 15:37 ` [PATCH 3.2 44/77] ipv4: igmp: Allow removing groups from a removed interface Ben Hutchings
@ 2015-12-24 15:37 ` Ben Hutchings
2015-12-24 15:37 ` [PATCH 3.2 62/77] net: ipmr: fix static mfc/dev leaks on table destruction Ben Hutchings
` (20 subsequent siblings)
78 siblings, 0 replies; 84+ messages in thread
From: Ben Hutchings @ 2015-12-24 15:37 UTC (permalink / raw)
To: linux-kernel, stable; +Cc: akpm, Mark Brown, Sachin Pandhare, Charles Keepax
3.2.75-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Sachin Pandhare <sachinpandhare@gmail.com>
commit e9f96bc53c1b959859599cb30ce6fd4fbb4448c2 upstream.
=46romdatasheet:
R17408 (4400h) HPF_C_1
R17409 (4401h) HPF_C_0
17048 -> 17408 (0x4400)
17049 -> 17409 (0x4401)
Signed-off-by: Sachin Pandhare <sachinpandhare@gmail.com>
Acked-by: Charles Keepax <ckeepax@opensource.wolfsonmicro.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
[bwh: Backported to 3.2: wm8962_reg is a sparse array, not an array of
{ offset, value } pairs]
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
---
sound/soc/codecs/wm8962.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
--- a/sound/soc/codecs/wm8962.c
+++ b/sound/soc/codecs/wm8962.c
@@ -373,8 +373,8 @@ static const u16 wm8962_reg[WM8962_MAX_R
[16924] = 0x0059, /* R16924 - HDBASS_PG_1 */
[16925] = 0x999A, /* R16925 - HDBASS_PG_0 */
- [17048] = 0x0083, /* R17408 - HPF_C_1 */
- [17049] = 0x98AD, /* R17409 - HPF_C_0 */
+ [17408] = 0x0083, /* R17408 - HPF_C_1 */
+ [17409] = 0x98AD, /* R17409 - HPF_C_0 */
[17920] = 0x007F, /* R17920 - ADCL_RETUNE_C1_1 */
[17921] = 0xFFFF, /* R17921 - ADCL_RETUNE_C1_0 */
^ permalink raw reply [flat|nested] 84+ messages in thread
* [PATCH 3.2 53/77] dm btree: fix bufio buffer leaks in dm_btree_del() error path
2015-12-24 15:37 [PATCH 3.2 00/77] 3.2.75-rc1 review Ben Hutchings
` (70 preceding siblings ...)
2015-12-24 15:37 ` [PATCH 3.2 35/77] RDS: fix race condition when sending a message on unbound socket Ben Hutchings
@ 2015-12-24 15:37 ` Ben Hutchings
2015-12-24 15:37 ` [PATCH 3.2 49/77] usb: xhci: fix config fail of FS hub behind a HS hub with MTT Ben Hutchings
` (6 subsequent siblings)
78 siblings, 0 replies; 84+ messages in thread
From: Ben Hutchings @ 2015-12-24 15:37 UTC (permalink / raw)
To: linux-kernel, stable; +Cc: akpm, Joe Thornber, Mike Snitzer
3.2.75-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Joe Thornber <ejt@redhat.com>
commit ed8b45a3679eb49069b094c0711b30833f27c734 upstream.
If dm_btree_del()'s call to push_frame() fails, e.g. due to
btree_node_validator finding invalid metadata, the dm_btree_del() error
path must unlock all frames (which have active dm-bufio buffers) that
were pushed onto the del_stack.
Otherwise, dm_bufio_client_destroy() will BUG_ON() because dm-bufio
buffers have leaked, e.g.:
device-mapper: bufio: leaked buffer 3, hold count 1, list 0
Signed-off-by: Joe Thornber <ejt@redhat.com>
Signed-off-by: Mike Snitzer <snitzer@redhat.com>
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
---
drivers/md/persistent-data/dm-btree.c | 16 +++++++++++++++-
1 file changed, 15 insertions(+), 1 deletion(-)
--- a/drivers/md/persistent-data/dm-btree.c
+++ b/drivers/md/persistent-data/dm-btree.c
@@ -231,6 +231,16 @@ static void pop_frame(struct del_stack *
dm_tm_unlock(s->tm, f->b);
}
+static void unlock_all_frames(struct del_stack *s)
+{
+ struct frame *f;
+
+ while (unprocessed_frames(s)) {
+ f = s->spine + s->top--;
+ dm_tm_unlock(s->tm, f->b);
+ }
+}
+
int dm_btree_del(struct dm_btree_info *info, dm_block_t root)
{
int r;
@@ -286,9 +296,13 @@ int dm_btree_del(struct dm_btree_info *i
f->current_child = f->nr_children;
}
}
-
out:
+ if (r) {
+ /* cleanup all frames of del_stack */
+ unlock_all_frames(s);
+ }
kfree(s);
+
return r;
}
EXPORT_SYMBOL_GPL(dm_btree_del);
^ permalink raw reply [flat|nested] 84+ messages in thread
* [PATCH 3.2 70/77] net: add validation for the socket syscall protocol argument
2015-12-24 15:37 [PATCH 3.2 00/77] 3.2.75-rc1 review Ben Hutchings
` (40 preceding siblings ...)
2015-12-24 15:37 ` [PATCH 3.2 39/77] sata_sil: disable trim Ben Hutchings
@ 2015-12-24 15:37 ` Ben Hutchings
2015-12-24 15:37 ` [PATCH 3.2 65/77] ipv6: add complete rcu protection around np->opt Ben Hutchings
` (36 subsequent siblings)
78 siblings, 0 replies; 84+ messages in thread
From: Ben Hutchings @ 2015-12-24 15:37 UTC (permalink / raw)
To: linux-kernel, stable
Cc: akpm, Hannes Frederic Sowa, Cong Wang, David S. Miller,
郭永刚
3.2.75-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Hannes Frederic Sowa <hannes@stressinduktion.org>
[ Upstream commit 79462ad02e861803b3840cc782248c7359451cd9 ]
郭永刚 reported that one could simply crash the kernel as root by
using a simple program:
int socket_fd;
struct sockaddr_in addr;
addr.sin_port = 0;
addr.sin_addr.s_addr = INADDR_ANY;
addr.sin_family = 10;
socket_fd = socket(10,3,0x40000000);
connect(socket_fd , &addr,16);
AF_INET, AF_INET6 sockets actually only support 8-bit protocol
identifiers. inet_sock's skc_protocol field thus is sized accordingly,
thus larger protocol identifiers simply cut off the higher bits and
store a zero in the protocol fields.
This could lead to e.g. NULL function pointer because as a result of
the cut off inet_num is zero and we call down to inet_autobind, which
is NULL for raw sockets.
kernel: Call Trace:
kernel: [<ffffffff816db90e>] ? inet_autobind+0x2e/0x70
kernel: [<ffffffff816db9a4>] inet_dgram_connect+0x54/0x80
kernel: [<ffffffff81645069>] SYSC_connect+0xd9/0x110
kernel: [<ffffffff810ac51b>] ? ptrace_notify+0x5b/0x80
kernel: [<ffffffff810236d8>] ? syscall_trace_enter_phase2+0x108/0x200
kernel: [<ffffffff81645e0e>] SyS_connect+0xe/0x10
kernel: [<ffffffff81779515>] tracesys_phase2+0x84/0x89
I found no particular commit which introduced this problem.
CVE: CVE-2015-8543
Cc: Cong Wang <cwang@twopensource.com>
Reported-by: 郭永刚 <guoyonggang@360.cn>
Signed-off-by: Hannes Frederic Sowa <hannes@stressinduktion.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
[bwh: Backported to 3.2: open-code U8_MAX]
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
---
include/net/sock.h | 1 +
net/ax25/af_ax25.c | 3 +++
net/decnet/af_decnet.c | 3 +++
net/ipv4/af_inet.c | 3 +++
net/ipv6/af_inet6.c | 3 +++
net/irda/af_irda.c | 3 +++
6 files changed, 16 insertions(+)
--- a/include/net/sock.h
+++ b/include/net/sock.h
@@ -302,6 +302,7 @@ struct sock {
sk_no_check : 2,
sk_userlocks : 4,
sk_protocol : 8,
+#define SK_PROTOCOL_MAX ((u8)~0U)
sk_type : 16;
kmemcheck_bitfield_end(flags);
int sk_wmem_queued;
--- a/net/ax25/af_ax25.c
+++ b/net/ax25/af_ax25.c
@@ -806,6 +806,9 @@ static int ax25_create(struct net *net,
struct sock *sk;
ax25_cb *ax25;
+ if (protocol < 0 || protocol > SK_PROTOCOL_MAX)
+ return -EINVAL;
+
if (!net_eq(net, &init_net))
return -EAFNOSUPPORT;
--- a/net/decnet/af_decnet.c
+++ b/net/decnet/af_decnet.c
@@ -681,6 +681,9 @@ static int dn_create(struct net *net, st
{
struct sock *sk;
+ if (protocol < 0 || protocol > SK_PROTOCOL_MAX)
+ return -EINVAL;
+
if (!net_eq(net, &init_net))
return -EAFNOSUPPORT;
--- a/net/ipv4/af_inet.c
+++ b/net/ipv4/af_inet.c
@@ -279,6 +279,9 @@ static int inet_create(struct net *net,
int try_loading_module = 0;
int err;
+ if (protocol < 0 || protocol >= IPPROTO_MAX)
+ return -EINVAL;
+
if (unlikely(!inet_ehash_secret))
if (sock->type != SOCK_RAW && sock->type != SOCK_DGRAM)
build_ehash_secret();
--- a/net/ipv6/af_inet6.c
+++ b/net/ipv6/af_inet6.c
@@ -109,6 +109,9 @@ static int inet6_create(struct net *net,
int try_loading_module = 0;
int err;
+ if (protocol < 0 || protocol >= IPPROTO_MAX)
+ return -EINVAL;
+
if (sock->type != SOCK_RAW &&
sock->type != SOCK_DGRAM &&
!inet_ehash_secret)
--- a/net/irda/af_irda.c
+++ b/net/irda/af_irda.c
@@ -1106,6 +1106,9 @@ static int irda_create(struct net *net,
IRDA_DEBUG(2, "%s()\n", __func__);
+ if (protocol < 0 || protocol > SK_PROTOCOL_MAX)
+ return -EINVAL;
+
if (net != &init_net)
return -EAFNOSUPPORT;
^ permalink raw reply [flat|nested] 84+ messages in thread
* [PATCH 3.2 27/77] unix: avoid use-after-free in ep_remove_wait_queue
2015-12-24 15:37 [PATCH 3.2 00/77] 3.2.75-rc1 review Ben Hutchings
` (4 preceding siblings ...)
2015-12-24 15:37 ` [PATCH 3.2 71/77] sh_eth: fix kernel oops in skb_put() Ben Hutchings
@ 2015-12-24 15:37 ` Ben Hutchings
2015-12-24 15:37 ` [PATCH 3.2 25/77] USB: cdc-acm - Add IGNORE_DEVICE quirk Ben Hutchings
` (72 subsequent siblings)
78 siblings, 0 replies; 84+ messages in thread
From: Ben Hutchings @ 2015-12-24 15:37 UTC (permalink / raw)
To: linux-kernel, stable; +Cc: akpm, Rainer Weikusat, David S. Miller, Jason Baron
3.2.75-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Rainer Weikusat <rweikusat@mobileactivedefense.com>
commit 7d267278a9ece963d77eefec61630223fce08c6c upstream.
Rainer Weikusat <rweikusat@mobileactivedefense.com> writes:
An AF_UNIX datagram socket being the client in an n:1 association with
some server socket is only allowed to send messages to the server if the
receive queue of this socket contains at most sk_max_ack_backlog
datagrams. This implies that prospective writers might be forced to go
to sleep despite none of the message presently enqueued on the server
receive queue were sent by them. In order to ensure that these will be
woken up once space becomes again available, the present unix_dgram_poll
routine does a second sock_poll_wait call with the peer_wait wait queue
of the server socket as queue argument (unix_dgram_recvmsg does a wake
up on this queue after a datagram was received). This is inherently
problematic because the server socket is only guaranteed to remain alive
for as long as the client still holds a reference to it. In case the
connection is dissolved via connect or by the dead peer detection logic
in unix_dgram_sendmsg, the server socket may be freed despite "the
polling mechanism" (in particular, epoll) still has a pointer to the
corresponding peer_wait queue. There's no way to forcibly deregister a
wait queue with epoll.
Based on an idea by Jason Baron, the patch below changes the code such
that a wait_queue_t belonging to the client socket is enqueued on the
peer_wait queue of the server whenever the peer receive queue full
condition is detected by either a sendmsg or a poll. A wake up on the
peer queue is then relayed to the ordinary wait queue of the client
socket via wake function. The connection to the peer wait queue is again
dissolved if either a wake up is about to be relayed or the client
socket reconnects or a dead peer is detected or the client socket is
itself closed. This enables removing the second sock_poll_wait from
unix_dgram_poll, thus avoiding the use-after-free, while still ensuring
that no blocked writer sleeps forever.
Signed-off-by: Rainer Weikusat <rweikusat@mobileactivedefense.com>
Fixes: ec0d215f9420 ("af_unix: fix 'poll for write'/connected DGRAM sockets")
Reviewed-by: Jason Baron <jbaron@akamai.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
[bwh: Backported to 3.2: adjust context]
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
---
include/net/af_unix.h | 1 +
net/unix/af_unix.c | 183 ++++++++++++++++++++++++++++++++++++++++++++------
2 files changed, 165 insertions(+), 19 deletions(-)
--- a/include/net/af_unix.h
+++ b/include/net/af_unix.h
@@ -58,6 +58,7 @@ struct unix_sock {
unsigned int gc_maybe_cycle : 1;
unsigned char recursion_level;
struct socket_wq peer_wq;
+ wait_queue_t peer_wake;
};
#define unix_sk(__sk) ((struct unix_sock *)__sk)
--- a/net/unix/af_unix.c
+++ b/net/unix/af_unix.c
@@ -303,6 +303,118 @@ found:
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 inline int unix_writable(struct sock *sk)
{
return (atomic_read(&sk->sk_wmem_alloc) << 2) <= sk->sk_sndbuf;
@@ -409,6 +521,8 @@ static void unix_release_sock(struct soc
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 */
unix_peer(sk) = NULL;
}
@@ -630,6 +744,7 @@ static struct sock *unix_create1(struct
INIT_LIST_HEAD(&u->link);
mutex_init(&u->readlock); /* single task reading 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);
out:
if (sk == NULL)
@@ -1005,6 +1120,8 @@ restart:
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)
@@ -1444,6 +1561,7 @@ static int unix_dgram_sendmsg(struct kio
long timeo;
struct scm_cookie tmp_scm;
int max_level;
+ int sk_locked;
if (NULL == siocb->scm)
siocb->scm = &tmp_scm;
@@ -1512,12 +1630,14 @@ restart:
goto out_free;
}
+ sk_locked = 0;
unix_state_lock(other);
+restart_locked:
err = -EPERM;
if (!unix_may_send(sk, other))
goto out_unlock;
- if (sock_flag(other, SOCK_DEAD)) {
+ if (unlikely(sock_flag(other, SOCK_DEAD))) {
/*
* Check with 1003.1g - what should
* datagram error
@@ -1525,10 +1645,14 @@ restart:
unix_state_unlock(other);
sock_put(other);
+ if (!sk_locked)
+ unix_state_lock(sk);
+
err = 0;
- unix_state_lock(sk);
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);
@@ -1554,21 +1678,38 @@ restart:
goto out_unlock;
}
- if (unix_peer(other) != sk && unix_recvq_full(other)) {
- if (!timeo) {
- err = -EAGAIN;
- goto out_unlock;
+ if (unlikely(unix_peer(other) != sk && unix_recvq_full(other))) {
+ if (timeo) {
+ timeo = unix_wait_for_peer(other, timeo);
+
+ err = sock_intr_errno(timeo);
+ if (signal_pending(current))
+ goto out_free;
+
+ goto restart;
}
- timeo = unix_wait_for_peer(other, timeo);
+ if (!sk_locked) {
+ unix_state_unlock(other);
+ unix_state_double_lock(sk, other);
+ }
- err = sock_intr_errno(timeo);
- if (signal_pending(current))
- goto out_free;
+ if (unix_peer(sk) != other ||
+ unix_dgram_peer_wake_me(sk, other)) {
+ err = -EAGAIN;
+ sk_locked = 1;
+ goto out_unlock;
+ }
- goto restart;
+ 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);
@@ -1582,6 +1723,8 @@ restart:
return len;
out_unlock:
+ if (sk_locked)
+ unix_state_unlock(sk);
unix_state_unlock(other);
out_free:
kfree_skb(skb);
@@ -2186,14 +2329,16 @@ static unsigned int unix_dgram_poll(stru
return mask;
writable = unix_writable(sk);
- other = unix_peer_get(sk);
- if (other) {
- if (unix_peer(other) != sk) {
- sock_poll_wait(file, &unix_sk(other)->peer_wait, wait);
- if (unix_recvq_full(other))
- writable = 0;
- }
- sock_put(other);
+ if (writable) {
+ unix_state_lock(sk);
+
+ other = unix_peer(sk);
+ if (other && unix_peer(other) != sk &&
+ unix_recvq_full(other) &&
+ unix_dgram_peer_wake_me(sk, other))
+ writable = 0;
+
+ unix_state_unlock(sk);
}
if (writable)
^ permalink raw reply [flat|nested] 84+ messages in thread
* [PATCH 3.2 65/77] ipv6: add complete rcu protection around np->opt
2015-12-24 15:37 [PATCH 3.2 00/77] 3.2.75-rc1 review Ben Hutchings
` (41 preceding siblings ...)
2015-12-24 15:37 ` [PATCH 3.2 70/77] net: add validation for the socket syscall protocol argument Ben Hutchings
@ 2015-12-24 15:37 ` Ben Hutchings
2015-12-24 15:37 ` [PATCH 3.2 63/77] ipv6: distinguish frag queues by device for multicast and link-local packets Ben Hutchings
` (35 subsequent siblings)
78 siblings, 0 replies; 84+ messages in thread
From: Ben Hutchings @ 2015-12-24 15:37 UTC (permalink / raw)
To: linux-kernel, stable
Cc: akpm, Dmitry Vyukov, Eric Dumazet, Hannes Frederic Sowa,
David S. Miller
3.2.75-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Eric Dumazet <edumazet@google.com>
[ Upstream commit 45f6fad84cc305103b28d73482b344d7f5b76f39 ]
This patch addresses multiple problems :
UDP/RAW sendmsg() need to get a stable struct ipv6_txoptions
while socket is not locked : Other threads can change np->opt
concurrently. Dmitry posted a syzkaller
(http://github.com/google/syzkaller) program desmonstrating
use-after-free.
Starting with TCP/DCCP lockless listeners, tcp_v6_syn_recv_sock()
and dccp_v6_request_recv_sock() also need to use RCU protection
to dereference np->opt once (before calling ipv6_dup_options())
This patch adds full RCU protection to np->opt
Reported-by: Dmitry Vyukov <dvyukov@google.com>
Signed-off-by: Eric Dumazet <edumazet@google.com>
Acked-by: Hannes Frederic Sowa <hannes@stressinduktion.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
[bwh: Backported to 3.2:
- Drop changes to l2tp
- Fix an additional use of np->opt in tcp_v6_send_synack()
- Fold in commit 43264e0bd963 ("ipv6: remove unnecessary codes in tcp_ipv6.c")
- Adjust context]
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
---
--- a/include/linux/ipv6.h
+++ b/include/linux/ipv6.h
@@ -369,7 +369,7 @@ struct ipv6_pinfo {
struct ipv6_ac_socklist *ipv6_ac_list;
struct ipv6_fl_socklist *ipv6_fl_list;
- struct ipv6_txoptions *opt;
+ struct ipv6_txoptions __rcu *opt;
struct sk_buff *pktoptions;
struct sk_buff *rxpmtu;
struct {
--- a/include/net/ipv6.h
+++ b/include/net/ipv6.h
@@ -191,6 +191,7 @@ extern rwlock_t ip6_ra_lock;
*/
struct ipv6_txoptions {
+ atomic_t refcnt;
/* Length of this structure */
int tot_len;
@@ -203,7 +204,7 @@ struct ipv6_txoptions {
struct ipv6_opt_hdr *dst0opt;
struct ipv6_rt_hdr *srcrt; /* Routing Header */
struct ipv6_opt_hdr *dst1opt;
-
+ struct rcu_head rcu;
/* Option buffer, as read by IPV6_PKTOPTIONS, starts here. */
};
@@ -229,6 +230,24 @@ struct ipv6_fl_socklist {
struct ip6_flowlabel *fl;
};
+static inline struct ipv6_txoptions *txopt_get(const struct ipv6_pinfo *np)
+{
+ struct ipv6_txoptions *opt;
+
+ rcu_read_lock();
+ opt = rcu_dereference(np->opt);
+ if (opt && !atomic_inc_not_zero(&opt->refcnt))
+ opt = NULL;
+ rcu_read_unlock();
+ return opt;
+}
+
+static inline void txopt_put(struct ipv6_txoptions *opt)
+{
+ if (opt && atomic_dec_and_test(&opt->refcnt))
+ kfree_rcu(opt, rcu);
+}
+
extern struct ip6_flowlabel *fl6_sock_lookup(struct sock *sk, __be32 label);
extern struct ipv6_txoptions *fl6_merge_options(struct ipv6_txoptions * opt_space,
struct ip6_flowlabel * fl,
--- a/net/dccp/ipv6.c
+++ b/net/dccp/ipv6.c
@@ -252,7 +252,9 @@ static int dccp_v6_send_response(struct
security_req_classify_flow(req, flowi6_to_flowi(&fl6));
- final_p = fl6_update_dst(&fl6, np->opt, &final);
+ rcu_read_lock();
+ final_p = fl6_update_dst(&fl6, rcu_dereference(np->opt), &final);
+ rcu_read_unlock();
dst = ip6_dst_lookup_flow(sk, &fl6, final_p, false);
if (IS_ERR(dst)) {
@@ -269,7 +271,10 @@ static int dccp_v6_send_response(struct
&ireq6->loc_addr,
&ireq6->rmt_addr);
ipv6_addr_copy(&fl6.daddr, &ireq6->rmt_addr);
- err = ip6_xmit(sk, skb, &fl6, np->opt, np->tclass);
+ rcu_read_lock();
+ err = ip6_xmit(sk, skb, &fl6, rcu_dereference(np->opt),
+ np->tclass);
+ rcu_read_unlock();
err = net_xmit_eval(err);
}
@@ -463,6 +468,7 @@ static struct sock *dccp_v6_request_recv
{
struct inet6_request_sock *ireq6 = inet6_rsk(req);
struct ipv6_pinfo *newnp, *np = inet6_sk(sk);
+ struct ipv6_txoptions *opt;
struct inet_sock *newinet;
struct dccp6_sock *newdp6;
struct sock *newsk;
@@ -586,13 +592,15 @@ static struct sock *dccp_v6_request_recv
* Yes, keeping reference count would be much more clever, but we make
* one more one thing there: reattach optmem to newsk.
*/
- if (np->opt != NULL)
- newnp->opt = ipv6_dup_options(newsk, np->opt);
-
+ opt = rcu_dereference(np->opt);
+ if (opt) {
+ opt = ipv6_dup_options(newsk, opt);
+ RCU_INIT_POINTER(newnp->opt, opt);
+ }
inet_csk(newsk)->icsk_ext_hdr_len = 0;
- if (newnp->opt != NULL)
- inet_csk(newsk)->icsk_ext_hdr_len = (newnp->opt->opt_nflen +
- newnp->opt->opt_flen);
+ if (opt)
+ inet_csk(newsk)->icsk_ext_hdr_len = opt->opt_nflen +
+ opt->opt_flen;
dccp_sync_mss(newsk, dst_mtu(dst));
@@ -844,6 +852,7 @@ static int dccp_v6_connect(struct sock *
struct ipv6_pinfo *np = inet6_sk(sk);
struct dccp_sock *dp = dccp_sk(sk);
struct in6_addr *saddr = NULL, *final_p, final;
+ struct ipv6_txoptions *opt;
struct flowi6 fl6;
struct dst_entry *dst;
int addr_type;
@@ -946,7 +955,8 @@ static int dccp_v6_connect(struct sock *
fl6.fl6_sport = inet->inet_sport;
security_sk_classify_flow(sk, flowi6_to_flowi(&fl6));
- final_p = fl6_update_dst(&fl6, np->opt, &final);
+ opt = rcu_dereference_protected(np->opt, sock_owned_by_user(sk));
+ final_p = fl6_update_dst(&fl6, opt, &final);
dst = ip6_dst_lookup_flow(sk, &fl6, final_p, true);
if (IS_ERR(dst)) {
@@ -966,9 +976,8 @@ static int dccp_v6_connect(struct sock *
__ip6_dst_store(sk, dst, NULL, NULL);
icsk->icsk_ext_hdr_len = 0;
- if (np->opt != NULL)
- icsk->icsk_ext_hdr_len = (np->opt->opt_flen +
- np->opt->opt_nflen);
+ if (opt)
+ icsk->icsk_ext_hdr_len = opt->opt_flen + opt->opt_nflen;
inet->inet_dport = usin->sin6_port;
--- a/net/ipv6/af_inet6.c
+++ b/net/ipv6/af_inet6.c
@@ -430,8 +430,11 @@ void inet6_destroy_sock(struct sock *sk)
/* Free tx options */
- if ((opt = xchg(&np->opt, NULL)) != NULL)
- sock_kfree_s(sk, opt, opt->tot_len);
+ opt = xchg((__force struct ipv6_txoptions **)&np->opt, NULL);
+ if (opt) {
+ atomic_sub(opt->tot_len, &sk->sk_omem_alloc);
+ txopt_put(opt);
+ }
}
EXPORT_SYMBOL_GPL(inet6_destroy_sock);
@@ -669,7 +672,10 @@ int inet6_sk_rebuild_header(struct sock
fl6.fl6_sport = inet->inet_sport;
security_sk_classify_flow(sk, flowi6_to_flowi(&fl6));
- final_p = fl6_update_dst(&fl6, np->opt, &final);
+ rcu_read_lock();
+ final_p = fl6_update_dst(&fl6, rcu_dereference(np->opt),
+ &final);
+ rcu_read_unlock();
dst = ip6_dst_lookup_flow(sk, &fl6, final_p, false);
if (IS_ERR(dst)) {
--- a/net/ipv6/datagram.c
+++ b/net/ipv6/datagram.c
@@ -166,8 +166,10 @@ ipv4_connected:
security_sk_classify_flow(sk, flowi6_to_flowi(&fl6));
- opt = flowlabel ? flowlabel->opt : np->opt;
+ rcu_read_lock();
+ opt = flowlabel ? flowlabel->opt : rcu_dereference(np->opt);
final_p = fl6_update_dst(&fl6, opt, &final);
+ rcu_read_unlock();
dst = ip6_dst_lookup_flow(sk, &fl6, final_p, true);
err = 0;
--- a/net/ipv6/exthdrs.c
+++ b/net/ipv6/exthdrs.c
@@ -748,6 +748,7 @@ ipv6_dup_options(struct sock *sk, struct
*((char**)&opt2->dst1opt) += dif;
if (opt2->srcrt)
*((char**)&opt2->srcrt) += dif;
+ atomic_set(&opt2->refcnt, 1);
}
return opt2;
}
@@ -812,7 +813,7 @@ ipv6_renew_options(struct sock *sk, stru
return ERR_PTR(-ENOBUFS);
memset(opt2, 0, tot_len);
-
+ atomic_set(&opt2->refcnt, 1);
opt2->tot_len = tot_len;
p = (char *)(opt2 + 1);
--- a/net/ipv6/inet6_connection_sock.c
+++ b/net/ipv6/inet6_connection_sock.c
@@ -66,7 +66,9 @@ struct dst_entry *inet6_csk_route_req(st
memset(&fl6, 0, sizeof(fl6));
fl6.flowi6_proto = IPPROTO_TCP;
ipv6_addr_copy(&fl6.daddr, &treq->rmt_addr);
- final_p = fl6_update_dst(&fl6, np->opt, &final);
+ rcu_read_lock();
+ final_p = fl6_update_dst(&fl6, rcu_dereference(np->opt), &final);
+ rcu_read_unlock();
ipv6_addr_copy(&fl6.saddr, &treq->loc_addr);
fl6.flowi6_oif = sk->sk_bound_dev_if;
fl6.flowi6_mark = sk->sk_mark;
@@ -225,7 +227,9 @@ int inet6_csk_xmit(struct sk_buff *skb,
fl6.fl6_dport = inet->inet_dport;
security_sk_classify_flow(sk, flowi6_to_flowi(&fl6));
- final_p = fl6_update_dst(&fl6, np->opt, &final);
+ rcu_read_lock();
+ final_p = fl6_update_dst(&fl6, rcu_dereference(np->opt), &final);
+ rcu_read_unlock();
dst = __inet6_csk_dst_check(sk, np->dst_cookie);
@@ -248,7 +252,8 @@ int inet6_csk_xmit(struct sk_buff *skb,
/* Restore final destination back after routing done */
ipv6_addr_copy(&fl6.daddr, &np->daddr);
- res = ip6_xmit(sk, skb, &fl6, np->opt, np->tclass);
+ res = ip6_xmit(sk, skb, &fl6, rcu_dereference(np->opt),
+ np->tclass);
rcu_read_unlock();
return res;
}
--- a/net/ipv6/ipv6_sockglue.c
+++ b/net/ipv6/ipv6_sockglue.c
@@ -110,10 +110,12 @@ struct ipv6_txoptions *ipv6_update_optio
icsk->icsk_ext_hdr_len = opt->opt_flen + opt->opt_nflen;
icsk->icsk_sync_mss(sk, icsk->icsk_pmtu_cookie);
}
- opt = xchg(&inet6_sk(sk)->opt, opt);
+ opt = xchg((__force struct ipv6_txoptions **)&inet6_sk(sk)->opt,
+ opt);
} else {
spin_lock(&sk->sk_dst_lock);
- opt = xchg(&inet6_sk(sk)->opt, opt);
+ opt = xchg((__force struct ipv6_txoptions **)&inet6_sk(sk)->opt,
+ opt);
spin_unlock(&sk->sk_dst_lock);
}
sk_dst_reset(sk);
@@ -213,9 +215,12 @@ static int do_ipv6_setsockopt(struct soc
sk->sk_socket->ops = &inet_dgram_ops;
sk->sk_family = PF_INET;
}
- opt = xchg(&np->opt, NULL);
- if (opt)
- sock_kfree_s(sk, opt, opt->tot_len);
+ opt = xchg((__force struct ipv6_txoptions **)&np->opt,
+ NULL);
+ if (opt) {
+ atomic_sub(opt->tot_len, &sk->sk_omem_alloc);
+ txopt_put(opt);
+ }
pktopt = xchg(&np->pktoptions, NULL);
kfree_skb(pktopt);
@@ -384,7 +389,8 @@ static int do_ipv6_setsockopt(struct soc
if (optname != IPV6_RTHDR && !capable(CAP_NET_RAW))
break;
- opt = ipv6_renew_options(sk, np->opt, optname,
+ opt = rcu_dereference_protected(np->opt, sock_owned_by_user(sk));
+ opt = ipv6_renew_options(sk, opt, optname,
(struct ipv6_opt_hdr __user *)optval,
optlen);
if (IS_ERR(opt)) {
@@ -413,8 +419,10 @@ static int do_ipv6_setsockopt(struct soc
retv = 0;
opt = ipv6_update_options(sk, opt);
sticky_done:
- if (opt)
- sock_kfree_s(sk, opt, opt->tot_len);
+ if (opt) {
+ atomic_sub(opt->tot_len, &sk->sk_omem_alloc);
+ txopt_put(opt);
+ }
break;
}
@@ -467,6 +475,7 @@ sticky_done:
break;
memset(opt, 0, sizeof(*opt));
+ atomic_set(&opt->refcnt, 1);
opt->tot_len = sizeof(*opt) + optlen;
retv = -EFAULT;
if (copy_from_user(opt+1, optval, optlen))
@@ -483,8 +492,10 @@ update:
retv = 0;
opt = ipv6_update_options(sk, opt);
done:
- if (opt)
- sock_kfree_s(sk, opt, opt->tot_len);
+ if (opt) {
+ atomic_sub(opt->tot_len, &sk->sk_omem_alloc);
+ txopt_put(opt);
+ }
break;
}
case IPV6_UNICAST_HOPS:
@@ -1053,10 +1064,11 @@ static int do_ipv6_getsockopt(struct soc
case IPV6_RTHDR:
case IPV6_DSTOPTS:
{
+ struct ipv6_txoptions *opt;
lock_sock(sk);
- len = ipv6_getsockopt_sticky(sk, np->opt,
- optname, optval, len);
+ opt = rcu_dereference_protected(np->opt, sock_owned_by_user(sk));
+ len = ipv6_getsockopt_sticky(sk, opt, optname, optval, len);
release_sock(sk);
/* check if ipv6_getsockopt_sticky() returns err code */
if (len < 0)
--- a/net/ipv6/raw.c
+++ b/net/ipv6/raw.c
@@ -724,6 +724,7 @@ static int rawv6_probe_proto_opt(struct
static int rawv6_sendmsg(struct kiocb *iocb, struct sock *sk,
struct msghdr *msg, size_t len)
{
+ struct ipv6_txoptions *opt_to_free = NULL;
struct ipv6_txoptions opt_space;
struct sockaddr_in6 * sin6 = (struct sockaddr_in6 *) msg->msg_name;
struct in6_addr *daddr, *final_p, final;
@@ -830,8 +831,10 @@ static int rawv6_sendmsg(struct kiocb *i
if (!(opt->opt_nflen|opt->opt_flen))
opt = NULL;
}
- if (opt == NULL)
- opt = np->opt;
+ if (!opt) {
+ opt = txopt_get(np);
+ opt_to_free = opt;
+ }
if (flowlabel)
opt = fl6_merge_options(&opt_space, flowlabel, opt);
opt = ipv6_fixup_options(&opt_space, opt);
@@ -896,6 +899,7 @@ done:
dst_release(dst);
out:
fl6_sock_release(flowlabel);
+ txopt_put(opt_to_free);
return err<0?err:len;
do_confirm:
dst_confirm(dst);
--- a/net/ipv6/syncookies.c
+++ b/net/ipv6/syncookies.c
@@ -238,7 +238,7 @@ struct sock *cookie_v6_check(struct sock
memset(&fl6, 0, sizeof(fl6));
fl6.flowi6_proto = IPPROTO_TCP;
ipv6_addr_copy(&fl6.daddr, &ireq6->rmt_addr);
- final_p = fl6_update_dst(&fl6, np->opt, &final);
+ final_p = fl6_update_dst(&fl6, rcu_dereference(np->opt), &final);
ipv6_addr_copy(&fl6.saddr, &ireq6->loc_addr);
fl6.flowi6_oif = sk->sk_bound_dev_if;
fl6.flowi6_mark = sk->sk_mark;
--- a/net/ipv6/tcp_ipv6.c
+++ b/net/ipv6/tcp_ipv6.c
@@ -131,6 +131,7 @@ static int tcp_v6_connect(struct sock *s
struct ipv6_pinfo *np = inet6_sk(sk);
struct tcp_sock *tp = tcp_sk(sk);
struct in6_addr *saddr = NULL, *final_p, final;
+ struct ipv6_txoptions *opt;
struct rt6_info *rt;
struct flowi6 fl6;
struct dst_entry *dst;
@@ -252,7 +253,8 @@ static int tcp_v6_connect(struct sock *s
fl6.fl6_dport = usin->sin6_port;
fl6.fl6_sport = inet->inet_sport;
- final_p = fl6_update_dst(&fl6, np->opt, &final);
+ opt = rcu_dereference_protected(np->opt, sock_owned_by_user(sk));
+ final_p = fl6_update_dst(&fl6, opt, &final);
security_sk_classify_flow(sk, flowi6_to_flowi(&fl6));
@@ -295,9 +297,9 @@ static int tcp_v6_connect(struct sock *s
}
icsk->icsk_ext_hdr_len = 0;
- if (np->opt)
- icsk->icsk_ext_hdr_len = (np->opt->opt_flen +
- np->opt->opt_nflen);
+ if (opt)
+ icsk->icsk_ext_hdr_len = opt->opt_flen +
+ opt->opt_nflen;
tp->rx_opt.mss_clamp = IPV6_MIN_MTU - sizeof(struct tcphdr) - sizeof(struct ipv6hdr);
@@ -481,7 +483,6 @@ static int tcp_v6_send_synack(struct soc
struct inet6_request_sock *treq = inet6_rsk(req);
struct ipv6_pinfo *np = inet6_sk(sk);
struct sk_buff * skb;
- struct ipv6_txoptions *opt = NULL;
struct in6_addr * final_p, final;
struct flowi6 fl6;
struct dst_entry *dst;
@@ -498,8 +499,7 @@ static int tcp_v6_send_synack(struct soc
fl6.fl6_sport = inet_rsk(req)->loc_port;
security_req_classify_flow(req, flowi6_to_flowi(&fl6));
- opt = np->opt;
- final_p = fl6_update_dst(&fl6, opt, &final);
+ final_p = fl6_update_dst(&fl6, rcu_dereference(np->opt), &final);
dst = ip6_dst_lookup_flow(sk, &fl6, final_p, false);
if (IS_ERR(dst)) {
@@ -513,13 +513,12 @@ static int tcp_v6_send_synack(struct soc
__tcp_v6_send_check(skb, &treq->loc_addr, &treq->rmt_addr);
ipv6_addr_copy(&fl6.daddr, &treq->rmt_addr);
- err = ip6_xmit(sk, skb, &fl6, opt, np->tclass);
+ err = ip6_xmit(sk, skb, &fl6, rcu_dereference(np->opt),
+ np->tclass);
err = net_xmit_eval(err);
}
done:
- if (opt && opt != np->opt)
- sock_kfree_s(sk, opt, opt->tot_len);
dst_release(dst);
return err;
}
@@ -1408,7 +1407,6 @@ static struct sock * tcp_v6_syn_recv_soc
}
treq = inet6_rsk(req);
- opt = np->opt;
if (sk_acceptq_is_full(sk))
goto out_overflow;
@@ -1476,16 +1474,15 @@ static struct sock * tcp_v6_syn_recv_soc
but we make one more one thing there: reattach optmem
to newsk.
*/
+ opt = rcu_dereference(np->opt);
if (opt) {
- newnp->opt = ipv6_dup_options(newsk, opt);
- if (opt != np->opt)
- sock_kfree_s(sk, opt, opt->tot_len);
+ opt = ipv6_dup_options(newsk, opt);
+ RCU_INIT_POINTER(newnp->opt, opt);
}
-
- inet_csk(newsk)->icsk_ext_hdr_len = 0;
- if (newnp->opt)
- inet_csk(newsk)->icsk_ext_hdr_len = (newnp->opt->opt_nflen +
- newnp->opt->opt_flen);
+ inet_csk(newsk)->icsk_ext_hdr_len = 0;
+ if (opt)
+ inet_csk(newsk)->icsk_ext_hdr_len = opt->opt_nflen +
+ opt->opt_flen;
tcp_mtup_init(newsk);
tcp_sync_mss(newsk, dst_mtu(dst));
@@ -1530,8 +1527,6 @@ static struct sock * tcp_v6_syn_recv_soc
out_overflow:
NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_LISTENOVERFLOWS);
out_nonewsk:
- if (opt && opt != np->opt)
- sock_kfree_s(sk, opt, opt->tot_len);
dst_release(dst);
out:
NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_LISTENDROPS);
--- a/net/ipv6/udp.c
+++ b/net/ipv6/udp.c
@@ -954,6 +954,7 @@ int udpv6_sendmsg(struct kiocb *iocb, st
struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *) msg->msg_name;
struct in6_addr *daddr, *final_p, final;
struct ipv6_txoptions *opt = NULL;
+ struct ipv6_txoptions *opt_to_free = NULL;
struct ip6_flowlabel *flowlabel = NULL;
struct flowi6 fl6;
struct dst_entry *dst;
@@ -1107,8 +1108,10 @@ do_udp_sendmsg:
opt = NULL;
connected = 0;
}
- if (opt == NULL)
- opt = np->opt;
+ if (!opt) {
+ opt = txopt_get(np);
+ opt_to_free = opt;
+ }
if (flowlabel)
opt = fl6_merge_options(&opt_space, flowlabel, opt);
opt = ipv6_fixup_options(&opt_space, opt);
@@ -1208,6 +1211,7 @@ do_append_data:
out:
dst_release(dst);
fl6_sock_release(flowlabel);
+ txopt_put(opt_to_free);
if (!err)
return len;
/*
^ permalink raw reply [flat|nested] 84+ messages in thread
* [PATCH 3.2 54/77] vgaarb: fix signal handling in vga_get()
2015-12-24 15:37 [PATCH 3.2 00/77] 3.2.75-rc1 review Ben Hutchings
` (46 preceding siblings ...)
2015-12-24 15:37 ` [PATCH 3.2 21/77] ip6mr: call del_timer_sync() in ip6mr_free_table() Ben Hutchings
@ 2015-12-24 15:37 ` Ben Hutchings
2015-12-24 15:37 ` [PATCH 3.2 46/77] drm: Fix an unwanted master inheritance v2 Ben Hutchings
` (30 subsequent siblings)
78 siblings, 0 replies; 84+ messages in thread
From: Ben Hutchings @ 2015-12-24 15:37 UTC (permalink / raw)
To: linux-kernel, stable
Cc: akpm, Kirill A. Shutemov, Dave Airlie, David Herrmann
3.2.75-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: "Kirill A. Shutemov" <kirill@shutemov.name>
commit 9f5bd30818c42c6c36a51f93b4df75a2ea2bd85e upstream.
There are few defects in vga_get() related to signal hadning:
- we shouldn't check for pending signals for TASK_UNINTERRUPTIBLE
case;
- if we found pending signal we must remove ourself from wait queue
and change task state back to running;
- -ERESTARTSYS is more appropriate, I guess.
Signed-off-by: Kirill A. Shutemov <kirill@shutemov.name>
Reviewed-by: David Herrmann <dh.herrmann@gmail.com>
Signed-off-by: Dave Airlie <airlied@redhat.com>
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
---
drivers/gpu/vga/vgaarb.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
--- a/drivers/gpu/vga/vgaarb.c
+++ b/drivers/gpu/vga/vgaarb.c
@@ -381,8 +381,10 @@ int vga_get(struct pci_dev *pdev, unsign
set_current_state(interruptible ?
TASK_INTERRUPTIBLE :
TASK_UNINTERRUPTIBLE);
- if (signal_pending(current)) {
- rc = -EINTR;
+ if (interruptible && signal_pending(current)) {
+ __set_current_state(TASK_RUNNING);
+ remove_wait_queue(&vga_wait_queue, &wait);
+ rc = -ERESTARTSYS;
break;
}
schedule();
^ permalink raw reply [flat|nested] 84+ messages in thread
* [PATCH 3.2 21/77] ip6mr: call del_timer_sync() in ip6mr_free_table()
2015-12-24 15:37 [PATCH 3.2 00/77] 3.2.75-rc1 review Ben Hutchings
` (45 preceding siblings ...)
2015-12-24 15:37 ` [PATCH 3.2 41/77] USB: whci-hcd: add check for dma mapping error Ben Hutchings
@ 2015-12-24 15:37 ` Ben Hutchings
2015-12-24 15:37 ` [PATCH 3.2 54/77] vgaarb: fix signal handling in vga_get() Ben Hutchings
` (31 subsequent siblings)
78 siblings, 0 replies; 84+ messages in thread
From: Ben Hutchings @ 2015-12-24 15:37 UTC (permalink / raw)
To: linux-kernel, stable
Cc: akpm, Hannes Frederic Sowa, David S. Miller, WANG Cong
3.2.75-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: WANG Cong <xiyou.wangcong@gmail.com>
commit 7ba0c47c34a1ea5bc7a24ca67309996cce0569b5 upstream.
We need to wait for the flying timers, since we
are going to free the mrtable right after it.
Cc: Hannes Frederic Sowa <hannes@stressinduktion.org>
Signed-off-by: Cong Wang <xiyou.wangcong@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
---
net/ipv6/ip6mr.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
--- a/net/ipv6/ip6mr.c
+++ b/net/ipv6/ip6mr.c
@@ -334,7 +334,7 @@ static struct mr6_table *ip6mr_new_table
static void ip6mr_free_table(struct mr6_table *mrt)
{
- del_timer(&mrt->ipmr_expire_timer);
+ del_timer_sync(&mrt->ipmr_expire_timer);
mroute_clean_tables(mrt);
kfree(mrt);
}
^ permalink raw reply [flat|nested] 84+ messages in thread
* [PATCH 3.2 60/77] tcp: initialize tp->copied_seq in case of cross SYN connection
2015-12-24 15:37 [PATCH 3.2 00/77] 3.2.75-rc1 review Ben Hutchings
` (26 preceding siblings ...)
2015-12-24 15:37 ` [PATCH 3.2 22/77] net: ip6mr: fix static mfc/dev leaks on table destruction Ben Hutchings
@ 2015-12-24 15:37 ` Ben Hutchings
2015-12-24 15:37 ` [PATCH 3.2 12/77] net: fix __netdev_update_features return on ndo_set_features failure Ben Hutchings
` (50 subsequent siblings)
78 siblings, 0 replies; 84+ messages in thread
From: Ben Hutchings @ 2015-12-24 15:37 UTC (permalink / raw)
To: linux-kernel, stable; +Cc: akpm, David S. Miller, Eric Dumazet, Dmitry Vyukov
3.2.75-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Eric Dumazet <edumazet@google.com>
[ Upstream commit 142a2e7ece8d8ac0e818eb2c91f99ca894730e2a ]
Dmitry provided a syzkaller (http://github.com/google/syzkaller)
generated program that triggers the WARNING at
net/ipv4/tcp.c:1729 in tcp_recvmsg() :
WARN_ON(tp->copied_seq != tp->rcv_nxt &&
!(flags & (MSG_PEEK | MSG_TRUNC)));
His program is specifically attempting a Cross SYN TCP exchange,
that we support (for the pleasure of hackers ?), but it looks we
lack proper tcp->copied_seq initialization.
Thanks again Dmitry for your report and testings.
Signed-off-by: Eric Dumazet <edumazet@google.com>
Reported-by: Dmitry Vyukov <dvyukov@google.com>
Tested-by: Dmitry Vyukov <dvyukov@google.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
---
net/ipv4/tcp_input.c | 1 +
1 file changed, 1 insertion(+)
--- a/net/ipv4/tcp_input.c
+++ b/net/ipv4/tcp_input.c
@@ -5811,6 +5811,7 @@ discard:
}
tp->rcv_nxt = TCP_SKB_CB(skb)->seq + 1;
+ tp->copied_seq = tp->rcv_nxt;
tp->rcv_wup = TCP_SKB_CB(skb)->seq + 1;
/* RFC1323: The window in SYN & SYN/ACK segments is
^ permalink raw reply [flat|nested] 84+ messages in thread
* [PATCH 3.2 45/77] locking: Add WARN_ON_ONCE lock assertion
2015-12-24 15:37 [PATCH 3.2 00/77] 3.2.75-rc1 review Ben Hutchings
` (14 preceding siblings ...)
2015-12-24 15:37 ` [PATCH 3.2 56/77] mm, vmstat: allow WQ concurrency to discover memory reclaim doesn't make any progress Ben Hutchings
@ 2015-12-24 15:37 ` Ben Hutchings
2015-12-24 15:37 ` [PATCH 3.2 61/77] net, scm: fix PaX detected msg_controllen overflow in scm_detach_fds Ben Hutchings
` (62 subsequent siblings)
78 siblings, 0 replies; 84+ messages in thread
From: Ben Hutchings @ 2015-12-24 15:37 UTC (permalink / raw)
To: linux-kernel, stable; +Cc: akpm, Greg Kroah-Hartman, Ingo Molnar, Peter Hurley
3.2.75-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Peter Hurley <peter@hurleysoftware.com>
commit 9a37110d20c95d1ebf6c04881177fe8f62831db2 upstream.
An interface may need to assert a lock invariant and not flood the
system logs; add a lockdep helper macro equivalent to
lockdep_assert_held() which only WARNs once.
Signed-off-by: Peter Hurley <peter@hurleysoftware.com>
Acked-by: Ingo Molnar <mingo@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
[bwh: Backported to 3.2: adjust context]
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
---
include/linux/lockdep.h | 5 +++++
1 file changed, 5 insertions(+)
--- a/include/linux/lockdep.h
+++ b/include/linux/lockdep.h
@@ -342,6 +342,9 @@ extern void lockdep_trace_alloc(gfp_t ma
#define lockdep_depth(tsk) (debug_locks ? (tsk)->lockdep_depth : 0)
#define lockdep_assert_held(l) WARN_ON(debug_locks && !lockdep_is_held(l))
+#define lockdep_assert_held_once(l) do { \
+ WARN_ON_ONCE(debug_locks && !lockdep_is_held(l)); \
+ } while (0)
#else /* !LOCKDEP */
@@ -362,6 +365,7 @@ static inline void lockdep_on(void)
# define lockdep_trace_alloc(g) do { } while (0)
# define lockdep_init() do { } while (0)
# define lockdep_info() do { } while (0)
+
# define lockdep_init_map(lock, name, key, sub) \
do { (void)(name); (void)(key); } while (0)
# define lockdep_set_class(lock, key) do { (void)(key); } while (0)
@@ -391,6 +395,7 @@ struct lock_class_key { };
#define lockdep_depth(tsk) (0)
#define lockdep_assert_held(l) do { } while (0)
+#define lockdep_assert_held_once(l) do { (void)(l); } while (0)
#endif /* !LOCKDEP */
^ permalink raw reply [flat|nested] 84+ messages in thread
* [PATCH 3.2 74/77] af_unix: Revert 'lock_interruptible' in stream receive code
2015-12-24 15:37 [PATCH 3.2 00/77] 3.2.75-rc1 review Ben Hutchings
` (64 preceding siblings ...)
2015-12-24 15:37 ` [PATCH 3.2 34/77] jbd2: Fix unreclaimed pages after truncate in data=journal mode Ben Hutchings
@ 2015-12-24 15:37 ` Ben Hutchings
2015-12-24 15:37 ` [PATCH 3.2 73/77] bluetooth: Validate socket address length in sco_sock_bind() Ben Hutchings
` (12 subsequent siblings)
78 siblings, 0 replies; 84+ messages in thread
From: Ben Hutchings @ 2015-12-24 15:37 UTC (permalink / raw)
To: linux-kernel, stable
Cc: akpm, David S. Miller, Rainer Weikusat, Hannes Frederic Sowa
3.2.75-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Rainer Weikusat <rweikusat@mobileactivedefense.com>
[ Upstream commit 3822b5c2fc62e3de8a0f33806ff279fb7df92432 ]
With b3ca9b02b00704053a38bfe4c31dbbb9c13595d0, the AF_UNIX SOCK_STREAM
receive code was changed from using mutex_lock(&u->readlock) to
mutex_lock_interruptible(&u->readlock) to prevent signals from being
delayed for an indefinite time if a thread sleeping on the mutex
happened to be selected for handling the signal. But this was never a
problem with the stream receive code (as opposed to its datagram
counterpart) as that never went to sleep waiting for new messages with the
mutex held and thus, wouldn't cause secondary readers to block on the
mutex waiting for the sleeping primary reader. As the interruptible
locking makes the code more complicated in exchange for no benefit,
change it back to using mutex_lock.
Signed-off-by: Rainer Weikusat <rweikusat@mobileactivedefense.com>
Acked-by: Hannes Frederic Sowa <hannes@stressinduktion.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
---
net/unix/af_unix.c | 13 +++----------
1 file changed, 3 insertions(+), 10 deletions(-)
--- a/net/unix/af_unix.c
+++ b/net/unix/af_unix.c
@@ -1913,14 +1913,7 @@ static int unix_dgram_recvmsg(struct kio
if (flags&MSG_OOB)
goto out;
- err = mutex_lock_interruptible(&u->readlock);
- if (unlikely(err)) {
- /* recvmsg() in non blocking mode is supposed to return -EAGAIN
- * sk_rcvtimeo is not honored by mutex_lock_interruptible()
- */
- err = noblock ? -EAGAIN : -ERESTARTSYS;
- goto out;
- }
+ mutex_lock(&u->readlock);
skb = skb_recv_datagram(sk, flags, noblock, &err);
if (!skb) {
@@ -2105,12 +2098,12 @@ static int unix_stream_recvmsg(struct ki
timeo = unix_stream_data_wait(sk, timeo);
- if (signal_pending(current)
- || mutex_lock_interruptible(&u->readlock)) {
+ if (signal_pending(current)) {
err = sock_intr_errno(timeo);
goto out;
}
+ mutex_lock(&u->readlock);
continue;
unlock:
unix_state_unlock(sk);
^ permalink raw reply [flat|nested] 84+ messages in thread
* [PATCH 3.2 68/77] sctp: update the netstamp_needed counter when copying sockets
2015-12-24 15:37 [PATCH 3.2 00/77] 3.2.75-rc1 review Ben Hutchings
` (9 preceding siblings ...)
2015-12-24 15:37 ` [PATCH 3.2 17/77] xhci: Workaround to get Intel xHCI reset working more reliably Ben Hutchings
@ 2015-12-24 15:37 ` Ben Hutchings
2015-12-24 15:37 ` [PATCH 3.2 51/77] 9p: ->evict_inode() should kick out ->i_data, not ->i_mapping Ben Hutchings
` (67 subsequent siblings)
78 siblings, 0 replies; 84+ messages in thread
From: Ben Hutchings @ 2015-12-24 15:37 UTC (permalink / raw)
To: linux-kernel, stable
Cc: akpm, Dmitry Vyukov, Vlad Yasevich, David S. Miller,
Marcelo Ricardo Leitner
3.2.75-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Marcelo Ricardo Leitner <marcelo.leitner@gmail.com>
[ Upstream commit 01ce63c90170283a9855d1db4fe81934dddce648 ]
Dmitry Vyukov reported that SCTP was triggering a WARN on socket destroy
related to disabling sock timestamp.
When SCTP accepts an association or peel one off, it copies sock flags
but forgot to call net_enable_timestamp() if a packet timestamping flag
was copied, leading to extra calls to net_disable_timestamp() whenever
such clones were closed.
The fix is to call net_enable_timestamp() whenever we copy a sock with
that flag on, like tcp does.
Reported-by: Dmitry Vyukov <dvyukov@google.com>
Signed-off-by: Marcelo Ricardo Leitner <marcelo.leitner@gmail.com>
Acked-by: Vlad Yasevich <vyasevich@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
[bwh: Backported to 3.2: SK_FLAGS_TIMESTAMP is newly defined]
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
---
--- a/include/net/sock.h
+++ b/include/net/sock.h
@@ -565,6 +565,8 @@ enum sock_flags {
SOCK_ZEROCOPY, /* buffers from userspace */
};
+#define SK_FLAGS_TIMESTAMP ((1UL << SOCK_TIMESTAMP) | (1UL << SOCK_TIMESTAMPING_RX_SOFTWARE))
+
static inline void sock_copy_flags(struct sock *nsk, struct sock *osk)
{
nsk->sk_flags = osk->sk_flags;
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -6731,6 +6731,9 @@ void sctp_copy_sock(struct sock *newsk,
newinet->mc_ttl = 1;
newinet->mc_index = 0;
newinet->mc_list = NULL;
+
+ if (newsk->sk_flags & SK_FLAGS_TIMESTAMP)
+ net_enable_timestamp();
}
static inline void sctp_copy_descendant(struct sock *sk_to,
^ permalink raw reply [flat|nested] 84+ messages in thread
* [PATCH 3.2 06/77] USB: serial: option: add support for Novatel MiFi USB620L
2015-12-24 15:37 [PATCH 3.2 00/77] 3.2.75-rc1 review Ben Hutchings
` (32 preceding siblings ...)
2015-12-24 15:37 ` [PATCH 3.2 26/77] USB: cdc_acm: Ignore Infineon Flash Loader utility Ben Hutchings
@ 2015-12-24 15:37 ` Ben Hutchings
2015-12-24 15:37 ` [PATCH 3.2 59/77] snmp: Remove duplicate OUTMCAST stat increment Ben Hutchings
` (44 subsequent siblings)
78 siblings, 0 replies; 84+ messages in thread
From: Ben Hutchings @ 2015-12-24 15:37 UTC (permalink / raw)
To: linux-kernel, stable; +Cc: akpm, Johan Hovold, Aleksander Morgado
3.2.75-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Aleksander Morgado <aleksander@aleksander.es>
commit e07af133c3e2716db25e3e1e1d9f10c2088e9c1a upstream.
Also known as Verizon U620L.
The device is modeswitched from 1410:9020 to 1410:9022 by selecting the
4th USB configuration:
$ sudo usb_modeswitch –v 0x1410 –p 0x9020 –u 4
This configuration provides a ECM interface as well as TTYs ('Enterprise
Mode' according to the U620 Linux integration guide).
Signed-off-by: Aleksander Morgado <aleksander@aleksander.es>
Signed-off-by: Johan Hovold <johan@kernel.org>
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
---
drivers/usb/serial/option.c | 2 ++
1 file changed, 2 insertions(+)
--- a/drivers/usb/serial/option.c
+++ b/drivers/usb/serial/option.c
@@ -162,6 +162,7 @@ static void option_instat_callback(struc
#define NOVATELWIRELESS_PRODUCT_HSPA_EMBEDDED_HIGHSPEED 0x9001
#define NOVATELWIRELESS_PRODUCT_E362 0x9010
#define NOVATELWIRELESS_PRODUCT_E371 0x9011
+#define NOVATELWIRELESS_PRODUCT_U620L 0x9022
#define NOVATELWIRELESS_PRODUCT_G2 0xA010
#define NOVATELWIRELESS_PRODUCT_MC551 0xB001
@@ -1058,6 +1059,7 @@ static const struct usb_device_id option
{ USB_DEVICE_AND_INTERFACE_INFO(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_MC551, 0xff, 0xff, 0xff) },
{ USB_DEVICE_AND_INTERFACE_INFO(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_E362, 0xff, 0xff, 0xff) },
{ USB_DEVICE_AND_INTERFACE_INFO(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_E371, 0xff, 0xff, 0xff) },
+ { USB_DEVICE_AND_INTERFACE_INFO(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_U620L, 0xff, 0x00, 0x00) },
{ USB_DEVICE(AMOI_VENDOR_ID, AMOI_PRODUCT_H01) },
{ USB_DEVICE(AMOI_VENDOR_ID, AMOI_PRODUCT_H01A) },
^ permalink raw reply [flat|nested] 84+ messages in thread
* [PATCH 3.2 51/77] 9p: ->evict_inode() should kick out ->i_data, not ->i_mapping
2015-12-24 15:37 [PATCH 3.2 00/77] 3.2.75-rc1 review Ben Hutchings
` (10 preceding siblings ...)
2015-12-24 15:37 ` [PATCH 3.2 68/77] sctp: update the netstamp_needed counter when copying sockets Ben Hutchings
@ 2015-12-24 15:37 ` Ben Hutchings
2015-12-24 15:37 ` [PATCH 3.2 43/77] dm btree: fix leak of bufio-backed block in btree_split_sibling error path Ben Hutchings
` (66 subsequent siblings)
78 siblings, 0 replies; 84+ messages in thread
From: Ben Hutchings @ 2015-12-24 15:37 UTC (permalink / raw)
To: linux-kernel, stable; +Cc: akpm, Suzuki K. Poulose, Al Viro
3.2.75-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Al Viro <viro@zeniv.linux.org.uk>
commit 4ad78628445d26e5e9487b2e8f23274ad7b0f5d3 upstream.
For block devices the pagecache is associated with the inode
on bdevfs, not with the aliasing ones on the mountable filesystems.
The latter have its own ->i_data empty and ->i_mapping pointing
to the (unique per major/minor) bdevfs inode. That guarantees
cache coherence between all block device inodes with the same
device number.
Eviction of an alias inode has no business trying to evict the
pages belonging to bdevfs one; moreover, ->i_mapping is only
safe to access when the thing is opened. At the time of
->evict_inode() the victim is definitely *not* opened. We are
about to kill the address space embedded into struct inode
(inode->i_data) and that's what we need to empty of any pages.
9p instance tries to empty inode->i_mapping instead, which is
both unsafe and bogus - if we have several device nodes with
the same device number in different places, closing one of them
should not try to empty the (shared) page cache.
Fortunately, other instances in the tree are OK; they are
evicting from &inode->i_data instead, as 9p one should.
Reported-by: "Suzuki K. Poulose" <Suzuki.Poulose@arm.com>
Tested-by: "Suzuki K. Poulose" <Suzuki.Poulose@arm.com>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
[bwh: Backported to 3.2: adjust context]
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
---
fs/9p/vfs_inode.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
--- a/fs/9p/vfs_inode.c
+++ b/fs/9p/vfs_inode.c
@@ -435,9 +435,9 @@ void v9fs_evict_inode(struct inode *inod
{
struct v9fs_inode *v9inode = V9FS_I(inode);
- truncate_inode_pages(inode->i_mapping, 0);
+ truncate_inode_pages(&inode->i_data, 0);
end_writeback(inode);
- filemap_fdatawrite(inode->i_mapping);
+ filemap_fdatawrite(&inode->i_data);
#ifdef CONFIG_9P_FSCACHE
v9fs_cache_inode_put_cookie(inode);
^ permalink raw reply [flat|nested] 84+ messages in thread
* [PATCH 3.2 52/77] ipmi: move timer init to before irq is setup
2015-12-24 15:37 [PATCH 3.2 00/77] 3.2.75-rc1 review Ben Hutchings
` (22 preceding siblings ...)
2015-12-24 15:37 ` [PATCH 3.2 19/77] usblp: do not set TASK_INTERRUPTIBLE before lock Ben Hutchings
@ 2015-12-24 15:37 ` Ben Hutchings
2015-12-24 15:37 ` [PATCH 3.2 75/77] af_unix: fix a fatal race with bit fields Ben Hutchings
` (54 subsequent siblings)
78 siblings, 0 replies; 84+ messages in thread
From: Ben Hutchings @ 2015-12-24 15:37 UTC (permalink / raw)
To: linux-kernel, stable; +Cc: akpm, Jan Stancek, Corey Minyard, Tony Camuso
3.2.75-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Jan Stancek <jstancek@redhat.com>
commit 27f972d3e00b50639deb4cc1392afaeb08d3cecc upstream.
We encountered a panic on boot in ipmi_si on a dell per320 due to an
uninitialized timer as follows.
static int smi_start_processing(void *send_info,
ipmi_smi_t intf)
{
/* Try to claim any interrupts. */
if (new_smi->irq_setup)
new_smi->irq_setup(new_smi);
--> IRQ arrives here and irq handler tries to modify uninitialized timer
which triggers BUG_ON(!timer->function) in __mod_timer().
Call Trace:
<IRQ>
[<ffffffffa0532617>] start_new_msg+0x47/0x80 [ipmi_si]
[<ffffffffa053269e>] start_check_enables+0x4e/0x60 [ipmi_si]
[<ffffffffa0532bd8>] smi_event_handler+0x1e8/0x640 [ipmi_si]
[<ffffffff810f5584>] ? __rcu_process_callbacks+0x54/0x350
[<ffffffffa053327c>] si_irq_handler+0x3c/0x60 [ipmi_si]
[<ffffffff810efaf0>] handle_IRQ_event+0x60/0x170
[<ffffffff810f245e>] handle_edge_irq+0xde/0x180
[<ffffffff8100fc59>] handle_irq+0x49/0xa0
[<ffffffff8154643c>] do_IRQ+0x6c/0xf0
[<ffffffff8100ba53>] ret_from_intr+0x0/0x11
/* Set up the timer that drives the interface. */
setup_timer(&new_smi->si_timer, smi_timeout, (long)new_smi);
The following patch fixes the problem.
To: Openipmi-developer@lists.sourceforge.net
To: Corey Minyard <minyard@acm.org>
CC: linux-kernel@vger.kernel.org
Signed-off-by: Jan Stancek <jstancek@redhat.com>
Signed-off-by: Tony Camuso <tcamuso@redhat.com>
Signed-off-by: Corey Minyard <cminyard@mvista.com>
[bwh: Backported to 3.2: adjust context]
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
---
drivers/char/ipmi/ipmi_si_intf.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
--- a/drivers/char/ipmi/ipmi_si_intf.c
+++ b/drivers/char/ipmi/ipmi_si_intf.c
@@ -1148,15 +1148,15 @@ static int smi_start_processing(void
new_smi->intf = intf;
- /* Try to claim any interrupts. */
- if (new_smi->irq_setup)
- new_smi->irq_setup(new_smi);
-
/* Set up the timer that drives the interface. */
setup_timer(&new_smi->si_timer, smi_timeout, (long)new_smi);
new_smi->last_timeout_jiffies = jiffies;
mod_timer(&new_smi->si_timer, jiffies + SI_TIMEOUT_JIFFIES);
+ /* Try to claim any interrupts. */
+ if (new_smi->irq_setup)
+ new_smi->irq_setup(new_smi);
+
/*
* Check if the user forcefully enabled the daemon.
*/
^ permalink raw reply [flat|nested] 84+ messages in thread
* [PATCH 3.2 18/77] USB: option: add XS Stick W100-2 from 4G Systems
2015-12-24 15:37 [PATCH 3.2 00/77] 3.2.75-rc1 review Ben Hutchings
` (73 preceding siblings ...)
2015-12-24 15:37 ` [PATCH 3.2 14/77] mac80211: mesh: fix call_rcu() usage Ben Hutchings
@ 2015-12-24 15:37 ` Ben Hutchings
2015-12-24 15:37 ` [PATCH 3.2 28/77] fix sysvfs symlinks Ben Hutchings
` (3 subsequent siblings)
78 siblings, 0 replies; 84+ messages in thread
From: Ben Hutchings @ 2015-12-24 15:37 UTC (permalink / raw)
To: linux-kernel, stable
Cc: akpm, Greg Kroah-Hartman, Thomas Schäfer, Bjørn Mork
3.2.75-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Bjørn Mork <bjorn@mork.no>
commit 638148e20c7f8f6e95017fdc13bce8549a6925e0 upstream.
Thomas reports
"
4gsystems sells two total different LTE-surfsticks under the same name.
..
The newer version of XS Stick W100 is from "omega"
..
Under windows the driver switches to the same ID, and uses MI03\6 for
network and MI01\6 for modem.
..
echo "1c9e 9b01" > /sys/bus/usb/drivers/qmi_wwan/new_id
echo "1c9e 9b01" > /sys/bus/usb-serial/drivers/option1/new_id
T: Bus=01 Lev=01 Prnt=01 Port=03 Cnt=01 Dev#= 4 Spd=480 MxCh= 0
D: Ver= 2.00 Cls=00(>ifc ) Sub=00 Prot=00 MxPS=64 #Cfgs= 1
P: Vendor=1c9e ProdID=9b01 Rev=02.32
S: Manufacturer=USB Modem
S: Product=USB Modem
S: SerialNumber=
C: #Ifs= 5 Cfg#= 1 Atr=80 MxPwr=500mA
I: If#= 0 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=ff Driver=option
I: If#= 1 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=ff Driver=option
I: If#= 2 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=ff Driver=option
I: If#= 3 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=ff Driver=qmi_wwan
I: If#= 4 Alt= 0 #EPs= 2 Cls=08(stor.) Sub=06 Prot=50 Driver=usb-storage
Now all important things are there:
wwp0s29f7u2i3 (net), ttyUSB2 (at), cdc-wdm0 (qmi), ttyUSB1 (at)
There is also ttyUSB0, but it is not usable, at least not for at.
The device works well with qmi and ModemManager-NetworkManager.
"
Reported-by: Thomas Schäfer <tschaefer@t-online.de>
Signed-off-by: Bjørn Mork <bjorn@mork.no>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
[bwh: Backported to 3.2: adjust context]
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
---
drivers/usb/serial/option.c | 9 +++++++++
1 file changed, 9 insertions(+)
--- a/drivers/usb/serial/option.c
+++ b/drivers/usb/serial/option.c
@@ -356,6 +356,7 @@ static void option_instat_callback(struc
/* This is the 4G XS Stick W14 a.k.a. Mobilcom Debitel Surf-Stick *
* It seems to contain a Qualcomm QSC6240/6290 chipset */
#define FOUR_G_SYSTEMS_PRODUCT_W14 0x9603
+#define FOUR_G_SYSTEMS_PRODUCT_W100 0x9b01
/* iBall 3.5G connect wireless modem */
#define IBALL_3_5G_CONNECT 0x9605
@@ -526,6 +527,11 @@ static const struct option_blacklist_inf
.sendsetup = BIT(0) | BIT(1),
};
+static const struct option_blacklist_info four_g_w100_blacklist = {
+ .sendsetup = BIT(1) | BIT(2),
+ .reserved = BIT(3),
+};
+
static const struct option_blacklist_info alcatel_x200_blacklist = {
.sendsetup = BIT(0) | BIT(1),
.reserved = BIT(4),
@@ -1642,6 +1648,9 @@ static const struct usb_device_id option
{ USB_DEVICE(LONGCHEER_VENDOR_ID, FOUR_G_SYSTEMS_PRODUCT_W14),
.driver_info = (kernel_ulong_t)&four_g_w14_blacklist
},
+ { USB_DEVICE(LONGCHEER_VENDOR_ID, FOUR_G_SYSTEMS_PRODUCT_W100),
+ .driver_info = (kernel_ulong_t)&four_g_w100_blacklist
+ },
{ USB_DEVICE(LONGCHEER_VENDOR_ID, ZOOM_PRODUCT_4597) },
{ USB_DEVICE(LONGCHEER_VENDOR_ID, IBALL_3_5G_CONNECT) },
{ USB_DEVICE(HAIER_VENDOR_ID, HAIER_PRODUCT_CE100) },
^ permalink raw reply [flat|nested] 84+ messages in thread
* [PATCH 3.2 72/77] pptp: verify sockaddr_len in pptp_bind() and pptp_connect()
2015-12-24 15:37 [PATCH 3.2 00/77] 3.2.75-rc1 review Ben Hutchings
` (38 preceding siblings ...)
2015-12-24 15:37 ` [PATCH 3.2 33/77] ext4: Fix handling of extended tv_sec Ben Hutchings
@ 2015-12-24 15:37 ` Ben Hutchings
2015-12-24 15:37 ` [PATCH 3.2 39/77] sata_sil: disable trim Ben Hutchings
` (38 subsequent siblings)
78 siblings, 0 replies; 84+ messages in thread
From: Ben Hutchings @ 2015-12-24 15:37 UTC (permalink / raw)
To: linux-kernel, stable; +Cc: akpm, WANG Cong, David S. Miller, Dmitry Vyukov
3.2.75-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: WANG Cong <xiyou.wangcong@gmail.com>
[ Upstream commit 09ccfd238e5a0e670d8178cf50180ea81ae09ae1 ]
Reported-by: Dmitry Vyukov <dvyukov@gmail.com>
Signed-off-by: Cong Wang <xiyou.wangcong@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
---
drivers/net/ppp/pptp.c | 6 ++++++
1 file changed, 6 insertions(+)
--- a/drivers/net/ppp/pptp.c
+++ b/drivers/net/ppp/pptp.c
@@ -420,6 +420,9 @@ static int pptp_bind(struct socket *sock
struct pptp_opt *opt = &po->proto.pptp;
int error = 0;
+ if (sockaddr_len < sizeof(struct sockaddr_pppox))
+ return -EINVAL;
+
lock_sock(sk);
opt->src_addr = sp->sa_addr.pptp;
@@ -441,6 +444,9 @@ static int pptp_connect(struct socket *s
struct flowi4 fl4;
int error = 0;
+ if (sockaddr_len < sizeof(struct sockaddr_pppox))
+ return -EINVAL;
+
if (sp->sa_protocol != PX_PROTO_PPTP)
return -EINVAL;
^ permalink raw reply [flat|nested] 84+ messages in thread
* [PATCH 3.2 76/77] isdn_ppp: Add checks for allocation failure in isdn_ppp_open()
2015-12-24 15:37 [PATCH 3.2 00/77] 3.2.75-rc1 review Ben Hutchings
` (59 preceding siblings ...)
2015-12-24 15:37 ` [PATCH 3.2 37/77] drm/ttm: Fixed a read/write lock imbalance Ben Hutchings
@ 2015-12-24 15:37 ` Ben Hutchings
2015-12-24 15:37 ` [PATCH 3.2 01/77] fuse: break infinite loop in fuse_fill_write_pages() Ben Hutchings
` (17 subsequent siblings)
78 siblings, 0 replies; 84+ messages in thread
From: Ben Hutchings @ 2015-12-24 15:37 UTC (permalink / raw)
To: linux-kernel, stable; +Cc: akpm, David S. Miller
3.2.75-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Ben Hutchings <ben@decadent.org.uk>
commit 0baa57d8dc32db78369d8b5176ef56c5e2e18ab3 upstream.
Compile-tested only.
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
Signed-off-by: David S. Miller <davem@davemloft.net>
---
drivers/isdn/i4l/isdn_ppp.c | 6 ++++++
1 file changed, 6 insertions(+)
--- a/drivers/isdn/i4l/isdn_ppp.c
+++ b/drivers/isdn/i4l/isdn_ppp.c
@@ -301,6 +301,8 @@ isdn_ppp_open(int min, struct file *file
is->compflags = 0;
is->reset = isdn_ppp_ccp_reset_alloc(is);
+ if (!is->reset)
+ return -ENOMEM;
is->lp = NULL;
is->mp_seqno = 0; /* MP sequence number */
@@ -320,6 +322,10 @@ isdn_ppp_open(int min, struct file *file
* VJ header compression init
*/
is->slcomp = slhc_init(16, 16); /* not necessary for 2. link in bundle */
+ if (!is->slcomp) {
+ isdn_ppp_ccp_reset_free(is);
+ return -ENOMEM;
+ }
#endif
#ifdef CONFIG_IPPP_FILTER
is->pass_filter = NULL;
^ permalink raw reply [flat|nested] 84+ messages in thread
* [PATCH 3.2 43/77] dm btree: fix leak of bufio-backed block in btree_split_sibling error path
2015-12-24 15:37 [PATCH 3.2 00/77] 3.2.75-rc1 review Ben Hutchings
` (11 preceding siblings ...)
2015-12-24 15:37 ` [PATCH 3.2 51/77] 9p: ->evict_inode() should kick out ->i_data, not ->i_mapping Ben Hutchings
@ 2015-12-24 15:37 ` Ben Hutchings
2015-12-24 15:37 ` [PATCH 3.2 47/77] sched/core: Remove false-positive warning from wake_up_process() Ben Hutchings
` (65 subsequent siblings)
78 siblings, 0 replies; 84+ messages in thread
From: Ben Hutchings @ 2015-12-24 15:37 UTC (permalink / raw)
To: linux-kernel, stable; +Cc: akpm, Mikulas Patocka, Mike Snitzer
3.2.75-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Mike Snitzer <snitzer@redhat.com>
commit 30ce6e1cc5a0f781d60227e9096c86e188d2c2bd upstream.
The block allocated at the start of btree_split_sibling() is never
released if later insert_at() fails.
Fix this by releasing the previously allocated bufio block using
unlock_block().
Reported-by: Mikulas Patocka <mpatocka@redhat.com>
Signed-off-by: Mike Snitzer <snitzer@redhat.com>
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
---
drivers/md/persistent-data/dm-btree.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
--- a/drivers/md/persistent-data/dm-btree.c
+++ b/drivers/md/persistent-data/dm-btree.c
@@ -451,8 +451,10 @@ static int btree_split_sibling(struct sh
r = insert_at(sizeof(__le64), pn, parent_index + 1,
le64_to_cpu(rn->keys[0]), &location);
- if (r)
+ if (r) {
+ unlock_block(s->info, right);
return r;
+ }
if (key < le64_to_cpu(rn->keys[0])) {
unlock_block(s->info, right);
^ permalink raw reply [flat|nested] 84+ messages in thread
* [PATCH 3.2 17/77] xhci: Workaround to get Intel xHCI reset working more reliably
2015-12-24 15:37 [PATCH 3.2 00/77] 3.2.75-rc1 review Ben Hutchings
` (8 preceding siblings ...)
2015-12-24 15:37 ` [PATCH 3.2 02/77] sctp: translate host order to network order when setting a hmacid Ben Hutchings
@ 2015-12-24 15:37 ` Ben Hutchings
2015-12-24 15:37 ` [PATCH 3.2 68/77] sctp: update the netstamp_needed counter when copying sockets Ben Hutchings
` (68 subsequent siblings)
78 siblings, 0 replies; 84+ messages in thread
From: Ben Hutchings @ 2015-12-24 15:37 UTC (permalink / raw)
To: linux-kernel, stable
Cc: akpm, Rajmohan Mani, Greg Kroah-Hartman, Joe Lawrence,
Mathias Nyman
3.2.75-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Rajmohan Mani <rajmohan.mani@intel.com>
commit a5964396190d0c40dd549c23848c282fffa5d1f2 upstream.
Existing Intel xHCI controllers require a delay of 1 mS,
after setting the CMD_RESET bit in command register, before
accessing any HC registers. This allows the HC to complete
the reset operation and be ready for HC register access.
Without this delay, the subsequent HC register access,
may result in a system hang, very rarely.
Verified CherryView / Braswell platforms go through over
5000 warm reboot cycles (which was not possible without
this patch), without any xHCI reset hang.
Signed-off-by: Rajmohan Mani <rajmohan.mani@intel.com>
Tested-by: Joe Lawrence <joe.lawrence@stratus.com>
Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
[bwh: Backported to 3.2: adjust context]
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
---
drivers/usb/host/xhci.c | 10 ++++++++++
1 file changed, 10 insertions(+)
--- a/drivers/usb/host/xhci.c
+++ b/drivers/usb/host/xhci.c
@@ -170,6 +170,16 @@ int xhci_reset(struct xhci_hcd *xhci)
command |= CMD_RESET;
xhci_writel(xhci, command, &xhci->op_regs->command);
+ /* Existing Intel xHCI controllers require a delay of 1 mS,
+ * after setting the CMD_RESET bit, and before accessing any
+ * HC registers. This allows the HC to complete the
+ * reset operation and be ready for HC register access.
+ * Without this delay, the subsequent HC register access,
+ * may result in a system hang very rarely.
+ */
+ if (xhci->quirks & XHCI_INTEL_HOST)
+ udelay(1000);
+
ret = handshake(xhci, &xhci->op_regs->command,
CMD_RESET, 0, 10 * 1000 * 1000);
if (ret)
^ permalink raw reply [flat|nested] 84+ messages in thread
* [PATCH 3.2 44/77] ipv4: igmp: Allow removing groups from a removed interface
2015-12-24 15:37 [PATCH 3.2 00/77] 3.2.75-rc1 review Ben Hutchings
` (55 preceding siblings ...)
2015-12-24 15:37 ` [PATCH 3.2 67/77] atl1c: Improve driver not to do order 4 GFP_ATOMIC allocation Ben Hutchings
@ 2015-12-24 15:37 ` Ben Hutchings
2015-12-24 15:37 ` [PATCH 3.2 11/77] ASoC: wm8962: correct addresses for HPF_C_0/1 Ben Hutchings
` (21 subsequent siblings)
78 siblings, 0 replies; 84+ messages in thread
From: Ben Hutchings @ 2015-12-24 15:37 UTC (permalink / raw)
To: linux-kernel, stable; +Cc: akpm, David S. Miller, Andrew Lunn
3.2.75-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Andrew Lunn <andrew@lunn.ch>
commit 4eba7bb1d72d9bde67d810d09bf62dc207b63c5c upstream.
When a multicast group is joined on a socket, a struct ip_mc_socklist
is appended to the sockets mc_list containing information about the
joined group.
If the interface is hot unplugged, this entry becomes stale. Prior to
commit 52ad353a5344f ("igmp: fix the problem when mc leave group") it
was possible to remove the stale entry by performing a
IP_DROP_MEMBERSHIP, passing either the old ifindex or ip address on
the interface. However, this fix enforces that the interface must
still exist. Thus with time, the number of stale entries grows, until
sysctl_igmp_max_memberships is reached and then it is not possible to
join and more groups.
The previous patch fixes an issue where a IP_DROP_MEMBERSHIP is
performed without specifying the interface, either by ifindex or ip
address. However here we do supply one of these. So loosen the
restriction on device existence to only apply when the interface has
not been specified. This then restores the ability to clean up the
stale entries.
Signed-off-by: Andrew Lunn <andrew@lunn.ch>
Fixes: 52ad353a5344f "(igmp: fix the problem when mc leave group")
Signed-off-by: David S. Miller <davem@davemloft.net>
[bwh: Backported to 3.2: adjust context]
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
---
net/ipv4/igmp.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
--- a/net/ipv4/igmp.c
+++ b/net/ipv4/igmp.c
@@ -1866,7 +1866,7 @@ int ip_mc_leave_group(struct sock *sk, s
rtnl_lock();
in_dev = ip_mc_find_dev(net, imr);
- if (!in_dev) {
+ if (!imr->imr_ifindex && !imr->imr_address.s_addr && !in_dev) {
ret = -ENODEV;
goto out;
}
@@ -1887,7 +1887,8 @@ int ip_mc_leave_group(struct sock *sk, s
*imlp = iml->next_rcu;
- ip_mc_dec_group(in_dev, group);
+ if (in_dev)
+ ip_mc_dec_group(in_dev, group);
rtnl_unlock();
/* decrease mem now to avoid the memleak warning */
atomic_sub(sizeof(*iml), &sk->sk_omem_alloc);
^ permalink raw reply [flat|nested] 84+ messages in thread
* [PATCH 3.2 00/77] 3.2.75-rc1 review
@ 2015-12-24 15:37 Ben Hutchings
2015-12-24 15:37 ` [PATCH 3.2 42/77] usb: Use the USB_SS_MULT() macro to decode burst multiplier for log message Ben Hutchings
` (78 more replies)
0 siblings, 79 replies; 84+ messages in thread
From: Ben Hutchings @ 2015-12-24 15:37 UTC (permalink / raw)
To: linux-kernel, stable; +Cc: torvalds, Guenter Roeck, Phil Jensen, akpm
This is the start of the stable review cycle for the 3.2.75 release.
There are 77 patches in this series, which will be posted as responses
to this one. If anyone has any issues with these being applied, please
let me know.
Responses should be made by Tue Dec 29 18:00:00 UTC 2015.
Anything received after that time might be too late.
A combined patch relative to 3.2.74 will be posted as an additional
response to this. A shortlog and diffstat can be found below.
Ben.
-------------
Aaro Koskinen (1):
broadcom: fix PHY_ID_BCM5481 entry in the id table
[3c25a860d17b7378822f35d8c9141db9507e3beb]
Al Viro (2):
9p: ->evict_inode() should kick out ->i_data, not ->i_mapping
[4ad78628445d26e5e9487b2e8f23274ad7b0f5d3]
fix sysvfs symlinks
[0ebf7f10d67a70e120f365018f1c5fce9ddc567d]
Aleksander Morgado (1):
USB: serial: option: add support for Novatel MiFi USB620L
[e07af133c3e2716db25e3e1e1d9f10c2088e9c1a]
Alexey Khoroshilov (1):
USB: whci-hcd: add check for dma mapping error
[f9fa1887dcf26bd346665a6ae3d3f53dec54cba1]
Andrew Lunn (1):
ipv4: igmp: Allow removing groups from a removed interface
[4eba7bb1d72d9bde67d810d09bf62dc207b63c5c]
Ben Hutchings (6):
USB: cdc-acm - Add IGNORE_DEVICE quirk
[16142655269aaf580488e074eabfdcf0fb4e3687]
USB: ti_usb_3410_502: Fix ID table size
[not upstream; only needed before 3.12]
isdn_ppp: Add checks for allocation failure in isdn_ppp_open()
[0baa57d8dc32db78369d8b5176ef56c5e2e18ab3]
ppp, slip: Validate VJ compression slot parameters completely
[4ab42d78e37a294ac7bc56901d563c642e03c4ae]
usb: Use the USB_SS_MULT() macro to decode burst multiplier for log message
[5377adb092664d336ac212499961cac5e8728794]
xhci: Add XHCI_INTEL_HOST quirk
[e3567d2c15a7a8e2f992a5f7c7683453ca406d82]
Bjørn Mork (1):
USB: option: add XS Stick W100-2 from 4G Systems
[638148e20c7f8f6e95017fdc13bce8549a6925e0]
Chunfeng Yun (1):
usb: xhci: fix config fail of FS hub behind a HS hub with MTT
[096b110a3dd3c868e4610937c80d2e3f3357c1a9]
Clemens Ladisch (3):
ALSA: usb-audio: add packet size quirk for the Medeli DD305
[98d362becb6621bebdda7ed0eac7ad7ec6c37898]
ALSA: usb-audio: prevent CH345 multiport output SysEx corruption
[1ca8b201309d842642f221db7f02f71c0af5be2d]
ALSA: usb-audio: work around CH345 input SysEx corruption
[a91e627e3f0ed820b11d86cdc04df38f65f33a70]
Daniel Borkmann (1):
net, scm: fix PaX detected msg_controllen overflow in scm_detach_fds
[6900317f5eff0a7070c5936e5383f589e0de7a09]
David S. Miller (1):
bluetooth: Validate socket address length in sco_sock_bind().
[5233252fce714053f0151680933571a2da9cbfb4]
David Turner (1):
ext4: Fix handling of extended tv_sec
[a4dad1ae24f850410c4e60f22823cba1289b8d52]
David Woodhouse (1):
USB: ti_usb_3410_5052: Add Honeywell HGI80 ID
[1bcb49e663f88bccee35b8688e6a3da2bea31fd4]
Diego Elio Pettenò (1):
USB: serial: ti_usb_3410_5052: add Abbott strip port ID to combined table as well.
[c9d09dc7ad106492c17c587b6eeb99fe3f43e522]
Dmitry V. Levin (1):
sh64: fix __NR_fgetxattr
[2d33fa1059da4c8e816627a688d950b613ec0474]
Eric Dumazet (5):
af_unix: fix a fatal race with bit fields
[60bc851ae59bfe99be6ee89d6bc50008c85ec75d]
ipv6: add complete rcu protection around np->opt
[45f6fad84cc305103b28d73482b344d7f5b76f39]
ipv6: sctp: clone options to avoid use after free
[9470e24f35ab81574da54e69df90c1eb4a96b43f]
ipv6: sctp: implement sctp_v6_destroy_sock()
[602dd62dfbda3e63a2d6a3cbde953ebe82bf5087]
tcp: initialize tp->copied_seq in case of cross SYN connection
[142a2e7ece8d8ac0e818eb2c91f99ca894730e2a]
Geert Uytterhoeven (1):
FS-Cache: Add missing initialization of ret in cachefiles_write_page()
[cf89752645e47d86ba8a4157f4b121fcb33434c5]
Hannes Frederic Sowa (1):
net: add validation for the socket syscall protocol argument
[79462ad02e861803b3840cc782248c7359451cd9]
Jan Kara (3):
jbd2: Fix unreclaimed pages after truncate in data=journal mode
[bc23f0c8d7ccd8d924c4e70ce311288cb3e61ea8]
vfs: Avoid softlockups with sendfile(2)
[c2489e07c0a71a56fb2c84bc0ee66cddfca7d068]
vfs: Make sendfile(2) killable even better
[c725bfce7968009756ed2836a8cd7ba4dc163011]
Jan Stancek (1):
ipmi: move timer init to before irq is setup
[27f972d3e00b50639deb4cc1392afaeb08d3cecc]
Jeff Layton (1):
nfs: if we have no valid attrs, then don't declare the attribute cache valid
[c812012f9ca7cf89c9e1a1cd512e6c3b5be04b85]
Jiri Slaby (1):
usblp: do not set TASK_INTERRUPTIBLE before lock
[19cd80a214821f4b558560ebd76bfb2c38b4f3d8]
Joe Thornber (1):
dm btree: fix bufio buffer leaks in dm_btree_del() error path
[ed8b45a3679eb49069b094c0711b30833f27c734]
Johannes Berg (1):
mac80211: mesh: fix call_rcu() usage
[c2e703a55245bfff3db53b1f7cbe59f1ee8a4339]
Jonas Jonsson (1):
USB: cdc_acm: Ignore Infineon Flash Loader utility
[f33a7f72e5fc033daccbb8d4753d7c5c41a4d67b]
Kees Cook (1):
mac: validate mac_partition is within sector
[02e2a5bfebe99edcf9d694575a75032d53fe1b73]
Kirill A. Shutemov (1):
vgaarb: fix signal handling in vga_get()
[9f5bd30818c42c6c36a51f93b4df75a2ea2bd85e]
Konstantin Shkolnyy (1):
USB: cp210x: Remove CP2110 ID from compatibility list
[7c90e610b60cd1ed6abafd806acfaedccbbe52d1]
Lucien (1):
sctp: translate host order to network order when setting a hmacid
[ed5a377d87dc4c87fb3e1f7f698cba38cd893103]
Marcelo Ricardo Leitner (1):
sctp: update the netstamp_needed counter when copying sockets
[01ce63c90170283a9855d1db4fe81934dddce648]
Michal Hocko (1):
mm, vmstat: allow WQ concurrency to discover memory reclaim doesn't make any progress
[373ccbe5927034b55bdc80b0f8b54d6e13fe8d12]
Michal Kubeček (1):
ipv6: distinguish frag queues by device for multicast and link-local packets
[264640fc2c5f4f913db5c73fa3eb1ead2c45e9d7]
Mike Snitzer (1):
dm btree: fix leak of bufio-backed block in btree_split_sibling error path
[30ce6e1cc5a0f781d60227e9096c86e188d2c2bd]
Mikulas Patocka (2):
parisc iommu: fix panic due to trying to allocate too large region
[e46e31a3696ae2d66f32c207df3969613726e636]
sata_sil: disable trim
[d98f1cd0a3b70ea91f1dfda3ac36c3b2e1a4d5e2]
Mirza Krak (1):
can: sja1000: clear interrupts on start
[7cecd9ab80f43972c056dc068338f7bcc407b71c]
Naoya Horiguchi (1):
mm: hugetlb: call huge_pte_alloc() only if ptep is null
[0d777df5d8953293be090d9ab5a355db893e8357]
Neil Horman (1):
snmp: Remove duplicate OUTMCAST stat increment
[41033f029e393a64e81966cbe34d66c6cf8a2e7e]
Nikolay Aleksandrov (3):
net: fix __netdev_update_features return on ndo_set_features failure
[00ee5927177792a6e139d50b6b7564d35705556a]
net: ip6mr: fix static mfc/dev leaks on table destruction
[4c6980462f32b4f282c5d8e5f7ea8070e2937725]
net: ipmr: fix static mfc/dev leaks on table destruction
[0e615e9601a15efeeb8942cf7cd4dadba0c8c5a7]
Pavel Machek (1):
atl1c: Improve driver not to do order 4 GFP_ATOMIC allocation
[f2a3771ae8aca879c32336c76ad05a017629bae2]
Peter Hurley (2):
locking: Add WARN_ON_ONCE lock assertion
[9a37110d20c95d1ebf6c04881177fe8f62831db2]
wan/x25: Fix use-after-free in x25_asy_open_tty()
[ee9159ddce14bc1dec9435ae4e3bd3153e783706]
Quentin Casasnovas (1):
RDS: fix race condition when sending a message on unbound socket
[8c7188b23474cca017b3ef354c4a58456f68303a]
Rainer Weikusat (2):
af_unix: Revert 'lock_interruptible' in stream receive code
[3822b5c2fc62e3de8a0f33806ff279fb7df92432]
unix: avoid use-after-free in ep_remove_wait_queue
[7d267278a9ece963d77eefec61630223fce08c6c]
Rajmohan Mani (1):
xhci: Workaround to get Intel xHCI reset working more reliably
[a5964396190d0c40dd549c23848c282fffa5d1f2]
Roman Gushchin (1):
fuse: break infinite loop in fuse_fill_write_pages()
[3ca8138f014a913f98e6ef40e939868e1e9ea876]
RongQing.Li (1):
dccp: remove unnecessary codes in ipv6.c
[0979e465c5ab205b63a1c1820fe833f396a120f0]
Sabrina Dubroca (1):
macvlan: fix leak in macvlan_handle_frame
[e639b8d8a7a728f0b05ef2df6cb6b45dc3d4e556]
Sachin Pandhare (1):
ASoC: wm8962: correct addresses for HPF_C_0/1
[e9f96bc53c1b959859599cb30ce6fd4fbb4448c2]
Sasha Levin (1):
sched/core: Remove false-positive warning from wake_up_process()
[119d6f6a3be8b424b200dcee56e74484d5445f7e]
Sergei Shtylyov (1):
sh_eth: fix kernel oops in skb_put()
[248be83dcb3feb3f6332eb3d010a016402138484]
Steven Rostedt (1):
ring-buffer: Update read stamp with first real commit on page
[b81f472a208d3e2b4392faa6d17037a89442f4ce]
Takashi Iwai (1):
ALSA: rme96: Fix unexpected volume reset after rate changes
[a74a821624c0c75388a193337babd17a8c02c740]
Thomas Hellstrom (2):
drm/ttm: Fixed a read/write lock imbalance
[025af189fb44250206dd8a32fa4a682392af3301]
drm: Fix an unwanted master inheritance v2
[a0af2e538c80f3e47f1d6ddf120a153ad909e8ad]
Uwe Kleine-König (1):
usb: musb: core: fix order of arguments to ulpi write callback
[705e63d2b29c8bbf091119084544d353bda70393]
WANG Cong (2):
ip6mr: call del_timer_sync() in ip6mr_free_table()
[7ba0c47c34a1ea5bc7a24ca67309996cce0569b5]
pptp: verify sockaddr_len in pptp_bind() and pptp_connect()
[09ccfd238e5a0e670d8178cf50180ea81ae09ae1]
Xiangliang Yu (1):
AHCI: Fix softreset failed issue of Port Multiplier
[023113d24ef9e1d2b44cb2446872b17e2b01d8b1]
Xunlei Pang (1):
sched/core: Clear the root_domain cpumasks in init_rootdomain()
[8295c69925ad53ec32ca54ac9fc194ff21bc40e2]
Makefile | 4 +-
arch/sh/include/asm/unistd_64.h | 2 +-
drivers/ata/libahci.c | 9 ++
drivers/ata/sata_sil.c | 3 +
drivers/char/ipmi/ipmi_si_intf.c | 8 +-
drivers/gpu/drm/drm_fops.c | 95 +++++++-----
drivers/gpu/drm/drm_stub.c | 7 +-
drivers/gpu/drm/ttm/ttm_lock.c | 2 +-
drivers/gpu/vga/vgaarb.c | 6 +-
drivers/isdn/i4l/isdn_ppp.c | 12 +-
drivers/md/persistent-data/dm-btree.c | 20 ++-
drivers/net/can/sja1000/sja1000.c | 3 +
drivers/net/ethernet/atheros/atl1c/atl1c_main.c | 7 +-
drivers/net/ethernet/renesas/sh_eth.c | 4 +-
drivers/net/macvlan.c | 2 +
drivers/net/phy/broadcom.c | 2 +-
drivers/net/ppp/ppp_generic.c | 6 +-
drivers/net/ppp/pptp.c | 6 +
drivers/net/slip/slhc.c | 12 +-
drivers/net/slip/slip.c | 2 +-
drivers/net/wan/x25_asy.c | 6 +-
drivers/parisc/iommu-helpers.h | 15 +-
drivers/usb/class/cdc-acm.c | 9 ++
drivers/usb/class/cdc-acm.h | 1 +
drivers/usb/class/usblp.c | 2 +-
drivers/usb/core/config.c | 3 +-
drivers/usb/host/whci/qset.c | 4 +
drivers/usb/host/xhci-pci.c | 2 +
drivers/usb/host/xhci.c | 18 +++
drivers/usb/host/xhci.h | 1 +
drivers/usb/musb/musb_core.c | 11 +-
drivers/usb/serial/cp210x.c | 1 -
drivers/usb/serial/option.c | 11 ++
drivers/usb/serial/ti_usb_3410_5052.c | 7 +-
drivers/usb/serial/ti_usb_3410_5052.h | 4 +
fs/9p/vfs_inode.c | 4 +-
fs/cachefiles/rdwr.c | 2 +-
fs/ext4/ext4.h | 51 +++++-
fs/fuse/file.c | 2 +-
fs/jbd2/transaction.c | 2 +
fs/nfs/inode.c | 6 +-
fs/partitions/mac.c | 10 +-
fs/splice.c | 8 +
fs/sysv/Makefile | 2 +-
fs/sysv/inode.c | 10 +-
fs/sysv/symlink.c | 20 ---
include/drm/drmP.h | 6 +
include/linux/ipv6.h | 2 +-
include/linux/lockdep.h | 5 +
include/net/af_unix.h | 6 +-
include/net/ipv6.h | 22 ++-
include/net/sock.h | 3 +
kernel/sched.c | 7 +-
kernel/trace/ring_buffer.c | 12 +-
mm/backing-dev.c | 19 ++-
mm/hugetlb.c | 8 +-
mm/vmstat.c | 6 +-
net/ax25/af_ax25.c | 3 +
net/bluetooth/sco.c | 3 +
net/core/dev.c | 2 +-
net/core/scm.c | 2 +
net/dccp/ipv6.c | 44 +++---
net/decnet/af_decnet.c | 3 +
net/ipv4/af_inet.c | 3 +
net/ipv4/igmp.c | 5 +-
net/ipv4/ipmr.c | 15 +-
net/ipv4/tcp_input.c | 1 +
net/ipv6/af_inet6.c | 15 +-
net/ipv6/datagram.c | 4 +-
net/ipv6/exthdrs.c | 3 +-
net/ipv6/inet6_connection_sock.c | 11 +-
net/ipv6/ip6mr.c | 17 +-
net/ipv6/ipv6_sockglue.c | 36 +++--
net/ipv6/mcast.c | 2 -
net/ipv6/netfilter/nf_conntrack_reasm.c | 6 +-
net/ipv6/raw.c | 8 +-
net/ipv6/reassembly.c | 14 +-
net/ipv6/syncookies.c | 2 +-
net/ipv6/tcp_ipv6.c | 37 ++---
net/ipv6/udp.c | 8 +-
net/irda/af_irda.c | 3 +
net/mac80211/mesh_pathtbl.c | 8 +-
net/rds/connection.c | 6 -
net/rds/send.c | 4 +-
net/sctp/auth.c | 4 +-
net/sctp/ipv6.c | 8 +
net/sctp/socket.c | 12 +-
net/unix/af_unix.c | 196 ++++++++++++++++++++----
net/unix/garbage.c | 12 +-
sound/pci/rme96.c | 41 +++--
sound/soc/codecs/wm8962.c | 4 +-
sound/usb/midi.c | 46 ++++++
sound/usb/quirks-table.h | 11 ++
sound/usb/quirks.c | 1 +
sound/usb/usbaudio.h | 1 +
95 files changed, 800 insertions(+), 321 deletions(-)
--
Ben Hutchings
If the facts do not conform to your theory, they must be disposed of.
^ permalink raw reply [flat|nested] 84+ messages in thread
* [PATCH 3.2 16/77] xhci: Add XHCI_INTEL_HOST quirk
2015-12-24 15:37 [PATCH 3.2 00/77] 3.2.75-rc1 review Ben Hutchings
` (75 preceding siblings ...)
2015-12-24 15:37 ` [PATCH 3.2 28/77] fix sysvfs symlinks Ben Hutchings
@ 2015-12-24 15:37 ` Ben Hutchings
2015-12-24 16:40 ` [PATCH 3.2 00/77] 3.2.75-rc1 review Ben Hutchings
2015-12-24 22:20 ` Guenter Roeck
78 siblings, 0 replies; 84+ messages in thread
From: Ben Hutchings @ 2015-12-24 15:37 UTC (permalink / raw)
To: linux-kernel, stable; +Cc: akpm
3.2.75-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Ben Hutchings <ben@decadent.org.uk>
Extracted from commit e3567d2c15a7 ("xhci: Add Intel U1/U2 timeout policy.")
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
---
--- a/drivers/usb/host/xhci-pci.c
+++ b/drivers/usb/host/xhci-pci.c
@@ -106,6 +106,8 @@ static void xhci_pci_quirks(struct devic
xhci->quirks |= XHCI_TRUST_TX_LENGTH;
if (pdev->vendor == PCI_VENDOR_ID_INTEL)
+ xhci->quirks |= XHCI_INTEL_HOST;
+ if (pdev->vendor == PCI_VENDOR_ID_INTEL)
xhci->quirks |= XHCI_AVOID_BEI;
if (pdev->vendor == PCI_VENDOR_ID_INTEL &&
pdev->device == PCI_DEVICE_ID_INTEL_PANTHERPOINT_XHCI) {
--- a/drivers/usb/host/xhci.h
+++ b/drivers/usb/host/xhci.h
@@ -1492,6 +1492,7 @@ struct xhci_hcd {
#define XHCI_SW_BW_CHECKING (1 << 8)
#define XHCI_AMD_0x96_HOST (1 << 9)
#define XHCI_TRUST_TX_LENGTH (1 << 10)
+#define XHCI_INTEL_HOST (1 << 12)
#define XHCI_SPURIOUS_REBOOT (1 << 13)
#define XHCI_COMP_MODE_QUIRK (1 << 14)
#define XHCI_AVOID_BEI (1 << 15)
^ permalink raw reply [flat|nested] 84+ messages in thread
* [PATCH 3.2 61/77] net, scm: fix PaX detected msg_controllen overflow in scm_detach_fds
2015-12-24 15:37 [PATCH 3.2 00/77] 3.2.75-rc1 review Ben Hutchings
` (15 preceding siblings ...)
2015-12-24 15:37 ` [PATCH 3.2 45/77] locking: Add WARN_ON_ONCE lock assertion Ben Hutchings
@ 2015-12-24 15:37 ` Ben Hutchings
2015-12-24 15:37 ` [PATCH 3.2 38/77] AHCI: Fix softreset failed issue of Port Multiplier Ben Hutchings
` (61 subsequent siblings)
78 siblings, 0 replies; 84+ messages in thread
From: Ben Hutchings @ 2015-12-24 15:37 UTC (permalink / raw)
To: linux-kernel, stable
Cc: akpm, David S. Miller, HacKurx, David Sterba, Brad Spengler,
Wei Yongjun, Emese Revfy, Hannes Frederic Sowa, Eric Dumazet,
PaX Team, Daniel Borkmann
3.2.75-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Daniel Borkmann <daniel@iogearbox.net>
[ Upstream commit 6900317f5eff0a7070c5936e5383f589e0de7a09 ]
David and HacKurx reported a following/similar size overflow triggered
in a grsecurity kernel, thanks to PaX's gcc size overflow plugin:
(Already fixed in later grsecurity versions by Brad and PaX Team.)
[ 1002.296137] PAX: size overflow detected in function scm_detach_fds net/core/scm.c:314
cicus.202_127 min, count: 4, decl: msg_controllen; num: 0; context: msghdr;
[ 1002.296145] CPU: 0 PID: 3685 Comm: scm_rights_recv Not tainted 4.2.3-grsec+ #7
[ 1002.296149] Hardware name: Apple Inc. MacBookAir5,1/Mac-66F35F19FE2A0D05, [...]
[ 1002.296153] ffffffff81c27366 0000000000000000 ffffffff81c27375 ffffc90007843aa8
[ 1002.296162] ffffffff818129ba 0000000000000000 ffffffff81c27366 ffffc90007843ad8
[ 1002.296169] ffffffff8121f838 fffffffffffffffc fffffffffffffffc ffffc90007843e60
[ 1002.296176] Call Trace:
[ 1002.296190] [<ffffffff818129ba>] dump_stack+0x45/0x57
[ 1002.296200] [<ffffffff8121f838>] report_size_overflow+0x38/0x60
[ 1002.296209] [<ffffffff816a979e>] scm_detach_fds+0x2ce/0x300
[ 1002.296220] [<ffffffff81791899>] unix_stream_read_generic+0x609/0x930
[ 1002.296228] [<ffffffff81791c9f>] unix_stream_recvmsg+0x4f/0x60
[ 1002.296236] [<ffffffff8178dc00>] ? unix_set_peek_off+0x50/0x50
[ 1002.296243] [<ffffffff8168fac7>] sock_recvmsg+0x47/0x60
[ 1002.296248] [<ffffffff81691522>] ___sys_recvmsg+0xe2/0x1e0
[ 1002.296257] [<ffffffff81693496>] __sys_recvmsg+0x46/0x80
[ 1002.296263] [<ffffffff816934fc>] SyS_recvmsg+0x2c/0x40
[ 1002.296271] [<ffffffff8181a3ab>] entry_SYSCALL_64_fastpath+0x12/0x85
Further investigation showed that this can happen when an *odd* number of
fds are being passed over AF_UNIX sockets.
In these cases CMSG_LEN(i * sizeof(int)) and CMSG_SPACE(i * sizeof(int)),
where i is the number of successfully passed fds, differ by 4 bytes due
to the extra CMSG_ALIGN() padding in CMSG_SPACE() to an 8 byte boundary
on 64 bit. The padding is used to align subsequent cmsg headers in the
control buffer.
When the control buffer passed in from the receiver side *lacks* these 4
bytes (e.g. due to buggy/wrong API usage), then msg->msg_controllen will
overflow in scm_detach_fds():
int cmlen = CMSG_LEN(i * sizeof(int)); <--- cmlen w/o tail-padding
err = put_user(SOL_SOCKET, &cm->cmsg_level);
if (!err)
err = put_user(SCM_RIGHTS, &cm->cmsg_type);
if (!err)
err = put_user(cmlen, &cm->cmsg_len);
if (!err) {
cmlen = CMSG_SPACE(i * sizeof(int)); <--- cmlen w/ 4 byte extra tail-padding
msg->msg_control += cmlen;
msg->msg_controllen -= cmlen; <--- iff no tail-padding space here ...
} ... wrap-around
F.e. it will wrap to a length of 18446744073709551612 bytes in case the
receiver passed in msg->msg_controllen of 20 bytes, and the sender
properly transferred 1 fd to the receiver, so that its CMSG_LEN results
in 20 bytes and CMSG_SPACE in 24 bytes.
In case of MSG_CMSG_COMPAT (scm_detach_fds_compat()), I haven't seen an
issue in my tests as alignment seems always on 4 byte boundary. Same
should be in case of native 32 bit, where we end up with 4 byte boundaries
as well.
In practice, passing msg->msg_controllen of 20 to recvmsg() while receiving
a single fd would mean that on successful return, msg->msg_controllen is
being set by the kernel to 24 bytes instead, thus more than the input
buffer advertised. It could f.e. become an issue if such application later
on zeroes or copies the control buffer based on the returned msg->msg_controllen
elsewhere.
Maximum number of fds we can send is a hard upper limit SCM_MAX_FD (253).
Going over the code, it seems like msg->msg_controllen is not being read
after scm_detach_fds() in scm_recv() anymore by the kernel, good!
Relevant recvmsg() handler are unix_dgram_recvmsg() (unix_seqpacket_recvmsg())
and unix_stream_recvmsg(). Both return back to their recvmsg() caller,
and ___sys_recvmsg() places the updated length, that is, new msg_control -
old msg_control pointer into msg->msg_controllen (hence the 24 bytes seen
in the example).
Long time ago, Wei Yongjun fixed something related in commit 1ac70e7ad24a
("[NET]: Fix function put_cmsg() which may cause usr application memory
overflow").
RFC3542, section 20.2. says:
The fields shown as "XX" are possible padding, between the cmsghdr
structure and the data, and between the data and the next cmsghdr
structure, if required by the implementation. While sending an
application may or may not include padding at the end of last
ancillary data in msg_controllen and implementations must accept both
as valid. On receiving a portable application must provide space for
padding at the end of the last ancillary data as implementations may
copy out the padding at the end of the control message buffer and
include it in the received msg_controllen. When recvmsg() is called
if msg_controllen is too small for all the ancillary data items
including any trailing padding after the last item an implementation
may set MSG_CTRUNC.
Since we didn't place MSG_CTRUNC for already quite a long time, just do
the same as in 1ac70e7ad24a to avoid an overflow.
Btw, even man-page author got this wrong :/ See db939c9b26e9 ("cmsg.3: Fix
error in SCM_RIGHTS code sample"). Some people must have copied this (?),
thus it got triggered in the wild (reported several times during boot by
David and HacKurx).
No Fixes tag this time as pre 2002 (that is, pre history tree).
Reported-by: David Sterba <dave@jikos.cz>
Reported-by: HacKurx <hackurx@gmail.com>
Cc: PaX Team <pageexec@freemail.hu>
Cc: Emese Revfy <re.emese@gmail.com>
Cc: Brad Spengler <spender@grsecurity.net>
Cc: Wei Yongjun <yongjun_wei@trendmicro.com.cn>
Cc: Eric Dumazet <edumazet@google.com>
Reviewed-by: Hannes Frederic Sowa <hannes@stressinduktion.org>
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
---
net/core/scm.c | 2 ++
1 file changed, 2 insertions(+)
--- a/net/core/scm.c
+++ b/net/core/scm.c
@@ -311,6 +311,8 @@ void scm_detach_fds(struct msghdr *msg,
err = put_user(cmlen, &cm->cmsg_len);
if (!err) {
cmlen = CMSG_SPACE(i*sizeof(int));
+ if (msg->msg_controllen < cmlen)
+ cmlen = msg->msg_controllen;
msg->msg_control += cmlen;
msg->msg_controllen -= cmlen;
}
^ permalink raw reply [flat|nested] 84+ messages in thread
* [PATCH 3.2 67/77] atl1c: Improve driver not to do order 4 GFP_ATOMIC allocation
2015-12-24 15:37 [PATCH 3.2 00/77] 3.2.75-rc1 review Ben Hutchings
` (54 preceding siblings ...)
2015-12-24 15:37 ` [PATCH 3.2 04/77] ALSA: usb-audio: prevent CH345 multiport output SysEx corruption Ben Hutchings
@ 2015-12-24 15:37 ` Ben Hutchings
2015-12-24 15:37 ` [PATCH 3.2 44/77] ipv4: igmp: Allow removing groups from a removed interface Ben Hutchings
` (22 subsequent siblings)
78 siblings, 0 replies; 84+ messages in thread
From: Ben Hutchings @ 2015-12-24 15:37 UTC (permalink / raw)
To: linux-kernel, stable; +Cc: akpm, David S. Miller, Michal Hocko, Pavel Machek
3.2.75-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Pavel Machek <pavel@ucw.cz>
[ Upstream commit f2a3771ae8aca879c32336c76ad05a017629bae2 ]
atl1c driver is doing order-4 allocation with GFP_ATOMIC
priority. That often breaks networking after resume. Switch to
GFP_KERNEL. Still not ideal, but should be significantly better.
atl1c_setup_ring_resources() is called from .open() function, and
already uses GFP_KERNEL, so this change is safe.
Signed-off-by: Pavel Machek <pavel@ucw.cz>
Acked-by: Michal Hocko <mhocko@suse.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
---
drivers/net/ethernet/atheros/atl1c/atl1c_main.c | 7 +++----
1 file changed, 3 insertions(+), 4 deletions(-)
--- a/drivers/net/ethernet/atheros/atl1c/atl1c_main.c
+++ b/drivers/net/ethernet/atheros/atl1c/atl1c_main.c
@@ -981,13 +981,12 @@ static int atl1c_setup_ring_resources(st
sizeof(struct atl1c_hw_stats) +
8 * 4 + 8 * 2 * num_rx_queues;
- ring_header->desc = pci_alloc_consistent(pdev, ring_header->size,
- &ring_header->dma);
+ ring_header->desc = dma_zalloc_coherent(&pdev->dev, ring_header->size,
+ &ring_header->dma, GFP_KERNEL);
if (unlikely(!ring_header->desc)) {
- dev_err(&pdev->dev, "pci_alloc_consistend failed\n");
+ dev_err(&pdev->dev, "could not get memory for DMA buffer\n");
goto err_nomem;
}
- memset(ring_header->desc, 0, ring_header->size);
/* init TPD ring */
tpd_ring[0].dma = roundup(ring_header->dma, 8);
^ permalink raw reply [flat|nested] 84+ messages in thread
* [PATCH 3.2 64/77] dccp: remove unnecessary codes in ipv6.c
2015-12-24 15:37 [PATCH 3.2 00/77] 3.2.75-rc1 review Ben Hutchings
` (43 preceding siblings ...)
2015-12-24 15:37 ` [PATCH 3.2 63/77] ipv6: distinguish frag queues by device for multicast and link-local packets Ben Hutchings
@ 2015-12-24 15:37 ` Ben Hutchings
2015-12-24 15:37 ` [PATCH 3.2 41/77] USB: whci-hcd: add check for dma mapping error Ben Hutchings
` (33 subsequent siblings)
78 siblings, 0 replies; 84+ messages in thread
From: Ben Hutchings @ 2015-12-24 15:37 UTC (permalink / raw)
To: linux-kernel, stable; +Cc: akpm, Eric Dumazet, RongQing.Li, David S. Miller
3.2.75-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: "RongQing.Li" <roy.qing.li@gmail.com>
commit 0979e465c5ab205b63a1c1820fe833f396a120f0 upstream.
opt always equals np->opts, so it is meaningless to define opt, and
check if opt does not equal np->opts and then try to free opt.
Signed-off-by: RongQing.Li <roy.qing.li@gmail.com>
Acked-by: Eric Dumazet <edumazet@google.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
[bwh: Backported to 3.2: adjust context]
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
---
net/dccp/ipv6.c | 21 +++++----------------
1 file changed, 5 insertions(+), 16 deletions(-)
--- a/net/dccp/ipv6.c
+++ b/net/dccp/ipv6.c
@@ -236,7 +236,6 @@ static int dccp_v6_send_response(struct
struct inet6_request_sock *ireq6 = inet6_rsk(req);
struct ipv6_pinfo *np = inet6_sk(sk);
struct sk_buff *skb;
- struct ipv6_txoptions *opt = NULL;
struct in6_addr *final_p, final;
struct flowi6 fl6;
int err = -1;
@@ -252,9 +251,8 @@ static int dccp_v6_send_response(struct
fl6.fl6_sport = inet_rsk(req)->loc_port;
security_req_classify_flow(req, flowi6_to_flowi(&fl6));
- opt = np->opt;
- final_p = fl6_update_dst(&fl6, opt, &final);
+ final_p = fl6_update_dst(&fl6, np->opt, &final);
dst = ip6_dst_lookup_flow(sk, &fl6, final_p, false);
if (IS_ERR(dst)) {
@@ -271,13 +269,11 @@ static int dccp_v6_send_response(struct
&ireq6->loc_addr,
&ireq6->rmt_addr);
ipv6_addr_copy(&fl6.daddr, &ireq6->rmt_addr);
- err = ip6_xmit(sk, skb, &fl6, opt, np->tclass);
+ err = ip6_xmit(sk, skb, &fl6, np->opt, np->tclass);
err = net_xmit_eval(err);
}
done:
- if (opt != NULL && opt != np->opt)
- sock_kfree_s(sk, opt, opt->tot_len);
dst_release(dst);
return err;
}
@@ -470,7 +466,6 @@ static struct sock *dccp_v6_request_recv
struct inet_sock *newinet;
struct dccp6_sock *newdp6;
struct sock *newsk;
- struct ipv6_txoptions *opt;
if (skb->protocol == htons(ETH_P_IP)) {
/*
@@ -515,7 +510,6 @@ static struct sock *dccp_v6_request_recv
return newsk;
}
- opt = np->opt;
if (sk_acceptq_is_full(sk))
goto out_overflow;
@@ -527,7 +521,7 @@ static struct sock *dccp_v6_request_recv
memset(&fl6, 0, sizeof(fl6));
fl6.flowi6_proto = IPPROTO_DCCP;
ipv6_addr_copy(&fl6.daddr, &ireq6->rmt_addr);
- final_p = fl6_update_dst(&fl6, opt, &final);
+ final_p = fl6_update_dst(&fl6, np->opt, &final);
ipv6_addr_copy(&fl6.saddr, &ireq6->loc_addr);
fl6.flowi6_oif = sk->sk_bound_dev_if;
fl6.fl6_dport = inet_rsk(req)->rmt_port;
@@ -592,11 +586,8 @@ static struct sock *dccp_v6_request_recv
* Yes, keeping reference count would be much more clever, but we make
* one more one thing there: reattach optmem to newsk.
*/
- if (opt != NULL) {
- newnp->opt = ipv6_dup_options(newsk, opt);
- if (opt != np->opt)
- sock_kfree_s(sk, opt, opt->tot_len);
- }
+ if (np->opt != NULL)
+ newnp->opt = ipv6_dup_options(newsk, np->opt);
inet_csk(newsk)->icsk_ext_hdr_len = 0;
if (newnp->opt != NULL)
@@ -623,8 +614,6 @@ out_nonewsk:
dst_release(dst);
out:
NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_LISTENDROPS);
- if (opt != NULL && opt != np->opt)
- sock_kfree_s(sk, opt, opt->tot_len);
return NULL;
}
^ permalink raw reply [flat|nested] 84+ messages in thread
* [PATCH 3.2 03/77] ALSA: usb-audio: add packet size quirk for the Medeli DD305
2015-12-24 15:37 [PATCH 3.2 00/77] 3.2.75-rc1 review Ben Hutchings
` (30 preceding siblings ...)
2015-12-24 15:37 ` [PATCH 3.2 13/77] FS-Cache: Add missing initialization of ret in cachefiles_write_page() Ben Hutchings
@ 2015-12-24 15:37 ` Ben Hutchings
2015-12-24 15:37 ` [PATCH 3.2 26/77] USB: cdc_acm: Ignore Infineon Flash Loader utility Ben Hutchings
` (46 subsequent siblings)
78 siblings, 0 replies; 84+ messages in thread
From: Ben Hutchings @ 2015-12-24 15:37 UTC (permalink / raw)
To: linux-kernel, stable; +Cc: akpm, Clemens Ladisch, Takashi Iwai
3.2.75-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Clemens Ladisch <clemens@ladisch.de>
commit 98d362becb6621bebdda7ed0eac7ad7ec6c37898 upstream.
Signed-off-by: Clemens Ladisch <clemens@ladisch.de>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
---
sound/usb/midi.c | 1 +
1 file changed, 1 insertion(+)
--- a/sound/usb/midi.c
+++ b/sound/usb/midi.c
@@ -1326,6 +1326,7 @@ static int snd_usbmidi_out_endpoint_crea
* Various chips declare a packet size larger than 4 bytes, but
* do not actually work with larger packets:
*/
+ case USB_ID(0x0a67, 0x5011): /* Medeli DD305 */
case USB_ID(0x0a92, 0x1020): /* ESI M4U */
case USB_ID(0x1430, 0x474b): /* RedOctane GH MIDI INTERFACE */
case USB_ID(0x15ca, 0x0101): /* Textech USB Midi Cable */
^ permalink raw reply [flat|nested] 84+ messages in thread
* [PATCH 3.2 33/77] ext4: Fix handling of extended tv_sec
2015-12-24 15:37 [PATCH 3.2 00/77] 3.2.75-rc1 review Ben Hutchings
` (37 preceding siblings ...)
2015-12-24 15:37 ` [PATCH 3.2 32/77] ring-buffer: Update read stamp with first real commit on page Ben Hutchings
@ 2015-12-24 15:37 ` Ben Hutchings
2015-12-24 21:21 ` David Turner
2015-12-24 15:37 ` [PATCH 3.2 72/77] pptp: verify sockaddr_len in pptp_bind() and pptp_connect() Ben Hutchings
` (39 subsequent siblings)
78 siblings, 1 reply; 84+ messages in thread
From: Ben Hutchings @ 2015-12-24 15:37 UTC (permalink / raw)
To: linux-kernel, stable; +Cc: akpm, Theodore Ts'o, David Turner, Mark Harris
3.2.75-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: David Turner <novalis@novalis.org>
commit a4dad1ae24f850410c4e60f22823cba1289b8d52 upstream.
In ext4, the bottom two bits of {a,c,m}time_extra are used to extend
the {a,c,m}time fields, deferring the year 2038 problem to the year
2446.
When decoding these extended fields, for times whose bottom 32 bits
would represent a negative number, sign extension causes the 64-bit
extended timestamp to be negative as well, which is not what's
intended. This patch corrects that issue, so that the only negative
{a,c,m}times are those between 1901 and 1970 (as per 32-bit signed
timestamps).
Some older kernels might have written pre-1970 dates with 1,1 in the
extra bits. This patch treats those incorrectly-encoded dates as
pre-1970, instead of post-2311, until kernel 4.20 is released.
Hopefully by then e2fsck will have fixed up the bad data.
Also add a comment explaining the encoding of ext4's extra {a,c,m}time
bits.
Signed-off-by: David Turner <novalis@novalis.org>
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
Reported-by: Mark Harris <mh8928@yahoo.com>
Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=23732
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
---
fs/ext4/ext4.h | 51 ++++++++++++++++++++++++++++++++++++++++++++-------
1 file changed, 44 insertions(+), 7 deletions(-)
--- a/fs/ext4/ext4.h
+++ b/fs/ext4/ext4.h
@@ -26,6 +26,7 @@
#include <linux/seqlock.h>
#include <linux/mutex.h>
#include <linux/timer.h>
+#include <linux/version.h>
#include <linux/wait.h>
#include <linux/blockgroup_lock.h>
#include <linux/percpu_counter.h>
@@ -698,19 +699,55 @@ struct move_extent {
<= (EXT4_GOOD_OLD_INODE_SIZE + \
(einode)->i_extra_isize)) \
+/*
+ * We use an encoding that preserves the times for extra epoch "00":
+ *
+ * extra msb of adjust for signed
+ * epoch 32-bit 32-bit tv_sec to
+ * bits time decoded 64-bit tv_sec 64-bit tv_sec valid time range
+ * 0 0 1 -0x80000000..-0x00000001 0x000000000 1901-12-13..1969-12-31
+ * 0 0 0 0x000000000..0x07fffffff 0x000000000 1970-01-01..2038-01-19
+ * 0 1 1 0x080000000..0x0ffffffff 0x100000000 2038-01-19..2106-02-07
+ * 0 1 0 0x100000000..0x17fffffff 0x100000000 2106-02-07..2174-02-25
+ * 1 0 1 0x180000000..0x1ffffffff 0x200000000 2174-02-25..2242-03-16
+ * 1 0 0 0x200000000..0x27fffffff 0x200000000 2242-03-16..2310-04-04
+ * 1 1 1 0x280000000..0x2ffffffff 0x300000000 2310-04-04..2378-04-22
+ * 1 1 0 0x300000000..0x37fffffff 0x300000000 2378-04-22..2446-05-10
+ *
+ * Note that previous versions of the kernel on 64-bit systems would
+ * incorrectly use extra epoch bits 1,1 for dates between 1901 and
+ * 1970. e2fsck will correct this, assuming that it is run on the
+ * affected filesystem before 2242.
+ */
+
static inline __le32 ext4_encode_extra_time(struct timespec *time)
{
- return cpu_to_le32((sizeof(time->tv_sec) > 4 ?
- (time->tv_sec >> 32) & EXT4_EPOCH_MASK : 0) |
- ((time->tv_nsec << EXT4_EPOCH_BITS) & EXT4_NSEC_MASK));
+ u32 extra = sizeof(time->tv_sec) > 4 ?
+ ((time->tv_sec - (s32)time->tv_sec) >> 32) & EXT4_EPOCH_MASK : 0;
+ return cpu_to_le32(extra | (time->tv_nsec << EXT4_EPOCH_BITS));
}
static inline void ext4_decode_extra_time(struct timespec *time, __le32 extra)
{
- if (sizeof(time->tv_sec) > 4)
- time->tv_sec |= (__u64)(le32_to_cpu(extra) & EXT4_EPOCH_MASK)
- << 32;
- time->tv_nsec = (le32_to_cpu(extra) & EXT4_NSEC_MASK) >> EXT4_EPOCH_BITS;
+ if (unlikely(sizeof(time->tv_sec) > 4 &&
+ (extra & cpu_to_le32(EXT4_EPOCH_MASK)))) {
+#if LINUX_VERSION_CODE < KERNEL_VERSION(4,20,0)
+ /* Handle legacy encoding of pre-1970 dates with epoch
+ * bits 1,1. We assume that by kernel version 4.20,
+ * everyone will have run fsck over the affected
+ * filesystems to correct the problem. (This
+ * backwards compatibility may be removed before this
+ * time, at the discretion of the ext4 developers.)
+ */
+ u64 extra_bits = le32_to_cpu(extra) & EXT4_EPOCH_MASK;
+ if (extra_bits == 3 && ((time->tv_sec) & 0x80000000) != 0)
+ extra_bits = 0;
+ time->tv_sec += extra_bits << 32;
+#else
+ time->tv_sec += (u64)(le32_to_cpu(extra) & EXT4_EPOCH_MASK) << 32;
+#endif
+ }
+ time->tv_nsec = (le32_to_cpu(extra) & EXT4_NSEC_MASK) >> EXT4_EPOCH_BITS;
}
#define EXT4_INODE_SET_XTIME(xtime, inode, raw_inode) \
^ permalink raw reply [flat|nested] 84+ messages in thread
* [PATCH 3.2 59/77] snmp: Remove duplicate OUTMCAST stat increment
2015-12-24 15:37 [PATCH 3.2 00/77] 3.2.75-rc1 review Ben Hutchings
` (33 preceding siblings ...)
2015-12-24 15:37 ` [PATCH 3.2 06/77] USB: serial: option: add support for Novatel MiFi USB620L Ben Hutchings
@ 2015-12-24 15:37 ` Ben Hutchings
2015-12-24 15:37 ` [PATCH 3.2 24/77] USB: cp210x: Remove CP2110 ID from compatibility list Ben Hutchings
` (43 subsequent siblings)
78 siblings, 0 replies; 84+ messages in thread
From: Ben Hutchings @ 2015-12-24 15:37 UTC (permalink / raw)
To: linux-kernel, stable; +Cc: akpm, Claus Jensen, David Miller, Neil Horman
3.2.75-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Neil Horman <nhorman@tuxdriver.com>
[ Upstream commit 41033f029e393a64e81966cbe34d66c6cf8a2e7e ]
the OUTMCAST stat is double incremented, getting bumped once in the mcast code
itself, and again in the common ip output path. Remove the mcast bump, as its
not needed
Validated by the reporter, with good results
Signed-off-by: Neil Horman <nhorman@tuxdriver.com>
Reported-by: Claus Jensen <claus.jensen@microsemi.com>
CC: Claus Jensen <claus.jensen@microsemi.com>
CC: David Miller <davem@davemloft.net>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
---
net/ipv6/mcast.c | 2 --
1 file changed, 2 deletions(-)
--- a/net/ipv6/mcast.c
+++ b/net/ipv6/mcast.c
@@ -1441,7 +1441,6 @@ out:
if (!err) {
ICMP6MSGOUT_INC_STATS(net, idev, ICMPV6_MLD2_REPORT);
ICMP6_INC_STATS(net, idev, ICMP6_MIB_OUTMSGS);
- IP6_UPD_PO_STATS(net, idev, IPSTATS_MIB_OUTMCAST, payload_len);
} else {
IP6_INC_STATS(net, idev, IPSTATS_MIB_OUTDISCARDS);
}
@@ -1811,7 +1810,6 @@ out:
if (!err) {
ICMP6MSGOUT_INC_STATS(net, idev, type);
ICMP6_INC_STATS(net, idev, ICMP6_MIB_OUTMSGS);
- IP6_UPD_PO_STATS(net, idev, IPSTATS_MIB_OUTMCAST, full_len);
} else
IP6_INC_STATS(net, idev, IPSTATS_MIB_OUTDISCARDS);
^ permalink raw reply [flat|nested] 84+ messages in thread
* [PATCH 3.2 55/77] parisc iommu: fix panic due to trying to allocate too large region
2015-12-24 15:37 [PATCH 3.2 00/77] 3.2.75-rc1 review Ben Hutchings
` (49 preceding siblings ...)
2015-12-24 15:37 ` [PATCH 3.2 05/77] ALSA: usb-audio: work around CH345 input SysEx corruption Ben Hutchings
@ 2015-12-24 15:37 ` Ben Hutchings
2015-12-24 15:37 ` [PATCH 3.2 29/77] vfs: Make sendfile(2) killable even better Ben Hutchings
` (27 subsequent siblings)
78 siblings, 0 replies; 84+ messages in thread
From: Ben Hutchings @ 2015-12-24 15:37 UTC (permalink / raw)
To: linux-kernel, stable; +Cc: akpm, Mikulas Patocka, Helge Deller
3.2.75-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Mikulas Patocka <mpatocka@redhat.com>
commit e46e31a3696ae2d66f32c207df3969613726e636 upstream.
When using the Promise TX2+ SATA controller on PA-RISC, the system often
crashes with kernel panic, for example just writing data with the dd
utility will make it crash.
Kernel panic - not syncing: drivers/parisc/sba_iommu.c: I/O MMU @ 000000000000a000 is out of mapping resources
CPU: 0 PID: 18442 Comm: mkspadfs Not tainted 4.4.0-rc2 #2
Backtrace:
[<000000004021497c>] show_stack+0x14/0x20
[<0000000040410bf0>] dump_stack+0x88/0x100
[<000000004023978c>] panic+0x124/0x360
[<0000000040452c18>] sba_alloc_range+0x698/0x6a0
[<0000000040453150>] sba_map_sg+0x260/0x5b8
[<000000000c18dbb4>] ata_qc_issue+0x264/0x4a8 [libata]
[<000000000c19535c>] ata_scsi_translate+0xe4/0x220 [libata]
[<000000000c19a93c>] ata_scsi_queuecmd+0xbc/0x320 [libata]
[<0000000040499bbc>] scsi_dispatch_cmd+0xfc/0x130
[<000000004049da34>] scsi_request_fn+0x6e4/0x970
[<00000000403e95a8>] __blk_run_queue+0x40/0x60
[<00000000403e9d8c>] blk_run_queue+0x3c/0x68
[<000000004049a534>] scsi_run_queue+0x2a4/0x360
[<000000004049be68>] scsi_end_request+0x1a8/0x238
[<000000004049de84>] scsi_io_completion+0xfc/0x688
[<0000000040493c74>] scsi_finish_command+0x17c/0x1d0
The cause of the crash is not exhaustion of the IOMMU space, there is
plenty of free pages. The function sba_alloc_range is called with size
0x11000, thus the pages_needed variable is 0x11. The function
sba_search_bitmap is called with bits_wanted 0x11 and boundary size is
0x10 (because dma_get_seg_boundary(dev) returns 0xffff).
The function sba_search_bitmap attempts to allocate 17 pages that must not
cross 16-page boundary - it can't satisfy this requirement
(iommu_is_span_boundary always returns true) and fails even if there are
many free entries in the IOMMU space.
How did it happen that we try to allocate 17 pages that don't cross
16-page boundary? The cause is in the function iommu_coalesce_chunks. This
function tries to coalesce adjacent entries in the scatterlist. The
function does several checks if it may coalesce one entry with the next,
one of those checks is this:
if (startsg->length + dma_len > max_seg_size)
break;
When it finishes coalescing adjacent entries, it allocates the mapping:
sg_dma_len(contig_sg) = dma_len;
dma_len = ALIGN(dma_len + dma_offset, IOVP_SIZE);
sg_dma_address(contig_sg) =
PIDE_FLAG
| (iommu_alloc_range(ioc, dev, dma_len) << IOVP_SHIFT)
| dma_offset;
It is possible that (startsg->length + dma_len > max_seg_size) is false
(we are just near the 0x10000 max_seg_size boundary), so the funcion
decides to coalesce this entry with the next entry. When the coalescing
succeeds, the function performs
dma_len = ALIGN(dma_len + dma_offset, IOVP_SIZE);
And now, because of non-zero dma_offset, dma_len is greater than 0x10000.
iommu_alloc_range (a pointer to sba_alloc_range) is called and it attempts
to allocate 17 pages for a device that must not cross 16-page boundary.
To fix the bug, we must make sure that dma_len after addition of
dma_offset and alignment doesn't cross the segment boundary. I.e. change
if (startsg->length + dma_len > max_seg_size)
break;
to
if (ALIGN(dma_len + dma_offset + startsg->length, IOVP_SIZE) > max_seg_size)
break;
This patch makes this change (it precalculates max_seg_boundary at the
beginning of the function iommu_coalesce_chunks). I also added a check
that the mapping length doesn't exceed dma_get_seg_boundary(dev) (it is
not needed for Promise TX2+ SATA, but it may be needed for other devices
that have dma_get_seg_boundary lower than dma_get_max_seg_size).
Signed-off-by: Mikulas Patocka <mpatocka@redhat.com>
Signed-off-by: Helge Deller <deller@gmx.de>
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
---
drivers/parisc/iommu-helpers.h | 15 ++++++++-------
1 file changed, 8 insertions(+), 7 deletions(-)
--- a/drivers/parisc/iommu-helpers.h
+++ b/drivers/parisc/iommu-helpers.h
@@ -104,7 +104,11 @@ iommu_coalesce_chunks(struct ioc *ioc, s
struct scatterlist *contig_sg; /* contig chunk head */
unsigned long dma_offset, dma_len; /* start/len of DMA stream */
unsigned int n_mappings = 0;
- unsigned int max_seg_size = dma_get_max_seg_size(dev);
+ unsigned int max_seg_size = min(dma_get_max_seg_size(dev),
+ (unsigned)DMA_CHUNK_SIZE);
+ unsigned int max_seg_boundary = dma_get_seg_boundary(dev) + 1;
+ if (max_seg_boundary) /* check if the addition above didn't overflow */
+ max_seg_size = min(max_seg_size, max_seg_boundary);
while (nents > 0) {
@@ -139,14 +143,11 @@ iommu_coalesce_chunks(struct ioc *ioc, s
/*
** First make sure current dma stream won't
- ** exceed DMA_CHUNK_SIZE if we coalesce the
+ ** exceed max_seg_size if we coalesce the
** next entry.
*/
- if(unlikely(ALIGN(dma_len + dma_offset + startsg->length,
- IOVP_SIZE) > DMA_CHUNK_SIZE))
- break;
-
- if (startsg->length + dma_len > max_seg_size)
+ if (unlikely(ALIGN(dma_len + dma_offset + startsg->length, IOVP_SIZE) >
+ max_seg_size))
break;
/*
^ permalink raw reply [flat|nested] 84+ messages in thread
* [PATCH 3.2 24/77] USB: cp210x: Remove CP2110 ID from compatibility list
2015-12-24 15:37 [PATCH 3.2 00/77] 3.2.75-rc1 review Ben Hutchings
` (34 preceding siblings ...)
2015-12-24 15:37 ` [PATCH 3.2 59/77] snmp: Remove duplicate OUTMCAST stat increment Ben Hutchings
@ 2015-12-24 15:37 ` Ben Hutchings
2015-12-24 15:37 ` [PATCH 3.2 77/77] ppp, slip: Validate VJ compression slot parameters completely Ben Hutchings
` (42 subsequent siblings)
78 siblings, 0 replies; 84+ messages in thread
From: Ben Hutchings @ 2015-12-24 15:37 UTC (permalink / raw)
To: linux-kernel, stable; +Cc: akpm, Johan Hovold, Konstantin Shkolnyy
3.2.75-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Konstantin Shkolnyy <konstantin.shkolnyy@gmail.com>
commit 7c90e610b60cd1ed6abafd806acfaedccbbe52d1 upstream.
CP2110 ID (0x10c4, 0xea80) doesn't belong here because it's a HID
and completely different from CP210x devices.
Signed-off-by: Konstantin Shkolnyy <konstantin.shkolnyy@gmail.com>
Signed-off-by: Johan Hovold <johan@kernel.org>
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
---
drivers/usb/serial/cp210x.c | 1 -
1 file changed, 1 deletion(-)
--- a/drivers/usb/serial/cp210x.c
+++ b/drivers/usb/serial/cp210x.c
@@ -138,7 +138,6 @@ static const struct usb_device_id id_tab
{ USB_DEVICE(0x10C4, 0xEA60) }, /* Silicon Labs factory default */
{ USB_DEVICE(0x10C4, 0xEA61) }, /* Silicon Labs factory default */
{ USB_DEVICE(0x10C4, 0xEA70) }, /* Silicon Labs factory default */
- { USB_DEVICE(0x10C4, 0xEA80) }, /* Silicon Labs factory default */
{ USB_DEVICE(0x10C4, 0xEA71) }, /* Infinity GPS-MIC-1 Radio Monophone */
{ USB_DEVICE(0x10C4, 0xF001) }, /* Elan Digital Systems USBscope50 */
{ USB_DEVICE(0x10C4, 0xF002) }, /* Elan Digital Systems USBwave12 */
^ permalink raw reply [flat|nested] 84+ messages in thread
* [PATCH 3.2 37/77] drm/ttm: Fixed a read/write lock imbalance
2015-12-24 15:37 [PATCH 3.2 00/77] 3.2.75-rc1 review Ben Hutchings
` (58 preceding siblings ...)
2015-12-24 15:37 ` [PATCH 3.2 62/77] net: ipmr: fix static mfc/dev leaks on table destruction Ben Hutchings
@ 2015-12-24 15:37 ` Ben Hutchings
2015-12-24 15:37 ` [PATCH 3.2 76/77] isdn_ppp: Add checks for allocation failure in isdn_ppp_open() Ben Hutchings
` (18 subsequent siblings)
78 siblings, 0 replies; 84+ messages in thread
From: Ben Hutchings @ 2015-12-24 15:37 UTC (permalink / raw)
To: linux-kernel, stable; +Cc: akpm, Sinclair Yeh, Thomas Hellstrom
3.2.75-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Thomas Hellstrom <thellstrom@vmware.com>
commit 025af189fb44250206dd8a32fa4a682392af3301 upstream.
In ttm_write_lock(), the uninterruptible path should call
__ttm_write_lock() not __ttm_read_lock(). This fixes a vmwgfx hang
on F23 start up.
syeh: Extracted this from one of Thomas' internal patches.
Signed-off-by: Thomas Hellstrom <thellstrom@vmware.com>
Reviewed-by: Sinclair Yeh <syeh@vmware.com>
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
---
drivers/gpu/drm/ttm/ttm_lock.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/gpu/drm/ttm/ttm_lock.c
+++ b/drivers/gpu/drm/ttm/ttm_lock.c
@@ -180,7 +180,7 @@ int ttm_write_lock(struct ttm_lock *lock
spin_unlock(&lock->lock);
}
} else
- wait_event(lock->queue, __ttm_read_lock(lock));
+ wait_event(lock->queue, __ttm_write_lock(lock));
return ret;
}
^ permalink raw reply [flat|nested] 84+ messages in thread
* [PATCH 3.2 35/77] RDS: fix race condition when sending a message on unbound socket
2015-12-24 15:37 [PATCH 3.2 00/77] 3.2.75-rc1 review Ben Hutchings
` (69 preceding siblings ...)
2015-12-24 15:37 ` [PATCH 3.2 30/77] vfs: Avoid softlockups with sendfile(2) Ben Hutchings
@ 2015-12-24 15:37 ` Ben Hutchings
2015-12-24 15:37 ` [PATCH 3.2 53/77] dm btree: fix bufio buffer leaks in dm_btree_del() error path Ben Hutchings
` (7 subsequent siblings)
78 siblings, 0 replies; 84+ messages in thread
From: Ben Hutchings @ 2015-12-24 15:37 UTC (permalink / raw)
To: linux-kernel, stable
Cc: akpm, Sasha Levin, David S. Miller, Quentin Casasnovas,
Santosh Shilimkar, Vegard Nossum
3.2.75-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Quentin Casasnovas <quentin.casasnovas@oracle.com>
commit 8c7188b23474cca017b3ef354c4a58456f68303a upstream.
Sasha's found a NULL pointer dereference in the RDS connection code when
sending a message to an apparently unbound socket. The problem is caused
by the code checking if the socket is bound in rds_sendmsg(), which checks
the rs_bound_addr field without taking a lock on the socket. This opens a
race where rs_bound_addr is temporarily set but where the transport is not
in rds_bind(), leading to a NULL pointer dereference when trying to
dereference 'trans' in __rds_conn_create().
Vegard wrote a reproducer for this issue, so kindly ask him to share if
you're interested.
I cannot reproduce the NULL pointer dereference using Vegard's reproducer
with this patch, whereas I could without.
Complete earlier incomplete fix to CVE-2015-6937:
74e98eb08588 ("RDS: verify the underlying transport exists before creating a connection")
Cc: David S. Miller <davem@davemloft.net>
Reviewed-by: Vegard Nossum <vegard.nossum@oracle.com>
Reviewed-by: Sasha Levin <sasha.levin@oracle.com>
Acked-by: Santosh Shilimkar <santosh.shilimkar@oracle.com>
Signed-off-by: Quentin Casasnovas <quentin.casasnovas@oracle.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
---
net/rds/connection.c | 6 ------
net/rds/send.c | 4 +++-
2 files changed, 3 insertions(+), 7 deletions(-)
--- a/net/rds/connection.c
+++ b/net/rds/connection.c
@@ -178,12 +178,6 @@ static struct rds_connection *__rds_conn
}
}
- if (trans == NULL) {
- kmem_cache_free(rds_conn_slab, conn);
- conn = ERR_PTR(-ENODEV);
- goto out;
- }
-
conn->c_trans = trans;
ret = trans->conn_alloc(conn, gfp);
--- a/net/rds/send.c
+++ b/net/rds/send.c
@@ -955,11 +955,13 @@ int rds_sendmsg(struct kiocb *iocb, stru
release_sock(sk);
}
- /* racing with another thread binding seems ok here */
+ lock_sock(sk);
if (daddr == 0 || rs->rs_bound_addr == 0) {
+ release_sock(sk);
ret = -ENOTCONN; /* XXX not a great errno */
goto out;
}
+ release_sock(sk);
/* size of rm including all sgs */
ret = rds_rm_size(msg, payload_len);
^ permalink raw reply [flat|nested] 84+ messages in thread
* Re: [PATCH 3.2 00/77] 3.2.75-rc1 review
2015-12-24 15:37 [PATCH 3.2 00/77] 3.2.75-rc1 review Ben Hutchings
` (76 preceding siblings ...)
2015-12-24 15:37 ` [PATCH 3.2 16/77] xhci: Add XHCI_INTEL_HOST quirk Ben Hutchings
@ 2015-12-24 16:40 ` Ben Hutchings
2015-12-24 22:20 ` Guenter Roeck
78 siblings, 0 replies; 84+ messages in thread
From: Ben Hutchings @ 2015-12-24 16:40 UTC (permalink / raw)
To: linux-kernel, stable; +Cc: torvalds, Guenter Roeck, Phil Jensen, akpm
[-- Attachment #1.1: Type: text/plain, Size: 163 bytes --]
This is the combined diff for 3.2.75-rc1 relative to 3.2.74.
Ben.
--
Ben Hutchings
If the facts do not conform to your theory, they must be disposed of.
[-- Attachment #1.2: linux-3.2.75-rc1.patch --]
[-- Type: text/x-patch, Size: 102753 bytes --]
diff --git a/Makefile b/Makefile
index 89a7d05..d7073cb 100644
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,7 @@
VERSION = 3
PATCHLEVEL = 2
-SUBLEVEL = 74
-EXTRAVERSION =
+SUBLEVEL = 75
+EXTRAVERSION = -rc1
NAME = Saber-toothed Squirrel
# *DOCUMENTATION*
diff --git a/arch/sh/include/asm/unistd_64.h b/arch/sh/include/asm/unistd_64.h
index c330c23..424f089 100644
--- a/arch/sh/include/asm/unistd_64.h
+++ b/arch/sh/include/asm/unistd_64.h
@@ -279,7 +279,7 @@
#define __NR_fsetxattr 256
#define __NR_getxattr 257
#define __NR_lgetxattr 258
-#define __NR_fgetxattr 269
+#define __NR_fgetxattr 259
#define __NR_listxattr 260
#define __NR_llistxattr 261
#define __NR_flistxattr 262
diff --git a/drivers/ata/libahci.c b/drivers/ata/libahci.c
index 41ffb8c..fa3eca3 100644
--- a/drivers/ata/libahci.c
+++ b/drivers/ata/libahci.c
@@ -1226,6 +1226,15 @@ static int ahci_exec_polled_cmd(struct ata_port *ap, int pmp,
ata_tf_to_fis(tf, pmp, is_cmd, fis);
ahci_fill_cmd_slot(pp, 0, cmd_fis_len | flags | (pmp << 12));
+ /* set port value for softreset of Port Multiplier */
+ if (pp->fbs_enabled && pp->fbs_last_dev != pmp) {
+ tmp = readl(port_mmio + PORT_FBS);
+ tmp &= ~(PORT_FBS_DEV_MASK | PORT_FBS_DEC);
+ tmp |= pmp << PORT_FBS_DEV_OFFSET;
+ writel(tmp, port_mmio + PORT_FBS);
+ pp->fbs_last_dev = pmp;
+ }
+
/* issue & wait */
writel(1, port_mmio + PORT_CMD_ISSUE);
diff --git a/drivers/ata/sata_sil.c b/drivers/ata/sata_sil.c
index 0c4ed89..7f0c7f0 100644
--- a/drivers/ata/sata_sil.c
+++ b/drivers/ata/sata_sil.c
@@ -631,6 +631,9 @@ static void sil_dev_config(struct ata_device *dev)
unsigned int n, quirks = 0;
unsigned char model_num[ATA_ID_PROD_LEN + 1];
+ /* This controller doesn't support trim */
+ dev->horkage |= ATA_HORKAGE_NOTRIM;
+
ata_id_c_string(dev->id, model_num, ATA_ID_PROD, sizeof(model_num));
for (n = 0; sil_blacklist[n].product; n++)
diff --git a/drivers/char/ipmi/ipmi_si_intf.c b/drivers/char/ipmi/ipmi_si_intf.c
index 9397ab4..636a8dd 100644
--- a/drivers/char/ipmi/ipmi_si_intf.c
+++ b/drivers/char/ipmi/ipmi_si_intf.c
@@ -1148,15 +1148,15 @@ static int smi_start_processing(void *send_info,
new_smi->intf = intf;
- /* Try to claim any interrupts. */
- if (new_smi->irq_setup)
- new_smi->irq_setup(new_smi);
-
/* Set up the timer that drives the interface. */
setup_timer(&new_smi->si_timer, smi_timeout, (long)new_smi);
new_smi->last_timeout_jiffies = jiffies;
mod_timer(&new_smi->si_timer, jiffies + SI_TIMEOUT_JIFFIES);
+ /* Try to claim any interrupts. */
+ if (new_smi->irq_setup)
+ new_smi->irq_setup(new_smi);
+
/*
* Check if the user forcefully enabled the daemon.
*/
diff --git a/drivers/gpu/drm/drm_fops.c b/drivers/gpu/drm/drm_fops.c
index 020b103..5f1a653 100644
--- a/drivers/gpu/drm/drm_fops.c
+++ b/drivers/gpu/drm/drm_fops.c
@@ -219,6 +219,62 @@ static int drm_cpu_valid(void)
}
/**
+ * drm_new_set_master - Allocate a new master object and become master for the
+ * associated master realm.
+ *
+ * @dev: The associated device.
+ * @fpriv: File private identifying the client.
+ *
+ * This function must be called with dev::struct_mutex held.
+ * Returns negative error code on failure. Zero on success.
+ */
+int drm_new_set_master(struct drm_device *dev, struct drm_file *fpriv)
+{
+ struct drm_master *old_master;
+ int ret;
+
+ lockdep_assert_held_once(&dev->struct_mutex);
+
+ /* create a new master */
+ fpriv->minor->master = drm_master_create(fpriv->minor);
+ if (!fpriv->minor->master)
+ return -ENOMEM;
+
+ /* take another reference for the copy in the local file priv */
+ old_master = fpriv->master;
+ fpriv->master = drm_master_get(fpriv->minor->master);
+
+ if (dev->driver->master_create) {
+ mutex_unlock(&dev->struct_mutex);
+ ret = dev->driver->master_create(dev, fpriv->master);
+ mutex_lock(&dev->struct_mutex);
+ if (ret)
+ goto out_err;
+ }
+ if (dev->driver->master_set) {
+ ret = dev->driver->master_set(dev, fpriv, true);
+ if (ret)
+ goto out_err;
+ }
+
+ fpriv->is_master = 1;
+ fpriv->allowed_master = 1;
+ fpriv->authenticated = 1;
+ if (old_master)
+ drm_master_put(&old_master);
+
+ return 0;
+
+out_err:
+ /* drop both references and restore old master on failure */
+ drm_master_put(&fpriv->minor->master);
+ drm_master_put(&fpriv->master);
+ fpriv->master = old_master;
+
+ return ret;
+}
+
+/**
* Called whenever a process opens /dev/drm.
*
* \param inode device inode.
@@ -279,43 +335,10 @@ static int drm_open_helper(struct inode *inode, struct file *filp,
mutex_lock(&dev->struct_mutex);
if (!priv->minor->master) {
/* create a new master */
- priv->minor->master = drm_master_create(priv->minor);
- if (!priv->minor->master) {
- mutex_unlock(&dev->struct_mutex);
- ret = -ENOMEM;
- goto out_free;
- }
-
- priv->is_master = 1;
- /* take another reference for the copy in the local file priv */
- priv->master = drm_master_get(priv->minor->master);
-
- priv->authenticated = 1;
-
- mutex_unlock(&dev->struct_mutex);
- if (dev->driver->master_create) {
- ret = dev->driver->master_create(dev, priv->master);
- if (ret) {
- mutex_lock(&dev->struct_mutex);
- /* drop both references if this fails */
- drm_master_put(&priv->minor->master);
- drm_master_put(&priv->master);
- mutex_unlock(&dev->struct_mutex);
- goto out_free;
- }
- }
- mutex_lock(&dev->struct_mutex);
- if (dev->driver->master_set) {
- ret = dev->driver->master_set(dev, priv, true);
- if (ret) {
- /* drop both references if this fails */
- drm_master_put(&priv->minor->master);
- drm_master_put(&priv->master);
- mutex_unlock(&dev->struct_mutex);
- goto out_free;
- }
- }
+ ret = drm_new_set_master(dev, priv);
mutex_unlock(&dev->struct_mutex);
+ if (ret)
+ goto out_free;
} else {
/* get a reference to the master */
priv->master = drm_master_get(priv->minor->master);
diff --git a/drivers/gpu/drm/drm_stub.c b/drivers/gpu/drm/drm_stub.c
index 6d7b083..6c1f6ce 100644
--- a/drivers/gpu/drm/drm_stub.c
+++ b/drivers/gpu/drm/drm_stub.c
@@ -225,6 +225,10 @@ int drm_setmaster_ioctl(struct drm_device *dev, void *data,
if (!file_priv->minor->master &&
file_priv->minor->master != file_priv->master) {
mutex_lock(&dev->struct_mutex);
+ if (!file_priv->allowed_master) {
+ ret = drm_new_set_master(dev, file_priv);
+ goto out_unlock;
+ }
file_priv->minor->master = drm_master_get(file_priv->master);
file_priv->is_master = 1;
if (dev->driver->master_set) {
@@ -234,10 +238,11 @@ int drm_setmaster_ioctl(struct drm_device *dev, void *data,
drm_master_put(&file_priv->minor->master);
}
}
+ out_unlock:
mutex_unlock(&dev->struct_mutex);
}
- return 0;
+ return ret;
}
int drm_dropmaster_ioctl(struct drm_device *dev, void *data,
diff --git a/drivers/gpu/drm/ttm/ttm_lock.c b/drivers/gpu/drm/ttm/ttm_lock.c
index 075daf4..9934b4d 100644
--- a/drivers/gpu/drm/ttm/ttm_lock.c
+++ b/drivers/gpu/drm/ttm/ttm_lock.c
@@ -180,7 +180,7 @@ int ttm_write_lock(struct ttm_lock *lock, bool interruptible)
spin_unlock(&lock->lock);
}
} else
- wait_event(lock->queue, __ttm_read_lock(lock));
+ wait_event(lock->queue, __ttm_write_lock(lock));
return ret;
}
diff --git a/drivers/gpu/vga/vgaarb.c b/drivers/gpu/vga/vgaarb.c
index 111d956..6a46d6e 100644
--- a/drivers/gpu/vga/vgaarb.c
+++ b/drivers/gpu/vga/vgaarb.c
@@ -381,8 +381,10 @@ int vga_get(struct pci_dev *pdev, unsigned int rsrc, int interruptible)
set_current_state(interruptible ?
TASK_INTERRUPTIBLE :
TASK_UNINTERRUPTIBLE);
- if (signal_pending(current)) {
- rc = -EINTR;
+ if (interruptible && signal_pending(current)) {
+ __set_current_state(TASK_RUNNING);
+ remove_wait_queue(&vga_wait_queue, &wait);
+ rc = -ERESTARTSYS;
break;
}
schedule();
diff --git a/drivers/isdn/i4l/isdn_ppp.c b/drivers/isdn/i4l/isdn_ppp.c
index 1b002b0..3604aa7 100644
--- a/drivers/isdn/i4l/isdn_ppp.c
+++ b/drivers/isdn/i4l/isdn_ppp.c
@@ -301,6 +301,8 @@ isdn_ppp_open(int min, struct file *file)
is->compflags = 0;
is->reset = isdn_ppp_ccp_reset_alloc(is);
+ if (!is->reset)
+ return -ENOMEM;
is->lp = NULL;
is->mp_seqno = 0; /* MP sequence number */
@@ -320,6 +322,10 @@ isdn_ppp_open(int min, struct file *file)
* VJ header compression init
*/
is->slcomp = slhc_init(16, 16); /* not necessary for 2. link in bundle */
+ if (IS_ERR(is->slcomp)) {
+ isdn_ppp_ccp_reset_free(is);
+ return PTR_ERR(is->slcomp);
+ }
#endif
#ifdef CONFIG_IPPP_FILTER
is->pass_filter = NULL;
@@ -568,10 +574,8 @@ isdn_ppp_ioctl(int min, struct file *file, unsigned int cmd, unsigned long arg)
is->maxcid = val;
#ifdef CONFIG_ISDN_PPP_VJ
sltmp = slhc_init(16, val);
- if (!sltmp) {
- printk(KERN_ERR "ippp, can't realloc slhc struct\n");
- return -ENOMEM;
- }
+ if (IS_ERR(sltmp))
+ return PTR_ERR(sltmp);
if (is->slcomp)
slhc_free(is->slcomp);
is->slcomp = sltmp;
diff --git a/drivers/md/persistent-data/dm-btree.c b/drivers/md/persistent-data/dm-btree.c
index 29e423f..a8f4f7e 100644
--- a/drivers/md/persistent-data/dm-btree.c
+++ b/drivers/md/persistent-data/dm-btree.c
@@ -231,6 +231,16 @@ static void pop_frame(struct del_stack *s)
dm_tm_unlock(s->tm, f->b);
}
+static void unlock_all_frames(struct del_stack *s)
+{
+ struct frame *f;
+
+ while (unprocessed_frames(s)) {
+ f = s->spine + s->top--;
+ dm_tm_unlock(s->tm, f->b);
+ }
+}
+
int dm_btree_del(struct dm_btree_info *info, dm_block_t root)
{
int r;
@@ -286,9 +296,13 @@ int dm_btree_del(struct dm_btree_info *info, dm_block_t root)
f->current_child = f->nr_children;
}
}
-
out:
+ if (r) {
+ /* cleanup all frames of del_stack */
+ unlock_all_frames(s);
+ }
kfree(s);
+
return r;
}
EXPORT_SYMBOL_GPL(dm_btree_del);
@@ -451,8 +465,10 @@ static int btree_split_sibling(struct shadow_spine *s, dm_block_t root,
r = insert_at(sizeof(__le64), pn, parent_index + 1,
le64_to_cpu(rn->keys[0]), &location);
- if (r)
+ if (r) {
+ unlock_block(s->info, right);
return r;
+ }
if (key < le64_to_cpu(rn->keys[0])) {
unlock_block(s->info, right);
diff --git a/drivers/net/can/sja1000/sja1000.c b/drivers/net/can/sja1000/sja1000.c
index 568b821..faff53b 100644
--- a/drivers/net/can/sja1000/sja1000.c
+++ b/drivers/net/can/sja1000/sja1000.c
@@ -177,6 +177,9 @@ static void sja1000_start(struct net_device *dev)
priv->write_reg(priv, REG_RXERR, 0x0);
priv->read_reg(priv, REG_ECC);
+ /* clear interrupt flags */
+ priv->read_reg(priv, REG_IR);
+
/* leave reset mode */
set_normal_mode(dev);
}
diff --git a/drivers/net/ethernet/atheros/atl1c/atl1c_main.c b/drivers/net/ethernet/atheros/atl1c/atl1c_main.c
index 5ae7df7..790f643 100644
--- a/drivers/net/ethernet/atheros/atl1c/atl1c_main.c
+++ b/drivers/net/ethernet/atheros/atl1c/atl1c_main.c
@@ -981,13 +981,12 @@ static int atl1c_setup_ring_resources(struct atl1c_adapter *adapter)
sizeof(struct atl1c_hw_stats) +
8 * 4 + 8 * 2 * num_rx_queues;
- ring_header->desc = pci_alloc_consistent(pdev, ring_header->size,
- &ring_header->dma);
+ ring_header->desc = dma_zalloc_coherent(&pdev->dev, ring_header->size,
+ &ring_header->dma, GFP_KERNEL);
if (unlikely(!ring_header->desc)) {
- dev_err(&pdev->dev, "pci_alloc_consistend failed\n");
+ dev_err(&pdev->dev, "could not get memory for DMA buffer\n");
goto err_nomem;
}
- memset(ring_header->desc, 0, ring_header->size);
/* init TPD ring */
tpd_ring[0].dma = roundup(ring_header->dma, 8);
diff --git a/drivers/net/ethernet/renesas/sh_eth.c b/drivers/net/ethernet/renesas/sh_eth.c
index b2077ca..e49208d 100644
--- a/drivers/net/ethernet/renesas/sh_eth.c
+++ b/drivers/net/ethernet/renesas/sh_eth.c
@@ -911,6 +911,7 @@ static int sh_eth_rx(struct net_device *ndev)
if (!(desc_status & RDFEND))
mdp->stats.rx_length_errors++;
+ skb = mdp->rx_skbuff[entry];
if (desc_status & (RD_RFS1 | RD_RFS2 | RD_RFS3 | RD_RFS4 |
RD_RFS5 | RD_RFS6 | RD_RFS10)) {
mdp->stats.rx_errors++;
@@ -926,12 +927,11 @@ static int sh_eth_rx(struct net_device *ndev)
mdp->stats.rx_missed_errors++;
if (desc_status & RD_RFS10)
mdp->stats.rx_over_errors++;
- } else {
+ } else if (skb) {
if (!mdp->cd->hw_swap)
sh_eth_soft_swap(
phys_to_virt(ALIGN(rxdesc->addr, 4)),
pkt_len + 2);
- skb = mdp->rx_skbuff[entry];
mdp->rx_skbuff[entry] = NULL;
if (mdp->cd->rpadir)
skb_reserve(skb, NET_IP_ALIGN);
diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c
index fed39de..f85441d 100644
--- a/drivers/net/macvlan.c
+++ b/drivers/net/macvlan.c
@@ -172,6 +172,7 @@ static rx_handler_result_t macvlan_handle_frame(struct sk_buff **pskb)
skb = ip_check_defrag(skb, IP_DEFRAG_MACVLAN);
if (!skb)
return RX_HANDLER_CONSUMED;
+ *pskb = skb;
eth = eth_hdr(skb);
src = macvlan_hash_lookup(port, eth->h_source);
if (!src)
@@ -221,6 +222,7 @@ static rx_handler_result_t macvlan_handle_frame(struct sk_buff **pskb)
if (!skb)
goto out;
+ *pskb = skb;
skb->dev = dev;
skb->pkt_type = PACKET_HOST;
diff --git a/drivers/net/phy/broadcom.c b/drivers/net/phy/broadcom.c
index e8be47d..3456737 100644
--- a/drivers/net/phy/broadcom.c
+++ b/drivers/net/phy/broadcom.c
@@ -935,7 +935,7 @@ static struct mdio_device_id __maybe_unused broadcom_tbl[] = {
{ PHY_ID_BCM5421, 0xfffffff0 },
{ PHY_ID_BCM5461, 0xfffffff0 },
{ PHY_ID_BCM5464, 0xfffffff0 },
- { PHY_ID_BCM5482, 0xfffffff0 },
+ { PHY_ID_BCM5481, 0xfffffff0 },
{ PHY_ID_BCM5482, 0xfffffff0 },
{ PHY_ID_BCM50610, 0xfffffff0 },
{ PHY_ID_BCM50610M, 0xfffffff0 },
diff --git a/drivers/net/ppp/ppp_generic.c b/drivers/net/ppp/ppp_generic.c
index 4782d79..82d4421 100644
--- a/drivers/net/ppp/ppp_generic.c
+++ b/drivers/net/ppp/ppp_generic.c
@@ -703,10 +703,8 @@ static long ppp_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
val &= 0xffff;
}
vj = slhc_init(val2+1, val+1);
- if (!vj) {
- netdev_err(ppp->dev,
- "PPP: no memory (VJ compressor)\n");
- err = -ENOMEM;
+ if (IS_ERR(vj)) {
+ err = PTR_ERR(vj);
break;
}
ppp_lock(ppp);
diff --git a/drivers/net/ppp/pptp.c b/drivers/net/ppp/pptp.c
index c974581..165ee14 100644
--- a/drivers/net/ppp/pptp.c
+++ b/drivers/net/ppp/pptp.c
@@ -420,6 +420,9 @@ static int pptp_bind(struct socket *sock, struct sockaddr *uservaddr,
struct pptp_opt *opt = &po->proto.pptp;
int error = 0;
+ if (sockaddr_len < sizeof(struct sockaddr_pppox))
+ return -EINVAL;
+
lock_sock(sk);
opt->src_addr = sp->sa_addr.pptp;
@@ -441,6 +444,9 @@ static int pptp_connect(struct socket *sock, struct sockaddr *uservaddr,
struct flowi4 fl4;
int error = 0;
+ if (sockaddr_len < sizeof(struct sockaddr_pppox))
+ return -EINVAL;
+
if (sp->sa_protocol != PX_PROTO_PPTP)
return -EINVAL;
diff --git a/drivers/net/slip/slhc.c b/drivers/net/slip/slhc.c
index 0a0a664..042425e 100644
--- a/drivers/net/slip/slhc.c
+++ b/drivers/net/slip/slhc.c
@@ -85,8 +85,9 @@ static long decode(unsigned char **cpp);
static unsigned char * put16(unsigned char *cp, unsigned short x);
static unsigned short pull16(unsigned char **cpp);
-/* Initialize compression data structure
+/* Allocate compression data structure
* slots must be in range 0 to 255 (zero meaning no compression)
+ * Returns pointer to structure or ERR_PTR() on error.
*/
struct slcompress *
slhc_init(int rslots, int tslots)
@@ -95,11 +96,14 @@ slhc_init(int rslots, int tslots)
register struct cstate *ts;
struct slcompress *comp;
+ if (rslots < 0 || rslots > 255 || tslots < 0 || tslots > 255)
+ return ERR_PTR(-EINVAL);
+
comp = kzalloc(sizeof(struct slcompress), GFP_KERNEL);
if (! comp)
goto out_fail;
- if ( rslots > 0 && rslots < 256 ) {
+ if (rslots > 0) {
size_t rsize = rslots * sizeof(struct cstate);
comp->rstate = kzalloc(rsize, GFP_KERNEL);
if (! comp->rstate)
@@ -107,7 +111,7 @@ slhc_init(int rslots, int tslots)
comp->rslot_limit = rslots - 1;
}
- if ( tslots > 0 && tslots < 256 ) {
+ if (tslots > 0) {
size_t tsize = tslots * sizeof(struct cstate);
comp->tstate = kzalloc(tsize, GFP_KERNEL);
if (! comp->tstate)
@@ -142,7 +146,7 @@ out_free2:
out_free:
kfree(comp);
out_fail:
- return NULL;
+ return ERR_PTR(-ENOMEM);
}
diff --git a/drivers/net/slip/slip.c b/drivers/net/slip/slip.c
index ba08341..1a6e2ea 100644
--- a/drivers/net/slip/slip.c
+++ b/drivers/net/slip/slip.c
@@ -164,7 +164,7 @@ static int sl_alloc_bufs(struct slip *sl, int mtu)
if (cbuff == NULL)
goto err_exit;
slcomp = slhc_init(16, 16);
- if (slcomp == NULL)
+ if (IS_ERR(slcomp))
goto err_exit;
#endif
spin_lock_bh(&sl->lock);
diff --git a/drivers/net/wan/x25_asy.c b/drivers/net/wan/x25_asy.c
index 8a10bb7..b80cab2 100644
--- a/drivers/net/wan/x25_asy.c
+++ b/drivers/net/wan/x25_asy.c
@@ -547,16 +547,12 @@ static void x25_asy_receive_buf(struct tty_struct *tty,
static int x25_asy_open_tty(struct tty_struct *tty)
{
- struct x25_asy *sl = tty->disc_data;
+ struct x25_asy *sl;
int err;
if (tty->ops->write == NULL)
return -EOPNOTSUPP;
- /* First make sure we're not already connected. */
- if (sl && sl->magic == X25_ASY_MAGIC)
- return -EEXIST;
-
/* OK. Find a free X.25 channel to use. */
sl = x25_asy_alloc();
if (sl == NULL)
diff --git a/drivers/parisc/iommu-helpers.h b/drivers/parisc/iommu-helpers.h
index 8c33491..c6aa388 100644
--- a/drivers/parisc/iommu-helpers.h
+++ b/drivers/parisc/iommu-helpers.h
@@ -104,7 +104,11 @@ iommu_coalesce_chunks(struct ioc *ioc, struct device *dev,
struct scatterlist *contig_sg; /* contig chunk head */
unsigned long dma_offset, dma_len; /* start/len of DMA stream */
unsigned int n_mappings = 0;
- unsigned int max_seg_size = dma_get_max_seg_size(dev);
+ unsigned int max_seg_size = min(dma_get_max_seg_size(dev),
+ (unsigned)DMA_CHUNK_SIZE);
+ unsigned int max_seg_boundary = dma_get_seg_boundary(dev) + 1;
+ if (max_seg_boundary) /* check if the addition above didn't overflow */
+ max_seg_size = min(max_seg_size, max_seg_boundary);
while (nents > 0) {
@@ -139,14 +143,11 @@ iommu_coalesce_chunks(struct ioc *ioc, struct device *dev,
/*
** First make sure current dma stream won't
- ** exceed DMA_CHUNK_SIZE if we coalesce the
+ ** exceed max_seg_size if we coalesce the
** next entry.
*/
- if(unlikely(ALIGN(dma_len + dma_offset + startsg->length,
- IOVP_SIZE) > DMA_CHUNK_SIZE))
- break;
-
- if (startsg->length + dma_len > max_seg_size)
+ if (unlikely(ALIGN(dma_len + dma_offset + startsg->length, IOVP_SIZE) >
+ max_seg_size))
break;
/*
diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c
index ca666d0..660c334 100644
--- a/drivers/usb/class/cdc-acm.c
+++ b/drivers/usb/class/cdc-acm.c
@@ -916,6 +916,10 @@ static int acm_probe(struct usb_interface *intf,
/* normal quirks */
quirks = (unsigned long)id->driver_info;
+
+ if (quirks == IGNORE_DEVICE)
+ return -ENODEV;
+
num_rx_buf = (quirks == SINGLE_RX_URB) ? 1 : ACM_NR;
/* handle quirks deadly to normal probing*/
@@ -1662,6 +1666,11 @@ static const struct usb_device_id acm_ids[] = {
.driver_info = NO_DATA_INTERFACE,
},
+ /* Exclude Infineon Flash Loader utility */
+ { USB_DEVICE(0x058b, 0x0041),
+ .driver_info = IGNORE_DEVICE,
+ },
+
/* control interfaces without any protocol set */
{ USB_INTERFACE_INFO(USB_CLASS_COMM, USB_CDC_SUBCLASS_ACM,
USB_CDC_PROTO_NONE) },
diff --git a/drivers/usb/class/cdc-acm.h b/drivers/usb/class/cdc-acm.h
index 7aa5e9a..9af5ad2 100644
--- a/drivers/usb/class/cdc-acm.h
+++ b/drivers/usb/class/cdc-acm.h
@@ -127,4 +127,5 @@ struct acm {
#define NO_CAP_LINE 4
#define NOT_A_MODEM 8
#define NO_DATA_INTERFACE 16
+#define IGNORE_DEVICE 32
#define CLEAR_HALT_CONDITIONS BIT(7)
diff --git a/drivers/usb/class/usblp.c b/drivers/usb/class/usblp.c
index cb3a932..a84c857 100644
--- a/drivers/usb/class/usblp.c
+++ b/drivers/usb/class/usblp.c
@@ -861,11 +861,11 @@ static int usblp_wwait(struct usblp *usblp, int nonblock)
add_wait_queue(&usblp->wwait, &waita);
for (;;) {
- set_current_state(TASK_INTERRUPTIBLE);
if (mutex_lock_interruptible(&usblp->mut)) {
rc = -EINTR;
break;
}
+ set_current_state(TASK_INTERRUPTIBLE);
rc = usblp_wtest(usblp, nonblock);
mutex_unlock(&usblp->mut);
if (rc <= 0)
diff --git a/drivers/usb/core/config.c b/drivers/usb/core/config.c
index 478d71b..ffc6989 100644
--- a/drivers/usb/core/config.c
+++ b/drivers/usb/core/config.c
@@ -117,7 +117,8 @@ static void usb_parse_ss_endpoint_companion(struct device *ddev, int cfgno,
USB_SS_MULT(desc->bmAttributes) > 3) {
dev_warn(ddev, "Isoc endpoint has Mult of %d in "
"config %d interface %d altsetting %d ep %d: "
- "setting to 3\n", desc->bmAttributes + 1,
+ "setting to 3\n",
+ USB_SS_MULT(desc->bmAttributes),
cfgno, inum, asnum, ep->desc.bEndpointAddress);
ep->ss_ep_comp.bmAttributes = 2;
}
diff --git a/drivers/usb/host/whci/qset.c b/drivers/usb/host/whci/qset.c
index 76083ae..412b4fe 100644
--- a/drivers/usb/host/whci/qset.c
+++ b/drivers/usb/host/whci/qset.c
@@ -377,6 +377,10 @@ static int qset_fill_page_list(struct whc *whc, struct whc_std *std, gfp_t mem_f
if (std->pl_virt == NULL)
return -ENOMEM;
std->dma_addr = dma_map_single(whc->wusbhc.dev, std->pl_virt, pl_len, DMA_TO_DEVICE);
+ if (dma_mapping_error(whc->wusbhc.dev, std->dma_addr)) {
+ kfree(std->pl_virt);
+ return -EFAULT;
+ }
for (p = 0; p < std->num_pointers; p++) {
std->pl_virt[p].buf_ptr = cpu_to_le64(dma_addr);
diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c
index a42ef09..5223884 100644
--- a/drivers/usb/host/xhci-pci.c
+++ b/drivers/usb/host/xhci-pci.c
@@ -106,6 +106,8 @@ static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci)
xhci->quirks |= XHCI_TRUST_TX_LENGTH;
if (pdev->vendor == PCI_VENDOR_ID_INTEL)
+ xhci->quirks |= XHCI_INTEL_HOST;
+ if (pdev->vendor == PCI_VENDOR_ID_INTEL)
xhci->quirks |= XHCI_AVOID_BEI;
if (pdev->vendor == PCI_VENDOR_ID_INTEL &&
pdev->device == PCI_DEVICE_ID_INTEL_PANTHERPOINT_XHCI) {
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
index 2f51dec..d7ddb5a 100644
--- a/drivers/usb/host/xhci.c
+++ b/drivers/usb/host/xhci.c
@@ -170,6 +170,16 @@ int xhci_reset(struct xhci_hcd *xhci)
command |= CMD_RESET;
xhci_writel(xhci, command, &xhci->op_regs->command);
+ /* Existing Intel xHCI controllers require a delay of 1 mS,
+ * after setting the CMD_RESET bit, and before accessing any
+ * HC registers. This allows the HC to complete the
+ * reset operation and be ready for HC register access.
+ * Without this delay, the subsequent HC register access,
+ * may result in a system hang very rarely.
+ */
+ if (xhci->quirks & XHCI_INTEL_HOST)
+ udelay(1000);
+
ret = handshake(xhci, &xhci->op_regs->command,
CMD_RESET, 0, 10 * 1000 * 1000);
if (ret)
@@ -4120,8 +4130,16 @@ int xhci_update_hub_device(struct usb_hcd *hcd, struct usb_device *hdev,
ctrl_ctx->add_flags |= cpu_to_le32(SLOT_FLAG);
slot_ctx = xhci_get_slot_ctx(xhci, config_cmd->in_ctx);
slot_ctx->dev_info |= cpu_to_le32(DEV_HUB);
+ /*
+ * refer to section 6.2.2: MTT should be 0 for full speed hub,
+ * but it may be already set to 1 when setup an xHCI virtual
+ * device, so clear it anyway.
+ */
if (tt->multi)
slot_ctx->dev_info |= cpu_to_le32(DEV_MTT);
+ else if (hdev->speed == USB_SPEED_FULL)
+ slot_ctx->dev_info &= cpu_to_le32(~DEV_MTT);
+
if (xhci->hci_version > 0x95) {
xhci_dbg(xhci, "xHCI version %x needs hub "
"TT think time and number of ports\n",
diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h
index d676ae0..15f58d1 100644
--- a/drivers/usb/host/xhci.h
+++ b/drivers/usb/host/xhci.h
@@ -1492,6 +1492,7 @@ struct xhci_hcd {
#define XHCI_SW_BW_CHECKING (1 << 8)
#define XHCI_AMD_0x96_HOST (1 << 9)
#define XHCI_TRUST_TX_LENGTH (1 << 10)
+#define XHCI_INTEL_HOST (1 << 12)
#define XHCI_SPURIOUS_REBOOT (1 << 13)
#define XHCI_COMP_MODE_QUIRK (1 << 14)
#define XHCI_AVOID_BEI (1 << 15)
diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c
index 6f7d84e..fb05cac 100644
--- a/drivers/usb/musb/musb_core.c
+++ b/drivers/usb/musb/musb_core.c
@@ -131,7 +131,7 @@ static inline struct musb *dev_to_musb(struct device *dev)
/*-------------------------------------------------------------------------*/
#ifndef CONFIG_BLACKFIN
-static int musb_ulpi_read(struct otg_transceiver *otg, u32 offset)
+static int musb_ulpi_read(struct otg_transceiver *otg, u32 reg)
{
void __iomem *addr = otg->io_priv;
int i = 0;
@@ -147,7 +147,7 @@ static int musb_ulpi_read(struct otg_transceiver *otg, u32 offset)
* ULPICarKitControlDisableUTMI after clearing POWER_SUSPENDM.
*/
- musb_writeb(addr, MUSB_ULPI_REG_ADDR, (u8)offset);
+ musb_writeb(addr, MUSB_ULPI_REG_ADDR, (u8)reg);
musb_writeb(addr, MUSB_ULPI_REG_CONTROL,
MUSB_ULPI_REG_REQ | MUSB_ULPI_RDN_WR);
@@ -165,8 +165,7 @@ static int musb_ulpi_read(struct otg_transceiver *otg, u32 offset)
return musb_readb(addr, MUSB_ULPI_REG_DATA);
}
-static int musb_ulpi_write(struct otg_transceiver *otg,
- u32 offset, u32 data)
+static int musb_ulpi_write(struct otg_transceiver *otg, u32 val, u32 reg)
{
void __iomem *addr = otg->io_priv;
int i = 0;
@@ -178,8 +177,8 @@ static int musb_ulpi_write(struct otg_transceiver *otg,
power &= ~MUSB_POWER_SUSPENDM;
musb_writeb(addr, MUSB_POWER, power);
- musb_writeb(addr, MUSB_ULPI_REG_ADDR, (u8)offset);
- musb_writeb(addr, MUSB_ULPI_REG_DATA, (u8)data);
+ musb_writeb(addr, MUSB_ULPI_REG_ADDR, (u8)reg);
+ musb_writeb(addr, MUSB_ULPI_REG_DATA, (u8)val);
musb_writeb(addr, MUSB_ULPI_REG_CONTROL, MUSB_ULPI_REG_REQ);
while (!(musb_readb(addr, MUSB_ULPI_REG_CONTROL)
diff --git a/drivers/usb/serial/cp210x.c b/drivers/usb/serial/cp210x.c
index 1a19724..1398597 100644
--- a/drivers/usb/serial/cp210x.c
+++ b/drivers/usb/serial/cp210x.c
@@ -138,7 +138,6 @@ static const struct usb_device_id id_table[] = {
{ USB_DEVICE(0x10C4, 0xEA60) }, /* Silicon Labs factory default */
{ USB_DEVICE(0x10C4, 0xEA61) }, /* Silicon Labs factory default */
{ USB_DEVICE(0x10C4, 0xEA70) }, /* Silicon Labs factory default */
- { USB_DEVICE(0x10C4, 0xEA80) }, /* Silicon Labs factory default */
{ USB_DEVICE(0x10C4, 0xEA71) }, /* Infinity GPS-MIC-1 Radio Monophone */
{ USB_DEVICE(0x10C4, 0xF001) }, /* Elan Digital Systems USBscope50 */
{ USB_DEVICE(0x10C4, 0xF002) }, /* Elan Digital Systems USBwave12 */
diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c
index 7e6d2ec..5a31169 100644
--- a/drivers/usb/serial/option.c
+++ b/drivers/usb/serial/option.c
@@ -162,6 +162,7 @@ static void option_instat_callback(struct urb *urb);
#define NOVATELWIRELESS_PRODUCT_HSPA_EMBEDDED_HIGHSPEED 0x9001
#define NOVATELWIRELESS_PRODUCT_E362 0x9010
#define NOVATELWIRELESS_PRODUCT_E371 0x9011
+#define NOVATELWIRELESS_PRODUCT_U620L 0x9022
#define NOVATELWIRELESS_PRODUCT_G2 0xA010
#define NOVATELWIRELESS_PRODUCT_MC551 0xB001
@@ -355,6 +356,7 @@ static void option_instat_callback(struct urb *urb);
/* This is the 4G XS Stick W14 a.k.a. Mobilcom Debitel Surf-Stick *
* It seems to contain a Qualcomm QSC6240/6290 chipset */
#define FOUR_G_SYSTEMS_PRODUCT_W14 0x9603
+#define FOUR_G_SYSTEMS_PRODUCT_W100 0x9b01
/* iBall 3.5G connect wireless modem */
#define IBALL_3_5G_CONNECT 0x9605
@@ -525,6 +527,11 @@ static const struct option_blacklist_info four_g_w14_blacklist = {
.sendsetup = BIT(0) | BIT(1),
};
+static const struct option_blacklist_info four_g_w100_blacklist = {
+ .sendsetup = BIT(1) | BIT(2),
+ .reserved = BIT(3),
+};
+
static const struct option_blacklist_info alcatel_x200_blacklist = {
.sendsetup = BIT(0) | BIT(1),
.reserved = BIT(4),
@@ -1058,6 +1065,7 @@ static const struct usb_device_id option_ids[] = {
{ USB_DEVICE_AND_INTERFACE_INFO(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_MC551, 0xff, 0xff, 0xff) },
{ USB_DEVICE_AND_INTERFACE_INFO(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_E362, 0xff, 0xff, 0xff) },
{ USB_DEVICE_AND_INTERFACE_INFO(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_E371, 0xff, 0xff, 0xff) },
+ { USB_DEVICE_AND_INTERFACE_INFO(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_U620L, 0xff, 0x00, 0x00) },
{ USB_DEVICE(AMOI_VENDOR_ID, AMOI_PRODUCT_H01) },
{ USB_DEVICE(AMOI_VENDOR_ID, AMOI_PRODUCT_H01A) },
@@ -1640,6 +1648,9 @@ static const struct usb_device_id option_ids[] = {
{ USB_DEVICE(LONGCHEER_VENDOR_ID, FOUR_G_SYSTEMS_PRODUCT_W14),
.driver_info = (kernel_ulong_t)&four_g_w14_blacklist
},
+ { USB_DEVICE(LONGCHEER_VENDOR_ID, FOUR_G_SYSTEMS_PRODUCT_W100),
+ .driver_info = (kernel_ulong_t)&four_g_w100_blacklist
+ },
{ USB_DEVICE(LONGCHEER_VENDOR_ID, ZOOM_PRODUCT_4597) },
{ USB_DEVICE(LONGCHEER_VENDOR_ID, IBALL_3_5G_CONNECT) },
{ USB_DEVICE(HAIER_VENDOR_ID, HAIER_PRODUCT_CE100) },
diff --git a/drivers/usb/serial/ti_usb_3410_5052.c b/drivers/usb/serial/ti_usb_3410_5052.c
index 885d15d..ad0445a 100644
--- a/drivers/usb/serial/ti_usb_3410_5052.c
+++ b/drivers/usb/serial/ti_usb_3410_5052.c
@@ -164,7 +164,7 @@ static unsigned int product_5052_count;
/* the array dimension is the number of default entries plus */
/* TI_EXTRA_VID_PID_COUNT user defined entries plus 1 terminating */
/* null entry */
-static struct usb_device_id ti_id_table_3410[15+TI_EXTRA_VID_PID_COUNT+1] = {
+static struct usb_device_id ti_id_table_3410[17+TI_EXTRA_VID_PID_COUNT+1] = {
{ USB_DEVICE(TI_VENDOR_ID, TI_3410_PRODUCT_ID) },
{ USB_DEVICE(TI_VENDOR_ID, TI_3410_EZ430_ID) },
{ USB_DEVICE(MTS_VENDOR_ID, MTS_GSM_NO_FW_PRODUCT_ID) },
@@ -181,6 +181,7 @@ static struct usb_device_id ti_id_table_3410[15+TI_EXTRA_VID_PID_COUNT+1] = {
{ USB_DEVICE(ABBOTT_VENDOR_ID, ABBOTT_STEREO_PLUG_ID) },
{ USB_DEVICE(ABBOTT_VENDOR_ID, ABBOTT_STRIP_PORT_ID) },
{ USB_DEVICE(TI_VENDOR_ID, FRI2_PRODUCT_ID) },
+ { USB_DEVICE(HONEYWELL_VENDOR_ID, HONEYWELL_HGI80_PRODUCT_ID) },
};
static struct usb_device_id ti_id_table_5052[5+TI_EXTRA_VID_PID_COUNT+1] = {
@@ -190,7 +191,7 @@ static struct usb_device_id ti_id_table_5052[5+TI_EXTRA_VID_PID_COUNT+1] = {
{ USB_DEVICE(TI_VENDOR_ID, TI_5052_FIRMWARE_PRODUCT_ID) },
};
-static struct usb_device_id ti_id_table_combined[19+2*TI_EXTRA_VID_PID_COUNT+1] = {
+static struct usb_device_id ti_id_table_combined[21+2*TI_EXTRA_VID_PID_COUNT+1] = {
{ USB_DEVICE(TI_VENDOR_ID, TI_3410_PRODUCT_ID) },
{ USB_DEVICE(TI_VENDOR_ID, TI_3410_EZ430_ID) },
{ USB_DEVICE(MTS_VENDOR_ID, MTS_GSM_NO_FW_PRODUCT_ID) },
@@ -209,7 +210,9 @@ static struct usb_device_id ti_id_table_combined[19+2*TI_EXTRA_VID_PID_COUNT+1]
{ USB_DEVICE(IBM_VENDOR_ID, IBM_454B_PRODUCT_ID) },
{ USB_DEVICE(IBM_VENDOR_ID, IBM_454C_PRODUCT_ID) },
{ USB_DEVICE(ABBOTT_VENDOR_ID, ABBOTT_PRODUCT_ID) },
+ { USB_DEVICE(ABBOTT_VENDOR_ID, ABBOTT_STRIP_PORT_ID) },
{ USB_DEVICE(TI_VENDOR_ID, FRI2_PRODUCT_ID) },
+ { USB_DEVICE(HONEYWELL_VENDOR_ID, HONEYWELL_HGI80_PRODUCT_ID) },
{ }
};
diff --git a/drivers/usb/serial/ti_usb_3410_5052.h b/drivers/usb/serial/ti_usb_3410_5052.h
index 4a2423e..98f35c6 100644
--- a/drivers/usb/serial/ti_usb_3410_5052.h
+++ b/drivers/usb/serial/ti_usb_3410_5052.h
@@ -56,6 +56,10 @@
#define ABBOTT_PRODUCT_ID ABBOTT_STEREO_PLUG_ID
#define ABBOTT_STRIP_PORT_ID 0x3420
+/* Honeywell vendor and product IDs */
+#define HONEYWELL_VENDOR_ID 0x10ac
+#define HONEYWELL_HGI80_PRODUCT_ID 0x0102 /* Honeywell HGI80 */
+
/* Commands */
#define TI_GET_VERSION 0x01
#define TI_GET_PORT_STATUS 0x02
diff --git a/fs/9p/vfs_inode.c b/fs/9p/vfs_inode.c
index bf1df72..adedfd4 100644
--- a/fs/9p/vfs_inode.c
+++ b/fs/9p/vfs_inode.c
@@ -435,9 +435,9 @@ void v9fs_evict_inode(struct inode *inode)
{
struct v9fs_inode *v9inode = V9FS_I(inode);
- truncate_inode_pages(inode->i_mapping, 0);
+ truncate_inode_pages(&inode->i_data, 0);
end_writeback(inode);
- filemap_fdatawrite(inode->i_mapping);
+ filemap_fdatawrite(&inode->i_data);
#ifdef CONFIG_9P_FSCACHE
v9fs_cache_inode_put_cookie(inode);
diff --git a/fs/cachefiles/rdwr.c b/fs/cachefiles/rdwr.c
index 00d9425..8c4292b 100644
--- a/fs/cachefiles/rdwr.c
+++ b/fs/cachefiles/rdwr.c
@@ -894,7 +894,7 @@ int cachefiles_write_page(struct fscache_storage *op, struct page *page)
loff_t pos, eof;
size_t len;
void *data;
- int ret;
+ int ret = -ENOBUFS;
ASSERT(op != NULL);
ASSERT(page != NULL);
diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
index 6858d9d..8c8115c 100644
--- a/fs/ext4/ext4.h
+++ b/fs/ext4/ext4.h
@@ -26,6 +26,7 @@
#include <linux/seqlock.h>
#include <linux/mutex.h>
#include <linux/timer.h>
+#include <linux/version.h>
#include <linux/wait.h>
#include <linux/blockgroup_lock.h>
#include <linux/percpu_counter.h>
@@ -698,19 +699,55 @@ struct move_extent {
<= (EXT4_GOOD_OLD_INODE_SIZE + \
(einode)->i_extra_isize)) \
+/*
+ * We use an encoding that preserves the times for extra epoch "00":
+ *
+ * extra msb of adjust for signed
+ * epoch 32-bit 32-bit tv_sec to
+ * bits time decoded 64-bit tv_sec 64-bit tv_sec valid time range
+ * 0 0 1 -0x80000000..-0x00000001 0x000000000 1901-12-13..1969-12-31
+ * 0 0 0 0x000000000..0x07fffffff 0x000000000 1970-01-01..2038-01-19
+ * 0 1 1 0x080000000..0x0ffffffff 0x100000000 2038-01-19..2106-02-07
+ * 0 1 0 0x100000000..0x17fffffff 0x100000000 2106-02-07..2174-02-25
+ * 1 0 1 0x180000000..0x1ffffffff 0x200000000 2174-02-25..2242-03-16
+ * 1 0 0 0x200000000..0x27fffffff 0x200000000 2242-03-16..2310-04-04
+ * 1 1 1 0x280000000..0x2ffffffff 0x300000000 2310-04-04..2378-04-22
+ * 1 1 0 0x300000000..0x37fffffff 0x300000000 2378-04-22..2446-05-10
+ *
+ * Note that previous versions of the kernel on 64-bit systems would
+ * incorrectly use extra epoch bits 1,1 for dates between 1901 and
+ * 1970. e2fsck will correct this, assuming that it is run on the
+ * affected filesystem before 2242.
+ */
+
static inline __le32 ext4_encode_extra_time(struct timespec *time)
{
- return cpu_to_le32((sizeof(time->tv_sec) > 4 ?
- (time->tv_sec >> 32) & EXT4_EPOCH_MASK : 0) |
- ((time->tv_nsec << EXT4_EPOCH_BITS) & EXT4_NSEC_MASK));
+ u32 extra = sizeof(time->tv_sec) > 4 ?
+ ((time->tv_sec - (s32)time->tv_sec) >> 32) & EXT4_EPOCH_MASK : 0;
+ return cpu_to_le32(extra | (time->tv_nsec << EXT4_EPOCH_BITS));
}
static inline void ext4_decode_extra_time(struct timespec *time, __le32 extra)
{
- if (sizeof(time->tv_sec) > 4)
- time->tv_sec |= (__u64)(le32_to_cpu(extra) & EXT4_EPOCH_MASK)
- << 32;
- time->tv_nsec = (le32_to_cpu(extra) & EXT4_NSEC_MASK) >> EXT4_EPOCH_BITS;
+ if (unlikely(sizeof(time->tv_sec) > 4 &&
+ (extra & cpu_to_le32(EXT4_EPOCH_MASK)))) {
+#if LINUX_VERSION_CODE < KERNEL_VERSION(4,20,0)
+ /* Handle legacy encoding of pre-1970 dates with epoch
+ * bits 1,1. We assume that by kernel version 4.20,
+ * everyone will have run fsck over the affected
+ * filesystems to correct the problem. (This
+ * backwards compatibility may be removed before this
+ * time, at the discretion of the ext4 developers.)
+ */
+ u64 extra_bits = le32_to_cpu(extra) & EXT4_EPOCH_MASK;
+ if (extra_bits == 3 && ((time->tv_sec) & 0x80000000) != 0)
+ extra_bits = 0;
+ time->tv_sec += extra_bits << 32;
+#else
+ time->tv_sec += (u64)(le32_to_cpu(extra) & EXT4_EPOCH_MASK) << 32;
+#endif
+ }
+ time->tv_nsec = (le32_to_cpu(extra) & EXT4_NSEC_MASK) >> EXT4_EPOCH_BITS;
}
#define EXT4_INODE_SET_XTIME(xtime, inode, raw_inode) \
diff --git a/fs/fuse/file.c b/fs/fuse/file.c
index 510d4aa..f507e6220 100644
--- a/fs/fuse/file.c
+++ b/fs/fuse/file.c
@@ -850,6 +850,7 @@ static ssize_t fuse_fill_write_pages(struct fuse_req *req,
mark_page_accessed(page);
+ iov_iter_advance(ii, tmp);
if (!tmp) {
unlock_page(page);
page_cache_release(page);
@@ -861,7 +862,6 @@ static ssize_t fuse_fill_write_pages(struct fuse_req *req,
req->pages[req->num_pages] = page;
req->num_pages++;
- iov_iter_advance(ii, tmp);
count += tmp;
pos += tmp;
offset += tmp;
diff --git a/fs/jbd2/transaction.c b/fs/jbd2/transaction.c
index 86dc68a..e3c41c5 100644
--- a/fs/jbd2/transaction.c
+++ b/fs/jbd2/transaction.c
@@ -1876,6 +1876,7 @@ static int journal_unmap_buffer(journal_t *journal, struct buffer_head *bh)
if (!buffer_dirty(bh)) {
/* bdflush has written it. We can drop it now */
+ __jbd2_journal_remove_checkpoint(jh);
goto zap_buffer;
}
@@ -1913,6 +1914,7 @@ static int journal_unmap_buffer(journal_t *journal, struct buffer_head *bh)
/* The orphan record's transaction has
* committed. We can cleanse this buffer */
clear_buffer_jbddirty(bh);
+ __jbd2_journal_remove_checkpoint(jh);
goto zap_buffer;
}
}
diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c
index b78b5b6..a1503a7 100644
--- a/fs/nfs/inode.c
+++ b/fs/nfs/inode.c
@@ -1389,7 +1389,11 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr)
nfsi->attrtimeo_timestamp = now;
}
}
- invalid &= ~NFS_INO_INVALID_ATTR;
+
+ /* Don't declare attrcache up to date if there were no attrs! */
+ if (fattr->valid != 0)
+ invalid &= ~NFS_INO_INVALID_ATTR;
+
/* Don't invalidate the data if we were to blame */
if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode)
|| S_ISLNK(inode->i_mode)))
diff --git a/fs/partitions/mac.c b/fs/partitions/mac.c
index 11f688b..f51c930 100644
--- a/fs/partitions/mac.c
+++ b/fs/partitions/mac.c
@@ -32,7 +32,7 @@ int mac_partition(struct parsed_partitions *state)
Sector sect;
unsigned char *data;
int slot, blocks_in_map;
- unsigned secsize;
+ unsigned secsize, datasize, partoffset;
#ifdef CONFIG_PPC_PMAC
int found_root = 0;
int found_root_goodness = 0;
@@ -50,10 +50,14 @@ int mac_partition(struct parsed_partitions *state)
}
secsize = be16_to_cpu(md->block_size);
put_dev_sector(sect);
- data = read_part_sector(state, secsize/512, §);
+ datasize = round_down(secsize, 512);
+ data = read_part_sector(state, datasize / 512, §);
if (!data)
return -1;
- part = (struct mac_partition *) (data + secsize%512);
+ partoffset = secsize % 512;
+ if (partoffset + sizeof(*part) > datasize)
+ return -1;
+ part = (struct mac_partition *) (data + partoffset);
if (be16_to_cpu(part->signature) != MAC_PARTITION_MAGIC) {
put_dev_sector(sect);
return 0; /* not a MacOS disk */
diff --git a/fs/splice.c b/fs/splice.c
index 8357b82..71c80f4 100644
--- a/fs/splice.c
+++ b/fs/splice.c
@@ -872,6 +872,13 @@ EXPORT_SYMBOL(splice_from_pipe_feed);
*/
int splice_from_pipe_next(struct pipe_inode_info *pipe, struct splice_desc *sd)
{
+ /*
+ * Check for signal early to make process killable when there are
+ * always buffers available
+ */
+ if (signal_pending(current))
+ return -ERESTARTSYS;
+
while (!pipe->nrbufs) {
if (!pipe->writers)
return 0;
@@ -950,6 +957,7 @@ ssize_t __splice_from_pipe(struct pipe_inode_info *pipe, struct splice_desc *sd,
splice_from_pipe_begin(sd);
do {
+ cond_resched();
ret = splice_from_pipe_next(pipe, sd);
if (ret > 0)
ret = splice_from_pipe_feed(pipe, sd, actor);
diff --git a/fs/sysv/Makefile b/fs/sysv/Makefile
index 3591f9d..7a75e70 100644
--- a/fs/sysv/Makefile
+++ b/fs/sysv/Makefile
@@ -5,4 +5,4 @@
obj-$(CONFIG_SYSV_FS) += sysv.o
sysv-objs := ialloc.o balloc.o inode.o itree.o file.o dir.o \
- namei.o super.o symlink.o
+ namei.o super.o
diff --git a/fs/sysv/inode.c b/fs/sysv/inode.c
index 25ffb3e..dacc1e1 100644
--- a/fs/sysv/inode.c
+++ b/fs/sysv/inode.c
@@ -176,14 +176,8 @@ void sysv_set_inode(struct inode *inode, dev_t rdev)
inode->i_fop = &sysv_dir_operations;
inode->i_mapping->a_ops = &sysv_aops;
} else if (S_ISLNK(inode->i_mode)) {
- if (inode->i_blocks) {
- inode->i_op = &sysv_symlink_inode_operations;
- inode->i_mapping->a_ops = &sysv_aops;
- } else {
- inode->i_op = &sysv_fast_symlink_inode_operations;
- nd_terminate_link(SYSV_I(inode)->i_data, inode->i_size,
- sizeof(SYSV_I(inode)->i_data) - 1);
- }
+ inode->i_op = &sysv_symlink_inode_operations;
+ inode->i_mapping->a_ops = &sysv_aops;
} else
init_special_inode(inode, inode->i_mode, rdev);
}
diff --git a/fs/sysv/symlink.c b/fs/sysv/symlink.c
deleted file mode 100644
index 00d2f8a..0000000
--- a/fs/sysv/symlink.c
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- * linux/fs/sysv/symlink.c
- *
- * Handling of System V filesystem fast symlinks extensions.
- * Aug 2001, Christoph Hellwig (hch@infradead.org)
- */
-
-#include "sysv.h"
-#include <linux/namei.h>
-
-static void *sysv_follow_link(struct dentry *dentry, struct nameidata *nd)
-{
- nd_set_link(nd, (char *)SYSV_I(dentry->d_inode)->i_data);
- return NULL;
-}
-
-const struct inode_operations sysv_fast_symlink_inode_operations = {
- .readlink = generic_readlink,
- .follow_link = sysv_follow_link,
-};
diff --git a/include/drm/drmP.h b/include/drm/drmP.h
index bf4b2dc..e7cd03c 100644
--- a/include/drm/drmP.h
+++ b/include/drm/drmP.h
@@ -430,6 +430,11 @@ struct drm_file {
void *driver_priv;
int is_master; /* this file private is a master for a minor */
+ /*
+ * This client is allowed to gain master privileges for @master.
+ * Protected by struct drm_device::struct_mutex.
+ */
+ unsigned allowed_master:1;
struct drm_master *master; /* master this node is currently associated with
N.B. not always minor->master */
struct list_head fbs;
@@ -1254,6 +1259,7 @@ extern int drm_fasync(int fd, struct file *filp, int on);
extern ssize_t drm_read(struct file *filp, char __user *buffer,
size_t count, loff_t *offset);
extern int drm_release(struct inode *inode, struct file *filp);
+extern int drm_new_set_master(struct drm_device *dev, struct drm_file *fpriv);
/* Mapping support (drm_vm.h) */
extern int drm_mmap(struct file *filp, struct vm_area_struct *vma);
diff --git a/include/linux/ipv6.h b/include/linux/ipv6.h
index 84b1447..00ef00d 100644
--- a/include/linux/ipv6.h
+++ b/include/linux/ipv6.h
@@ -369,7 +369,7 @@ struct ipv6_pinfo {
struct ipv6_ac_socklist *ipv6_ac_list;
struct ipv6_fl_socklist *ipv6_fl_list;
- struct ipv6_txoptions *opt;
+ struct ipv6_txoptions __rcu *opt;
struct sk_buff *pktoptions;
struct sk_buff *rxpmtu;
struct {
diff --git a/include/linux/lockdep.h b/include/linux/lockdep.h
index b6a56e3..8b9bbf1 100644
--- a/include/linux/lockdep.h
+++ b/include/linux/lockdep.h
@@ -342,6 +342,9 @@ extern void lockdep_trace_alloc(gfp_t mask);
#define lockdep_depth(tsk) (debug_locks ? (tsk)->lockdep_depth : 0)
#define lockdep_assert_held(l) WARN_ON(debug_locks && !lockdep_is_held(l))
+#define lockdep_assert_held_once(l) do { \
+ WARN_ON_ONCE(debug_locks && !lockdep_is_held(l)); \
+ } while (0)
#else /* !LOCKDEP */
@@ -362,6 +365,7 @@ static inline void lockdep_on(void)
# define lockdep_trace_alloc(g) do { } while (0)
# define lockdep_init() do { } while (0)
# define lockdep_info() do { } while (0)
+
# define lockdep_init_map(lock, name, key, sub) \
do { (void)(name); (void)(key); } while (0)
# define lockdep_set_class(lock, key) do { (void)(key); } while (0)
@@ -391,6 +395,7 @@ struct lock_class_key { };
#define lockdep_depth(tsk) (0)
#define lockdep_assert_held(l) do { } while (0)
+#define lockdep_assert_held_once(l) do { (void)(l); } while (0)
#endif /* !LOCKDEP */
diff --git a/include/net/af_unix.h b/include/net/af_unix.h
index 91ab5b0..f4842f7 100644
--- a/include/net/af_unix.h
+++ b/include/net/af_unix.h
@@ -54,10 +54,12 @@ struct unix_sock {
struct list_head link;
atomic_long_t inflight;
spinlock_t lock;
- unsigned int gc_candidate : 1;
- unsigned int gc_maybe_cycle : 1;
unsigned char recursion_level;
+ unsigned long gc_flags;
+#define UNIX_GC_CANDIDATE 0
+#define UNIX_GC_MAYBE_CYCLE 1
struct socket_wq peer_wq;
+ wait_queue_t peer_wake;
};
#define unix_sk(__sk) ((struct unix_sock *)__sk)
diff --git a/include/net/ipv6.h b/include/net/ipv6.h
index ab2e6d7..25f0491 100644
--- a/include/net/ipv6.h
+++ b/include/net/ipv6.h
@@ -191,6 +191,7 @@ extern rwlock_t ip6_ra_lock;
*/
struct ipv6_txoptions {
+ atomic_t refcnt;
/* Length of this structure */
int tot_len;
@@ -203,7 +204,7 @@ struct ipv6_txoptions {
struct ipv6_opt_hdr *dst0opt;
struct ipv6_rt_hdr *srcrt; /* Routing Header */
struct ipv6_opt_hdr *dst1opt;
-
+ struct rcu_head rcu;
/* Option buffer, as read by IPV6_PKTOPTIONS, starts here. */
};
@@ -229,6 +230,24 @@ struct ipv6_fl_socklist {
struct ip6_flowlabel *fl;
};
+static inline struct ipv6_txoptions *txopt_get(const struct ipv6_pinfo *np)
+{
+ struct ipv6_txoptions *opt;
+
+ rcu_read_lock();
+ opt = rcu_dereference(np->opt);
+ if (opt && !atomic_inc_not_zero(&opt->refcnt))
+ opt = NULL;
+ rcu_read_unlock();
+ return opt;
+}
+
+static inline void txopt_put(struct ipv6_txoptions *opt)
+{
+ if (opt && atomic_dec_and_test(&opt->refcnt))
+ kfree_rcu(opt, rcu);
+}
+
extern struct ip6_flowlabel *fl6_sock_lookup(struct sock *sk, __be32 label);
extern struct ipv6_txoptions *fl6_merge_options(struct ipv6_txoptions * opt_space,
struct ip6_flowlabel * fl,
@@ -382,6 +401,7 @@ struct ip6_create_arg {
u32 user;
const struct in6_addr *src;
const struct in6_addr *dst;
+ int iif;
};
void ip6_frag_init(struct inet_frag_queue *q, void *a);
diff --git a/include/net/sock.h b/include/net/sock.h
index c8dcbb8..ce6f641 100644
--- a/include/net/sock.h
+++ b/include/net/sock.h
@@ -302,6 +302,7 @@ struct sock {
sk_no_check : 2,
sk_userlocks : 4,
sk_protocol : 8,
+#define SK_PROTOCOL_MAX ((u8)~0U)
sk_type : 16;
kmemcheck_bitfield_end(flags);
int sk_wmem_queued;
@@ -565,6 +566,8 @@ enum sock_flags {
SOCK_ZEROCOPY, /* buffers from userspace */
};
+#define SK_FLAGS_TIMESTAMP ((1UL << SOCK_TIMESTAMP) | (1UL << SOCK_TIMESTAMPING_RX_SOFTWARE))
+
static inline void sock_copy_flags(struct sock *nsk, struct sock *osk)
{
nsk->sk_flags = osk->sk_flags;
diff --git a/kernel/sched.c b/kernel/sched.c
index 27c3092..a7a40b5 100644
--- a/kernel/sched.c
+++ b/kernel/sched.c
@@ -2932,7 +2932,6 @@ out:
*/
int wake_up_process(struct task_struct *p)
{
- WARN_ON(task_is_stopped_or_traced(p));
return try_to_wake_up(p, TASK_NORMAL, 0);
}
EXPORT_SYMBOL(wake_up_process);
@@ -7171,11 +7170,11 @@ static int init_rootdomain(struct root_domain *rd)
{
memset(rd, 0, sizeof(*rd));
- if (!alloc_cpumask_var(&rd->span, GFP_KERNEL))
+ if (!zalloc_cpumask_var(&rd->span, GFP_KERNEL))
goto out;
- if (!alloc_cpumask_var(&rd->online, GFP_KERNEL))
+ if (!zalloc_cpumask_var(&rd->online, GFP_KERNEL))
goto free_span;
- if (!alloc_cpumask_var(&rd->rto_mask, GFP_KERNEL))
+ if (!zalloc_cpumask_var(&rd->rto_mask, GFP_KERNEL))
goto free_online;
if (cpupri_init(&rd->cpupri) != 0)
diff --git a/kernel/trace/ring_buffer.c b/kernel/trace/ring_buffer.c
index b252661..2a6f853 100644
--- a/kernel/trace/ring_buffer.c
+++ b/kernel/trace/ring_buffer.c
@@ -1581,12 +1581,6 @@ rb_set_commit_to_write(struct ring_buffer_per_cpu *cpu_buffer)
goto again;
}
-static void rb_reset_reader_page(struct ring_buffer_per_cpu *cpu_buffer)
-{
- cpu_buffer->read_stamp = cpu_buffer->reader_page->page->time_stamp;
- cpu_buffer->reader_page->read = 0;
-}
-
static void rb_inc_iter(struct ring_buffer_iter *iter)
{
struct ring_buffer_per_cpu *cpu_buffer = iter->cpu_buffer;
@@ -3064,7 +3058,7 @@ rb_get_reader_page(struct ring_buffer_per_cpu *cpu_buffer)
/* Finally update the reader page to the new head */
cpu_buffer->reader_page = reader;
- rb_reset_reader_page(cpu_buffer);
+ cpu_buffer->reader_page->read = 0;
if (overwrite != cpu_buffer->last_overrun) {
cpu_buffer->lost_events = overwrite - cpu_buffer->last_overrun;
@@ -3074,6 +3068,10 @@ rb_get_reader_page(struct ring_buffer_per_cpu *cpu_buffer)
goto again;
out:
+ /* Update the read_stamp on the first event */
+ if (reader && reader->read == 0)
+ cpu_buffer->read_stamp = reader->page->time_stamp;
+
arch_spin_unlock(&cpu_buffer->lock);
local_irq_restore(flags);
diff --git a/mm/backing-dev.c b/mm/backing-dev.c
index 2b49dd2..17f5403 100644
--- a/mm/backing-dev.c
+++ b/mm/backing-dev.c
@@ -847,8 +847,9 @@ EXPORT_SYMBOL(congestion_wait);
* jiffies for either a BDI to exit congestion of the given @sync queue
* or a write to complete.
*
- * In the absence of zone congestion, cond_resched() is called to yield
- * the processor if necessary but otherwise does not sleep.
+ * In the absence of zone congestion, a short sleep or a cond_resched is
+ * performed to yield the processor and to allow other subsystems to make
+ * a forward progress.
*
* The return value is 0 if the sleep is for the full timeout. Otherwise,
* it is the number of jiffies that were still remaining when the function
@@ -868,7 +869,19 @@ long wait_iff_congested(struct zone *zone, int sync, long timeout)
*/
if (atomic_read(&nr_bdi_congested[sync]) == 0 ||
!zone_is_reclaim_congested(zone)) {
- cond_resched();
+
+ /*
+ * Memory allocation/reclaim might be called from a WQ
+ * context and the current implementation of the WQ
+ * concurrency control doesn't recognize that a particular
+ * WQ is congested if the worker thread is looping without
+ * ever sleeping. Therefore we have to do a short sleep
+ * here rather than calling cond_resched().
+ */
+ if (current->flags & PF_WQ_WORKER)
+ schedule_timeout(1);
+ else
+ cond_resched();
/* In case we scheduled, work out time remaining */
ret = timeout - (jiffies - start);
diff --git a/mm/hugetlb.c b/mm/hugetlb.c
index 776c630..9256590 100644
--- a/mm/hugetlb.c
+++ b/mm/hugetlb.c
@@ -2818,12 +2818,12 @@ int hugetlb_fault(struct mm_struct *mm, struct vm_area_struct *vma,
} else if (unlikely(is_hugetlb_entry_hwpoisoned(entry)))
return VM_FAULT_HWPOISON_LARGE |
VM_FAULT_SET_HINDEX(h - hstates);
+ } else {
+ ptep = huge_pte_alloc(mm, address, huge_page_size(h));
+ if (!ptep)
+ return VM_FAULT_OOM;
}
- ptep = huge_pte_alloc(mm, address, huge_page_size(h));
- if (!ptep)
- return VM_FAULT_OOM;
-
/*
* Serialize hugepage allocation and instantiation, so that we don't
* get spurious allocation failures if two CPUs race to instantiate
diff --git a/mm/vmstat.c b/mm/vmstat.c
index 8fd603b..14d8cb4 100644
--- a/mm/vmstat.c
+++ b/mm/vmstat.c
@@ -1139,13 +1139,14 @@ static const struct file_operations proc_vmstat_file_operations = {
#endif /* CONFIG_PROC_FS */
#ifdef CONFIG_SMP
+static struct workqueue_struct *vmstat_wq;
static DEFINE_PER_CPU(struct delayed_work, vmstat_work);
int sysctl_stat_interval __read_mostly = HZ;
static void vmstat_update(struct work_struct *w)
{
refresh_cpu_vm_stats(smp_processor_id());
- schedule_delayed_work(&__get_cpu_var(vmstat_work),
+ queue_delayed_work(vmstat_wq, &__get_cpu_var(vmstat_work),
round_jiffies_relative(sysctl_stat_interval));
}
@@ -1154,7 +1155,7 @@ static void __cpuinit start_cpu_timer(int cpu)
struct delayed_work *work = &per_cpu(vmstat_work, cpu);
INIT_DELAYED_WORK_DEFERRABLE(work, vmstat_update);
- schedule_delayed_work_on(cpu, work, __round_jiffies_relative(HZ, cpu));
+ queue_delayed_work_on(cpu, vmstat_wq, work, __round_jiffies_relative(HZ, cpu));
}
/*
@@ -1204,6 +1205,7 @@ static int __init setup_vmstat(void)
register_cpu_notifier(&vmstat_notifier);
+ vmstat_wq = alloc_workqueue("vmstat", WQ_FREEZABLE|WQ_MEM_RECLAIM, 0);
for_each_online_cpu(cpu)
start_cpu_timer(cpu);
#endif
diff --git a/net/ax25/af_ax25.c b/net/ax25/af_ax25.c
index 7b8db0e..a314cfd 100644
--- a/net/ax25/af_ax25.c
+++ b/net/ax25/af_ax25.c
@@ -806,6 +806,9 @@ static int ax25_create(struct net *net, struct socket *sock, int protocol,
struct sock *sk;
ax25_cb *ax25;
+ if (protocol < 0 || protocol > SK_PROTOCOL_MAX)
+ return -EINVAL;
+
if (!net_eq(net, &init_net))
return -EAFNOSUPPORT;
diff --git a/net/bluetooth/sco.c b/net/bluetooth/sco.c
index 2e80aee7..9f0e5a4 100644
--- a/net/bluetooth/sco.c
+++ b/net/bluetooth/sco.c
@@ -475,6 +475,9 @@ static int sco_sock_bind(struct socket *sock, struct sockaddr *addr, int addr_le
if (!addr || addr->sa_family != AF_BLUETOOTH)
return -EINVAL;
+ if (addr_len < sizeof(struct sockaddr_sco))
+ return -EINVAL;
+
lock_sock(sk);
if (sk->sk_state != BT_OPEN) {
diff --git a/net/core/dev.c b/net/core/dev.c
index 7f43202..9a95205 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -5446,7 +5446,7 @@ int __netdev_update_features(struct net_device *dev)
netdev_err(dev,
"set_features() failed (%d); wanted 0x%08x, left 0x%08x\n",
err, features, dev->features);
- return -1;
+ return 0;
}
if (!err)
diff --git a/net/core/scm.c b/net/core/scm.c
index ff52ad0..51b4d52 100644
--- a/net/core/scm.c
+++ b/net/core/scm.c
@@ -311,6 +311,8 @@ void scm_detach_fds(struct msghdr *msg, struct scm_cookie *scm)
err = put_user(cmlen, &cm->cmsg_len);
if (!err) {
cmlen = CMSG_SPACE(i*sizeof(int));
+ if (msg->msg_controllen < cmlen)
+ cmlen = msg->msg_controllen;
msg->msg_control += cmlen;
msg->msg_controllen -= cmlen;
}
diff --git a/net/dccp/ipv6.c b/net/dccp/ipv6.c
index 592b78c..0987c89 100644
--- a/net/dccp/ipv6.c
+++ b/net/dccp/ipv6.c
@@ -236,7 +236,6 @@ static int dccp_v6_send_response(struct sock *sk, struct request_sock *req,
struct inet6_request_sock *ireq6 = inet6_rsk(req);
struct ipv6_pinfo *np = inet6_sk(sk);
struct sk_buff *skb;
- struct ipv6_txoptions *opt = NULL;
struct in6_addr *final_p, final;
struct flowi6 fl6;
int err = -1;
@@ -252,9 +251,10 @@ static int dccp_v6_send_response(struct sock *sk, struct request_sock *req,
fl6.fl6_sport = inet_rsk(req)->loc_port;
security_req_classify_flow(req, flowi6_to_flowi(&fl6));
- opt = np->opt;
- final_p = fl6_update_dst(&fl6, opt, &final);
+ rcu_read_lock();
+ final_p = fl6_update_dst(&fl6, rcu_dereference(np->opt), &final);
+ rcu_read_unlock();
dst = ip6_dst_lookup_flow(sk, &fl6, final_p, false);
if (IS_ERR(dst)) {
@@ -271,13 +271,14 @@ static int dccp_v6_send_response(struct sock *sk, struct request_sock *req,
&ireq6->loc_addr,
&ireq6->rmt_addr);
ipv6_addr_copy(&fl6.daddr, &ireq6->rmt_addr);
- err = ip6_xmit(sk, skb, &fl6, opt, np->tclass);
+ rcu_read_lock();
+ err = ip6_xmit(sk, skb, &fl6, rcu_dereference(np->opt),
+ np->tclass);
+ rcu_read_unlock();
err = net_xmit_eval(err);
}
done:
- if (opt != NULL && opt != np->opt)
- sock_kfree_s(sk, opt, opt->tot_len);
dst_release(dst);
return err;
}
@@ -467,10 +468,10 @@ static struct sock *dccp_v6_request_recv_sock(struct sock *sk,
{
struct inet6_request_sock *ireq6 = inet6_rsk(req);
struct ipv6_pinfo *newnp, *np = inet6_sk(sk);
+ struct ipv6_txoptions *opt;
struct inet_sock *newinet;
struct dccp6_sock *newdp6;
struct sock *newsk;
- struct ipv6_txoptions *opt;
if (skb->protocol == htons(ETH_P_IP)) {
/*
@@ -515,7 +516,6 @@ static struct sock *dccp_v6_request_recv_sock(struct sock *sk,
return newsk;
}
- opt = np->opt;
if (sk_acceptq_is_full(sk))
goto out_overflow;
@@ -527,7 +527,7 @@ static struct sock *dccp_v6_request_recv_sock(struct sock *sk,
memset(&fl6, 0, sizeof(fl6));
fl6.flowi6_proto = IPPROTO_DCCP;
ipv6_addr_copy(&fl6.daddr, &ireq6->rmt_addr);
- final_p = fl6_update_dst(&fl6, opt, &final);
+ final_p = fl6_update_dst(&fl6, np->opt, &final);
ipv6_addr_copy(&fl6.saddr, &ireq6->loc_addr);
fl6.flowi6_oif = sk->sk_bound_dev_if;
fl6.fl6_dport = inet_rsk(req)->rmt_port;
@@ -592,16 +592,15 @@ static struct sock *dccp_v6_request_recv_sock(struct sock *sk,
* Yes, keeping reference count would be much more clever, but we make
* one more one thing there: reattach optmem to newsk.
*/
- if (opt != NULL) {
- newnp->opt = ipv6_dup_options(newsk, opt);
- if (opt != np->opt)
- sock_kfree_s(sk, opt, opt->tot_len);
+ opt = rcu_dereference(np->opt);
+ if (opt) {
+ opt = ipv6_dup_options(newsk, opt);
+ RCU_INIT_POINTER(newnp->opt, opt);
}
-
inet_csk(newsk)->icsk_ext_hdr_len = 0;
- if (newnp->opt != NULL)
- inet_csk(newsk)->icsk_ext_hdr_len = (newnp->opt->opt_nflen +
- newnp->opt->opt_flen);
+ if (opt)
+ inet_csk(newsk)->icsk_ext_hdr_len = opt->opt_nflen +
+ opt->opt_flen;
dccp_sync_mss(newsk, dst_mtu(dst));
@@ -623,8 +622,6 @@ out_nonewsk:
dst_release(dst);
out:
NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_LISTENDROPS);
- if (opt != NULL && opt != np->opt)
- sock_kfree_s(sk, opt, opt->tot_len);
return NULL;
}
@@ -855,6 +852,7 @@ static int dccp_v6_connect(struct sock *sk, struct sockaddr *uaddr,
struct ipv6_pinfo *np = inet6_sk(sk);
struct dccp_sock *dp = dccp_sk(sk);
struct in6_addr *saddr = NULL, *final_p, final;
+ struct ipv6_txoptions *opt;
struct flowi6 fl6;
struct dst_entry *dst;
int addr_type;
@@ -957,7 +955,8 @@ static int dccp_v6_connect(struct sock *sk, struct sockaddr *uaddr,
fl6.fl6_sport = inet->inet_sport;
security_sk_classify_flow(sk, flowi6_to_flowi(&fl6));
- final_p = fl6_update_dst(&fl6, np->opt, &final);
+ opt = rcu_dereference_protected(np->opt, sock_owned_by_user(sk));
+ final_p = fl6_update_dst(&fl6, opt, &final);
dst = ip6_dst_lookup_flow(sk, &fl6, final_p, true);
if (IS_ERR(dst)) {
@@ -977,9 +976,8 @@ static int dccp_v6_connect(struct sock *sk, struct sockaddr *uaddr,
__ip6_dst_store(sk, dst, NULL, NULL);
icsk->icsk_ext_hdr_len = 0;
- if (np->opt != NULL)
- icsk->icsk_ext_hdr_len = (np->opt->opt_flen +
- np->opt->opt_nflen);
+ if (opt)
+ icsk->icsk_ext_hdr_len = opt->opt_flen + opt->opt_nflen;
inet->inet_dport = usin->sin6_port;
diff --git a/net/decnet/af_decnet.c b/net/decnet/af_decnet.c
index 16fbf8c..c0486c8 100644
--- a/net/decnet/af_decnet.c
+++ b/net/decnet/af_decnet.c
@@ -681,6 +681,9 @@ static int dn_create(struct net *net, struct socket *sock, int protocol,
{
struct sock *sk;
+ if (protocol < 0 || protocol > SK_PROTOCOL_MAX)
+ return -EINVAL;
+
if (!net_eq(net, &init_net))
return -EAFNOSUPPORT;
diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c
index 5d228de..e2ab968 100644
--- a/net/ipv4/af_inet.c
+++ b/net/ipv4/af_inet.c
@@ -279,6 +279,9 @@ static int inet_create(struct net *net, struct socket *sock, int protocol,
int try_loading_module = 0;
int err;
+ if (protocol < 0 || protocol >= IPPROTO_MAX)
+ return -EINVAL;
+
if (unlikely(!inet_ehash_secret))
if (sock->type != SOCK_RAW && sock->type != SOCK_DGRAM)
build_ehash_secret();
diff --git a/net/ipv4/igmp.c b/net/ipv4/igmp.c
index 03e9486..d9c1d58 100644
--- a/net/ipv4/igmp.c
+++ b/net/ipv4/igmp.c
@@ -1866,7 +1866,7 @@ int ip_mc_leave_group(struct sock *sk, struct ip_mreqn *imr)
rtnl_lock();
in_dev = ip_mc_find_dev(net, imr);
- if (!in_dev) {
+ if (!imr->imr_ifindex && !imr->imr_address.s_addr && !in_dev) {
ret = -ENODEV;
goto out;
}
@@ -1887,7 +1887,8 @@ int ip_mc_leave_group(struct sock *sk, struct ip_mreqn *imr)
*imlp = iml->next_rcu;
- ip_mc_dec_group(in_dev, group);
+ if (in_dev)
+ ip_mc_dec_group(in_dev, group);
rtnl_unlock();
/* decrease mem now to avoid the memleak warning */
atomic_sub(sizeof(*iml), &sk->sk_omem_alloc);
diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c
index 581dcb3..95b47ff 100644
--- a/net/ipv4/ipmr.c
+++ b/net/ipv4/ipmr.c
@@ -134,7 +134,7 @@ static int ipmr_cache_report(struct mr_table *mrt,
struct sk_buff *pkt, vifi_t vifi, int assert);
static int __ipmr_fill_mroute(struct mr_table *mrt, struct sk_buff *skb,
struct mfc_cache *c, struct rtmsg *rtm);
-static void mroute_clean_tables(struct mr_table *mrt);
+static void mroute_clean_tables(struct mr_table *mrt, bool all);
static void ipmr_expire_process(unsigned long arg);
#ifdef CONFIG_IP_MROUTE_MULTIPLE_TABLES
@@ -346,7 +346,7 @@ static struct mr_table *ipmr_new_table(struct net *net, u32 id)
static void ipmr_free_table(struct mr_table *mrt)
{
del_timer_sync(&mrt->ipmr_expire_timer);
- mroute_clean_tables(mrt);
+ mroute_clean_tables(mrt, true);
kfree(mrt);
}
@@ -1143,7 +1143,7 @@ static int ipmr_mfc_add(struct net *net, struct mr_table *mrt,
* Close the multicast socket, and clear the vif tables etc
*/
-static void mroute_clean_tables(struct mr_table *mrt)
+static void mroute_clean_tables(struct mr_table *mrt, bool all)
{
int i;
LIST_HEAD(list);
@@ -1152,8 +1152,9 @@ static void mroute_clean_tables(struct mr_table *mrt)
/* Shut down all active vif entries */
for (i = 0; i < mrt->maxvif; i++) {
- if (!(mrt->vif_table[i].flags & VIFF_STATIC))
- vif_delete(mrt, i, 0, &list);
+ if (!all && (mrt->vif_table[i].flags & VIFF_STATIC))
+ continue;
+ vif_delete(mrt, i, 0, &list);
}
unregister_netdevice_many(&list);
@@ -1161,7 +1162,7 @@ static void mroute_clean_tables(struct mr_table *mrt)
for (i = 0; i < MFC_LINES; i++) {
list_for_each_entry_safe(c, next, &mrt->mfc_cache_array[i], list) {
- if (c->mfc_flags & MFC_STATIC)
+ if (!all && (c->mfc_flags & MFC_STATIC))
continue;
list_del_rcu(&c->list);
ipmr_cache_free(c);
@@ -1191,7 +1192,7 @@ static void mrtsock_destruct(struct sock *sk)
if (sk == rtnl_dereference(mrt->mroute_sk)) {
IPV4_DEVCONF_ALL(net, MC_FORWARDING)--;
RCU_INIT_POINTER(mrt->mroute_sk, NULL);
- mroute_clean_tables(mrt);
+ mroute_clean_tables(mrt, false);
}
}
rtnl_unlock();
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
index f8b5899..3877e16 100644
--- a/net/ipv4/tcp_input.c
+++ b/net/ipv4/tcp_input.c
@@ -5811,6 +5811,7 @@ discard:
}
tp->rcv_nxt = TCP_SKB_CB(skb)->seq + 1;
+ tp->copied_seq = tp->rcv_nxt;
tp->rcv_wup = TCP_SKB_CB(skb)->seq + 1;
/* RFC1323: The window in SYN & SYN/ACK segments is
diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c
index d27c797..d578137 100644
--- a/net/ipv6/af_inet6.c
+++ b/net/ipv6/af_inet6.c
@@ -109,6 +109,9 @@ static int inet6_create(struct net *net, struct socket *sock, int protocol,
int try_loading_module = 0;
int err;
+ if (protocol < 0 || protocol >= IPPROTO_MAX)
+ return -EINVAL;
+
if (sock->type != SOCK_RAW &&
sock->type != SOCK_DGRAM &&
!inet_ehash_secret)
@@ -430,8 +433,11 @@ void inet6_destroy_sock(struct sock *sk)
/* Free tx options */
- if ((opt = xchg(&np->opt, NULL)) != NULL)
- sock_kfree_s(sk, opt, opt->tot_len);
+ opt = xchg((__force struct ipv6_txoptions **)&np->opt, NULL);
+ if (opt) {
+ atomic_sub(opt->tot_len, &sk->sk_omem_alloc);
+ txopt_put(opt);
+ }
}
EXPORT_SYMBOL_GPL(inet6_destroy_sock);
@@ -669,7 +675,10 @@ int inet6_sk_rebuild_header(struct sock *sk)
fl6.fl6_sport = inet->inet_sport;
security_sk_classify_flow(sk, flowi6_to_flowi(&fl6));
- final_p = fl6_update_dst(&fl6, np->opt, &final);
+ rcu_read_lock();
+ final_p = fl6_update_dst(&fl6, rcu_dereference(np->opt),
+ &final);
+ rcu_read_unlock();
dst = ip6_dst_lookup_flow(sk, &fl6, final_p, false);
if (IS_ERR(dst)) {
diff --git a/net/ipv6/datagram.c b/net/ipv6/datagram.c
index 67f3632..9e4bacc 100644
--- a/net/ipv6/datagram.c
+++ b/net/ipv6/datagram.c
@@ -166,8 +166,10 @@ ipv4_connected:
security_sk_classify_flow(sk, flowi6_to_flowi(&fl6));
- opt = flowlabel ? flowlabel->opt : np->opt;
+ rcu_read_lock();
+ opt = flowlabel ? flowlabel->opt : rcu_dereference(np->opt);
final_p = fl6_update_dst(&fl6, opt, &final);
+ rcu_read_unlock();
dst = ip6_dst_lookup_flow(sk, &fl6, final_p, true);
err = 0;
diff --git a/net/ipv6/exthdrs.c b/net/ipv6/exthdrs.c
index bf22a22..ef7b872 100644
--- a/net/ipv6/exthdrs.c
+++ b/net/ipv6/exthdrs.c
@@ -748,6 +748,7 @@ ipv6_dup_options(struct sock *sk, struct ipv6_txoptions *opt)
*((char**)&opt2->dst1opt) += dif;
if (opt2->srcrt)
*((char**)&opt2->srcrt) += dif;
+ atomic_set(&opt2->refcnt, 1);
}
return opt2;
}
@@ -812,7 +813,7 @@ ipv6_renew_options(struct sock *sk, struct ipv6_txoptions *opt,
return ERR_PTR(-ENOBUFS);
memset(opt2, 0, tot_len);
-
+ atomic_set(&opt2->refcnt, 1);
opt2->tot_len = tot_len;
p = (char *)(opt2 + 1);
diff --git a/net/ipv6/inet6_connection_sock.c b/net/ipv6/inet6_connection_sock.c
index 1567fb1..a232371 100644
--- a/net/ipv6/inet6_connection_sock.c
+++ b/net/ipv6/inet6_connection_sock.c
@@ -66,7 +66,9 @@ struct dst_entry *inet6_csk_route_req(struct sock *sk,
memset(&fl6, 0, sizeof(fl6));
fl6.flowi6_proto = IPPROTO_TCP;
ipv6_addr_copy(&fl6.daddr, &treq->rmt_addr);
- final_p = fl6_update_dst(&fl6, np->opt, &final);
+ rcu_read_lock();
+ final_p = fl6_update_dst(&fl6, rcu_dereference(np->opt), &final);
+ rcu_read_unlock();
ipv6_addr_copy(&fl6.saddr, &treq->loc_addr);
fl6.flowi6_oif = sk->sk_bound_dev_if;
fl6.flowi6_mark = sk->sk_mark;
@@ -225,7 +227,9 @@ int inet6_csk_xmit(struct sk_buff *skb, struct flowi *fl_unused)
fl6.fl6_dport = inet->inet_dport;
security_sk_classify_flow(sk, flowi6_to_flowi(&fl6));
- final_p = fl6_update_dst(&fl6, np->opt, &final);
+ rcu_read_lock();
+ final_p = fl6_update_dst(&fl6, rcu_dereference(np->opt), &final);
+ rcu_read_unlock();
dst = __inet6_csk_dst_check(sk, np->dst_cookie);
@@ -248,7 +252,8 @@ int inet6_csk_xmit(struct sk_buff *skb, struct flowi *fl_unused)
/* Restore final destination back after routing done */
ipv6_addr_copy(&fl6.daddr, &np->daddr);
- res = ip6_xmit(sk, skb, &fl6, np->opt, np->tclass);
+ res = ip6_xmit(sk, skb, &fl6, rcu_dereference(np->opt),
+ np->tclass);
rcu_read_unlock();
return res;
}
diff --git a/net/ipv6/ip6mr.c b/net/ipv6/ip6mr.c
index 99ee86d..02b3c82 100644
--- a/net/ipv6/ip6mr.c
+++ b/net/ipv6/ip6mr.c
@@ -118,7 +118,7 @@ static int __ip6mr_fill_mroute(struct mr6_table *mrt, struct sk_buff *skb,
struct mfc6_cache *c, struct rtmsg *rtm);
static int ip6mr_rtm_dumproute(struct sk_buff *skb,
struct netlink_callback *cb);
-static void mroute_clean_tables(struct mr6_table *mrt);
+static void mroute_clean_tables(struct mr6_table *mrt, bool all);
static void ipmr_expire_process(unsigned long arg);
#ifdef CONFIG_IPV6_MROUTE_MULTIPLE_TABLES
@@ -334,8 +334,8 @@ static struct mr6_table *ip6mr_new_table(struct net *net, u32 id)
static void ip6mr_free_table(struct mr6_table *mrt)
{
- del_timer(&mrt->ipmr_expire_timer);
- mroute_clean_tables(mrt);
+ del_timer_sync(&mrt->ipmr_expire_timer);
+ mroute_clean_tables(mrt, true);
kfree(mrt);
}
@@ -1473,7 +1473,7 @@ static int ip6mr_mfc_add(struct net *net, struct mr6_table *mrt,
* Close the multicast socket, and clear the vif tables etc
*/
-static void mroute_clean_tables(struct mr6_table *mrt)
+static void mroute_clean_tables(struct mr6_table *mrt, bool all)
{
int i;
LIST_HEAD(list);
@@ -1483,8 +1483,9 @@ static void mroute_clean_tables(struct mr6_table *mrt)
* Shut down all active vif entries
*/
for (i = 0; i < mrt->maxvif; i++) {
- if (!(mrt->vif6_table[i].flags & VIFF_STATIC))
- mif6_delete(mrt, i, &list);
+ if (!all && (mrt->vif6_table[i].flags & VIFF_STATIC))
+ continue;
+ mif6_delete(mrt, i, &list);
}
unregister_netdevice_many(&list);
@@ -1493,7 +1494,7 @@ static void mroute_clean_tables(struct mr6_table *mrt)
*/
for (i = 0; i < MFC6_LINES; i++) {
list_for_each_entry_safe(c, next, &mrt->mfc6_cache_array[i], list) {
- if (c->mfc_flags & MFC_STATIC)
+ if (!all && (c->mfc_flags & MFC_STATIC))
continue;
write_lock_bh(&mrt_lock);
list_del(&c->list);
@@ -1547,7 +1548,7 @@ int ip6mr_sk_done(struct sock *sk)
net->ipv6.devconf_all->mc_forwarding--;
write_unlock_bh(&mrt_lock);
- mroute_clean_tables(mrt);
+ mroute_clean_tables(mrt, false);
err = 0;
break;
}
diff --git a/net/ipv6/ipv6_sockglue.c b/net/ipv6/ipv6_sockglue.c
index b204df8..9af3f5c 100644
--- a/net/ipv6/ipv6_sockglue.c
+++ b/net/ipv6/ipv6_sockglue.c
@@ -110,10 +110,12 @@ struct ipv6_txoptions *ipv6_update_options(struct sock *sk,
icsk->icsk_ext_hdr_len = opt->opt_flen + opt->opt_nflen;
icsk->icsk_sync_mss(sk, icsk->icsk_pmtu_cookie);
}
- opt = xchg(&inet6_sk(sk)->opt, opt);
+ opt = xchg((__force struct ipv6_txoptions **)&inet6_sk(sk)->opt,
+ opt);
} else {
spin_lock(&sk->sk_dst_lock);
- opt = xchg(&inet6_sk(sk)->opt, opt);
+ opt = xchg((__force struct ipv6_txoptions **)&inet6_sk(sk)->opt,
+ opt);
spin_unlock(&sk->sk_dst_lock);
}
sk_dst_reset(sk);
@@ -213,9 +215,12 @@ static int do_ipv6_setsockopt(struct sock *sk, int level, int optname,
sk->sk_socket->ops = &inet_dgram_ops;
sk->sk_family = PF_INET;
}
- opt = xchg(&np->opt, NULL);
- if (opt)
- sock_kfree_s(sk, opt, opt->tot_len);
+ opt = xchg((__force struct ipv6_txoptions **)&np->opt,
+ NULL);
+ if (opt) {
+ atomic_sub(opt->tot_len, &sk->sk_omem_alloc);
+ txopt_put(opt);
+ }
pktopt = xchg(&np->pktoptions, NULL);
kfree_skb(pktopt);
@@ -384,7 +389,8 @@ static int do_ipv6_setsockopt(struct sock *sk, int level, int optname,
if (optname != IPV6_RTHDR && !capable(CAP_NET_RAW))
break;
- opt = ipv6_renew_options(sk, np->opt, optname,
+ opt = rcu_dereference_protected(np->opt, sock_owned_by_user(sk));
+ opt = ipv6_renew_options(sk, opt, optname,
(struct ipv6_opt_hdr __user *)optval,
optlen);
if (IS_ERR(opt)) {
@@ -413,8 +419,10 @@ static int do_ipv6_setsockopt(struct sock *sk, int level, int optname,
retv = 0;
opt = ipv6_update_options(sk, opt);
sticky_done:
- if (opt)
- sock_kfree_s(sk, opt, opt->tot_len);
+ if (opt) {
+ atomic_sub(opt->tot_len, &sk->sk_omem_alloc);
+ txopt_put(opt);
+ }
break;
}
@@ -467,6 +475,7 @@ sticky_done:
break;
memset(opt, 0, sizeof(*opt));
+ atomic_set(&opt->refcnt, 1);
opt->tot_len = sizeof(*opt) + optlen;
retv = -EFAULT;
if (copy_from_user(opt+1, optval, optlen))
@@ -483,8 +492,10 @@ update:
retv = 0;
opt = ipv6_update_options(sk, opt);
done:
- if (opt)
- sock_kfree_s(sk, opt, opt->tot_len);
+ if (opt) {
+ atomic_sub(opt->tot_len, &sk->sk_omem_alloc);
+ txopt_put(opt);
+ }
break;
}
case IPV6_UNICAST_HOPS:
@@ -1053,10 +1064,11 @@ static int do_ipv6_getsockopt(struct sock *sk, int level, int optname,
case IPV6_RTHDR:
case IPV6_DSTOPTS:
{
+ struct ipv6_txoptions *opt;
lock_sock(sk);
- len = ipv6_getsockopt_sticky(sk, np->opt,
- optname, optval, len);
+ opt = rcu_dereference_protected(np->opt, sock_owned_by_user(sk));
+ len = ipv6_getsockopt_sticky(sk, opt, optname, optval, len);
release_sock(sk);
/* check if ipv6_getsockopt_sticky() returns err code */
if (len < 0)
diff --git a/net/ipv6/mcast.c b/net/ipv6/mcast.c
index 7bb6644..9129a7c 100644
--- a/net/ipv6/mcast.c
+++ b/net/ipv6/mcast.c
@@ -1441,7 +1441,6 @@ out:
if (!err) {
ICMP6MSGOUT_INC_STATS(net, idev, ICMPV6_MLD2_REPORT);
ICMP6_INC_STATS(net, idev, ICMP6_MIB_OUTMSGS);
- IP6_UPD_PO_STATS(net, idev, IPSTATS_MIB_OUTMCAST, payload_len);
} else {
IP6_INC_STATS(net, idev, IPSTATS_MIB_OUTDISCARDS);
}
@@ -1811,7 +1810,6 @@ out:
if (!err) {
ICMP6MSGOUT_INC_STATS(net, idev, type);
ICMP6_INC_STATS(net, idev, ICMP6_MIB_OUTMSGS);
- IP6_UPD_PO_STATS(net, idev, IPSTATS_MIB_OUTMCAST, full_len);
} else
IP6_INC_STATS(net, idev, IPSTATS_MIB_OUTDISCARDS);
diff --git a/net/ipv6/netfilter/nf_conntrack_reasm.c b/net/ipv6/netfilter/nf_conntrack_reasm.c
index 52e2f65..2252b87 100644
--- a/net/ipv6/netfilter/nf_conntrack_reasm.c
+++ b/net/ipv6/netfilter/nf_conntrack_reasm.c
@@ -162,7 +162,7 @@ out:
/* Creation primitives. */
static __inline__ struct nf_ct_frag6_queue *
-fq_find(__be32 id, u32 user, struct in6_addr *src, struct in6_addr *dst)
+fq_find(__be32 id, u32 user, struct in6_addr *src, struct in6_addr *dst, int iif)
{
struct inet_frag_queue *q;
struct ip6_create_arg arg;
@@ -172,6 +172,7 @@ fq_find(__be32 id, u32 user, struct in6_addr *src, struct in6_addr *dst)
arg.user = user;
arg.src = src;
arg.dst = dst;
+ arg.iif = iif;
read_lock_bh(&nf_frags.lock);
hash = inet6_hash_frag(id, src, dst, nf_frags.rnd);
@@ -558,7 +559,8 @@ struct sk_buff *nf_ct_frag6_gather(struct sk_buff *skb, u32 user)
if (atomic_read(&nf_init_frags.mem) > nf_init_frags.high_thresh)
nf_ct_frag6_evictor();
- fq = fq_find(fhdr->identification, user, &hdr->saddr, &hdr->daddr);
+ fq = fq_find(fhdr->identification, user, &hdr->saddr, &hdr->daddr,
+ skb->dev ? skb->dev->ifindex : 0);
if (fq == NULL) {
pr_debug("Can't find and can't create new queue\n");
goto ret_orig;
diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c
index 240c102f..d1e528c 100644
--- a/net/ipv6/raw.c
+++ b/net/ipv6/raw.c
@@ -724,6 +724,7 @@ static int rawv6_probe_proto_opt(struct flowi6 *fl6, struct msghdr *msg)
static int rawv6_sendmsg(struct kiocb *iocb, struct sock *sk,
struct msghdr *msg, size_t len)
{
+ struct ipv6_txoptions *opt_to_free = NULL;
struct ipv6_txoptions opt_space;
struct sockaddr_in6 * sin6 = (struct sockaddr_in6 *) msg->msg_name;
struct in6_addr *daddr, *final_p, final;
@@ -830,8 +831,10 @@ static int rawv6_sendmsg(struct kiocb *iocb, struct sock *sk,
if (!(opt->opt_nflen|opt->opt_flen))
opt = NULL;
}
- if (opt == NULL)
- opt = np->opt;
+ if (!opt) {
+ opt = txopt_get(np);
+ opt_to_free = opt;
+ }
if (flowlabel)
opt = fl6_merge_options(&opt_space, flowlabel, opt);
opt = ipv6_fixup_options(&opt_space, opt);
@@ -896,6 +899,7 @@ done:
dst_release(dst);
out:
fl6_sock_release(flowlabel);
+ txopt_put(opt_to_free);
return err<0?err:len;
do_confirm:
dst_confirm(dst);
diff --git a/net/ipv6/reassembly.c b/net/ipv6/reassembly.c
index eba5deb..5378faa 100644
--- a/net/ipv6/reassembly.c
+++ b/net/ipv6/reassembly.c
@@ -144,8 +144,11 @@ int ip6_frag_match(struct inet_frag_queue *q, void *a)
fq = container_of(q, struct frag_queue, q);
return (fq->id == arg->id && fq->user == arg->user &&
- ipv6_addr_equal(&fq->saddr, arg->src) &&
- ipv6_addr_equal(&fq->daddr, arg->dst));
+ ipv6_addr_equal(&fq->saddr, arg->src) &&
+ ipv6_addr_equal(&fq->daddr, arg->dst) &&
+ (arg->iif == fq->iif ||
+ !(ipv6_addr_type(arg->dst) & (IPV6_ADDR_MULTICAST |
+ IPV6_ADDR_LINKLOCAL))));
}
EXPORT_SYMBOL(ip6_frag_match);
@@ -228,7 +231,8 @@ out:
}
static __inline__ struct frag_queue *
-fq_find(struct net *net, __be32 id, const struct in6_addr *src, const struct in6_addr *dst)
+fq_find(struct net *net, __be32 id, const struct in6_addr *src,
+ const struct in6_addr *dst, int iif)
{
struct inet_frag_queue *q;
struct ip6_create_arg arg;
@@ -238,6 +242,7 @@ fq_find(struct net *net, __be32 id, const struct in6_addr *src, const struct in6
arg.user = IP6_DEFRAG_LOCAL_DELIVER;
arg.src = src;
arg.dst = dst;
+ arg.iif = iif;
read_lock(&ip6_frags.lock);
hash = inet6_hash_frag(id, src, dst, ip6_frags.rnd);
@@ -583,7 +588,8 @@ static int ipv6_frag_rcv(struct sk_buff *skb)
if (atomic_read(&net->ipv6.frags.mem) > net->ipv6.frags.high_thresh)
ip6_evictor(net, ip6_dst_idev(skb_dst(skb)));
- fq = fq_find(net, fhdr->identification, &hdr->saddr, &hdr->daddr);
+ fq = fq_find(net, fhdr->identification, &hdr->saddr, &hdr->daddr,
+ skb->dev ? skb->dev->ifindex : 0);
if (fq != NULL) {
int ret;
diff --git a/net/ipv6/syncookies.c b/net/ipv6/syncookies.c
index 5a0d664..cfc6284 100644
--- a/net/ipv6/syncookies.c
+++ b/net/ipv6/syncookies.c
@@ -238,7 +238,7 @@ struct sock *cookie_v6_check(struct sock *sk, struct sk_buff *skb)
memset(&fl6, 0, sizeof(fl6));
fl6.flowi6_proto = IPPROTO_TCP;
ipv6_addr_copy(&fl6.daddr, &ireq6->rmt_addr);
- final_p = fl6_update_dst(&fl6, np->opt, &final);
+ final_p = fl6_update_dst(&fl6, rcu_dereference(np->opt), &final);
ipv6_addr_copy(&fl6.saddr, &ireq6->loc_addr);
fl6.flowi6_oif = sk->sk_bound_dev_if;
fl6.flowi6_mark = sk->sk_mark;
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
index 655cc60..0170679 100644
--- a/net/ipv6/tcp_ipv6.c
+++ b/net/ipv6/tcp_ipv6.c
@@ -131,6 +131,7 @@ static int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr,
struct ipv6_pinfo *np = inet6_sk(sk);
struct tcp_sock *tp = tcp_sk(sk);
struct in6_addr *saddr = NULL, *final_p, final;
+ struct ipv6_txoptions *opt;
struct rt6_info *rt;
struct flowi6 fl6;
struct dst_entry *dst;
@@ -252,7 +253,8 @@ static int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr,
fl6.fl6_dport = usin->sin6_port;
fl6.fl6_sport = inet->inet_sport;
- final_p = fl6_update_dst(&fl6, np->opt, &final);
+ opt = rcu_dereference_protected(np->opt, sock_owned_by_user(sk));
+ final_p = fl6_update_dst(&fl6, opt, &final);
security_sk_classify_flow(sk, flowi6_to_flowi(&fl6));
@@ -295,9 +297,9 @@ static int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr,
}
icsk->icsk_ext_hdr_len = 0;
- if (np->opt)
- icsk->icsk_ext_hdr_len = (np->opt->opt_flen +
- np->opt->opt_nflen);
+ if (opt)
+ icsk->icsk_ext_hdr_len = opt->opt_flen +
+ opt->opt_nflen;
tp->rx_opt.mss_clamp = IPV6_MIN_MTU - sizeof(struct tcphdr) - sizeof(struct ipv6hdr);
@@ -481,7 +483,6 @@ static int tcp_v6_send_synack(struct sock *sk, struct request_sock *req,
struct inet6_request_sock *treq = inet6_rsk(req);
struct ipv6_pinfo *np = inet6_sk(sk);
struct sk_buff * skb;
- struct ipv6_txoptions *opt = NULL;
struct in6_addr * final_p, final;
struct flowi6 fl6;
struct dst_entry *dst;
@@ -498,8 +499,7 @@ static int tcp_v6_send_synack(struct sock *sk, struct request_sock *req,
fl6.fl6_sport = inet_rsk(req)->loc_port;
security_req_classify_flow(req, flowi6_to_flowi(&fl6));
- opt = np->opt;
- final_p = fl6_update_dst(&fl6, opt, &final);
+ final_p = fl6_update_dst(&fl6, rcu_dereference(np->opt), &final);
dst = ip6_dst_lookup_flow(sk, &fl6, final_p, false);
if (IS_ERR(dst)) {
@@ -513,13 +513,12 @@ static int tcp_v6_send_synack(struct sock *sk, struct request_sock *req,
__tcp_v6_send_check(skb, &treq->loc_addr, &treq->rmt_addr);
ipv6_addr_copy(&fl6.daddr, &treq->rmt_addr);
- err = ip6_xmit(sk, skb, &fl6, opt, np->tclass);
+ err = ip6_xmit(sk, skb, &fl6, rcu_dereference(np->opt),
+ np->tclass);
err = net_xmit_eval(err);
}
done:
- if (opt && opt != np->opt)
- sock_kfree_s(sk, opt, opt->tot_len);
dst_release(dst);
return err;
}
@@ -1408,7 +1407,6 @@ static struct sock * tcp_v6_syn_recv_sock(struct sock *sk, struct sk_buff *skb,
}
treq = inet6_rsk(req);
- opt = np->opt;
if (sk_acceptq_is_full(sk))
goto out_overflow;
@@ -1476,16 +1474,15 @@ static struct sock * tcp_v6_syn_recv_sock(struct sock *sk, struct sk_buff *skb,
but we make one more one thing there: reattach optmem
to newsk.
*/
+ opt = rcu_dereference(np->opt);
if (opt) {
- newnp->opt = ipv6_dup_options(newsk, opt);
- if (opt != np->opt)
- sock_kfree_s(sk, opt, opt->tot_len);
+ opt = ipv6_dup_options(newsk, opt);
+ RCU_INIT_POINTER(newnp->opt, opt);
}
-
- inet_csk(newsk)->icsk_ext_hdr_len = 0;
- if (newnp->opt)
- inet_csk(newsk)->icsk_ext_hdr_len = (newnp->opt->opt_nflen +
- newnp->opt->opt_flen);
+ inet_csk(newsk)->icsk_ext_hdr_len = 0;
+ if (opt)
+ inet_csk(newsk)->icsk_ext_hdr_len = opt->opt_nflen +
+ opt->opt_flen;
tcp_mtup_init(newsk);
tcp_sync_mss(newsk, dst_mtu(dst));
@@ -1530,8 +1527,6 @@ static struct sock * tcp_v6_syn_recv_sock(struct sock *sk, struct sk_buff *skb,
out_overflow:
NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_LISTENOVERFLOWS);
out_nonewsk:
- if (opt && opt != np->opt)
- sock_kfree_s(sk, opt, opt->tot_len);
dst_release(dst);
out:
NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_LISTENDROPS);
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c
index 888892e..3308803 100644
--- a/net/ipv6/udp.c
+++ b/net/ipv6/udp.c
@@ -954,6 +954,7 @@ int udpv6_sendmsg(struct kiocb *iocb, struct sock *sk,
struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *) msg->msg_name;
struct in6_addr *daddr, *final_p, final;
struct ipv6_txoptions *opt = NULL;
+ struct ipv6_txoptions *opt_to_free = NULL;
struct ip6_flowlabel *flowlabel = NULL;
struct flowi6 fl6;
struct dst_entry *dst;
@@ -1107,8 +1108,10 @@ do_udp_sendmsg:
opt = NULL;
connected = 0;
}
- if (opt == NULL)
- opt = np->opt;
+ if (!opt) {
+ opt = txopt_get(np);
+ opt_to_free = opt;
+ }
if (flowlabel)
opt = fl6_merge_options(&opt_space, flowlabel, opt);
opt = ipv6_fixup_options(&opt_space, opt);
@@ -1208,6 +1211,7 @@ do_append_data:
out:
dst_release(dst);
fl6_sock_release(flowlabel);
+ txopt_put(opt_to_free);
if (!err)
return len;
/*
diff --git a/net/irda/af_irda.c b/net/irda/af_irda.c
index f5d011a..03c8ea9 100644
--- a/net/irda/af_irda.c
+++ b/net/irda/af_irda.c
@@ -1106,6 +1106,9 @@ static int irda_create(struct net *net, struct socket *sock, int protocol,
IRDA_DEBUG(2, "%s()\n", __func__);
+ if (protocol < 0 || protocol > SK_PROTOCOL_MAX)
+ return -EINVAL;
+
if (net != &init_net)
return -EAFNOSUPPORT;
diff --git a/net/mac80211/mesh_pathtbl.c b/net/mac80211/mesh_pathtbl.c
index 7f54c50..806157d 100644
--- a/net/mac80211/mesh_pathtbl.c
+++ b/net/mac80211/mesh_pathtbl.c
@@ -779,10 +779,8 @@ void mesh_plink_broken(struct sta_info *sta)
static void mesh_path_node_reclaim(struct rcu_head *rp)
{
struct mpath_node *node = container_of(rp, struct mpath_node, rcu);
- struct ieee80211_sub_if_data *sdata = node->mpath->sdata;
del_timer_sync(&node->mpath->timer);
- atomic_dec(&sdata->u.mesh.mpaths);
kfree(node->mpath);
kfree(node);
}
@@ -790,8 +788,9 @@ static void mesh_path_node_reclaim(struct rcu_head *rp)
/* needs to be called with the corresponding hashwlock taken */
static void __mesh_path_del(struct mesh_table *tbl, struct mpath_node *node)
{
- struct mesh_path *mpath;
- mpath = node->mpath;
+ struct mesh_path *mpath = node->mpath;
+ struct ieee80211_sub_if_data *sdata = node->mpath->sdata;
+
spin_lock(&mpath->state_lock);
mpath->flags |= MESH_PATH_RESOLVING;
if (mpath->is_gate)
@@ -799,6 +798,7 @@ static void __mesh_path_del(struct mesh_table *tbl, struct mpath_node *node)
hlist_del_rcu(&node->list);
call_rcu(&node->rcu, mesh_path_node_reclaim);
spin_unlock(&mpath->state_lock);
+ atomic_dec(&sdata->u.mesh.mpaths);
atomic_dec(&tbl->entries);
}
diff --git a/net/rds/connection.c b/net/rds/connection.c
index be3eecd..9e07c75 100644
--- a/net/rds/connection.c
+++ b/net/rds/connection.c
@@ -178,12 +178,6 @@ static struct rds_connection *__rds_conn_create(__be32 laddr, __be32 faddr,
}
}
- if (trans == NULL) {
- kmem_cache_free(rds_conn_slab, conn);
- conn = ERR_PTR(-ENODEV);
- goto out;
- }
-
conn->c_trans = trans;
ret = trans->conn_alloc(conn, gfp);
diff --git a/net/rds/send.c b/net/rds/send.c
index 88eace5..31c9fa4 100644
--- a/net/rds/send.c
+++ b/net/rds/send.c
@@ -955,11 +955,13 @@ int rds_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg,
release_sock(sk);
}
- /* racing with another thread binding seems ok here */
+ lock_sock(sk);
if (daddr == 0 || rs->rs_bound_addr == 0) {
+ release_sock(sk);
ret = -ENOTCONN; /* XXX not a great errno */
goto out;
}
+ release_sock(sk);
/* size of rm including all sgs */
ret = rds_rm_size(msg, payload_len);
diff --git a/net/sctp/auth.c b/net/sctp/auth.c
index 53d455c..c428d9e 100644
--- a/net/sctp/auth.c
+++ b/net/sctp/auth.c
@@ -804,8 +804,8 @@ int sctp_auth_ep_set_hmacs(struct sctp_endpoint *ep,
if (!has_sha1)
return -EINVAL;
- memcpy(ep->auth_hmacs_list->hmac_ids, &hmacs->shmac_idents[0],
- hmacs->shmac_num_idents * sizeof(__u16));
+ for (i = 0; i < hmacs->shmac_num_idents; i++)
+ ep->auth_hmacs_list->hmac_ids[i] = htons(hmacs->shmac_idents[i]);
ep->auth_hmacs_list->param_hdr.length = htons(sizeof(sctp_paramhdr_t) +
hmacs->shmac_num_idents * sizeof(__u16));
return 0;
diff --git a/net/sctp/ipv6.c b/net/sctp/ipv6.c
index 0b6a391..1f9a6f7 100644
--- a/net/sctp/ipv6.c
+++ b/net/sctp/ipv6.c
@@ -635,6 +635,7 @@ static struct sock *sctp_v6_create_accept_sk(struct sock *sk,
struct sock *newsk;
struct ipv6_pinfo *newnp, *np = inet6_sk(sk);
struct sctp6_sock *newsctp6sk;
+ struct ipv6_txoptions *opt;
newsk = sk_alloc(sock_net(sk), PF_INET6, GFP_KERNEL, sk->sk_prot);
if (!newsk)
@@ -654,6 +655,13 @@ static struct sock *sctp_v6_create_accept_sk(struct sock *sk,
memcpy(newnp, np, sizeof(struct ipv6_pinfo));
+ rcu_read_lock();
+ opt = rcu_dereference(np->opt);
+ if (opt)
+ opt = ipv6_dup_options(newsk, opt);
+ RCU_INIT_POINTER(newnp->opt, opt);
+ rcu_read_unlock();
+
/* Initialize sk's sport, dport, rcv_saddr and daddr for getsockname()
* and getpeername().
*/
diff --git a/net/sctp/socket.c b/net/sctp/socket.c
index 24e88af..396283b 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -6731,6 +6731,9 @@ void sctp_copy_sock(struct sock *newsk, struct sock *sk,
newinet->mc_ttl = 1;
newinet->mc_index = 0;
newinet->mc_list = NULL;
+
+ if (newsk->sk_flags & SK_FLAGS_TIMESTAMP)
+ net_enable_timestamp();
}
static inline void sctp_copy_descendant(struct sock *sk_to,
@@ -6910,6 +6913,13 @@ struct proto sctp_prot = {
#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
+#include <net/transp_v6.h>
+static void sctp_v6_destroy_sock(struct sock *sk)
+{
+ sctp_destroy_sock(sk);
+ inet6_destroy_sock(sk);
+}
+
struct proto sctpv6_prot = {
.name = "SCTPv6",
.owner = THIS_MODULE,
@@ -6919,7 +6929,7 @@ struct proto sctpv6_prot = {
.accept = sctp_accept,
.ioctl = sctp_ioctl,
.init = sctp_init_sock,
- .destroy = sctp_destroy_sock,
+ .destroy = sctp_v6_destroy_sock,
.shutdown = sctp_shutdown,
.setsockopt = sctp_setsockopt,
.getsockopt = sctp_getsockopt,
diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c
index 9b1f371..e60fbcd 100644
--- a/net/unix/af_unix.c
+++ b/net/unix/af_unix.c
@@ -303,6 +303,118 @@ found:
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 inline int unix_writable(struct sock *sk)
{
return (atomic_read(&sk->sk_wmem_alloc) << 2) <= sk->sk_sndbuf;
@@ -409,6 +521,8 @@ static void unix_release_sock(struct sock *sk, int embrion)
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 */
unix_peer(sk) = NULL;
}
@@ -630,6 +744,7 @@ static struct sock *unix_create1(struct net *net, struct socket *sock)
INIT_LIST_HEAD(&u->link);
mutex_init(&u->readlock); /* single task reading 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);
out:
if (sk == NULL)
@@ -1005,6 +1120,8 @@ restart:
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)
@@ -1444,6 +1561,7 @@ static int unix_dgram_sendmsg(struct kiocb *kiocb, struct socket *sock,
long timeo;
struct scm_cookie tmp_scm;
int max_level;
+ int sk_locked;
if (NULL == siocb->scm)
siocb->scm = &tmp_scm;
@@ -1512,12 +1630,14 @@ restart:
goto out_free;
}
+ sk_locked = 0;
unix_state_lock(other);
+restart_locked:
err = -EPERM;
if (!unix_may_send(sk, other))
goto out_unlock;
- if (sock_flag(other, SOCK_DEAD)) {
+ if (unlikely(sock_flag(other, SOCK_DEAD))) {
/*
* Check with 1003.1g - what should
* datagram error
@@ -1525,10 +1645,14 @@ restart:
unix_state_unlock(other);
sock_put(other);
+ if (!sk_locked)
+ unix_state_lock(sk);
+
err = 0;
- unix_state_lock(sk);
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);
@@ -1554,21 +1678,38 @@ restart:
goto out_unlock;
}
- if (unix_peer(other) != sk && unix_recvq_full(other)) {
- if (!timeo) {
- err = -EAGAIN;
- goto out_unlock;
+ if (unlikely(unix_peer(other) != sk && unix_recvq_full(other))) {
+ if (timeo) {
+ timeo = unix_wait_for_peer(other, timeo);
+
+ err = sock_intr_errno(timeo);
+ if (signal_pending(current))
+ goto out_free;
+
+ goto restart;
}
- timeo = unix_wait_for_peer(other, timeo);
+ if (!sk_locked) {
+ unix_state_unlock(other);
+ unix_state_double_lock(sk, other);
+ }
- err = sock_intr_errno(timeo);
- if (signal_pending(current))
- goto out_free;
+ if (unix_peer(sk) != other ||
+ unix_dgram_peer_wake_me(sk, other)) {
+ err = -EAGAIN;
+ sk_locked = 1;
+ goto out_unlock;
+ }
- goto restart;
+ 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);
@@ -1582,6 +1723,8 @@ restart:
return len;
out_unlock:
+ if (sk_locked)
+ unix_state_unlock(sk);
unix_state_unlock(other);
out_free:
kfree_skb(skb);
@@ -1770,14 +1913,7 @@ static int unix_dgram_recvmsg(struct kiocb *iocb, struct socket *sock,
if (flags&MSG_OOB)
goto out;
- err = mutex_lock_interruptible(&u->readlock);
- if (unlikely(err)) {
- /* recvmsg() in non blocking mode is supposed to return -EAGAIN
- * sk_rcvtimeo is not honored by mutex_lock_interruptible()
- */
- err = noblock ? -EAGAIN : -ERESTARTSYS;
- goto out;
- }
+ mutex_lock(&u->readlock);
skb = skb_recv_datagram(sk, flags, noblock, &err);
if (!skb) {
@@ -1962,12 +2098,12 @@ static int unix_stream_recvmsg(struct kiocb *iocb, struct socket *sock,
timeo = unix_stream_data_wait(sk, timeo);
- if (signal_pending(current)
- || mutex_lock_interruptible(&u->readlock)) {
+ if (signal_pending(current)) {
err = sock_intr_errno(timeo);
goto out;
}
+ mutex_lock(&u->readlock);
continue;
unlock:
unix_state_unlock(sk);
@@ -2186,14 +2322,16 @@ static unsigned int unix_dgram_poll(struct file *file, struct socket *sock,
return mask;
writable = unix_writable(sk);
- other = unix_peer_get(sk);
- if (other) {
- if (unix_peer(other) != sk) {
- sock_poll_wait(file, &unix_sk(other)->peer_wait, wait);
- if (unix_recvq_full(other))
- writable = 0;
- }
- sock_put(other);
+ if (writable) {
+ unix_state_lock(sk);
+
+ other = unix_peer(sk);
+ if (other && unix_peer(other) != sk &&
+ unix_recvq_full(other) &&
+ unix_dgram_peer_wake_me(sk, other))
+ writable = 0;
+
+ unix_state_unlock(sk);
}
if (writable)
diff --git a/net/unix/garbage.c b/net/unix/garbage.c
index b6f4b99..00d3e56 100644
--- a/net/unix/garbage.c
+++ b/net/unix/garbage.c
@@ -185,7 +185,7 @@ static void scan_inflight(struct sock *x, void (*func)(struct unix_sock *),
* have been added to the queues after
* starting the garbage collection
*/
- if (u->gc_candidate) {
+ if (test_bit(UNIX_GC_CANDIDATE, &u->gc_flags)) {
hit = true;
func(u);
}
@@ -254,7 +254,7 @@ static void inc_inflight_move_tail(struct unix_sock *u)
* of the list, so that it's checked even if it was already
* passed over
*/
- if (u->gc_maybe_cycle)
+ if (test_bit(UNIX_GC_MAYBE_CYCLE, &u->gc_flags))
list_move_tail(&u->link, &gc_candidates);
}
@@ -315,8 +315,8 @@ void unix_gc(void)
BUG_ON(total_refs < inflight_refs);
if (total_refs == inflight_refs) {
list_move_tail(&u->link, &gc_candidates);
- u->gc_candidate = 1;
- u->gc_maybe_cycle = 1;
+ __set_bit(UNIX_GC_CANDIDATE, &u->gc_flags);
+ __set_bit(UNIX_GC_MAYBE_CYCLE, &u->gc_flags);
}
}
@@ -344,7 +344,7 @@ void unix_gc(void)
if (atomic_long_read(&u->inflight) > 0) {
list_move_tail(&u->link, ¬_cycle_list);
- u->gc_maybe_cycle = 0;
+ __clear_bit(UNIX_GC_MAYBE_CYCLE, &u->gc_flags);
scan_children(&u->sk, inc_inflight_move_tail, NULL);
}
}
@@ -356,7 +356,7 @@ void unix_gc(void)
*/
while (!list_empty(¬_cycle_list)) {
u = list_entry(not_cycle_list.next, struct unix_sock, link);
- u->gc_candidate = 0;
+ __clear_bit(UNIX_GC_CANDIDATE, &u->gc_flags);
list_move_tail(&u->link, &gc_inflight_list);
}
diff --git a/sound/pci/rme96.c b/sound/pci/rme96.c
index 4585c97..3240ee7 100644
--- a/sound/pci/rme96.c
+++ b/sound/pci/rme96.c
@@ -704,10 +704,11 @@ snd_rme96_playback_setrate(struct rme96 *rme96,
{
/* change to/from double-speed: reset the DAC (if available) */
snd_rme96_reset_dac(rme96);
+ return 1; /* need to restore volume */
} else {
writel(rme96->wcreg, rme96->iobase + RME96_IO_CONTROL_REGISTER);
+ return 0;
}
- return 0;
}
static int
@@ -945,6 +946,7 @@ snd_rme96_playback_hw_params(struct snd_pcm_substream *substream,
struct rme96 *rme96 = snd_pcm_substream_chip(substream);
struct snd_pcm_runtime *runtime = substream->runtime;
int err, rate, dummy;
+ bool apply_dac_volume = false;
runtime->dma_area = (void __force *)(rme96->iobase +
RME96_IO_PLAY_BUFFER);
@@ -958,24 +960,26 @@ snd_rme96_playback_hw_params(struct snd_pcm_substream *substream,
{
/* slave clock */
if ((int)params_rate(params) != rate) {
- spin_unlock_irq(&rme96->lock);
- return -EIO;
- }
- } else if ((err = snd_rme96_playback_setrate(rme96, params_rate(params))) < 0) {
- spin_unlock_irq(&rme96->lock);
- return err;
- }
- if ((err = snd_rme96_playback_setformat(rme96, params_format(params))) < 0) {
- spin_unlock_irq(&rme96->lock);
- return err;
+ err = -EIO;
+ goto error;
+ }
+ } else {
+ err = snd_rme96_playback_setrate(rme96, params_rate(params));
+ if (err < 0)
+ goto error;
+ apply_dac_volume = err > 0; /* need to restore volume later? */
}
+
+ err = snd_rme96_playback_setformat(rme96, params_format(params));
+ if (err < 0)
+ goto error;
snd_rme96_setframelog(rme96, params_channels(params), 1);
if (rme96->capture_periodsize != 0) {
if (params_period_size(params) << rme96->playback_frlog !=
rme96->capture_periodsize)
{
- spin_unlock_irq(&rme96->lock);
- return -EBUSY;
+ err = -EBUSY;
+ goto error;
}
}
rme96->playback_periodsize =
@@ -986,9 +990,16 @@ snd_rme96_playback_hw_params(struct snd_pcm_substream *substream,
rme96->wcreg &= ~(RME96_WCR_PRO | RME96_WCR_DOLBY | RME96_WCR_EMP);
writel(rme96->wcreg |= rme96->wcreg_spdif_stream, rme96->iobase + RME96_IO_CONTROL_REGISTER);
}
+
+ err = 0;
+ error:
spin_unlock_irq(&rme96->lock);
-
- return 0;
+ if (apply_dac_volume) {
+ usleep_range(3000, 10000);
+ snd_rme96_apply_dac_volume(rme96);
+ }
+
+ return err;
}
static int
diff --git a/sound/soc/codecs/wm8962.c b/sound/soc/codecs/wm8962.c
index 8b687da..c79bd83 100644
--- a/sound/soc/codecs/wm8962.c
+++ b/sound/soc/codecs/wm8962.c
@@ -373,8 +373,8 @@ static const u16 wm8962_reg[WM8962_MAX_REGISTER + 1] = {
[16924] = 0x0059, /* R16924 - HDBASS_PG_1 */
[16925] = 0x999A, /* R16925 - HDBASS_PG_0 */
- [17048] = 0x0083, /* R17408 - HPF_C_1 */
- [17049] = 0x98AD, /* R17409 - HPF_C_0 */
+ [17408] = 0x0083, /* R17408 - HPF_C_1 */
+ [17409] = 0x98AD, /* R17409 - HPF_C_0 */
[17920] = 0x007F, /* R17920 - ADCL_RETUNE_C1_1 */
[17921] = 0xFFFF, /* R17921 - ADCL_RETUNE_C1_0 */
diff --git a/sound/usb/midi.c b/sound/usb/midi.c
index de86e74..075f324 100644
--- a/sound/usb/midi.c
+++ b/sound/usb/midi.c
@@ -174,6 +174,8 @@ struct snd_usb_midi_in_endpoint {
u8 running_status_length;
} ports[0x10];
u8 seen_f5;
+ bool in_sysex;
+ u8 last_cin;
u8 error_resubmit;
int current_port;
};
@@ -465,6 +467,39 @@ static void snd_usbmidi_maudio_broken_running_status_input(
}
/*
+ * QinHeng CH345 is buggy: every second packet inside a SysEx has not CIN 4
+ * but the previously seen CIN, but still with three data bytes.
+ */
+static void ch345_broken_sysex_input(struct snd_usb_midi_in_endpoint *ep,
+ uint8_t *buffer, int buffer_length)
+{
+ unsigned int i, cin, length;
+
+ for (i = 0; i + 3 < buffer_length; i += 4) {
+ if (buffer[i] == 0 && i > 0)
+ break;
+ cin = buffer[i] & 0x0f;
+ if (ep->in_sysex &&
+ cin == ep->last_cin &&
+ (buffer[i + 1 + (cin == 0x6)] & 0x80) == 0)
+ cin = 0x4;
+#if 0
+ if (buffer[i + 1] == 0x90) {
+ /*
+ * Either a corrupted running status or a real note-on
+ * message; impossible to detect reliably.
+ */
+ }
+#endif
+ length = snd_usbmidi_cin_length[cin];
+ snd_usbmidi_input_data(ep, 0, &buffer[i + 1], length);
+ ep->in_sysex = cin == 0x4;
+ if (!ep->in_sysex)
+ ep->last_cin = cin;
+ }
+}
+
+/*
* CME protocol: like the standard protocol, but SysEx commands are sent as a
* single USB packet preceded by a 0x0F byte.
*/
@@ -650,6 +685,12 @@ static struct usb_protocol_ops snd_usbmidi_cme_ops = {
.output_packet = snd_usbmidi_output_standard_packet,
};
+static struct usb_protocol_ops snd_usbmidi_ch345_broken_sysex_ops = {
+ .input = ch345_broken_sysex_input,
+ .output = snd_usbmidi_standard_output,
+ .output_packet = snd_usbmidi_output_standard_packet,
+};
+
/*
* AKAI MPD16 protocol:
*
@@ -1326,6 +1367,7 @@ static int snd_usbmidi_out_endpoint_create(struct snd_usb_midi* umidi,
* Various chips declare a packet size larger than 4 bytes, but
* do not actually work with larger packets:
*/
+ case USB_ID(0x0a67, 0x5011): /* Medeli DD305 */
case USB_ID(0x0a92, 0x1020): /* ESI M4U */
case USB_ID(0x1430, 0x474b): /* RedOctane GH MIDI INTERFACE */
case USB_ID(0x15ca, 0x0101): /* Textech USB Midi Cable */
@@ -2214,6 +2256,10 @@ int snd_usbmidi_create(struct snd_card *card,
err = snd_usbmidi_detect_per_port_endpoints(umidi, endpoints);
break;
+ case QUIRK_MIDI_CH345:
+ umidi->usb_protocol_ops = &snd_usbmidi_ch345_broken_sysex_ops;
+ err = snd_usbmidi_detect_per_port_endpoints(umidi, endpoints);
+ break;
default:
snd_printd(KERN_ERR "invalid quirk type %d\n", quirk->type);
err = -ENXIO;
diff --git a/sound/usb/quirks-table.h b/sound/usb/quirks-table.h
index c014f00..0f18c75 100644
--- a/sound/usb/quirks-table.h
+++ b/sound/usb/quirks-table.h
@@ -2611,6 +2611,17 @@ YAMAHA_DEVICE(0x7010, "UB99"),
.idProduct = 0x1020,
},
+/* QinHeng devices */
+{
+ USB_DEVICE(0x1a86, 0x752d),
+ .driver_info = (unsigned long) &(const struct snd_usb_audio_quirk) {
+ .vendor_name = "QinHeng",
+ .product_name = "CH345",
+ .ifnum = 1,
+ .type = QUIRK_MIDI_CH345
+ }
+},
+
/* KeithMcMillen Stringport */
{
USB_DEVICE(0x1f38, 0x0001),
diff --git a/sound/usb/quirks.c b/sound/usb/quirks.c
index 9c82f8b..b01d3cf 100644
--- a/sound/usb/quirks.c
+++ b/sound/usb/quirks.c
@@ -311,6 +311,7 @@ int snd_usb_create_quirk(struct snd_usb_audio *chip,
[QUIRK_MIDI_CME] = create_any_midi_quirk,
[QUIRK_MIDI_AKAI] = create_any_midi_quirk,
[QUIRK_MIDI_FTDI] = create_any_midi_quirk,
+ [QUIRK_MIDI_CH345] = create_any_midi_quirk,
[QUIRK_AUDIO_STANDARD_INTERFACE] = create_standard_audio_quirk,
[QUIRK_AUDIO_FIXED_ENDPOINT] = create_fixed_stream_quirk,
[QUIRK_AUDIO_EDIROL_UAXX] = create_uaxx_quirk,
diff --git a/sound/usb/usbaudio.h b/sound/usb/usbaudio.h
index 6c805a5..5e0e58a 100644
--- a/sound/usb/usbaudio.h
+++ b/sound/usb/usbaudio.h
@@ -81,6 +81,7 @@ enum quirk_type {
QUIRK_MIDI_AKAI,
QUIRK_MIDI_US122L,
QUIRK_MIDI_FTDI,
+ QUIRK_MIDI_CH345,
QUIRK_AUDIO_STANDARD_INTERFACE,
QUIRK_AUDIO_FIXED_ENDPOINT,
QUIRK_AUDIO_EDIROL_UAXX,
[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 811 bytes --]
^ permalink raw reply related [flat|nested] 84+ messages in thread
* Re: [PATCH 3.2 33/77] ext4: Fix handling of extended tv_sec
2015-12-24 15:37 ` [PATCH 3.2 33/77] ext4: Fix handling of extended tv_sec Ben Hutchings
@ 2015-12-24 21:21 ` David Turner
0 siblings, 0 replies; 84+ messages in thread
From: David Turner @ 2015-12-24 21:21 UTC (permalink / raw)
To: Ben Hutchings, linux-kernel, stable; +Cc: akpm, Theodore Ts'o, Mark Harris
LGTM.
On Thu, 2015-12-24 at 15:37 +0000, Ben Hutchings wrote:
> 3.2.75-rc1 review patch. If anyone has any objections, please let me
> know.
>
> ------------------
>
> From: David Turner <novalis@novalis.org>
>
> commit a4dad1ae24f850410c4e60f22823cba1289b8d52 upstream.
>
> In ext4, the bottom two bits of {a,c,m}time_extra are used to extend
> the {a,c,m}time fields, deferring the year 2038 problem to the year
> 2446.
>
> When decoding these extended fields, for times whose bottom 32 bits
> would represent a negative number, sign extension causes the 64-bit
> extended timestamp to be negative as well, which is not what's
> intended. This patch corrects that issue, so that the only negative
> {a,c,m}times are those between 1901 and 1970 (as per 32-bit signed
> timestamps).
>
> Some older kernels might have written pre-1970 dates with 1,1 in the
> extra bits. This patch treats those incorrectly-encoded dates as
> pre-1970, instead of post-2311, until kernel 4.20 is released.
> Hopefully by then e2fsck will have fixed up the bad data.
>
> Also add a comment explaining the encoding of ext4's extra
> {a,c,m}time
> bits.
>
> Signed-off-by: David Turner <novalis@novalis.org>
> Signed-off-by: Theodore Ts'o <tytso@mit.edu>
> Reported-by: Mark Harris <mh8928@yahoo.com>
> Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=23732
> Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
> ---
> fs/ext4/ext4.h | 51 ++++++++++++++++++++++++++++++++++++++++++++----
> ---
> 1 file changed, 44 insertions(+), 7 deletions(-)
>
> --- a/fs/ext4/ext4.h
> +++ b/fs/ext4/ext4.h
> @@ -26,6 +26,7 @@
> #include <linux/seqlock.h>
> #include <linux/mutex.h>
> #include <linux/timer.h>
> +#include <linux/version.h>
> #include <linux/wait.h>
> #include <linux/blockgroup_lock.h>
> #include <linux/percpu_counter.h>
> @@ -698,19 +699,55 @@ struct move_extent {
> <= (EXT4_GOOD_OLD_INODE_SIZE + \
> (einode)->i_extra_isize)) \
>
> +/*
> + * We use an encoding that preserves the times for extra epoch "00":
> + *
> + * extra msb of adjust for signed
> + * epoch 32-bit 32-bit tv_sec to
> + * bits time decoded 64-bit tv_sec 64-bit tv_sec valid
> time range
> + * 0 0 1 -0x80000000..-0x00000001 0x000000000 1901-12
> -13..1969-12-31
> + * 0 0 0 0x000000000..0x07fffffff 0x000000000 1970-01
> -01..2038-01-19
> + * 0 1 1 0x080000000..0x0ffffffff 0x100000000 2038-01
> -19..2106-02-07
> + * 0 1 0 0x100000000..0x17fffffff 0x100000000 2106-02
> -07..2174-02-25
> + * 1 0 1 0x180000000..0x1ffffffff 0x200000000 2174-02
> -25..2242-03-16
> + * 1 0 0 0x200000000..0x27fffffff 0x200000000 2242-03
> -16..2310-04-04
> + * 1 1 1 0x280000000..0x2ffffffff 0x300000000 2310-04
> -04..2378-04-22
> + * 1 1 0 0x300000000..0x37fffffff 0x300000000 2378-04
> -22..2446-05-10
> + *
> + * Note that previous versions of the kernel on 64-bit systems would
> + * incorrectly use extra epoch bits 1,1 for dates between 1901 and
> + * 1970. e2fsck will correct this, assuming that it is run on the
> + * affected filesystem before 2242.
> + */
> +
> static inline __le32 ext4_encode_extra_time(struct timespec *time)
> {
> - return cpu_to_le32((sizeof(time->tv_sec) > 4 ?
> - (time->tv_sec >> 32) & EXT4_EPOCH_MASK :
> 0) |
> - ((time->tv_nsec << EXT4_EPOCH_BITS) &
> EXT4_NSEC_MASK));
> + u32 extra = sizeof(time->tv_sec) > 4 ?
> + ((time->tv_sec - (s32)time->tv_sec) >> 32) &
> EXT4_EPOCH_MASK : 0;
> + return cpu_to_le32(extra | (time->tv_nsec <<
> EXT4_EPOCH_BITS));
> }
>
> static inline void ext4_decode_extra_time(struct timespec *time,
> __le32 extra)
> {
> - if (sizeof(time->tv_sec) > 4)
> - time->tv_sec |= (__u64)(le32_to_cpu(extra) &
> EXT4_EPOCH_MASK)
> - << 32;
> - time->tv_nsec = (le32_to_cpu(extra) & EXT4_NSEC_MASK) >>
> EXT4_EPOCH_BITS;
> + if (unlikely(sizeof(time->tv_sec) > 4 &&
> + (extra & cpu_to_le32(EXT4_EPOCH_MASK)))) {
> +#if LINUX_VERSION_CODE < KERNEL_VERSION(4,20,0)
> + /* Handle legacy encoding of pre-1970 dates with
> epoch
> + * bits 1,1. We assume that by kernel version 4.20,
> + * everyone will have run fsck over the affected
> + * filesystems to correct the problem. (This
> + * backwards compatibility may be removed before
> this
> + * time, at the discretion of the ext4 developers.)
> + */
> + u64 extra_bits = le32_to_cpu(extra) &
> EXT4_EPOCH_MASK;
> + if (extra_bits == 3 && ((time->tv_sec) & 0x80000000)
> != 0)
> + extra_bits = 0;
> + time->tv_sec += extra_bits << 32;
> +#else
> + time->tv_sec += (u64)(le32_to_cpu(extra) &
> EXT4_EPOCH_MASK) << 32;
> +#endif
> + }
> + time->tv_nsec = (le32_to_cpu(extra) & EXT4_NSEC_MASK) >>
> EXT4_EPOCH_BITS;
> }
>
> #define EXT4_INODE_SET_XTIME(xtime, inode, raw_inode)
> \
>
^ permalink raw reply [flat|nested] 84+ messages in thread
* Re: [PATCH 3.2 00/77] 3.2.75-rc1 review
2015-12-24 15:37 [PATCH 3.2 00/77] 3.2.75-rc1 review Ben Hutchings
` (77 preceding siblings ...)
2015-12-24 16:40 ` [PATCH 3.2 00/77] 3.2.75-rc1 review Ben Hutchings
@ 2015-12-24 22:20 ` Guenter Roeck
2015-12-24 22:31 ` Ben Hutchings
78 siblings, 1 reply; 84+ messages in thread
From: Guenter Roeck @ 2015-12-24 22:20 UTC (permalink / raw)
To: Ben Hutchings, linux-kernel, stable; +Cc: torvalds, Phil Jensen, akpm
On 12/24/2015 07:37 AM, Ben Hutchings wrote:
> This is the start of the stable review cycle for the 3.2.75 release.
> There are 77 patches in this series, which will be posted as responses
> to this one. If anyone has any issues with these being applied, please
> let me know.
>
> Responses should be made by Tue Dec 29 18:00:00 UTC 2015.
> Anything received after that time might be too late.
>
Build results:
total: 92 pass: 92 fail: 0
Qemu test results:
total: 58 pass: 58 fail: 0
Details are available at http://server.roeck-us.net:8010/builders.
Guenter
^ permalink raw reply [flat|nested] 84+ messages in thread
* Re: [PATCH 3.2 00/77] 3.2.75-rc1 review
2015-12-24 22:20 ` Guenter Roeck
@ 2015-12-24 22:31 ` Ben Hutchings
0 siblings, 0 replies; 84+ messages in thread
From: Ben Hutchings @ 2015-12-24 22:31 UTC (permalink / raw)
To: Guenter Roeck, linux-kernel, stable; +Cc: torvalds, Phil Jensen, akpm
[-- Attachment #1: Type: text/plain, Size: 805 bytes --]
On Thu, 2015-12-24 at 14:20 -0800, Guenter Roeck wrote:
> On 12/24/2015 07:37 AM, Ben Hutchings wrote:
> > This is the start of the stable review cycle for the 3.2.75
> > release.
> > There are 77 patches in this series, which will be posted as
> > responses
> > to this one. If anyone has any issues with these being applied,
> > please
> > let me know.
> >
> > Responses should be made by Tue Dec 29 18:00:00 UTC 2015.
> > Anything received after that time might be too late.
> >
>
> Build results:
> total: 92 pass: 92 fail: 0
> Qemu test results:
> total: 58 pass: 58 fail: 0
>
> Details are available at http://server.roeck-us.net:8010/builders.
Thanks for checking.
Ben.
--
Ben Hutchings
If the facts do not conform to your theory, they must be disposed of.
[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 811 bytes --]
^ permalink raw reply [flat|nested] 84+ messages in thread
* Re: [PATCH 3.2 46/77] drm: Fix an unwanted master inheritance v2
2015-12-24 15:37 ` [PATCH 3.2 46/77] drm: Fix an unwanted master inheritance v2 Ben Hutchings
@ 2015-12-25 14:13 ` Thomas Hellstrom
2015-12-26 4:31 ` Ben Hutchings
0 siblings, 1 reply; 84+ messages in thread
From: Thomas Hellstrom @ 2015-12-25 14:13 UTC (permalink / raw)
To: Ben Hutchings, linux-kernel, stable; +Cc: akpm, Dave Airlie
On 12/24/2015 04:37 PM, Ben Hutchings wrote:
> 3.2.75-rc1 review patch. If anyone has any objections, please let me know.
>
> ------------------
>
> From: Thomas Hellstrom <thellstrom@vmware.com>
>
> commit a0af2e538c80f3e47f1d6ddf120a153ad909e8ad upstream.
>
> A client calling drmSetMaster() using a file descriptor that was opened
> when another client was master would inherit the latter client's master
> object and all its authenticated clients.
>
> This is unwanted behaviour, and when this happens, instead allocate a
> brand new master object for the client calling drmSetMaster().
>
> Fixes a BUG() throw in vmw_master_set().
>
> Signed-off-by: Thomas Hellstrom <thellstrom@vmware.com>
> Signed-off-by: Dave Airlie <airlied@redhat.com>
> [bwh: Backported to 3.2:
> - s/master_mutex/struct_mutex/
> - drm_new_set_master() must drop struct_mutex while calling
> drm_driver::master_create
> - Adjust filename, context, indentation]
> Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
> ---
> --- a/drivers/gpu/drm/drm_stub.c
> +++ b/drivers/gpu/drm/drm_stub.c
> @@ -225,6 +225,10 @@ int drm_setmaster_ioctl(struct drm_devic
> if (!file_priv->minor->master &&
> file_priv->minor->master != file_priv->master) {
> mutex_lock(&dev->struct_mutex);
> + if (!file_priv->allowed_master) {
> + ret = drm_new_set_master(dev, file_priv);
> + goto out_unlock;
> + }
> file_priv->minor->master = drm_master_get(file_priv->master);
> file_priv->is_master = 1;
> if (dev->driver->master_set) {
> @@ -234,10 +238,11 @@ int drm_setmaster_ioctl(struct drm_devic
> drm_master_put(&file_priv->minor->master);
> }
> }
> + out_unlock:
> mutex_unlock(&dev->struct_mutex);
> }
>
> - return 0;
> + return ret;
> }
>
> int drm_dropmaster_ioctl(struct drm_device *dev, void *data,
> --- a/drivers/gpu/drm/drm_fops.c
> +++ b/drivers/gpu/drm/drm_fops.c
> @@ -219,6 +219,62 @@ static int drm_cpu_valid(void)
> }
>
> /**
> + * drm_new_set_master - Allocate a new master object and become master for the
> + * associated master realm.
> + *
> + * @dev: The associated device.
> + * @fpriv: File private identifying the client.
> + *
> + * This function must be called with dev::struct_mutex held.
> + * Returns negative error code on failure. Zero on success.
> + */
> +int drm_new_set_master(struct drm_device *dev, struct drm_file *fpriv)
> +{
> + struct drm_master *old_master;
> + int ret;
> +
> + lockdep_assert_held_once(&dev->struct_mutex);
> +
Is lockdep_assert_held_once() backported into the 3.2 series? If not,
this line could probably be replaced by lockdep_assert_held() for stable
kernels or removed entirely.
Thanks,
Thomas
^ permalink raw reply [flat|nested] 84+ messages in thread
* Re: [PATCH 3.2 46/77] drm: Fix an unwanted master inheritance v2
2015-12-25 14:13 ` Thomas Hellstrom
@ 2015-12-26 4:31 ` Ben Hutchings
0 siblings, 0 replies; 84+ messages in thread
From: Ben Hutchings @ 2015-12-26 4:31 UTC (permalink / raw)
To: Thomas Hellstrom, linux-kernel, stable; +Cc: akpm, Dave Airlie
[-- Attachment #1: Type: text/plain, Size: 1280 bytes --]
On Fri, 2015-12-25 at 15:13 +0100, Thomas Hellstrom wrote:
> On 12/24/2015 04:37 PM, Ben Hutchings wrote:
> > 3.2.75-rc1 review patch. If anyone has any objections, please let me know.
> >
> > ------------------
> >
> > From: Thomas Hellstrom <thellstrom@vmware.com>
> >
> > commit a0af2e538c80f3e47f1d6ddf120a153ad909e8ad upstream.
[...]
> > /**
> > + * drm_new_set_master - Allocate a new master object and become master for the
> > + * associated master realm.
> > + *
> > + * @dev: The associated device.
> > + * @fpriv: File private identifying the client.
> > + *
> > + * This function must be called with dev::struct_mutex held.
> > + * Returns negative error code on failure. Zero on success.
> > + */
> > +int drm_new_set_master(struct drm_device *dev, struct drm_file *fpriv)
> > +{
> > + struct drm_master *old_master;
> > + int ret;
> > +
> > + lockdep_assert_held_once(&dev->struct_mutex);
> > +
>
> Is lockdep_assert_held_once() backported into the 3.2 series?
Patch 45/77 in this series adds it.
Ben.
> If not,
> this line could probably be replaced by lockdep_assert_held() for stable
> kernels or removed entirely.
--
Ben Hutchings
I say we take off; nuke the site from orbit. It's the only way to be sure.
[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 811 bytes --]
^ permalink raw reply [flat|nested] 84+ messages in thread
end of thread, other threads:[~2015-12-26 4:31 UTC | newest]
Thread overview: 84+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-12-24 15:37 [PATCH 3.2 00/77] 3.2.75-rc1 review Ben Hutchings
2015-12-24 15:37 ` [PATCH 3.2 42/77] usb: Use the USB_SS_MULT() macro to decode burst multiplier for log message Ben Hutchings
2015-12-24 15:37 ` [PATCH 3.2 50/77] ALSA: rme96: Fix unexpected volume reset after rate changes Ben Hutchings
2015-12-24 15:37 ` [PATCH 3.2 07/77] USB: serial: ti_usb_3410_5052: add Abbott strip port ID to combined table as well Ben Hutchings
2015-12-24 15:37 ` [PATCH 3.2 23/77] can: sja1000: clear interrupts on start Ben Hutchings
2015-12-24 15:37 ` [PATCH 3.2 71/77] sh_eth: fix kernel oops in skb_put() Ben Hutchings
2015-12-24 15:37 ` [PATCH 3.2 27/77] unix: avoid use-after-free in ep_remove_wait_queue Ben Hutchings
2015-12-24 15:37 ` [PATCH 3.2 25/77] USB: cdc-acm - Add IGNORE_DEVICE quirk Ben Hutchings
2015-12-24 15:37 ` [PATCH 3.2 40/77] wan/x25: Fix use-after-free in x25_asy_open_tty() Ben Hutchings
2015-12-24 15:37 ` [PATCH 3.2 02/77] sctp: translate host order to network order when setting a hmacid Ben Hutchings
2015-12-24 15:37 ` [PATCH 3.2 17/77] xhci: Workaround to get Intel xHCI reset working more reliably Ben Hutchings
2015-12-24 15:37 ` [PATCH 3.2 68/77] sctp: update the netstamp_needed counter when copying sockets Ben Hutchings
2015-12-24 15:37 ` [PATCH 3.2 51/77] 9p: ->evict_inode() should kick out ->i_data, not ->i_mapping Ben Hutchings
2015-12-24 15:37 ` [PATCH 3.2 43/77] dm btree: fix leak of bufio-backed block in btree_split_sibling error path Ben Hutchings
2015-12-24 15:37 ` [PATCH 3.2 47/77] sched/core: Remove false-positive warning from wake_up_process() Ben Hutchings
2015-12-24 15:37 ` [PATCH 3.2 56/77] mm, vmstat: allow WQ concurrency to discover memory reclaim doesn't make any progress Ben Hutchings
2015-12-24 15:37 ` [PATCH 3.2 45/77] locking: Add WARN_ON_ONCE lock assertion Ben Hutchings
2015-12-24 15:37 ` [PATCH 3.2 61/77] net, scm: fix PaX detected msg_controllen overflow in scm_detach_fds Ben Hutchings
2015-12-24 15:37 ` [PATCH 3.2 38/77] AHCI: Fix softreset failed issue of Port Multiplier Ben Hutchings
2015-12-24 15:37 ` [PATCH 3.2 15/77] macvlan: fix leak in macvlan_handle_frame Ben Hutchings
2015-12-24 15:37 ` [PATCH 3.2 66/77] ipv6: sctp: implement sctp_v6_destroy_sock() Ben Hutchings
2015-12-24 15:37 ` [PATCH 3.2 10/77] usb: musb: core: fix order of arguments to ulpi write callback Ben Hutchings
2015-12-24 15:37 ` [PATCH 3.2 31/77] broadcom: fix PHY_ID_BCM5481 entry in the id table Ben Hutchings
2015-12-24 15:37 ` [PATCH 3.2 19/77] usblp: do not set TASK_INTERRUPTIBLE before lock Ben Hutchings
2015-12-24 15:37 ` [PATCH 3.2 52/77] ipmi: move timer init to before irq is setup Ben Hutchings
2015-12-24 15:37 ` [PATCH 3.2 75/77] af_unix: fix a fatal race with bit fields Ben Hutchings
2015-12-24 15:37 ` [PATCH 3.2 57/77] mm: hugetlb: call huge_pte_alloc() only if ptep is null Ben Hutchings
2015-12-24 15:37 ` [PATCH 3.2 22/77] net: ip6mr: fix static mfc/dev leaks on table destruction Ben Hutchings
2015-12-24 15:37 ` [PATCH 3.2 60/77] tcp: initialize tp->copied_seq in case of cross SYN connection Ben Hutchings
2015-12-24 15:37 ` [PATCH 3.2 12/77] net: fix __netdev_update_features return on ndo_set_features failure Ben Hutchings
2015-12-24 15:37 ` [PATCH 3.2 36/77] nfs: if we have no valid attrs, then don't declare the attribute cache valid Ben Hutchings
2015-12-24 15:37 ` [PATCH 3.2 13/77] FS-Cache: Add missing initialization of ret in cachefiles_write_page() Ben Hutchings
2015-12-24 15:37 ` [PATCH 3.2 03/77] ALSA: usb-audio: add packet size quirk for the Medeli DD305 Ben Hutchings
2015-12-24 15:37 ` [PATCH 3.2 26/77] USB: cdc_acm: Ignore Infineon Flash Loader utility Ben Hutchings
2015-12-24 15:37 ` [PATCH 3.2 06/77] USB: serial: option: add support for Novatel MiFi USB620L Ben Hutchings
2015-12-24 15:37 ` [PATCH 3.2 59/77] snmp: Remove duplicate OUTMCAST stat increment Ben Hutchings
2015-12-24 15:37 ` [PATCH 3.2 24/77] USB: cp210x: Remove CP2110 ID from compatibility list Ben Hutchings
2015-12-24 15:37 ` [PATCH 3.2 77/77] ppp, slip: Validate VJ compression slot parameters completely Ben Hutchings
2015-12-24 15:37 ` [PATCH 3.2 32/77] ring-buffer: Update read stamp with first real commit on page Ben Hutchings
2015-12-24 15:37 ` [PATCH 3.2 33/77] ext4: Fix handling of extended tv_sec Ben Hutchings
2015-12-24 21:21 ` David Turner
2015-12-24 15:37 ` [PATCH 3.2 72/77] pptp: verify sockaddr_len in pptp_bind() and pptp_connect() Ben Hutchings
2015-12-24 15:37 ` [PATCH 3.2 39/77] sata_sil: disable trim Ben Hutchings
2015-12-24 15:37 ` [PATCH 3.2 70/77] net: add validation for the socket syscall protocol argument Ben Hutchings
2015-12-24 15:37 ` [PATCH 3.2 65/77] ipv6: add complete rcu protection around np->opt Ben Hutchings
2015-12-24 15:37 ` [PATCH 3.2 63/77] ipv6: distinguish frag queues by device for multicast and link-local packets Ben Hutchings
2015-12-24 15:37 ` [PATCH 3.2 64/77] dccp: remove unnecessary codes in ipv6.c Ben Hutchings
2015-12-24 15:37 ` [PATCH 3.2 41/77] USB: whci-hcd: add check for dma mapping error Ben Hutchings
2015-12-24 15:37 ` [PATCH 3.2 21/77] ip6mr: call del_timer_sync() in ip6mr_free_table() Ben Hutchings
2015-12-24 15:37 ` [PATCH 3.2 54/77] vgaarb: fix signal handling in vga_get() Ben Hutchings
2015-12-24 15:37 ` [PATCH 3.2 46/77] drm: Fix an unwanted master inheritance v2 Ben Hutchings
2015-12-25 14:13 ` Thomas Hellstrom
2015-12-26 4:31 ` Ben Hutchings
2015-12-24 15:37 ` [PATCH 3.2 05/77] ALSA: usb-audio: work around CH345 input SysEx corruption Ben Hutchings
2015-12-24 15:37 ` [PATCH 3.2 55/77] parisc iommu: fix panic due to trying to allocate too large region Ben Hutchings
2015-12-24 15:37 ` [PATCH 3.2 29/77] vfs: Make sendfile(2) killable even better Ben Hutchings
2015-12-24 15:37 ` [PATCH 3.2 20/77] mac: validate mac_partition is within sector Ben Hutchings
2015-12-24 15:37 ` [PATCH 3.2 58/77] sh64: fix __NR_fgetxattr Ben Hutchings
2015-12-24 15:37 ` [PATCH 3.2 04/77] ALSA: usb-audio: prevent CH345 multiport output SysEx corruption Ben Hutchings
2015-12-24 15:37 ` [PATCH 3.2 67/77] atl1c: Improve driver not to do order 4 GFP_ATOMIC allocation Ben Hutchings
2015-12-24 15:37 ` [PATCH 3.2 44/77] ipv4: igmp: Allow removing groups from a removed interface Ben Hutchings
2015-12-24 15:37 ` [PATCH 3.2 11/77] ASoC: wm8962: correct addresses for HPF_C_0/1 Ben Hutchings
2015-12-24 15:37 ` [PATCH 3.2 62/77] net: ipmr: fix static mfc/dev leaks on table destruction Ben Hutchings
2015-12-24 15:37 ` [PATCH 3.2 37/77] drm/ttm: Fixed a read/write lock imbalance Ben Hutchings
2015-12-24 15:37 ` [PATCH 3.2 76/77] isdn_ppp: Add checks for allocation failure in isdn_ppp_open() Ben Hutchings
2015-12-24 15:37 ` [PATCH 3.2 01/77] fuse: break infinite loop in fuse_fill_write_pages() Ben Hutchings
2015-12-24 15:37 ` [PATCH 3.2 48/77] sched/core: Clear the root_domain cpumasks in init_rootdomain() Ben Hutchings
2015-12-24 15:37 ` [PATCH 3.2 08/77] USB: ti_usb_3410_502: Fix ID table size Ben Hutchings
2015-12-24 15:37 ` [PATCH 3.2 34/77] jbd2: Fix unreclaimed pages after truncate in data=journal mode Ben Hutchings
2015-12-24 15:37 ` [PATCH 3.2 74/77] af_unix: Revert 'lock_interruptible' in stream receive code Ben Hutchings
2015-12-24 15:37 ` [PATCH 3.2 73/77] bluetooth: Validate socket address length in sco_sock_bind() Ben Hutchings
2015-12-24 15:37 ` [PATCH 3.2 09/77] USB: ti_usb_3410_5052: Add Honeywell HGI80 ID Ben Hutchings
2015-12-24 15:37 ` [PATCH 3.2 69/77] ipv6: sctp: clone options to avoid use after free Ben Hutchings
2015-12-24 15:37 ` [PATCH 3.2 30/77] vfs: Avoid softlockups with sendfile(2) Ben Hutchings
2015-12-24 15:37 ` [PATCH 3.2 35/77] RDS: fix race condition when sending a message on unbound socket Ben Hutchings
2015-12-24 15:37 ` [PATCH 3.2 53/77] dm btree: fix bufio buffer leaks in dm_btree_del() error path Ben Hutchings
2015-12-24 15:37 ` [PATCH 3.2 49/77] usb: xhci: fix config fail of FS hub behind a HS hub with MTT Ben Hutchings
2015-12-24 15:37 ` [PATCH 3.2 14/77] mac80211: mesh: fix call_rcu() usage Ben Hutchings
2015-12-24 15:37 ` [PATCH 3.2 18/77] USB: option: add XS Stick W100-2 from 4G Systems Ben Hutchings
2015-12-24 15:37 ` [PATCH 3.2 28/77] fix sysvfs symlinks Ben Hutchings
2015-12-24 15:37 ` [PATCH 3.2 16/77] xhci: Add XHCI_INTEL_HOST quirk Ben Hutchings
2015-12-24 16:40 ` [PATCH 3.2 00/77] 3.2.75-rc1 review Ben Hutchings
2015-12-24 22:20 ` Guenter Roeck
2015-12-24 22:31 ` Ben Hutchings
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).