1 |
Author: tomwij |
2 |
Date: 2013-06-30 09:17:24 +0000 (Sun, 30 Jun 2013) |
3 |
New Revision: 2416 |
4 |
|
5 |
Added: |
6 |
genpatches-2.6/trunk/3.2/1047_linux-3.2.48.patch |
7 |
Modified: |
8 |
genpatches-2.6/trunk/3.2/0000_README |
9 |
Log: |
10 |
Linux patch 3.2.48. |
11 |
|
12 |
Modified: genpatches-2.6/trunk/3.2/0000_README |
13 |
=================================================================== |
14 |
--- genpatches-2.6/trunk/3.2/0000_README 2013-06-27 21:14:45 UTC (rev 2415) |
15 |
+++ genpatches-2.6/trunk/3.2/0000_README 2013-06-30 09:17:24 UTC (rev 2416) |
16 |
@@ -228,6 +228,10 @@ |
17 |
From: http://www.kernel.org |
18 |
Desc: Linux 3.2.47 |
19 |
|
20 |
+Patch: 1047_linux-3.2.48.patch |
21 |
+From: http://www.kernel.org |
22 |
+Desc: Linux 3.2.48 |
23 |
+ |
24 |
Patch: 1500_XATTR_USER_PREFIX.patch |
25 |
From: https://bugs.gentoo.org/show_bug.cgi?id=470644 |
26 |
Desc: Support for namespace user.pax.* on tmpfs. |
27 |
|
28 |
Added: genpatches-2.6/trunk/3.2/1047_linux-3.2.48.patch |
29 |
=================================================================== |
30 |
--- genpatches-2.6/trunk/3.2/1047_linux-3.2.48.patch (rev 0) |
31 |
+++ genpatches-2.6/trunk/3.2/1047_linux-3.2.48.patch 2013-06-30 09:17:24 UTC (rev 2416) |
32 |
@@ -0,0 +1,952 @@ |
33 |
+diff --git a/Makefile b/Makefile |
34 |
+index 40e2a11..299e2eb 100644 |
35 |
+--- a/Makefile |
36 |
++++ b/Makefile |
37 |
+@@ -1,6 +1,6 @@ |
38 |
+ VERSION = 3 |
39 |
+ PATCHLEVEL = 2 |
40 |
+-SUBLEVEL = 47 |
41 |
++SUBLEVEL = 48 |
42 |
+ EXTRAVERSION = |
43 |
+ NAME = Saber-toothed Squirrel |
44 |
+ |
45 |
+diff --git a/arch/arm/include/asm/cacheflush.h b/arch/arm/include/asm/cacheflush.h |
46 |
+index 1252a26..1397408 100644 |
47 |
+--- a/arch/arm/include/asm/cacheflush.h |
48 |
++++ b/arch/arm/include/asm/cacheflush.h |
49 |
+@@ -301,9 +301,7 @@ static inline void flush_anon_page(struct vm_area_struct *vma, |
50 |
+ } |
51 |
+ |
52 |
+ #define ARCH_HAS_FLUSH_KERNEL_DCACHE_PAGE |
53 |
+-static inline void flush_kernel_dcache_page(struct page *page) |
54 |
+-{ |
55 |
+-} |
56 |
++extern void flush_kernel_dcache_page(struct page *); |
57 |
+ |
58 |
+ #define flush_dcache_mmap_lock(mapping) \ |
59 |
+ spin_lock_irq(&(mapping)->tree_lock) |
60 |
+diff --git a/arch/arm/mm/flush.c b/arch/arm/mm/flush.c |
61 |
+index 8fda9f7..fe61cab 100644 |
62 |
+--- a/arch/arm/mm/flush.c |
63 |
++++ b/arch/arm/mm/flush.c |
64 |
+@@ -304,6 +304,39 @@ void flush_dcache_page(struct page *page) |
65 |
+ EXPORT_SYMBOL(flush_dcache_page); |
66 |
+ |
67 |
+ /* |
68 |
++ * Ensure cache coherency for the kernel mapping of this page. We can |
69 |
++ * assume that the page is pinned via kmap. |
70 |
++ * |
71 |
++ * If the page only exists in the page cache and there are no user |
72 |
++ * space mappings, this is a no-op since the page was already marked |
73 |
++ * dirty at creation. Otherwise, we need to flush the dirty kernel |
74 |
++ * cache lines directly. |
75 |
++ */ |
76 |
++void flush_kernel_dcache_page(struct page *page) |
77 |
++{ |
78 |
++ if (cache_is_vivt() || cache_is_vipt_aliasing()) { |
79 |
++ struct address_space *mapping; |
80 |
++ |
81 |
++ mapping = page_mapping(page); |
82 |
++ |
83 |
++ if (!mapping || mapping_mapped(mapping)) { |
84 |
++ void *addr; |
85 |
++ |
86 |
++ addr = page_address(page); |
87 |
++ /* |
88 |
++ * kmap_atomic() doesn't set the page virtual |
89 |
++ * address for highmem pages, and |
90 |
++ * kunmap_atomic() takes care of cache |
91 |
++ * flushing already. |
92 |
++ */ |
93 |
++ if (!IS_ENABLED(CONFIG_HIGHMEM) || addr) |
94 |
++ __cpuc_flush_dcache_area(addr, PAGE_SIZE); |
95 |
++ } |
96 |
++ } |
97 |
++} |
98 |
++EXPORT_SYMBOL(flush_kernel_dcache_page); |
99 |
++ |
100 |
++/* |
101 |
+ * Flush an anonymous page so that users of get_user_pages() |
102 |
+ * can safely access the data. The expected sequence is: |
103 |
+ * |
104 |
+diff --git a/arch/arm/mm/nommu.c b/arch/arm/mm/nommu.c |
105 |
+index 941a98c..a5018fb 100644 |
106 |
+--- a/arch/arm/mm/nommu.c |
107 |
++++ b/arch/arm/mm/nommu.c |
108 |
+@@ -53,6 +53,12 @@ void flush_dcache_page(struct page *page) |
109 |
+ } |
110 |
+ EXPORT_SYMBOL(flush_dcache_page); |
111 |
+ |
112 |
++void flush_kernel_dcache_page(struct page *page) |
113 |
++{ |
114 |
++ __cpuc_flush_dcache_area(page_address(page), PAGE_SIZE); |
115 |
++} |
116 |
++EXPORT_SYMBOL(flush_kernel_dcache_page); |
117 |
++ |
118 |
+ void copy_to_user_page(struct vm_area_struct *vma, struct page *page, |
119 |
+ unsigned long uaddr, void *dst, const void *src, |
120 |
+ unsigned long len) |
121 |
+diff --git a/arch/tile/lib/exports.c b/arch/tile/lib/exports.c |
122 |
+index 2a81d32..e51e5cd 100644 |
123 |
+--- a/arch/tile/lib/exports.c |
124 |
++++ b/arch/tile/lib/exports.c |
125 |
+@@ -90,4 +90,6 @@ uint64_t __ashrdi3(uint64_t, unsigned int); |
126 |
+ EXPORT_SYMBOL(__ashrdi3); |
127 |
+ uint64_t __ashldi3(uint64_t, unsigned int); |
128 |
+ EXPORT_SYMBOL(__ashldi3); |
129 |
++int __ffsdi2(uint64_t); |
130 |
++EXPORT_SYMBOL(__ffsdi2); |
131 |
+ #endif |
132 |
+diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig |
133 |
+index 9a42703..fb2e69d 100644 |
134 |
+--- a/arch/x86/Kconfig |
135 |
++++ b/arch/x86/Kconfig |
136 |
+@@ -2120,6 +2120,7 @@ source "fs/Kconfig.binfmt" |
137 |
+ config IA32_EMULATION |
138 |
+ bool "IA32 Emulation" |
139 |
+ depends on X86_64 |
140 |
++ select BINFMT_ELF |
141 |
+ select COMPAT_BINFMT_ELF |
142 |
+ ---help--- |
143 |
+ Include code to run 32-bit programs under a 64-bit kernel. You should |
144 |
+diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c |
145 |
+index e82a53a..57867e4 100644 |
146 |
+--- a/arch/x86/kvm/x86.c |
147 |
++++ b/arch/x86/kvm/x86.c |
148 |
+@@ -551,8 +551,6 @@ int __kvm_set_xcr(struct kvm_vcpu *vcpu, u32 index, u64 xcr) |
149 |
+ if (index != XCR_XFEATURE_ENABLED_MASK) |
150 |
+ return 1; |
151 |
+ xcr0 = xcr; |
152 |
+- if (kvm_x86_ops->get_cpl(vcpu) != 0) |
153 |
+- return 1; |
154 |
+ if (!(xcr0 & XSTATE_FP)) |
155 |
+ return 1; |
156 |
+ if ((xcr0 & XSTATE_YMM) && !(xcr0 & XSTATE_SSE)) |
157 |
+@@ -566,7 +564,8 @@ int __kvm_set_xcr(struct kvm_vcpu *vcpu, u32 index, u64 xcr) |
158 |
+ |
159 |
+ int kvm_set_xcr(struct kvm_vcpu *vcpu, u32 index, u64 xcr) |
160 |
+ { |
161 |
+- if (__kvm_set_xcr(vcpu, index, xcr)) { |
162 |
++ if (kvm_x86_ops->get_cpl(vcpu) != 0 || |
163 |
++ __kvm_set_xcr(vcpu, index, xcr)) { |
164 |
+ kvm_inject_gp(vcpu, 0); |
165 |
+ return 1; |
166 |
+ } |
167 |
+diff --git a/arch/x86/platform/efi/efi.c b/arch/x86/platform/efi/efi.c |
168 |
+index 07ef7e8..f9537e3 100644 |
169 |
+--- a/arch/x86/platform/efi/efi.c |
170 |
++++ b/arch/x86/platform/efi/efi.c |
171 |
+@@ -49,6 +49,13 @@ |
172 |
+ #define EFI_DEBUG 1 |
173 |
+ #define PFX "EFI: " |
174 |
+ |
175 |
++#define EFI_MIN_RESERVE 5120 |
176 |
++ |
177 |
++#define EFI_DUMMY_GUID \ |
178 |
++ EFI_GUID(0x4424ac57, 0xbe4b, 0x47dd, 0x9e, 0x97, 0xed, 0x50, 0xf0, 0x9f, 0x92, 0xa9) |
179 |
++ |
180 |
++static efi_char16_t efi_dummy_name[6] = { 'D', 'U', 'M', 'M', 'Y', 0 }; |
181 |
++ |
182 |
+ struct efi __read_mostly efi = { |
183 |
+ .mps = EFI_INVALID_TABLE_ADDR, |
184 |
+ .acpi = EFI_INVALID_TABLE_ADDR, |
185 |
+@@ -787,6 +794,13 @@ void __init efi_enter_virtual_mode(void) |
186 |
+ early_iounmap(memmap.map, memmap.nr_map * memmap.desc_size); |
187 |
+ memmap.map = NULL; |
188 |
+ kfree(new_memmap); |
189 |
++ |
190 |
++ /* clean DUMMY object */ |
191 |
++ efi.set_variable(efi_dummy_name, &EFI_DUMMY_GUID, |
192 |
++ EFI_VARIABLE_NON_VOLATILE | |
193 |
++ EFI_VARIABLE_BOOTSERVICE_ACCESS | |
194 |
++ EFI_VARIABLE_RUNTIME_ACCESS, |
195 |
++ 0, NULL); |
196 |
+ } |
197 |
+ |
198 |
+ /* |
199 |
+@@ -838,22 +852,70 @@ efi_status_t efi_query_variable_store(u32 attributes, unsigned long size) |
200 |
+ efi_status_t status; |
201 |
+ u64 storage_size, remaining_size, max_size; |
202 |
+ |
203 |
++ if (!(attributes & EFI_VARIABLE_NON_VOLATILE)) |
204 |
++ return 0; |
205 |
++ |
206 |
+ status = efi.query_variable_info(attributes, &storage_size, |
207 |
+ &remaining_size, &max_size); |
208 |
+ if (status != EFI_SUCCESS) |
209 |
+ return status; |
210 |
+ |
211 |
+- if (!max_size && remaining_size > size) |
212 |
+- printk_once(KERN_ERR FW_BUG "Broken EFI implementation" |
213 |
+- " is returning MaxVariableSize=0\n"); |
214 |
++ /* |
215 |
++ * Some firmware implementations refuse to boot if there's insufficient |
216 |
++ * space in the variable store. We account for that by refusing the |
217 |
++ * write if permitting it would reduce the available space to under |
218 |
++ * 5KB. This figure was provided by Samsung, so should be safe. |
219 |
++ */ |
220 |
++ if ((remaining_size - size < EFI_MIN_RESERVE) && |
221 |
++ !efi_no_storage_paranoia) { |
222 |
++ |
223 |
++ /* |
224 |
++ * Triggering garbage collection may require that the firmware |
225 |
++ * generate a real EFI_OUT_OF_RESOURCES error. We can force |
226 |
++ * that by attempting to use more space than is available. |
227 |
++ */ |
228 |
++ unsigned long dummy_size = remaining_size + 1024; |
229 |
++ void *dummy = kzalloc(dummy_size, GFP_ATOMIC); |
230 |
++ |
231 |
++ if (!dummy) |
232 |
++ return EFI_OUT_OF_RESOURCES; |
233 |
+ |
234 |
+- if (!storage_size || size > remaining_size || |
235 |
+- (max_size && size > max_size)) |
236 |
+- return EFI_OUT_OF_RESOURCES; |
237 |
++ status = efi.set_variable(efi_dummy_name, &EFI_DUMMY_GUID, |
238 |
++ EFI_VARIABLE_NON_VOLATILE | |
239 |
++ EFI_VARIABLE_BOOTSERVICE_ACCESS | |
240 |
++ EFI_VARIABLE_RUNTIME_ACCESS, |
241 |
++ dummy_size, dummy); |
242 |
+ |
243 |
+- if (!efi_no_storage_paranoia && |
244 |
+- (remaining_size - size) < (storage_size / 2)) |
245 |
+- return EFI_OUT_OF_RESOURCES; |
246 |
++ if (status == EFI_SUCCESS) { |
247 |
++ /* |
248 |
++ * This should have failed, so if it didn't make sure |
249 |
++ * that we delete it... |
250 |
++ */ |
251 |
++ efi.set_variable(efi_dummy_name, &EFI_DUMMY_GUID, |
252 |
++ EFI_VARIABLE_NON_VOLATILE | |
253 |
++ EFI_VARIABLE_BOOTSERVICE_ACCESS | |
254 |
++ EFI_VARIABLE_RUNTIME_ACCESS, |
255 |
++ 0, dummy); |
256 |
++ } |
257 |
++ |
258 |
++ kfree(dummy); |
259 |
++ |
260 |
++ /* |
261 |
++ * The runtime code may now have triggered a garbage collection |
262 |
++ * run, so check the variable info again |
263 |
++ */ |
264 |
++ status = efi.query_variable_info(attributes, &storage_size, |
265 |
++ &remaining_size, &max_size); |
266 |
++ |
267 |
++ if (status != EFI_SUCCESS) |
268 |
++ return status; |
269 |
++ |
270 |
++ /* |
271 |
++ * There still isn't enough room, so return an error |
272 |
++ */ |
273 |
++ if (remaining_size - size < EFI_MIN_RESERVE) |
274 |
++ return EFI_OUT_OF_RESOURCES; |
275 |
++ } |
276 |
+ |
277 |
+ return EFI_SUCCESS; |
278 |
+ } |
279 |
+diff --git a/drivers/block/virtio_blk.c b/drivers/block/virtio_blk.c |
280 |
+index 166cb36..c5f7b2c 100644 |
281 |
+--- a/drivers/block/virtio_blk.c |
282 |
++++ b/drivers/block/virtio_blk.c |
283 |
+@@ -343,6 +343,7 @@ static void virtblk_config_changed_work(struct work_struct *work) |
284 |
+ cap_str_10, cap_str_2); |
285 |
+ |
286 |
+ set_capacity(vblk->disk, capacity); |
287 |
++ revalidate_disk(vblk->disk); |
288 |
+ done: |
289 |
+ mutex_unlock(&vblk->config_lock); |
290 |
+ } |
291 |
+diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c |
292 |
+index 4fddd21..38a7793 100644 |
293 |
+--- a/drivers/gpu/drm/i915/intel_ringbuffer.c |
294 |
++++ b/drivers/gpu/drm/i915/intel_ringbuffer.c |
295 |
+@@ -408,11 +408,6 @@ static int init_render_ring(struct intel_ring_buffer *ring) |
296 |
+ if (INTEL_INFO(dev)->gen >= 6) |
297 |
+ I915_WRITE(MI_MODE, GFX_MODE_ENABLE(ASYNC_FLIP_PERF_DISABLE)); |
298 |
+ |
299 |
+- /* Required for the hardware to program scanline values for waiting */ |
300 |
+- if (INTEL_INFO(dev)->gen == 6) |
301 |
+- I915_WRITE(GFX_MODE, |
302 |
+- GFX_MODE_ENABLE(GFX_TLB_INVALIDATE_ALWAYS)); |
303 |
+- |
304 |
+ if (IS_GEN7(dev)) |
305 |
+ I915_WRITE(GFX_MODE_GEN7, |
306 |
+ GFX_MODE_DISABLE(GFX_TLB_INVALIDATE_ALWAYS) | |
307 |
+diff --git a/drivers/net/ethernet/freescale/gianfar_ptp.c b/drivers/net/ethernet/freescale/gianfar_ptp.c |
308 |
+index 69c3adf..c2ab21c 100644 |
309 |
+--- a/drivers/net/ethernet/freescale/gianfar_ptp.c |
310 |
++++ b/drivers/net/ethernet/freescale/gianfar_ptp.c |
311 |
+@@ -520,6 +520,7 @@ static int gianfar_ptp_probe(struct platform_device *dev) |
312 |
+ return 0; |
313 |
+ |
314 |
+ no_clock: |
315 |
++ iounmap(etsects->regs); |
316 |
+ no_ioremap: |
317 |
+ release_resource(etsects->rsrc); |
318 |
+ no_resource: |
319 |
+diff --git a/drivers/net/ethernet/realtek/r8169.c b/drivers/net/ethernet/realtek/r8169.c |
320 |
+index f698183..ed7a5a6 100644 |
321 |
+--- a/drivers/net/ethernet/realtek/r8169.c |
322 |
++++ b/drivers/net/ethernet/realtek/r8169.c |
323 |
+@@ -5524,7 +5524,20 @@ err_out: |
324 |
+ return -EIO; |
325 |
+ } |
326 |
+ |
327 |
+-static inline void rtl8169_tso_csum(struct rtl8169_private *tp, |
328 |
++static bool rtl_skb_pad(struct sk_buff *skb) |
329 |
++{ |
330 |
++ if (skb_padto(skb, ETH_ZLEN)) |
331 |
++ return false; |
332 |
++ skb_put(skb, ETH_ZLEN - skb->len); |
333 |
++ return true; |
334 |
++} |
335 |
++ |
336 |
++static bool rtl_test_hw_pad_bug(struct rtl8169_private *tp, struct sk_buff *skb) |
337 |
++{ |
338 |
++ return skb->len < ETH_ZLEN && tp->mac_version == RTL_GIGA_MAC_VER_34; |
339 |
++} |
340 |
++ |
341 |
++static inline bool rtl8169_tso_csum(struct rtl8169_private *tp, |
342 |
+ struct sk_buff *skb, u32 *opts) |
343 |
+ { |
344 |
+ const struct rtl_tx_desc_info *info = tx_desc_info + tp->txd_version; |
345 |
+@@ -5537,13 +5550,20 @@ static inline void rtl8169_tso_csum(struct rtl8169_private *tp, |
346 |
+ } else if (skb->ip_summed == CHECKSUM_PARTIAL) { |
347 |
+ const struct iphdr *ip = ip_hdr(skb); |
348 |
+ |
349 |
++ if (unlikely(rtl_test_hw_pad_bug(tp, skb))) |
350 |
++ return skb_checksum_help(skb) == 0 && rtl_skb_pad(skb); |
351 |
++ |
352 |
+ if (ip->protocol == IPPROTO_TCP) |
353 |
+ opts[offset] |= info->checksum.tcp; |
354 |
+ else if (ip->protocol == IPPROTO_UDP) |
355 |
+ opts[offset] |= info->checksum.udp; |
356 |
+ else |
357 |
+ WARN_ON_ONCE(1); |
358 |
++ } else { |
359 |
++ if (unlikely(rtl_test_hw_pad_bug(tp, skb))) |
360 |
++ return rtl_skb_pad(skb); |
361 |
+ } |
362 |
++ return true; |
363 |
+ } |
364 |
+ |
365 |
+ static netdev_tx_t rtl8169_start_xmit(struct sk_buff *skb, |
366 |
+@@ -5575,6 +5595,12 @@ static netdev_tx_t rtl8169_start_xmit(struct sk_buff *skb, |
367 |
+ if (unlikely(le32_to_cpu(txd->opts1) & DescOwn)) |
368 |
+ goto err_stop_0; |
369 |
+ |
370 |
++ opts[1] = cpu_to_le32(rtl8169_tx_vlan_tag(tp, skb)); |
371 |
++ opts[0] = DescOwn; |
372 |
++ |
373 |
++ if (!rtl8169_tso_csum(tp, skb, opts)) |
374 |
++ goto err_update_stats; |
375 |
++ |
376 |
+ len = skb_headlen(skb); |
377 |
+ mapping = dma_map_single(d, skb->data, len, DMA_TO_DEVICE); |
378 |
+ if (unlikely(dma_mapping_error(d, mapping))) { |
379 |
+@@ -5586,11 +5612,6 @@ static netdev_tx_t rtl8169_start_xmit(struct sk_buff *skb, |
380 |
+ tp->tx_skb[entry].len = len; |
381 |
+ txd->addr = cpu_to_le64(mapping); |
382 |
+ |
383 |
+- opts[1] = cpu_to_le32(rtl8169_tx_vlan_tag(tp, skb)); |
384 |
+- opts[0] = DescOwn; |
385 |
+- |
386 |
+- rtl8169_tso_csum(tp, skb, opts); |
387 |
+- |
388 |
+ frags = rtl8169_xmit_frags(tp, skb, opts); |
389 |
+ if (frags < 0) |
390 |
+ goto err_dma_1; |
391 |
+diff --git a/drivers/usb/serial/ti_usb_3410_5052.c b/drivers/usb/serial/ti_usb_3410_5052.c |
392 |
+index 4b805be..9d3b39e 100644 |
393 |
+--- a/drivers/usb/serial/ti_usb_3410_5052.c |
394 |
++++ b/drivers/usb/serial/ti_usb_3410_5052.c |
395 |
+@@ -178,7 +178,8 @@ static struct usb_device_id ti_id_table_3410[15+TI_EXTRA_VID_PID_COUNT+1] = { |
396 |
+ { USB_DEVICE(IBM_VENDOR_ID, IBM_4543_PRODUCT_ID) }, |
397 |
+ { USB_DEVICE(IBM_VENDOR_ID, IBM_454B_PRODUCT_ID) }, |
398 |
+ { USB_DEVICE(IBM_VENDOR_ID, IBM_454C_PRODUCT_ID) }, |
399 |
+- { USB_DEVICE(ABBOTT_VENDOR_ID, ABBOTT_PRODUCT_ID) }, |
400 |
++ { USB_DEVICE(ABBOTT_VENDOR_ID, ABBOTT_STEREO_PLUG_ID) }, |
401 |
++ { USB_DEVICE(ABBOTT_VENDOR_ID, ABBOTT_STRIP_PORT_ID) }, |
402 |
+ { USB_DEVICE(TI_VENDOR_ID, FRI2_PRODUCT_ID) }, |
403 |
+ }; |
404 |
+ |
405 |
+diff --git a/drivers/usb/serial/ti_usb_3410_5052.h b/drivers/usb/serial/ti_usb_3410_5052.h |
406 |
+index b353e7e..4a2423e 100644 |
407 |
+--- a/drivers/usb/serial/ti_usb_3410_5052.h |
408 |
++++ b/drivers/usb/serial/ti_usb_3410_5052.h |
409 |
+@@ -52,7 +52,9 @@ |
410 |
+ |
411 |
+ /* Abbott Diabetics vendor and product ids */ |
412 |
+ #define ABBOTT_VENDOR_ID 0x1a61 |
413 |
+-#define ABBOTT_PRODUCT_ID 0x3410 |
414 |
++#define ABBOTT_STEREO_PLUG_ID 0x3410 |
415 |
++#define ABBOTT_PRODUCT_ID ABBOTT_STEREO_PLUG_ID |
416 |
++#define ABBOTT_STRIP_PORT_ID 0x3420 |
417 |
+ |
418 |
+ /* Commands */ |
419 |
+ #define TI_GET_VERSION 0x01 |
420 |
+diff --git a/fs/ncpfs/dir.c b/fs/ncpfs/dir.c |
421 |
+index 9c51f62..844bd64 100644 |
422 |
+--- a/fs/ncpfs/dir.c |
423 |
++++ b/fs/ncpfs/dir.c |
424 |
+@@ -1033,15 +1033,6 @@ static int ncp_rmdir(struct inode *dir, struct dentry *dentry) |
425 |
+ DPRINTK("ncp_rmdir: removing %s/%s\n", |
426 |
+ dentry->d_parent->d_name.name, dentry->d_name.name); |
427 |
+ |
428 |
+- /* |
429 |
+- * fail with EBUSY if there are still references to this |
430 |
+- * directory. |
431 |
+- */ |
432 |
+- dentry_unhash(dentry); |
433 |
+- error = -EBUSY; |
434 |
+- if (!d_unhashed(dentry)) |
435 |
+- goto out; |
436 |
+- |
437 |
+ len = sizeof(__name); |
438 |
+ error = ncp_io2vol(server, __name, &len, dentry->d_name.name, |
439 |
+ dentry->d_name.len, !ncp_preserve_case(dir)); |
440 |
+diff --git a/include/linux/rculist_nulls.h b/include/linux/rculist_nulls.h |
441 |
+index 2ae1371..1c33dd7 100644 |
442 |
+--- a/include/linux/rculist_nulls.h |
443 |
++++ b/include/linux/rculist_nulls.h |
444 |
+@@ -105,9 +105,14 @@ static inline void hlist_nulls_add_head_rcu(struct hlist_nulls_node *n, |
445 |
+ * @head: the head for your list. |
446 |
+ * @member: the name of the hlist_nulls_node within the struct. |
447 |
+ * |
448 |
++ * The barrier() is needed to make sure compiler doesn't cache first element [1], |
449 |
++ * as this loop can be restarted [2] |
450 |
++ * [1] Documentation/atomic_ops.txt around line 114 |
451 |
++ * [2] Documentation/RCU/rculist_nulls.txt around line 146 |
452 |
+ */ |
453 |
+ #define hlist_nulls_for_each_entry_rcu(tpos, pos, head, member) \ |
454 |
+- for (pos = rcu_dereference_raw(hlist_nulls_first_rcu(head)); \ |
455 |
++ for (({barrier();}), \ |
456 |
++ pos = rcu_dereference_raw(hlist_nulls_first_rcu(head)); \ |
457 |
+ (!is_a_nulls(pos)) && \ |
458 |
+ ({ tpos = hlist_nulls_entry(pos, typeof(*tpos), member); 1; }); \ |
459 |
+ pos = rcu_dereference_raw(hlist_nulls_next_rcu(pos))) |
460 |
+diff --git a/include/linux/socket.h b/include/linux/socket.h |
461 |
+index 2acd2e2..7e9f2d3 100644 |
462 |
+--- a/include/linux/socket.h |
463 |
++++ b/include/linux/socket.h |
464 |
+@@ -336,6 +336,9 @@ extern int put_cmsg(struct msghdr*, int level, int type, int len, void *data); |
465 |
+ |
466 |
+ struct timespec; |
467 |
+ |
468 |
++/* The __sys_...msg variants allow MSG_CMSG_COMPAT */ |
469 |
++extern long __sys_recvmsg(int fd, struct msghdr __user *msg, unsigned flags); |
470 |
++extern long __sys_sendmsg(int fd, struct msghdr __user *msg, unsigned flags); |
471 |
+ extern int __sys_recvmmsg(int fd, struct mmsghdr __user *mmsg, unsigned int vlen, |
472 |
+ unsigned int flags, struct timespec *timeout); |
473 |
+ extern int __sys_sendmmsg(int fd, struct mmsghdr __user *mmsg, |
474 |
+diff --git a/net/compat.c b/net/compat.c |
475 |
+index 6def90e..8c979cc 100644 |
476 |
+--- a/net/compat.c |
477 |
++++ b/net/compat.c |
478 |
+@@ -733,19 +733,25 @@ static unsigned char nas[21] = { |
479 |
+ |
480 |
+ asmlinkage long compat_sys_sendmsg(int fd, struct compat_msghdr __user *msg, unsigned flags) |
481 |
+ { |
482 |
+- return sys_sendmsg(fd, (struct msghdr __user *)msg, flags | MSG_CMSG_COMPAT); |
483 |
++ if (flags & MSG_CMSG_COMPAT) |
484 |
++ return -EINVAL; |
485 |
++ return __sys_sendmsg(fd, (struct msghdr __user *)msg, flags | MSG_CMSG_COMPAT); |
486 |
+ } |
487 |
+ |
488 |
+ asmlinkage long compat_sys_sendmmsg(int fd, struct compat_mmsghdr __user *mmsg, |
489 |
+ unsigned vlen, unsigned int flags) |
490 |
+ { |
491 |
++ if (flags & MSG_CMSG_COMPAT) |
492 |
++ return -EINVAL; |
493 |
+ return __sys_sendmmsg(fd, (struct mmsghdr __user *)mmsg, vlen, |
494 |
+ flags | MSG_CMSG_COMPAT); |
495 |
+ } |
496 |
+ |
497 |
+ asmlinkage long compat_sys_recvmsg(int fd, struct compat_msghdr __user *msg, unsigned int flags) |
498 |
+ { |
499 |
+- return sys_recvmsg(fd, (struct msghdr __user *)msg, flags | MSG_CMSG_COMPAT); |
500 |
++ if (flags & MSG_CMSG_COMPAT) |
501 |
++ return -EINVAL; |
502 |
++ return __sys_recvmsg(fd, (struct msghdr __user *)msg, flags | MSG_CMSG_COMPAT); |
503 |
+ } |
504 |
+ |
505 |
+ asmlinkage long compat_sys_recv(int fd, void __user *buf, size_t len, unsigned flags) |
506 |
+@@ -767,6 +773,9 @@ asmlinkage long compat_sys_recvmmsg(int fd, struct compat_mmsghdr __user *mmsg, |
507 |
+ int datagrams; |
508 |
+ struct timespec ktspec; |
509 |
+ |
510 |
++ if (flags & MSG_CMSG_COMPAT) |
511 |
++ return -EINVAL; |
512 |
++ |
513 |
+ if (timeout == NULL) |
514 |
+ return __sys_recvmmsg(fd, (struct mmsghdr __user *)mmsg, vlen, |
515 |
+ flags | MSG_CMSG_COMPAT, NULL); |
516 |
+diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c |
517 |
+index d55110e..5f28fab 100644 |
518 |
+--- a/net/ipv4/ip_gre.c |
519 |
++++ b/net/ipv4/ip_gre.c |
520 |
+@@ -716,6 +716,7 @@ static netdev_tx_t ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev |
521 |
+ tiph = &tunnel->parms.iph; |
522 |
+ } |
523 |
+ |
524 |
++ memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt)); |
525 |
+ if ((dst = tiph->daddr) == 0) { |
526 |
+ /* NBMA tunnel */ |
527 |
+ |
528 |
+@@ -851,7 +852,6 @@ static netdev_tx_t ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev |
529 |
+ skb_reset_transport_header(skb); |
530 |
+ skb_push(skb, gre_hlen); |
531 |
+ skb_reset_network_header(skb); |
532 |
+- memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt)); |
533 |
+ IPCB(skb)->flags &= ~(IPSKB_XFRM_TUNNEL_SIZE | IPSKB_XFRM_TRANSFORMED | |
534 |
+ IPSKB_REROUTED); |
535 |
+ skb_dst_drop(skb); |
536 |
+diff --git a/net/ipv4/ipip.c b/net/ipv4/ipip.c |
537 |
+index 17ad951..5dc5137 100644 |
538 |
+--- a/net/ipv4/ipip.c |
539 |
++++ b/net/ipv4/ipip.c |
540 |
+@@ -448,6 +448,7 @@ static netdev_tx_t ipip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev) |
541 |
+ if (tos & 1) |
542 |
+ tos = old_iph->tos; |
543 |
+ |
544 |
++ memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt)); |
545 |
+ if (!dst) { |
546 |
+ /* NBMA tunnel */ |
547 |
+ if ((rt = skb_rtable(skb)) == NULL) { |
548 |
+@@ -531,7 +532,6 @@ static netdev_tx_t ipip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev) |
549 |
+ skb->transport_header = skb->network_header; |
550 |
+ skb_push(skb, sizeof(struct iphdr)); |
551 |
+ skb_reset_network_header(skb); |
552 |
+- memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt)); |
553 |
+ IPCB(skb)->flags &= ~(IPSKB_XFRM_TUNNEL_SIZE | IPSKB_XFRM_TRANSFORMED | |
554 |
+ IPSKB_REROUTED); |
555 |
+ skb_dst_drop(skb); |
556 |
+diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c |
557 |
+index fe381c2..ec8b4b7e 100644 |
558 |
+--- a/net/ipv4/tcp.c |
559 |
++++ b/net/ipv4/tcp.c |
560 |
+@@ -3037,8 +3037,11 @@ int tcp_md5_hash_skb_data(struct tcp_md5sig_pool *hp, |
561 |
+ |
562 |
+ for (i = 0; i < shi->nr_frags; ++i) { |
563 |
+ const struct skb_frag_struct *f = &shi->frags[i]; |
564 |
+- struct page *page = skb_frag_page(f); |
565 |
+- sg_set_page(&sg, page, skb_frag_size(f), f->page_offset); |
566 |
++ unsigned int offset = f->page_offset; |
567 |
++ struct page *page = skb_frag_page(f) + (offset >> PAGE_SHIFT); |
568 |
++ |
569 |
++ sg_set_page(&sg, page, skb_frag_size(f), |
570 |
++ offset_in_page(offset)); |
571 |
+ if (crypto_hash_update(desc, &sg, skb_frag_size(f))) |
572 |
+ return 1; |
573 |
+ } |
574 |
+diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c |
575 |
+index 5c1807c..3add486 100644 |
576 |
+--- a/net/ipv4/tcp_output.c |
577 |
++++ b/net/ipv4/tcp_output.c |
578 |
+@@ -835,11 +835,13 @@ static int tcp_transmit_skb(struct sock *sk, struct sk_buff *skb, int clone_it, |
579 |
+ &md5); |
580 |
+ tcp_header_size = tcp_options_size + sizeof(struct tcphdr); |
581 |
+ |
582 |
+- if (tcp_packets_in_flight(tp) == 0) { |
583 |
++ if (tcp_packets_in_flight(tp) == 0) |
584 |
+ tcp_ca_event(sk, CA_EVENT_TX_START); |
585 |
+- skb->ooo_okay = 1; |
586 |
+- } else |
587 |
+- skb->ooo_okay = 0; |
588 |
++ |
589 |
++ /* if no packet is in qdisc/device queue, then allow XPS to select |
590 |
++ * another queue. |
591 |
++ */ |
592 |
++ skb->ooo_okay = sk_wmem_alloc_get(sk) == 0; |
593 |
+ |
594 |
+ skb_push(skb, tcp_header_size); |
595 |
+ skb_reset_transport_header(skb); |
596 |
+diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c |
597 |
+index d84033b..d603caa 100644 |
598 |
+--- a/net/ipv6/addrconf.c |
599 |
++++ b/net/ipv6/addrconf.c |
600 |
+@@ -2437,8 +2437,10 @@ static void init_loopback(struct net_device *dev) |
601 |
+ sp_rt = addrconf_dst_alloc(idev, &sp_ifa->addr, 0); |
602 |
+ |
603 |
+ /* Failure cases are ignored */ |
604 |
+- if (!IS_ERR(sp_rt)) |
605 |
++ if (!IS_ERR(sp_rt)) { |
606 |
++ sp_ifa->rt = sp_rt; |
607 |
+ ip6_ins_rt(sp_rt); |
608 |
++ } |
609 |
+ } |
610 |
+ read_unlock_bh(&idev->lock); |
611 |
+ } |
612 |
+diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c |
613 |
+index 3ccd9b2..6aadaa8 100644 |
614 |
+--- a/net/ipv6/ip6_output.c |
615 |
++++ b/net/ipv6/ip6_output.c |
616 |
+@@ -1233,7 +1233,7 @@ int ip6_append_data(struct sock *sk, int getfrag(void *from, char *to, |
617 |
+ if (WARN_ON(np->cork.opt)) |
618 |
+ return -EINVAL; |
619 |
+ |
620 |
+- np->cork.opt = kmalloc(opt->tot_len, sk->sk_allocation); |
621 |
++ np->cork.opt = kzalloc(opt->tot_len, sk->sk_allocation); |
622 |
+ if (unlikely(np->cork.opt == NULL)) |
623 |
+ return -ENOBUFS; |
624 |
+ |
625 |
+diff --git a/net/l2tp/l2tp_ppp.c b/net/l2tp/l2tp_ppp.c |
626 |
+index 6f60175..74410e6 100644 |
627 |
+--- a/net/l2tp/l2tp_ppp.c |
628 |
++++ b/net/l2tp/l2tp_ppp.c |
629 |
+@@ -350,19 +350,19 @@ static int pppol2tp_sendmsg(struct kiocb *iocb, struct socket *sock, struct msgh |
630 |
+ skb_put(skb, 2); |
631 |
+ |
632 |
+ /* Copy user data into skb */ |
633 |
+- error = memcpy_fromiovec(skb->data, m->msg_iov, total_len); |
634 |
++ error = memcpy_fromiovec(skb_put(skb, total_len), m->msg_iov, |
635 |
++ total_len); |
636 |
+ if (error < 0) { |
637 |
+ kfree_skb(skb); |
638 |
+ goto error_put_sess_tun; |
639 |
+ } |
640 |
+- skb_put(skb, total_len); |
641 |
+ |
642 |
+ l2tp_xmit_skb(session, skb, session->hdr_len); |
643 |
+ |
644 |
+ sock_put(ps->tunnel_sock); |
645 |
+ sock_put(sk); |
646 |
+ |
647 |
+- return error; |
648 |
++ return total_len; |
649 |
+ |
650 |
+ error_put_sess_tun: |
651 |
+ sock_put(ps->tunnel_sock); |
652 |
+diff --git a/net/netlabel/netlabel_domainhash.c b/net/netlabel/netlabel_domainhash.c |
653 |
+index e5330ed..bf99567 100644 |
654 |
+--- a/net/netlabel/netlabel_domainhash.c |
655 |
++++ b/net/netlabel/netlabel_domainhash.c |
656 |
+@@ -245,6 +245,71 @@ static void netlbl_domhsh_audit_add(struct netlbl_dom_map *entry, |
657 |
+ } |
658 |
+ } |
659 |
+ |
660 |
++/** |
661 |
++ * netlbl_domhsh_validate - Validate a new domain mapping entry |
662 |
++ * @entry: the entry to validate |
663 |
++ * |
664 |
++ * This function validates the new domain mapping entry to ensure that it is |
665 |
++ * a valid entry. Returns zero on success, negative values on failure. |
666 |
++ * |
667 |
++ */ |
668 |
++static int netlbl_domhsh_validate(const struct netlbl_dom_map *entry) |
669 |
++{ |
670 |
++ struct netlbl_af4list *iter4; |
671 |
++ struct netlbl_domaddr4_map *map4; |
672 |
++#if IS_ENABLED(CONFIG_IPV6) |
673 |
++ struct netlbl_af6list *iter6; |
674 |
++ struct netlbl_domaddr6_map *map6; |
675 |
++#endif /* IPv6 */ |
676 |
++ |
677 |
++ if (entry == NULL) |
678 |
++ return -EINVAL; |
679 |
++ |
680 |
++ switch (entry->type) { |
681 |
++ case NETLBL_NLTYPE_UNLABELED: |
682 |
++ if (entry->type_def.cipsov4 != NULL || |
683 |
++ entry->type_def.addrsel != NULL) |
684 |
++ return -EINVAL; |
685 |
++ break; |
686 |
++ case NETLBL_NLTYPE_CIPSOV4: |
687 |
++ if (entry->type_def.cipsov4 == NULL) |
688 |
++ return -EINVAL; |
689 |
++ break; |
690 |
++ case NETLBL_NLTYPE_ADDRSELECT: |
691 |
++ netlbl_af4list_foreach(iter4, &entry->type_def.addrsel->list4) { |
692 |
++ map4 = netlbl_domhsh_addr4_entry(iter4); |
693 |
++ switch (map4->type) { |
694 |
++ case NETLBL_NLTYPE_UNLABELED: |
695 |
++ if (map4->type_def.cipsov4 != NULL) |
696 |
++ return -EINVAL; |
697 |
++ break; |
698 |
++ case NETLBL_NLTYPE_CIPSOV4: |
699 |
++ if (map4->type_def.cipsov4 == NULL) |
700 |
++ return -EINVAL; |
701 |
++ break; |
702 |
++ default: |
703 |
++ return -EINVAL; |
704 |
++ } |
705 |
++ } |
706 |
++#if IS_ENABLED(CONFIG_IPV6) |
707 |
++ netlbl_af6list_foreach(iter6, &entry->type_def.addrsel->list6) { |
708 |
++ map6 = netlbl_domhsh_addr6_entry(iter6); |
709 |
++ switch (map6->type) { |
710 |
++ case NETLBL_NLTYPE_UNLABELED: |
711 |
++ break; |
712 |
++ default: |
713 |
++ return -EINVAL; |
714 |
++ } |
715 |
++ } |
716 |
++#endif /* IPv6 */ |
717 |
++ break; |
718 |
++ default: |
719 |
++ return -EINVAL; |
720 |
++ } |
721 |
++ |
722 |
++ return 0; |
723 |
++} |
724 |
++ |
725 |
+ /* |
726 |
+ * Domain Hash Table Functions |
727 |
+ */ |
728 |
+@@ -311,6 +376,10 @@ int netlbl_domhsh_add(struct netlbl_dom_map *entry, |
729 |
+ struct netlbl_af6list *tmp6; |
730 |
+ #endif /* IPv6 */ |
731 |
+ |
732 |
++ ret_val = netlbl_domhsh_validate(entry); |
733 |
++ if (ret_val != 0) |
734 |
++ return ret_val; |
735 |
++ |
736 |
+ /* XXX - we can remove this RCU read lock as the spinlock protects the |
737 |
+ * entire function, but before we do we need to fixup the |
738 |
+ * netlbl_af[4,6]list RCU functions to do "the right thing" with |
739 |
+diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c |
740 |
+index 5a70215..a2ac2c3 100644 |
741 |
+--- a/net/packet/af_packet.c |
742 |
++++ b/net/packet/af_packet.c |
743 |
+@@ -2820,12 +2820,11 @@ static int packet_getname_spkt(struct socket *sock, struct sockaddr *uaddr, |
744 |
+ return -EOPNOTSUPP; |
745 |
+ |
746 |
+ uaddr->sa_family = AF_PACKET; |
747 |
++ memset(uaddr->sa_data, 0, sizeof(uaddr->sa_data)); |
748 |
+ rcu_read_lock(); |
749 |
+ dev = dev_get_by_index_rcu(sock_net(sk), pkt_sk(sk)->ifindex); |
750 |
+ if (dev) |
751 |
+- strncpy(uaddr->sa_data, dev->name, 14); |
752 |
+- else |
753 |
+- memset(uaddr->sa_data, 0, 14); |
754 |
++ strlcpy(uaddr->sa_data, dev->name, sizeof(uaddr->sa_data)); |
755 |
+ rcu_read_unlock(); |
756 |
+ *uaddr_len = sizeof(*uaddr); |
757 |
+ |
758 |
+diff --git a/net/sctp/socket.c b/net/sctp/socket.c |
759 |
+index 5e0d86e..ba0108f 100644 |
760 |
+--- a/net/sctp/socket.c |
761 |
++++ b/net/sctp/socket.c |
762 |
+@@ -3929,6 +3929,12 @@ SCTP_STATIC void sctp_destroy_sock(struct sock *sk) |
763 |
+ |
764 |
+ /* Release our hold on the endpoint. */ |
765 |
+ sp = sctp_sk(sk); |
766 |
++ /* This could happen during socket init, thus we bail out |
767 |
++ * early, since the rest of the below is not setup either. |
768 |
++ */ |
769 |
++ if (sp->ep == NULL) |
770 |
++ return; |
771 |
++ |
772 |
+ if (sp->do_auto_asconf) { |
773 |
+ sp->do_auto_asconf = 0; |
774 |
+ list_del(&sp->auto_asconf_list); |
775 |
+diff --git a/net/socket.c b/net/socket.c |
776 |
+index 68879db..cf546a3 100644 |
777 |
+--- a/net/socket.c |
778 |
++++ b/net/socket.c |
779 |
+@@ -1876,9 +1876,9 @@ struct used_address { |
780 |
+ unsigned int name_len; |
781 |
+ }; |
782 |
+ |
783 |
+-static int __sys_sendmsg(struct socket *sock, struct msghdr __user *msg, |
784 |
+- struct msghdr *msg_sys, unsigned flags, |
785 |
+- struct used_address *used_address) |
786 |
++static int ___sys_sendmsg(struct socket *sock, struct msghdr __user *msg, |
787 |
++ struct msghdr *msg_sys, unsigned flags, |
788 |
++ struct used_address *used_address) |
789 |
+ { |
790 |
+ struct compat_msghdr __user *msg_compat = |
791 |
+ (struct compat_msghdr __user *)msg; |
792 |
+@@ -1998,22 +1998,30 @@ out: |
793 |
+ * BSD sendmsg interface |
794 |
+ */ |
795 |
+ |
796 |
+-SYSCALL_DEFINE3(sendmsg, int, fd, struct msghdr __user *, msg, unsigned, flags) |
797 |
++long __sys_sendmsg(int fd, struct msghdr __user *msg, unsigned flags) |
798 |
+ { |
799 |
+ int fput_needed, err; |
800 |
+ struct msghdr msg_sys; |
801 |
+- struct socket *sock = sockfd_lookup_light(fd, &err, &fput_needed); |
802 |
++ struct socket *sock; |
803 |
+ |
804 |
++ sock = sockfd_lookup_light(fd, &err, &fput_needed); |
805 |
+ if (!sock) |
806 |
+ goto out; |
807 |
+ |
808 |
+- err = __sys_sendmsg(sock, msg, &msg_sys, flags, NULL); |
809 |
++ err = ___sys_sendmsg(sock, msg, &msg_sys, flags, NULL); |
810 |
+ |
811 |
+ fput_light(sock->file, fput_needed); |
812 |
+ out: |
813 |
+ return err; |
814 |
+ } |
815 |
+ |
816 |
++SYSCALL_DEFINE3(sendmsg, int, fd, struct msghdr __user *, msg, unsigned int, flags) |
817 |
++{ |
818 |
++ if (flags & MSG_CMSG_COMPAT) |
819 |
++ return -EINVAL; |
820 |
++ return __sys_sendmsg(fd, msg, flags); |
821 |
++} |
822 |
++ |
823 |
+ /* |
824 |
+ * Linux sendmmsg interface |
825 |
+ */ |
826 |
+@@ -2044,15 +2052,16 @@ int __sys_sendmmsg(int fd, struct mmsghdr __user *mmsg, unsigned int vlen, |
827 |
+ |
828 |
+ while (datagrams < vlen) { |
829 |
+ if (MSG_CMSG_COMPAT & flags) { |
830 |
+- err = __sys_sendmsg(sock, (struct msghdr __user *)compat_entry, |
831 |
+- &msg_sys, flags, &used_address); |
832 |
++ err = ___sys_sendmsg(sock, (struct msghdr __user *)compat_entry, |
833 |
++ &msg_sys, flags, &used_address); |
834 |
+ if (err < 0) |
835 |
+ break; |
836 |
+ err = __put_user(err, &compat_entry->msg_len); |
837 |
+ ++compat_entry; |
838 |
+ } else { |
839 |
+- err = __sys_sendmsg(sock, (struct msghdr __user *)entry, |
840 |
+- &msg_sys, flags, &used_address); |
841 |
++ err = ___sys_sendmsg(sock, |
842 |
++ (struct msghdr __user *)entry, |
843 |
++ &msg_sys, flags, &used_address); |
844 |
+ if (err < 0) |
845 |
+ break; |
846 |
+ err = put_user(err, &entry->msg_len); |
847 |
+@@ -2076,11 +2085,13 @@ int __sys_sendmmsg(int fd, struct mmsghdr __user *mmsg, unsigned int vlen, |
848 |
+ SYSCALL_DEFINE4(sendmmsg, int, fd, struct mmsghdr __user *, mmsg, |
849 |
+ unsigned int, vlen, unsigned int, flags) |
850 |
+ { |
851 |
++ if (flags & MSG_CMSG_COMPAT) |
852 |
++ return -EINVAL; |
853 |
+ return __sys_sendmmsg(fd, mmsg, vlen, flags); |
854 |
+ } |
855 |
+ |
856 |
+-static int __sys_recvmsg(struct socket *sock, struct msghdr __user *msg, |
857 |
+- struct msghdr *msg_sys, unsigned flags, int nosec) |
858 |
++static int ___sys_recvmsg(struct socket *sock, struct msghdr __user *msg, |
859 |
++ struct msghdr *msg_sys, unsigned flags, int nosec) |
860 |
+ { |
861 |
+ struct compat_msghdr __user *msg_compat = |
862 |
+ (struct compat_msghdr __user *)msg; |
863 |
+@@ -2177,23 +2188,31 @@ out: |
864 |
+ * BSD recvmsg interface |
865 |
+ */ |
866 |
+ |
867 |
+-SYSCALL_DEFINE3(recvmsg, int, fd, struct msghdr __user *, msg, |
868 |
+- unsigned int, flags) |
869 |
++long __sys_recvmsg(int fd, struct msghdr __user *msg, unsigned flags) |
870 |
+ { |
871 |
+ int fput_needed, err; |
872 |
+ struct msghdr msg_sys; |
873 |
+- struct socket *sock = sockfd_lookup_light(fd, &err, &fput_needed); |
874 |
++ struct socket *sock; |
875 |
+ |
876 |
++ sock = sockfd_lookup_light(fd, &err, &fput_needed); |
877 |
+ if (!sock) |
878 |
+ goto out; |
879 |
+ |
880 |
+- err = __sys_recvmsg(sock, msg, &msg_sys, flags, 0); |
881 |
++ err = ___sys_recvmsg(sock, msg, &msg_sys, flags, 0); |
882 |
+ |
883 |
+ fput_light(sock->file, fput_needed); |
884 |
+ out: |
885 |
+ return err; |
886 |
+ } |
887 |
+ |
888 |
++SYSCALL_DEFINE3(recvmsg, int, fd, struct msghdr __user *, msg, |
889 |
++ unsigned int, flags) |
890 |
++{ |
891 |
++ if (flags & MSG_CMSG_COMPAT) |
892 |
++ return -EINVAL; |
893 |
++ return __sys_recvmsg(fd, msg, flags); |
894 |
++} |
895 |
++ |
896 |
+ /* |
897 |
+ * Linux recvmmsg interface |
898 |
+ */ |
899 |
+@@ -2231,17 +2250,18 @@ int __sys_recvmmsg(int fd, struct mmsghdr __user *mmsg, unsigned int vlen, |
900 |
+ * No need to ask LSM for more than the first datagram. |
901 |
+ */ |
902 |
+ if (MSG_CMSG_COMPAT & flags) { |
903 |
+- err = __sys_recvmsg(sock, (struct msghdr __user *)compat_entry, |
904 |
+- &msg_sys, flags & ~MSG_WAITFORONE, |
905 |
+- datagrams); |
906 |
++ err = ___sys_recvmsg(sock, (struct msghdr __user *)compat_entry, |
907 |
++ &msg_sys, flags & ~MSG_WAITFORONE, |
908 |
++ datagrams); |
909 |
+ if (err < 0) |
910 |
+ break; |
911 |
+ err = __put_user(err, &compat_entry->msg_len); |
912 |
+ ++compat_entry; |
913 |
+ } else { |
914 |
+- err = __sys_recvmsg(sock, (struct msghdr __user *)entry, |
915 |
+- &msg_sys, flags & ~MSG_WAITFORONE, |
916 |
+- datagrams); |
917 |
++ err = ___sys_recvmsg(sock, |
918 |
++ (struct msghdr __user *)entry, |
919 |
++ &msg_sys, flags & ~MSG_WAITFORONE, |
920 |
++ datagrams); |
921 |
+ if (err < 0) |
922 |
+ break; |
923 |
+ err = put_user(err, &entry->msg_len); |
924 |
+@@ -2308,6 +2328,9 @@ SYSCALL_DEFINE5(recvmmsg, int, fd, struct mmsghdr __user *, mmsg, |
925 |
+ int datagrams; |
926 |
+ struct timespec timeout_sys; |
927 |
+ |
928 |
++ if (flags & MSG_CMSG_COMPAT) |
929 |
++ return -EINVAL; |
930 |
++ |
931 |
+ if (!timeout) |
932 |
+ return __sys_recvmmsg(fd, mmsg, vlen, flags, NULL); |
933 |
+ |
934 |
+diff --git a/sound/usb/card.c b/sound/usb/card.c |
935 |
+index acb7fac..3b79a4a 100644 |
936 |
+--- a/sound/usb/card.c |
937 |
++++ b/sound/usb/card.c |
938 |
+@@ -149,14 +149,32 @@ static int snd_usb_create_stream(struct snd_usb_audio *chip, int ctrlif, int int |
939 |
+ return -EINVAL; |
940 |
+ } |
941 |
+ |
942 |
++ alts = &iface->altsetting[0]; |
943 |
++ altsd = get_iface_desc(alts); |
944 |
++ |
945 |
++ /* |
946 |
++ * Android with both accessory and audio interfaces enabled gets the |
947 |
++ * interface numbers wrong. |
948 |
++ */ |
949 |
++ if ((chip->usb_id == USB_ID(0x18d1, 0x2d04) || |
950 |
++ chip->usb_id == USB_ID(0x18d1, 0x2d05)) && |
951 |
++ interface == 0 && |
952 |
++ altsd->bInterfaceClass == USB_CLASS_VENDOR_SPEC && |
953 |
++ altsd->bInterfaceSubClass == USB_SUBCLASS_VENDOR_SPEC) { |
954 |
++ interface = 2; |
955 |
++ iface = usb_ifnum_to_if(dev, interface); |
956 |
++ if (!iface) |
957 |
++ return -EINVAL; |
958 |
++ alts = &iface->altsetting[0]; |
959 |
++ altsd = get_iface_desc(alts); |
960 |
++ } |
961 |
++ |
962 |
+ if (usb_interface_claimed(iface)) { |
963 |
+ snd_printdd(KERN_INFO "%d:%d:%d: skipping, already claimed\n", |
964 |
+ dev->devnum, ctrlif, interface); |
965 |
+ return -EINVAL; |
966 |
+ } |
967 |
+ |
968 |
+- alts = &iface->altsetting[0]; |
969 |
+- altsd = get_iface_desc(alts); |
970 |
+ if ((altsd->bInterfaceClass == USB_CLASS_AUDIO || |
971 |
+ altsd->bInterfaceClass == USB_CLASS_VENDOR_SPEC) && |
972 |
+ altsd->bInterfaceSubClass == USB_SUBCLASS_MIDISTREAMING) { |
973 |
+diff --git a/sound/usb/mixer.c b/sound/usb/mixer.c |
974 |
+index 97ec155..aeb26eb 100644 |
975 |
+--- a/sound/usb/mixer.c |
976 |
++++ b/sound/usb/mixer.c |
977 |
+@@ -821,6 +821,7 @@ static void volume_control_quirks(struct usb_mixer_elem_info *cval, |
978 |
+ |
979 |
+ case USB_ID(0x046d, 0x0808): |
980 |
+ case USB_ID(0x046d, 0x0809): |
981 |
++ case USB_ID(0x046d, 0x081b): /* HD Webcam c310 */ |
982 |
+ case USB_ID(0x046d, 0x081d): /* HD Webcam c510 */ |
983 |
+ case USB_ID(0x046d, 0x0825): /* HD Webcam c270 */ |
984 |
+ case USB_ID(0x046d, 0x0991): |