--- /dev/null
+From 69e0927b3774563c19b5fb32e91d75edc147fb62 Mon Sep 17 00:00:00 2001
+From: Douglas Gilbert <dgilbert@interlog.com>
+Date: Sun, 14 Jan 2018 17:00:48 -0500
+Subject: blk_rq_map_user_iov: fix error override
+
+From: Douglas Gilbert <dgilbert@interlog.com>
+
+commit 69e0927b3774563c19b5fb32e91d75edc147fb62 upstream.
+
+During stress tests by syzkaller on the sg driver the block layer
+infrequently returns EINVAL. Closer inspection shows the block
+layer was trying to return ENOMEM (which is much more
+understandable) but for some reason overroad that useful error.
+
+Patch below does not show this (unchanged) line:
+ ret =__blk_rq_map_user_iov(rq, map_data, &i, gfp_mask, copy);
+That 'ret' was being overridden when that function failed.
+
+Signed-off-by: Douglas Gilbert <dgilbert@interlog.com>
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ block/blk-map.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/block/blk-map.c
++++ b/block/blk-map.c
+@@ -119,7 +119,7 @@ int blk_rq_map_user_iov(struct request_q
+ unsigned long align = q->dma_pad_mask | queue_dma_alignment(q);
+ struct bio *bio = NULL;
+ struct iov_iter i;
+- int ret;
++ int ret = -EINVAL;
+
+ if (!iter_is_iovec(iter))
+ goto fail;
+@@ -148,7 +148,7 @@ unmap_rq:
+ __blk_rq_unmap_user(bio);
+ fail:
+ rq->bio = NULL;
+- return -EINVAL;
++ return ret;
+ }
+ EXPORT_SYMBOL(blk_rq_map_user_iov);
+
--- /dev/null
+From d8c7fe9f2a486a6e5f0d5229ca43807af5ab22c6 Mon Sep 17 00:00:00 2001
+From: Eric Biggers <ebiggers@google.com>
+Date: Mon, 18 Dec 2017 16:40:26 -0800
+Subject: crypto: x86/twofish-3way - Fix %rbp usage
+
+From: Eric Biggers <ebiggers@google.com>
+
+commit d8c7fe9f2a486a6e5f0d5229ca43807af5ab22c6 upstream.
+
+Using %rbp as a temporary register breaks frame pointer convention and
+breaks stack traces when unwinding from an interrupt in the crypto code.
+
+In twofish-3way, we can't simply replace %rbp with another register
+because there are none available. Instead, we use the stack to hold the
+values that %rbp, %r11, and %r12 were holding previously. Each of these
+values represents the half of the output from the previous Feistel round
+that is being passed on unchanged to the following round. They are only
+used once per round, when they are exchanged with %rax, %rbx, and %rcx.
+
+As a result, we free up 3 registers (one per block) and can reassign
+them so that %rbp is not used, and additionally %r14 and %r15 are not
+used so they do not need to be saved/restored.
+
+There may be a small overhead caused by replacing 'xchg REG, REG' with
+the needed sequence 'mov MEM, REG; mov REG, MEM; mov REG, REG' once per
+round. But, counterintuitively, when I tested "ctr-twofish-3way" on a
+Haswell processor, the new version was actually about 2% faster.
+(Perhaps 'xchg' is not as well optimized as plain moves.)
+
+Reported-by: syzbot <syzkaller@googlegroups.com>
+Signed-off-by: Eric Biggers <ebiggers@google.com>
+Reviewed-by: Josh Poimboeuf <jpoimboe@redhat.com>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/x86/crypto/twofish-x86_64-asm_64-3way.S | 118 ++++++++++++++-------------
+ 1 file changed, 63 insertions(+), 55 deletions(-)
+
+--- a/arch/x86/crypto/twofish-x86_64-asm_64-3way.S
++++ b/arch/x86/crypto/twofish-x86_64-asm_64-3way.S
+@@ -55,29 +55,31 @@
+ #define RAB1bl %bl
+ #define RAB2bl %cl
+
++#define CD0 0x0(%rsp)
++#define CD1 0x8(%rsp)
++#define CD2 0x10(%rsp)
++
++# used only before/after all rounds
+ #define RCD0 %r8
+ #define RCD1 %r9
+ #define RCD2 %r10
+
+-#define RCD0d %r8d
+-#define RCD1d %r9d
+-#define RCD2d %r10d
+-
+-#define RX0 %rbp
+-#define RX1 %r11
+-#define RX2 %r12
+-
+-#define RX0d %ebp
+-#define RX1d %r11d
+-#define RX2d %r12d
+-
+-#define RY0 %r13
+-#define RY1 %r14
+-#define RY2 %r15
+-
+-#define RY0d %r13d
+-#define RY1d %r14d
+-#define RY2d %r15d
++# used only during rounds
++#define RX0 %r8
++#define RX1 %r9
++#define RX2 %r10
++
++#define RX0d %r8d
++#define RX1d %r9d
++#define RX2d %r10d
++
++#define RY0 %r11
++#define RY1 %r12
++#define RY2 %r13
++
++#define RY0d %r11d
++#define RY1d %r12d
++#define RY2d %r13d
+
+ #define RT0 %rdx
+ #define RT1 %rsi
+@@ -85,6 +87,8 @@
+ #define RT0d %edx
+ #define RT1d %esi
+
++#define RT1bl %sil
++
+ #define do16bit_ror(rot, op1, op2, T0, T1, tmp1, tmp2, ab, dst) \
+ movzbl ab ## bl, tmp2 ## d; \
+ movzbl ab ## bh, tmp1 ## d; \
+@@ -92,6 +96,11 @@
+ op1##l T0(CTX, tmp2, 4), dst ## d; \
+ op2##l T1(CTX, tmp1, 4), dst ## d;
+
++#define swap_ab_with_cd(ab, cd, tmp) \
++ movq cd, tmp; \
++ movq ab, cd; \
++ movq tmp, ab;
++
+ /*
+ * Combined G1 & G2 function. Reordered with help of rotates to have moves
+ * at begining.
+@@ -110,15 +119,15 @@
+ /* G1,2 && G2,2 */ \
+ do16bit_ror(32, xor, xor, Tx2, Tx3, RT0, RT1, ab ## 0, x ## 0); \
+ do16bit_ror(16, xor, xor, Ty3, Ty0, RT0, RT1, ab ## 0, y ## 0); \
+- xchgq cd ## 0, ab ## 0; \
++ swap_ab_with_cd(ab ## 0, cd ## 0, RT0); \
+ \
+ do16bit_ror(32, xor, xor, Tx2, Tx3, RT0, RT1, ab ## 1, x ## 1); \
+ do16bit_ror(16, xor, xor, Ty3, Ty0, RT0, RT1, ab ## 1, y ## 1); \
+- xchgq cd ## 1, ab ## 1; \
++ swap_ab_with_cd(ab ## 1, cd ## 1, RT0); \
+ \
+ do16bit_ror(32, xor, xor, Tx2, Tx3, RT0, RT1, ab ## 2, x ## 2); \
+ do16bit_ror(16, xor, xor, Ty3, Ty0, RT0, RT1, ab ## 2, y ## 2); \
+- xchgq cd ## 2, ab ## 2;
++ swap_ab_with_cd(ab ## 2, cd ## 2, RT0);
+
+ #define enc_round_end(ab, x, y, n) \
+ addl y ## d, x ## d; \
+@@ -168,6 +177,16 @@
+ decrypt_round3(ba, dc, (n*2)+1); \
+ decrypt_round3(ba, dc, (n*2));
+
++#define push_cd() \
++ pushq RCD2; \
++ pushq RCD1; \
++ pushq RCD0;
++
++#define pop_cd() \
++ popq RCD0; \
++ popq RCD1; \
++ popq RCD2;
++
+ #define inpack3(in, n, xy, m) \
+ movq 4*(n)(in), xy ## 0; \
+ xorq w+4*m(CTX), xy ## 0; \
+@@ -223,11 +242,8 @@ ENTRY(__twofish_enc_blk_3way)
+ * %rdx: src, RIO
+ * %rcx: bool, if true: xor output
+ */
+- pushq %r15;
+- pushq %r14;
+ pushq %r13;
+ pushq %r12;
+- pushq %rbp;
+ pushq %rbx;
+
+ pushq %rcx; /* bool xor */
+@@ -235,40 +251,36 @@ ENTRY(__twofish_enc_blk_3way)
+
+ inpack_enc3();
+
+- encrypt_cycle3(RAB, RCD, 0);
+- encrypt_cycle3(RAB, RCD, 1);
+- encrypt_cycle3(RAB, RCD, 2);
+- encrypt_cycle3(RAB, RCD, 3);
+- encrypt_cycle3(RAB, RCD, 4);
+- encrypt_cycle3(RAB, RCD, 5);
+- encrypt_cycle3(RAB, RCD, 6);
+- encrypt_cycle3(RAB, RCD, 7);
++ push_cd();
++ encrypt_cycle3(RAB, CD, 0);
++ encrypt_cycle3(RAB, CD, 1);
++ encrypt_cycle3(RAB, CD, 2);
++ encrypt_cycle3(RAB, CD, 3);
++ encrypt_cycle3(RAB, CD, 4);
++ encrypt_cycle3(RAB, CD, 5);
++ encrypt_cycle3(RAB, CD, 6);
++ encrypt_cycle3(RAB, CD, 7);
++ pop_cd();
+
+ popq RIO; /* dst */
+- popq %rbp; /* bool xor */
++ popq RT1; /* bool xor */
+
+- testb %bpl, %bpl;
++ testb RT1bl, RT1bl;
+ jnz .L__enc_xor3;
+
+ outunpack_enc3(mov);
+
+ popq %rbx;
+- popq %rbp;
+ popq %r12;
+ popq %r13;
+- popq %r14;
+- popq %r15;
+ ret;
+
+ .L__enc_xor3:
+ outunpack_enc3(xor);
+
+ popq %rbx;
+- popq %rbp;
+ popq %r12;
+ popq %r13;
+- popq %r14;
+- popq %r15;
+ ret;
+ ENDPROC(__twofish_enc_blk_3way)
+
+@@ -278,35 +290,31 @@ ENTRY(twofish_dec_blk_3way)
+ * %rsi: dst
+ * %rdx: src, RIO
+ */
+- pushq %r15;
+- pushq %r14;
+ pushq %r13;
+ pushq %r12;
+- pushq %rbp;
+ pushq %rbx;
+
+ pushq %rsi; /* dst */
+
+ inpack_dec3();
+
+- decrypt_cycle3(RAB, RCD, 7);
+- decrypt_cycle3(RAB, RCD, 6);
+- decrypt_cycle3(RAB, RCD, 5);
+- decrypt_cycle3(RAB, RCD, 4);
+- decrypt_cycle3(RAB, RCD, 3);
+- decrypt_cycle3(RAB, RCD, 2);
+- decrypt_cycle3(RAB, RCD, 1);
+- decrypt_cycle3(RAB, RCD, 0);
++ push_cd();
++ decrypt_cycle3(RAB, CD, 7);
++ decrypt_cycle3(RAB, CD, 6);
++ decrypt_cycle3(RAB, CD, 5);
++ decrypt_cycle3(RAB, CD, 4);
++ decrypt_cycle3(RAB, CD, 3);
++ decrypt_cycle3(RAB, CD, 2);
++ decrypt_cycle3(RAB, CD, 1);
++ decrypt_cycle3(RAB, CD, 0);
++ pop_cd();
+
+ popq RIO; /* dst */
+
+ outunpack_dec3();
+
+ popq %rbx;
+- popq %rbp;
+ popq %r12;
+ popq %r13;
+- popq %r14;
+- popq %r15;
+ ret;
+ ENDPROC(twofish_dec_blk_3way)
--- /dev/null
+From a77660d231f8b3d84fd23ed482e0964f7aa546d6 Mon Sep 17 00:00:00 2001
+From: Dmitry Vyukov <dvyukov@google.com>
+Date: Tue, 6 Feb 2018 15:40:28 -0800
+Subject: kcov: detect double association with a single task
+
+From: Dmitry Vyukov <dvyukov@google.com>
+
+commit a77660d231f8b3d84fd23ed482e0964f7aa546d6 upstream.
+
+Currently KCOV_ENABLE does not check if the current task is already
+associated with another kcov descriptor. As the result it is possible
+to associate a single task with more than one kcov descriptor, which
+later leads to a memory leak of the old descriptor. This relation is
+really meant to be one-to-one (task has only one back link).
+
+Extend validation to detect such misuse.
+
+Link: http://lkml.kernel.org/r/20180122082520.15716-1-dvyukov@google.com
+Fixes: 5c9a8750a640 ("kernel: add kcov code coverage")
+Signed-off-by: Dmitry Vyukov <dvyukov@google.com>
+Reported-by: Shankara Pailoor <sp3485@columbia.edu>
+Cc: Dmitry Vyukov <dvyukov@google.com>
+Cc: syzbot <syzkaller@googlegroups.com>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ kernel/kcov.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/kernel/kcov.c
++++ b/kernel/kcov.c
+@@ -358,7 +358,8 @@ static int kcov_ioctl_locked(struct kcov
+ */
+ if (kcov->mode != KCOV_MODE_INIT || !kcov->area)
+ return -EINVAL;
+- if (kcov->t != NULL)
++ t = current;
++ if (kcov->t != NULL || t->kcov != NULL)
+ return -EBUSY;
+ if (arg == KCOV_TRACE_PC)
+ kcov->mode = KCOV_MODE_TRACE_PC;
+@@ -370,7 +371,6 @@ static int kcov_ioctl_locked(struct kcov
+ #endif
+ else
+ return -EINVAL;
+- t = current;
+ /* Cache in task struct for performance. */
+ t->kcov_size = kcov->size;
+ t->kcov_area = kcov->area;
--- /dev/null
+From efdab992813fb2ed825745625b83c05032e9cda2 Mon Sep 17 00:00:00 2001
+From: Wanpeng Li <wanpeng.li@hotmail.com>
+Date: Wed, 13 Dec 2017 10:46:40 +0100
+Subject: KVM: x86: fix escape of guest dr6 to the host
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Wanpeng Li <wanpeng.li@hotmail.com>
+
+commit efdab992813fb2ed825745625b83c05032e9cda2 upstream.
+
+syzkaller reported:
+
+ WARNING: CPU: 0 PID: 12927 at arch/x86/kernel/traps.c:780 do_debug+0x222/0x250
+ CPU: 0 PID: 12927 Comm: syz-executor Tainted: G OE 4.15.0-rc2+ #16
+ RIP: 0010:do_debug+0x222/0x250
+ Call Trace:
+ <#DB>
+ debug+0x3e/0x70
+ RIP: 0010:copy_user_enhanced_fast_string+0x10/0x20
+ </#DB>
+ _copy_from_user+0x5b/0x90
+ SyS_timer_create+0x33/0x80
+ entry_SYSCALL_64_fastpath+0x23/0x9a
+
+The testcase sets a watchpoint (with perf_event_open) on a buffer that is
+passed to timer_create() as the struct sigevent argument. In timer_create(),
+copy_from_user()'s rep movsb triggers the BP. The testcase also sets
+the debug registers for the guest.
+
+However, KVM only restores host debug registers when the host has active
+watchpoints, which triggers a race condition when running the testcase with
+multiple threads. The guest's DR6.BS bit can escape to the host before
+another thread invokes timer_create(), and do_debug() complains.
+
+The fix is to respect do_debug()'s dr6 invariant when leaving KVM.
+
+Reported-by: Dmitry Vyukov <dvyukov@google.com>
+Cc: Paolo Bonzini <pbonzini@redhat.com>
+Cc: Radim Krčmář <rkrcmar@redhat.com>
+Cc: David Hildenbrand <david@redhat.com>
+Cc: Dmitry Vyukov <dvyukov@google.com>
+Reviewed-by: David Hildenbrand <david@redhat.com>
+Signed-off-by: Wanpeng Li <wanpeng.li@hotmail.com>
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+Signed-off-by: Radim Krčmář <rkrcmar@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/x86/kvm/x86.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+--- a/arch/x86/kvm/x86.c
++++ b/arch/x86/kvm/x86.c
+@@ -2939,6 +2939,12 @@ void kvm_arch_vcpu_put(struct kvm_vcpu *
+ pagefault_enable();
+ kvm_x86_ops->vcpu_put(vcpu);
+ vcpu->arch.last_host_tsc = rdtsc();
++ /*
++ * If userspace has set any breakpoints or watchpoints, dr6 is restored
++ * on every vmexit, but if not, we might have a stale dr6 from the
++ * guest. do_debug expects dr6 to be cleared after it runs, do the same.
++ */
++ set_debugreg(0, 6);
+ }
+
+ static int kvm_vcpu_ioctl_get_lapic(struct kvm_vcpu *vcpu,
--- /dev/null
+From 72c27a68a2a3f650f0dc7891ee98f02283fc11af Mon Sep 17 00:00:00 2001
+From: Andrey Konovalov <andreyknvl@google.com>
+Date: Thu, 2 Nov 2017 09:52:27 -0400
+Subject: media: pvrusb2: properly check endpoint types
+
+From: Andrey Konovalov <andreyknvl@google.com>
+
+commit 72c27a68a2a3f650f0dc7891ee98f02283fc11af upstream.
+
+As syzkaller detected, pvrusb2 driver submits bulk urb withount checking
+the the endpoint type is actually blunk. Add a check.
+
+usb 1-1: BOGUS urb xfer, pipe 3 != type 1
+------------[ cut here ]------------
+WARNING: CPU: 1 PID: 2713 at drivers/usb/core/urb.c:449 usb_submit_urb+0xf8a/0x11d0
+Modules linked in:
+CPU: 1 PID: 2713 Comm: pvrusb2-context Not tainted
+4.14.0-rc1-42251-gebb2c2437d80 #210
+Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Bochs 01/01/2011
+task: ffff88006b7a18c0 task.stack: ffff880069978000
+RIP: 0010:usb_submit_urb+0xf8a/0x11d0 drivers/usb/core/urb.c:448
+RSP: 0018:ffff88006997f990 EFLAGS: 00010286
+RAX: 0000000000000029 RBX: ffff880063661900 RCX: 0000000000000000
+RDX: 0000000000000029 RSI: ffffffff86876d60 RDI: ffffed000d32ff24
+RBP: ffff88006997fa90 R08: 1ffff1000d32fdca R09: 0000000000000000
+R10: 0000000000000000 R11: 0000000000000000 R12: 1ffff1000d32ff39
+R13: 0000000000000001 R14: 0000000000000003 R15: ffff880068bbed68
+FS: 0000000000000000(0000) GS:ffff88006c600000(0000) knlGS:0000000000000000
+CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+CR2: 0000000001032000 CR3: 000000006a0ff000 CR4: 00000000000006f0
+Call Trace:
+ pvr2_send_request_ex+0xa57/0x1d80 drivers/media/usb/pvrusb2/pvrusb2-hdw.c:3645
+ pvr2_hdw_check_firmware drivers/media/usb/pvrusb2/pvrusb2-hdw.c:1812
+ pvr2_hdw_setup_low drivers/media/usb/pvrusb2/pvrusb2-hdw.c:2107
+ pvr2_hdw_setup drivers/media/usb/pvrusb2/pvrusb2-hdw.c:2250
+ pvr2_hdw_initialize+0x548/0x3c10 drivers/media/usb/pvrusb2/pvrusb2-hdw.c:2327
+ pvr2_context_check drivers/media/usb/pvrusb2/pvrusb2-context.c:118
+ pvr2_context_thread_func+0x361/0x8c0 drivers/media/usb/pvrusb2/pvrusb2-context.c:167
+ kthread+0x3a1/0x470 kernel/kthread.c:231
+ ret_from_fork+0x2a/0x40 arch/x86/entry/entry_64.S:431
+Code: 48 8b 85 30 ff ff ff 48 8d b8 98 00 00 00 e8 ee 82 89 fe 45 89
+e8 44 89 f1 4c 89 fa 48 89 c6 48 c7 c7 40 c0 ea 86 e8 30 1b dc fc <0f>
+ff e9 9b f7 ff ff e8 aa 95 25 fd e9 80 f7 ff ff e8 50 74 f3
+---[ end trace 6919030503719da6 ]---
+
+Signed-off-by: Andrey Konovalov <andreyknvl@google.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>
+
+---
+ drivers/media/usb/pvrusb2/pvrusb2-hdw.c | 12 ++++++++++++
+ 1 file changed, 12 insertions(+)
+
+--- a/drivers/media/usb/pvrusb2/pvrusb2-hdw.c
++++ b/drivers/media/usb/pvrusb2/pvrusb2-hdw.c
+@@ -3648,6 +3648,12 @@ static int pvr2_send_request_ex(struct p
+ hdw);
+ hdw->ctl_write_urb->actual_length = 0;
+ hdw->ctl_write_pend_flag = !0;
++ if (usb_urb_ep_type_check(hdw->ctl_write_urb)) {
++ pvr2_trace(
++ PVR2_TRACE_ERROR_LEGS,
++ "Invalid write control endpoint");
++ return -EINVAL;
++ }
+ status = usb_submit_urb(hdw->ctl_write_urb,GFP_KERNEL);
+ if (status < 0) {
+ pvr2_trace(PVR2_TRACE_ERROR_LEGS,
+@@ -3672,6 +3678,12 @@ status);
+ hdw);
+ hdw->ctl_read_urb->actual_length = 0;
+ hdw->ctl_read_pend_flag = !0;
++ if (usb_urb_ep_type_check(hdw->ctl_read_urb)) {
++ pvr2_trace(
++ PVR2_TRACE_ERROR_LEGS,
++ "Invalid read control endpoint");
++ return -EINVAL;
++ }
+ status = usb_submit_urb(hdw->ctl_read_urb,GFP_KERNEL);
+ if (status < 0) {
+ pvr2_trace(PVR2_TRACE_ERROR_LEGS,
--- /dev/null
+From 8d74e9f88d65af8bb2e095aff506aa6eac755ada Mon Sep 17 00:00:00 2001
+From: Willem de Bruijn <willemb@google.com>
+Date: Tue, 12 Dec 2017 11:39:04 -0500
+Subject: net: avoid skb_warn_bad_offload on IS_ERR
+
+From: Willem de Bruijn <willemb@google.com>
+
+commit 8d74e9f88d65af8bb2e095aff506aa6eac755ada upstream.
+
+skb_warn_bad_offload warns when packets enter the GSO stack that
+require skb_checksum_help or vice versa. Do not warn on arbitrary
+bad packets. Packet sockets can craft many. Syzkaller was able to
+demonstrate another one with eth_type games.
+
+In particular, suppress the warning when segmentation returns an
+error, which is for reasons other than checksum offload.
+
+See also commit 36c92474498a ("net: WARN if skb_checksum_help() is
+called on skb requiring segmentation") for context on this warning.
+
+Signed-off-by: Willem de Bruijn <willemb@google.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ net/core/dev.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/net/core/dev.c
++++ b/net/core/dev.c
+@@ -2815,7 +2815,7 @@ struct sk_buff *__skb_gso_segment(struct
+
+ segs = skb_mac_gso_segment(skb, features);
+
+- if (unlikely(skb_needs_check(skb, tx_path)))
++ if (unlikely(skb_needs_check(skb, tx_path) && !IS_ERR(segs)))
+ skb_warn_bad_offload(skb);
+
+ return segs;
--- /dev/null
+From 40ca54e3a686f13117f3de0c443f8026dadf7c44 Mon Sep 17 00:00:00 2001
+From: Eric Dumazet <edumazet@google.com>
+Date: Sat, 27 Jan 2018 10:58:43 -0800
+Subject: net_sched: gen_estimator: fix lockdep splat
+
+From: Eric Dumazet <edumazet@google.com>
+
+commit 40ca54e3a686f13117f3de0c443f8026dadf7c44 upstream.
+
+syzbot reported a lockdep splat in gen_new_estimator() /
+est_fetch_counters() when attempting to lock est->stats_lock.
+
+Since est_fetch_counters() is called from BH context from timer
+interrupt, we need to block BH as well when calling it from process
+context.
+
+Most qdiscs use per cpu counters and are immune to the problem,
+but net/sched/act_api.c and net/netfilter/xt_RATEEST.c are using
+a spinlock to protect their data. They both call gen_new_estimator()
+while object is created and not yet alive, so this bug could
+not trigger a deadlock, only a lockdep splat.
+
+Fixes: 1c0d32fde5bd ("net_sched: gen_estimator: complete rewrite of rate estimators")
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Reported-by: syzbot <syzkaller@googlegroups.com>
+Acked-by: Cong Wang <xiyou.wangcong@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ net/core/gen_estimator.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+--- a/net/core/gen_estimator.c
++++ b/net/core/gen_estimator.c
+@@ -159,7 +159,11 @@ int gen_new_estimator(struct gnet_stats_
+ est->intvl_log = intvl_log;
+ est->cpu_bstats = cpu_bstats;
+
++ if (stats_lock)
++ local_bh_disable();
+ est_fetch_counters(est, &b);
++ if (stats_lock)
++ local_bh_enable();
+ est->last_bytes = b.bytes;
+ est->last_packets = b.packets;
+ old = rcu_dereference_protected(*rate_est, 1);
--- /dev/null
+From 1a38956cce5eabd7b74f94bab70265e4df83165e Mon Sep 17 00:00:00 2001
+From: Dmitry Vyukov <dvyukov@google.com>
+Date: Tue, 30 Jan 2018 15:21:34 +0100
+Subject: netfilter: ipt_CLUSTERIP: fix out-of-bounds accesses in clusterip_tg_check()
+
+From: Dmitry Vyukov <dvyukov@google.com>
+
+commit 1a38956cce5eabd7b74f94bab70265e4df83165e upstream.
+
+Commit 136e92bbec0a switched local_nodes from an array to a bitmask
+but did not add proper bounds checks. As the result
+clusterip_config_init_nodelist() can both over-read
+ipt_clusterip_tgt_info.local_nodes and over-write
+clusterip_config.local_nodes.
+
+Add bounds checks for both.
+
+Fixes: 136e92bbec0a ("[NETFILTER] CLUSTERIP: use a bitmap to store node responsibility data")
+Signed-off-by: Dmitry Vyukov <dvyukov@google.com>
+Reported-by: syzbot <syzkaller@googlegroups.com>
+Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ net/ipv4/netfilter/ipt_CLUSTERIP.c | 16 +++++++++++++---
+ 1 file changed, 13 insertions(+), 3 deletions(-)
+
+--- a/net/ipv4/netfilter/ipt_CLUSTERIP.c
++++ b/net/ipv4/netfilter/ipt_CLUSTERIP.c
+@@ -431,7 +431,7 @@ static int clusterip_tg_check(const stru
+ struct ipt_clusterip_tgt_info *cipinfo = par->targinfo;
+ const struct ipt_entry *e = par->entryinfo;
+ struct clusterip_config *config;
+- int ret;
++ int ret, i;
+
+ if (par->nft_compat) {
+ pr_err("cannot use CLUSTERIP target from nftables compat\n");
+@@ -450,8 +450,18 @@ static int clusterip_tg_check(const stru
+ pr_info("Please specify destination IP\n");
+ return -EINVAL;
+ }
+-
+- /* FIXME: further sanity checks */
++ if (cipinfo->num_local_nodes > ARRAY_SIZE(cipinfo->local_nodes)) {
++ pr_info("bad num_local_nodes %u\n", cipinfo->num_local_nodes);
++ return -EINVAL;
++ }
++ for (i = 0; i < cipinfo->num_local_nodes; i++) {
++ if (cipinfo->local_nodes[i] - 1 >=
++ sizeof(config->local_nodes) * 8) {
++ pr_info("bad local_nodes[%d] %u\n",
++ i, cipinfo->local_nodes[i]);
++ return -EINVAL;
++ }
++ }
+
+ config = clusterip_config_find_get(par->net, e->ip.dst.s_addr, 1);
+ if (!config) {
--- /dev/null
+From 3f34cfae1238848fd53f25e5c8fd59da57901f4b Mon Sep 17 00:00:00 2001
+From: Paolo Abeni <pabeni@redhat.com>
+Date: Tue, 30 Jan 2018 19:01:40 +0100
+Subject: netfilter: on sockopt() acquire sock lock only in the required scope
+
+From: Paolo Abeni <pabeni@redhat.com>
+
+commit 3f34cfae1238848fd53f25e5c8fd59da57901f4b upstream.
+
+Syzbot reported several deadlocks in the netfilter area caused by
+rtnl lock and socket lock being acquired with a different order on
+different code paths, leading to backtraces like the following one:
+
+======================================================
+WARNING: possible circular locking dependency detected
+4.15.0-rc9+ #212 Not tainted
+------------------------------------------------------
+syzkaller041579/3682 is trying to acquire lock:
+ (sk_lock-AF_INET6){+.+.}, at: [<000000008775e4dd>] lock_sock
+include/net/sock.h:1463 [inline]
+ (sk_lock-AF_INET6){+.+.}, at: [<000000008775e4dd>]
+do_ipv6_setsockopt.isra.8+0x3c5/0x39d0 net/ipv6/ipv6_sockglue.c:167
+
+but task is already holding lock:
+ (rtnl_mutex){+.+.}, at: [<000000004342eaa9>] rtnl_lock+0x17/0x20
+net/core/rtnetlink.c:74
+
+which lock already depends on the new lock.
+
+the existing dependency chain (in reverse order) is:
+
+-> #1 (rtnl_mutex){+.+.}:
+ __mutex_lock_common kernel/locking/mutex.c:756 [inline]
+ __mutex_lock+0x16f/0x1a80 kernel/locking/mutex.c:893
+ mutex_lock_nested+0x16/0x20 kernel/locking/mutex.c:908
+ rtnl_lock+0x17/0x20 net/core/rtnetlink.c:74
+ register_netdevice_notifier+0xad/0x860 net/core/dev.c:1607
+ tee_tg_check+0x1a0/0x280 net/netfilter/xt_TEE.c:106
+ xt_check_target+0x22c/0x7d0 net/netfilter/x_tables.c:845
+ check_target net/ipv6/netfilter/ip6_tables.c:538 [inline]
+ find_check_entry.isra.7+0x935/0xcf0
+net/ipv6/netfilter/ip6_tables.c:580
+ translate_table+0xf52/0x1690 net/ipv6/netfilter/ip6_tables.c:749
+ do_replace net/ipv6/netfilter/ip6_tables.c:1165 [inline]
+ do_ip6t_set_ctl+0x370/0x5f0 net/ipv6/netfilter/ip6_tables.c:1691
+ nf_sockopt net/netfilter/nf_sockopt.c:106 [inline]
+ nf_setsockopt+0x67/0xc0 net/netfilter/nf_sockopt.c:115
+ ipv6_setsockopt+0x115/0x150 net/ipv6/ipv6_sockglue.c:928
+ udpv6_setsockopt+0x45/0x80 net/ipv6/udp.c:1422
+ sock_common_setsockopt+0x95/0xd0 net/core/sock.c:2978
+ SYSC_setsockopt net/socket.c:1849 [inline]
+ SyS_setsockopt+0x189/0x360 net/socket.c:1828
+ entry_SYSCALL_64_fastpath+0x29/0xa0
+
+-> #0 (sk_lock-AF_INET6){+.+.}:
+ lock_acquire+0x1d5/0x580 kernel/locking/lockdep.c:3914
+ lock_sock_nested+0xc2/0x110 net/core/sock.c:2780
+ lock_sock include/net/sock.h:1463 [inline]
+ do_ipv6_setsockopt.isra.8+0x3c5/0x39d0 net/ipv6/ipv6_sockglue.c:167
+ ipv6_setsockopt+0xd7/0x150 net/ipv6/ipv6_sockglue.c:922
+ udpv6_setsockopt+0x45/0x80 net/ipv6/udp.c:1422
+ sock_common_setsockopt+0x95/0xd0 net/core/sock.c:2978
+ SYSC_setsockopt net/socket.c:1849 [inline]
+ SyS_setsockopt+0x189/0x360 net/socket.c:1828
+ entry_SYSCALL_64_fastpath+0x29/0xa0
+
+other info that might help us debug this:
+
+ Possible unsafe locking scenario:
+
+ CPU0 CPU1
+ ---- ----
+ lock(rtnl_mutex);
+ lock(sk_lock-AF_INET6);
+ lock(rtnl_mutex);
+ lock(sk_lock-AF_INET6);
+
+ *** DEADLOCK ***
+
+1 lock held by syzkaller041579/3682:
+ #0: (rtnl_mutex){+.+.}, at: [<000000004342eaa9>] rtnl_lock+0x17/0x20
+net/core/rtnetlink.c:74
+
+The problem, as Florian noted, is that nf_setsockopt() is always
+called with the socket held, even if the lock itself is required only
+for very tight scopes and only for some operation.
+
+This patch addresses the issues moving the lock_sock() call only
+where really needed, namely in ipv*_getorigdst(), so that nf_setsockopt()
+does not need anymore to acquire both locks.
+
+Fixes: 22265a5c3c10 ("netfilter: xt_TEE: resolve oif using netdevice notifiers")
+Reported-by: syzbot+a4c2dc980ac1af699b36@syzkaller.appspotmail.com
+Suggested-by: Florian Westphal <fw@strlen.de>
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ net/ipv4/ip_sockglue.c | 14 ++++----------
+ net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c | 6 +++++-
+ net/ipv6/ipv6_sockglue.c | 17 +++++------------
+ net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c | 18 ++++++++++++------
+ 4 files changed, 26 insertions(+), 29 deletions(-)
+
+--- a/net/ipv4/ip_sockglue.c
++++ b/net/ipv4/ip_sockglue.c
+@@ -1251,11 +1251,8 @@ int ip_setsockopt(struct sock *sk, int l
+ if (err == -ENOPROTOOPT && optname != IP_HDRINCL &&
+ optname != IP_IPSEC_POLICY &&
+ optname != IP_XFRM_POLICY &&
+- !ip_mroute_opt(optname)) {
+- lock_sock(sk);
++ !ip_mroute_opt(optname))
+ err = nf_setsockopt(sk, PF_INET, optname, optval, optlen);
+- release_sock(sk);
+- }
+ #endif
+ return err;
+ }
+@@ -1280,12 +1277,9 @@ int compat_ip_setsockopt(struct sock *sk
+ if (err == -ENOPROTOOPT && optname != IP_HDRINCL &&
+ optname != IP_IPSEC_POLICY &&
+ optname != IP_XFRM_POLICY &&
+- !ip_mroute_opt(optname)) {
+- lock_sock(sk);
+- err = compat_nf_setsockopt(sk, PF_INET, optname,
+- optval, optlen);
+- release_sock(sk);
+- }
++ !ip_mroute_opt(optname))
++ err = compat_nf_setsockopt(sk, PF_INET, optname, optval,
++ optlen);
+ #endif
+ return err;
+ }
+--- a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
++++ b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
+@@ -218,15 +218,19 @@ getorigdst(struct sock *sk, int optval,
+ struct nf_conntrack_tuple tuple;
+
+ memset(&tuple, 0, sizeof(tuple));
++
++ lock_sock(sk);
+ tuple.src.u3.ip = inet->inet_rcv_saddr;
+ tuple.src.u.tcp.port = inet->inet_sport;
+ tuple.dst.u3.ip = inet->inet_daddr;
+ tuple.dst.u.tcp.port = inet->inet_dport;
+ tuple.src.l3num = PF_INET;
+ tuple.dst.protonum = sk->sk_protocol;
++ release_sock(sk);
+
+ /* We only do TCP and SCTP at the moment: is there a better way? */
+- if (sk->sk_protocol != IPPROTO_TCP && sk->sk_protocol != IPPROTO_SCTP) {
++ if (tuple.dst.protonum != IPPROTO_TCP &&
++ tuple.dst.protonum != IPPROTO_SCTP) {
+ pr_debug("SO_ORIGINAL_DST: Not a TCP/SCTP socket\n");
+ return -ENOPROTOOPT;
+ }
+--- a/net/ipv6/ipv6_sockglue.c
++++ b/net/ipv6/ipv6_sockglue.c
+@@ -923,12 +923,8 @@ int ipv6_setsockopt(struct sock *sk, int
+ #ifdef CONFIG_NETFILTER
+ /* we need to exclude all possible ENOPROTOOPTs except default case */
+ if (err == -ENOPROTOOPT && optname != IPV6_IPSEC_POLICY &&
+- optname != IPV6_XFRM_POLICY) {
+- lock_sock(sk);
+- err = nf_setsockopt(sk, PF_INET6, optname, optval,
+- optlen);
+- release_sock(sk);
+- }
++ optname != IPV6_XFRM_POLICY)
++ err = nf_setsockopt(sk, PF_INET6, optname, optval, optlen);
+ #endif
+ return err;
+ }
+@@ -958,12 +954,9 @@ int compat_ipv6_setsockopt(struct sock *
+ #ifdef CONFIG_NETFILTER
+ /* we need to exclude all possible ENOPROTOOPTs except default case */
+ if (err == -ENOPROTOOPT && optname != IPV6_IPSEC_POLICY &&
+- optname != IPV6_XFRM_POLICY) {
+- lock_sock(sk);
+- err = compat_nf_setsockopt(sk, PF_INET6, optname,
+- optval, optlen);
+- release_sock(sk);
+- }
++ optname != IPV6_XFRM_POLICY)
++ err = compat_nf_setsockopt(sk, PF_INET6, optname, optval,
++ optlen);
+ #endif
+ return err;
+ }
+--- a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
++++ b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
+@@ -226,20 +226,27 @@ static const struct nf_hook_ops ipv6_con
+ static int
+ ipv6_getorigdst(struct sock *sk, int optval, void __user *user, int *len)
+ {
+- const struct inet_sock *inet = inet_sk(sk);
++ struct nf_conntrack_tuple tuple = { .src.l3num = NFPROTO_IPV6 };
+ const struct ipv6_pinfo *inet6 = inet6_sk(sk);
++ const struct inet_sock *inet = inet_sk(sk);
+ const struct nf_conntrack_tuple_hash *h;
+ struct sockaddr_in6 sin6;
+- struct nf_conntrack_tuple tuple = { .src.l3num = NFPROTO_IPV6 };
+ struct nf_conn *ct;
++ __be32 flow_label;
++ int bound_dev_if;
+
++ lock_sock(sk);
+ tuple.src.u3.in6 = sk->sk_v6_rcv_saddr;
+ tuple.src.u.tcp.port = inet->inet_sport;
+ tuple.dst.u3.in6 = sk->sk_v6_daddr;
+ tuple.dst.u.tcp.port = inet->inet_dport;
+ tuple.dst.protonum = sk->sk_protocol;
++ bound_dev_if = sk->sk_bound_dev_if;
++ flow_label = inet6->flow_label;
++ release_sock(sk);
+
+- if (sk->sk_protocol != IPPROTO_TCP && sk->sk_protocol != IPPROTO_SCTP)
++ if (tuple.dst.protonum != IPPROTO_TCP &&
++ tuple.dst.protonum != IPPROTO_SCTP)
+ return -ENOPROTOOPT;
+
+ if (*len < 0 || (unsigned int) *len < sizeof(sin6))
+@@ -257,14 +264,13 @@ ipv6_getorigdst(struct sock *sk, int opt
+
+ sin6.sin6_family = AF_INET6;
+ sin6.sin6_port = ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.u.tcp.port;
+- sin6.sin6_flowinfo = inet6->flow_label & IPV6_FLOWINFO_MASK;
++ sin6.sin6_flowinfo = flow_label & IPV6_FLOWINFO_MASK;
+ memcpy(&sin6.sin6_addr,
+ &ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.u3.in6,
+ sizeof(sin6.sin6_addr));
+
+ nf_ct_put(ct);
+- sin6.sin6_scope_id = ipv6_iface_scope_id(&sin6.sin6_addr,
+- sk->sk_bound_dev_if);
++ sin6.sin6_scope_id = ipv6_iface_scope_id(&sin6.sin6_addr, bound_dev_if);
+ return copy_to_user(user, &sin6, sizeof(sin6)) ? -EFAULT : 0;
+ }
+
--- /dev/null
+From da17c73b6eb74aad3c3c0654394635675b623b3e Mon Sep 17 00:00:00 2001
+From: Eric Dumazet <edumazet@google.com>
+Date: Wed, 24 Jan 2018 17:16:09 -0800
+Subject: netfilter: x_tables: avoid out-of-bounds reads in xt_request_find_{match|target}
+
+From: Eric Dumazet <edumazet@google.com>
+
+commit da17c73b6eb74aad3c3c0654394635675b623b3e upstream.
+
+It looks like syzbot found its way into netfilter territory.
+
+Issue here is that @name comes from user space and might
+not be null terminated.
+
+Out-of-bound reads happen, KASAN is not happy.
+
+v2 added similar fix for xt_request_find_target(),
+as Florian advised.
+
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Reported-by: syzbot <syzkaller@googlegroups.com>
+Acked-by: Florian Westphal <fw@strlen.de>
+Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ net/netfilter/x_tables.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+--- a/net/netfilter/x_tables.c
++++ b/net/netfilter/x_tables.c
+@@ -209,6 +209,9 @@ xt_request_find_match(uint8_t nfproto, c
+ {
+ struct xt_match *match;
+
++ if (strnlen(name, XT_EXTENSION_MAXNAMELEN) == XT_EXTENSION_MAXNAMELEN)
++ return ERR_PTR(-EINVAL);
++
+ match = xt_find_match(nfproto, name, revision);
+ if (IS_ERR(match)) {
+ request_module("%st_%s", xt_prefix[nfproto], name);
+@@ -251,6 +254,9 @@ struct xt_target *xt_request_find_target
+ {
+ struct xt_target *target;
+
++ if (strnlen(name, XT_EXTENSION_MAXNAMELEN) == XT_EXTENSION_MAXNAMELEN)
++ return ERR_PTR(-EINVAL);
++
+ target = xt_find_target(af, name, revision);
+ if (IS_ERR(target)) {
+ request_module("%st_%s", xt_prefix[af], name);
--- /dev/null
+From 889c604fd0b5f6d3b8694ade229ee44124de1127 Mon Sep 17 00:00:00 2001
+From: Dmitry Vyukov <dvyukov@google.com>
+Date: Thu, 28 Dec 2017 09:48:54 +0100
+Subject: netfilter: x_tables: fix int overflow in xt_alloc_table_info()
+
+From: Dmitry Vyukov <dvyukov@google.com>
+
+commit 889c604fd0b5f6d3b8694ade229ee44124de1127 upstream.
+
+syzkaller triggered OOM kills by passing ipt_replace.size = -1
+to IPT_SO_SET_REPLACE. The root cause is that SMP_ALIGN() in
+xt_alloc_table_info() causes int overflow and the size check passes
+when it should not. SMP_ALIGN() is no longer needed leftover.
+
+Remove SMP_ALIGN() call in xt_alloc_table_info().
+
+Reported-by: syzbot+4396883fa8c4f64e0175@syzkaller.appspotmail.com
+Signed-off-by: Dmitry Vyukov <dvyukov@google.com>
+Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ net/netfilter/x_tables.c | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+--- a/net/netfilter/x_tables.c
++++ b/net/netfilter/x_tables.c
+@@ -39,7 +39,6 @@ MODULE_LICENSE("GPL");
+ MODULE_AUTHOR("Harald Welte <laforge@netfilter.org>");
+ MODULE_DESCRIPTION("{ip,ip6,arp,eb}_tables backend module");
+
+-#define SMP_ALIGN(x) (((x) + SMP_CACHE_BYTES-1) & ~(SMP_CACHE_BYTES-1))
+ #define XT_PCPU_BLOCK_SIZE 4096
+
+ struct compat_delta {
+@@ -1000,7 +999,7 @@ struct xt_table_info *xt_alloc_table_inf
+ return NULL;
+
+ /* Pedantry: prevent them from hitting BUG() in vmalloc.c --RR */
+- if ((SMP_ALIGN(size) >> PAGE_SHIFT) + 2 > totalram_pages)
++ if ((size >> PAGE_SHIFT) + 2 > totalram_pages)
+ return NULL;
+
+ info = kvmalloc(sz, GFP_KERNEL);
--- /dev/null
+From ba7cd5d95f25cc6005f687dabdb4e7a6063adda9 Mon Sep 17 00:00:00 2001
+From: Cong Wang <xiyou.wangcong@gmail.com>
+Date: Wed, 31 Jan 2018 15:02:47 -0800
+Subject: netfilter: xt_cgroup: initialize info->priv in cgroup_mt_check_v1()
+
+From: Cong Wang <xiyou.wangcong@gmail.com>
+
+commit ba7cd5d95f25cc6005f687dabdb4e7a6063adda9 upstream.
+
+xt_cgroup_info_v1->priv is an internal pointer only used for kernel,
+we should not trust what user-space provides.
+
+Reported-by: <syzbot+4fbcfcc0d2e6592bd641@syzkaller.appspotmail.com>
+Fixes: c38c4597e4bf ("netfilter: implement xt_cgroup cgroup2 path match")
+Cc: Pablo Neira Ayuso <pablo@netfilter.org>
+Signed-off-by: Cong Wang <xiyou.wangcong@gmail.com>
+Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ net/netfilter/xt_cgroup.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/net/netfilter/xt_cgroup.c
++++ b/net/netfilter/xt_cgroup.c
+@@ -52,6 +52,7 @@ static int cgroup_mt_check_v1(const stru
+ return -EINVAL;
+ }
+
++ info->priv = NULL;
+ if (info->has_path) {
+ cgrp = cgroup_get_from_path(info->path);
+ if (IS_ERR(cgrp)) {
--- /dev/null
+From 7dc68e98757a8eccf8ca7a53a29b896f1eef1f76 Mon Sep 17 00:00:00 2001
+From: Cong Wang <xiyou.wangcong@gmail.com>
+Date: Mon, 5 Feb 2018 14:41:45 -0800
+Subject: netfilter: xt_RATEEST: acquire xt_rateest_mutex for hash insert
+
+From: Cong Wang <xiyou.wangcong@gmail.com>
+
+commit 7dc68e98757a8eccf8ca7a53a29b896f1eef1f76 upstream.
+
+rateest_hash is supposed to be protected by xt_rateest_mutex,
+and, as suggested by Eric, lookup and insert should be atomic,
+so we should acquire the xt_rateest_mutex once for both.
+
+So introduce a non-locking helper for internal use and keep the
+locking one for external.
+
+Reported-by: <syzbot+5cb189720978275e4c75@syzkaller.appspotmail.com>
+Fixes: 5859034d7eb8 ("[NETFILTER]: x_tables: add RATEEST target")
+Signed-off-by: Cong Wang <xiyou.wangcong@gmail.com>
+Reviewed-by: Florian Westphal <fw@strlen.de>
+Reviewed-by: Eric Dumazet <edumazet@google.com>
+Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ net/netfilter/xt_RATEEST.c | 22 +++++++++++++++++-----
+ 1 file changed, 17 insertions(+), 5 deletions(-)
+
+--- a/net/netfilter/xt_RATEEST.c
++++ b/net/netfilter/xt_RATEEST.c
+@@ -39,23 +39,31 @@ static void xt_rateest_hash_insert(struc
+ hlist_add_head(&est->list, &rateest_hash[h]);
+ }
+
+-struct xt_rateest *xt_rateest_lookup(const char *name)
++static struct xt_rateest *__xt_rateest_lookup(const char *name)
+ {
+ struct xt_rateest *est;
+ unsigned int h;
+
+ h = xt_rateest_hash(name);
+- mutex_lock(&xt_rateest_mutex);
+ hlist_for_each_entry(est, &rateest_hash[h], list) {
+ if (strcmp(est->name, name) == 0) {
+ est->refcnt++;
+- mutex_unlock(&xt_rateest_mutex);
+ return est;
+ }
+ }
+- mutex_unlock(&xt_rateest_mutex);
++
+ return NULL;
+ }
++
++struct xt_rateest *xt_rateest_lookup(const char *name)
++{
++ struct xt_rateest *est;
++
++ mutex_lock(&xt_rateest_mutex);
++ est = __xt_rateest_lookup(name);
++ mutex_unlock(&xt_rateest_mutex);
++ return est;
++}
+ EXPORT_SYMBOL_GPL(xt_rateest_lookup);
+
+ void xt_rateest_put(struct xt_rateest *est)
+@@ -100,8 +108,10 @@ static int xt_rateest_tg_checkentry(cons
+
+ net_get_random_once(&jhash_rnd, sizeof(jhash_rnd));
+
+- est = xt_rateest_lookup(info->name);
++ mutex_lock(&xt_rateest_mutex);
++ est = __xt_rateest_lookup(info->name);
+ if (est) {
++ mutex_unlock(&xt_rateest_mutex);
+ /*
+ * If estimator parameters are specified, they must match the
+ * existing estimator.
+@@ -139,11 +149,13 @@ static int xt_rateest_tg_checkentry(cons
+
+ info->est = est;
+ xt_rateest_hash_insert(est);
++ mutex_unlock(&xt_rateest_mutex);
+ return 0;
+
+ err2:
+ kfree(est);
+ err1:
++ mutex_unlock(&xt_rateest_mutex);
+ return ret;
+ }
+
--- /dev/null
+From 6e6e41c3112276288ccaf80c70916779b84bb276 Mon Sep 17 00:00:00 2001
+From: Jason Wang <jasowang@redhat.com>
+Date: Fri, 9 Feb 2018 17:45:49 +0800
+Subject: ptr_ring: fail early if queue occupies more than KMALLOC_MAX_SIZE
+
+From: Jason Wang <jasowang@redhat.com>
+
+commit 6e6e41c3112276288ccaf80c70916779b84bb276 upstream.
+
+To avoid slab to warn about exceeded size, fail early if queue
+occupies more than KMALLOC_MAX_SIZE.
+
+Reported-by: syzbot+e4d4f9ddd4295539735d@syzkaller.appspotmail.com
+Fixes: 2e0ab8ca83c12 ("ptr_ring: array based FIFO for pointers")
+Signed-off-by: Jason Wang <jasowang@redhat.com>
+Acked-by: Michael S. Tsirkin <mst@redhat.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ include/linux/ptr_ring.h | 2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/include/linux/ptr_ring.h
++++ b/include/linux/ptr_ring.h
+@@ -453,6 +453,8 @@ static inline int ptr_ring_consume_batch
+
+ static inline void **__ptr_ring_init_queue_alloc(unsigned int size, gfp_t gfp)
+ {
++ if (size * sizeof(void *) > KMALLOC_MAX_SIZE)
++ return NULL;
+ return kcalloc(size, sizeof(void *), gfp);
+ }
+
--- /dev/null
+From 0bf7800f1799b5b1fd7d4f024e9ece53ac489011 Mon Sep 17 00:00:00 2001
+From: Jason Wang <jasowang@redhat.com>
+Date: Fri, 9 Feb 2018 17:45:50 +0800
+Subject: ptr_ring: try vmalloc() when kmalloc() fails
+
+From: Jason Wang <jasowang@redhat.com>
+
+commit 0bf7800f1799b5b1fd7d4f024e9ece53ac489011 upstream.
+
+This patch switch to use kvmalloc_array() for using a vmalloc()
+fallback to help in case kmalloc() fails.
+
+Reported-by: syzbot+e4d4f9ddd4295539735d@syzkaller.appspotmail.com
+Fixes: 2e0ab8ca83c12 ("ptr_ring: array based FIFO for pointers")
+Signed-off-by: Jason Wang <jasowang@redhat.com>
+Acked-by: Michael S. Tsirkin <mst@redhat.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ include/linux/ptr_ring.h | 13 ++++++++-----
+ 1 file changed, 8 insertions(+), 5 deletions(-)
+
+--- a/include/linux/ptr_ring.h
++++ b/include/linux/ptr_ring.h
+@@ -451,11 +451,14 @@ static inline int ptr_ring_consume_batch
+ __PTR_RING_PEEK_CALL_v; \
+ })
+
++/* Not all gfp_t flags (besides GFP_KERNEL) are allowed. See
++ * documentation for vmalloc for which of them are legal.
++ */
+ static inline void **__ptr_ring_init_queue_alloc(unsigned int size, gfp_t gfp)
+ {
+ if (size * sizeof(void *) > KMALLOC_MAX_SIZE)
+ return NULL;
+- return kcalloc(size, sizeof(void *), gfp);
++ return kvmalloc_array(size, sizeof(void *), gfp | __GFP_ZERO);
+ }
+
+ static inline void __ptr_ring_set_size(struct ptr_ring *r, int size)
+@@ -588,7 +591,7 @@ static inline int ptr_ring_resize(struct
+ spin_unlock(&(r)->producer_lock);
+ spin_unlock_irqrestore(&(r)->consumer_lock, flags);
+
+- kfree(old);
++ kvfree(old);
+
+ return 0;
+ }
+@@ -628,7 +631,7 @@ static inline int ptr_ring_resize_multip
+ }
+
+ for (i = 0; i < nrings; ++i)
+- kfree(queues[i]);
++ kvfree(queues[i]);
+
+ kfree(queues);
+
+@@ -636,7 +639,7 @@ static inline int ptr_ring_resize_multip
+
+ nomem:
+ while (--i >= 0)
+- kfree(queues[i]);
++ kvfree(queues[i]);
+
+ kfree(queues);
+
+@@ -651,7 +654,7 @@ static inline void ptr_ring_cleanup(stru
+ if (destroy)
+ while ((ptr = ptr_ring_consume(r)))
+ destroy(ptr);
+- kfree(r->queue);
++ kvfree(r->queue);
+ }
+
+ #endif /* _LINUX_PTR_RING_H */
--- /dev/null
+From f10b4cff98c6977668434fbf5dd58695eeca2897 Mon Sep 17 00:00:00 2001
+From: Sowmini Varadhan <sowmini.varadhan@oracle.com>
+Date: Thu, 30 Nov 2017 11:11:29 -0800
+Subject: rds: tcp: atomically purge entries from rds_tcp_conn_list during netns delete
+
+From: Sowmini Varadhan <sowmini.varadhan@oracle.com>
+
+commit f10b4cff98c6977668434fbf5dd58695eeca2897 upstream.
+
+The rds_tcp_kill_sock() function parses the rds_tcp_conn_list
+to find the rds_connection entries marked for deletion as part
+of the netns deletion under the protection of the rds_tcp_conn_lock.
+Since the rds_tcp_conn_list tracks rds_tcp_connections (which
+have a 1:1 mapping with rds_conn_path), multiple tc entries in
+the rds_tcp_conn_list will map to a single rds_connection, and will
+be deleted as part of the rds_conn_destroy() operation that is
+done outside the rds_tcp_conn_lock.
+
+The rds_tcp_conn_list traversal done under the protection of
+rds_tcp_conn_lock should not leave any doomed tc entries in
+the list after the rds_tcp_conn_lock is released, else another
+concurrently executiong netns delete (for a differnt netns) thread
+may trip on these entries.
+
+Reported-by: syzbot <syzkaller@googlegroups.com>
+Signed-off-by: Sowmini Varadhan <sowmini.varadhan@oracle.com>
+Acked-by: Santosh Shilimkar <santosh.shilimkar@oracle.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ net/rds/tcp.c | 9 +++++++--
+ net/rds/tcp.h | 1 +
+ 2 files changed, 8 insertions(+), 2 deletions(-)
+
+--- a/net/rds/tcp.c
++++ b/net/rds/tcp.c
+@@ -307,7 +307,8 @@ static void rds_tcp_conn_free(void *arg)
+ rdsdebug("freeing tc %p\n", tc);
+
+ spin_lock_irqsave(&rds_tcp_conn_lock, flags);
+- list_del(&tc->t_tcp_node);
++ if (!tc->t_tcp_node_detached)
++ list_del(&tc->t_tcp_node);
+ spin_unlock_irqrestore(&rds_tcp_conn_lock, flags);
+
+ kmem_cache_free(rds_tcp_conn_slab, tc);
+@@ -532,8 +533,12 @@ static void rds_tcp_kill_sock(struct net
+
+ if (net != c_net || !tc->t_sock)
+ continue;
+- if (!list_has_conn(&tmp_list, tc->t_cpath->cp_conn))
++ if (!list_has_conn(&tmp_list, tc->t_cpath->cp_conn)) {
+ list_move_tail(&tc->t_tcp_node, &tmp_list);
++ } else {
++ list_del(&tc->t_tcp_node);
++ tc->t_tcp_node_detached = true;
++ }
+ }
+ spin_unlock_irq(&rds_tcp_conn_lock);
+ list_for_each_entry_safe(tc, _tc, &tmp_list, t_tcp_node) {
+--- a/net/rds/tcp.h
++++ b/net/rds/tcp.h
+@@ -12,6 +12,7 @@ struct rds_tcp_incoming {
+ struct rds_tcp_connection {
+
+ struct list_head t_tcp_node;
++ bool t_tcp_node_detached;
+ struct rds_conn_path *t_cpath;
+ /* t_conn_path_lock synchronizes the connection establishment between
+ * rds_tcp_accept_one and rds_tcp_conn_path_connect
--- /dev/null
+From 681648e67d43cf269c5590ecf021ed481f4551fc Mon Sep 17 00:00:00 2001
+From: Sowmini Varadhan <sowmini.varadhan@oracle.com>
+Date: Thu, 30 Nov 2017 11:11:28 -0800
+Subject: rds: tcp: correctly sequence cleanup on netns deletion.
+
+From: Sowmini Varadhan <sowmini.varadhan@oracle.com>
+
+commit 681648e67d43cf269c5590ecf021ed481f4551fc upstream.
+
+Commit 8edc3affc077 ("rds: tcp: Take explicit refcounts on struct net")
+introduces a regression in rds-tcp netns cleanup. The cleanup_net(),
+(and thus rds_tcp_dev_event notification) is only called from put_net()
+when all netns refcounts go to 0, but this cannot happen if the
+rds_connection itself is holding a c_net ref that it expects to
+release in rds_tcp_kill_sock.
+
+Instead, the rds_tcp_kill_sock callback should make sure to
+tear down state carefully, ensuring that the socket teardown
+is only done after all data-structures and workqs that depend
+on it are quiesced.
+
+The original motivation for commit 8edc3affc077 ("rds: tcp: Take explicit
+refcounts on struct net") was to resolve a race condition reported by
+syzkaller where workqs for tx/rx/connect were triggered after the
+namespace was deleted. Those worker threads should have been
+cancelled/flushed before socket tear-down and indeed,
+rds_conn_path_destroy() does try to sequence this by doing
+ /* cancel cp_send_w */
+ /* cancel cp_recv_w */
+ /* flush cp_down_w */
+ /* free data structures */
+Here the "flush cp_down_w" will trigger rds_conn_shutdown and thus
+invoke rds_tcp_conn_path_shutdown() to close the tcp socket, so that
+we ought to have satisfied the requirement that "socket-close is
+done after all other dependent state is quiesced". However,
+rds_conn_shutdown has a bug in that it *always* triggers the reconnect
+workq (and if connection is successful, we always restart tx/rx
+workqs so with the right timing, we risk the race conditions reported
+by syzkaller).
+
+Netns deletion is like module teardown- no need to restart a
+reconnect in this case. We can use the c_destroy_in_prog bit
+to avoid restarting the reconnect.
+
+Fixes: 8edc3affc077 ("rds: tcp: Take explicit refcounts on struct net")
+Signed-off-by: Sowmini Varadhan <sowmini.varadhan@oracle.com>
+Acked-by: Santosh Shilimkar <santosh.shilimkar@oracle.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ net/rds/connection.c | 3 ++-
+ net/rds/rds.h | 6 +++---
+ net/rds/tcp.c | 4 ++--
+ 3 files changed, 7 insertions(+), 6 deletions(-)
+
+--- a/net/rds/connection.c
++++ b/net/rds/connection.c
+@@ -366,6 +366,8 @@ void rds_conn_shutdown(struct rds_conn_p
+ * to the conn hash, so we never trigger a reconnect on this
+ * conn - the reconnect is always triggered by the active peer. */
+ cancel_delayed_work_sync(&cp->cp_conn_w);
++ if (conn->c_destroy_in_prog)
++ return;
+ rcu_read_lock();
+ if (!hlist_unhashed(&conn->c_hash_node)) {
+ rcu_read_unlock();
+@@ -445,7 +447,6 @@ void rds_conn_destroy(struct rds_connect
+ */
+ rds_cong_remove_conn(conn);
+
+- put_net(conn->c_net);
+ kfree(conn->c_path);
+ kmem_cache_free(rds_conn_slab, conn);
+
+--- a/net/rds/rds.h
++++ b/net/rds/rds.h
+@@ -150,7 +150,7 @@ struct rds_connection {
+
+ /* Protocol version */
+ unsigned int c_version;
+- struct net *c_net;
++ possible_net_t c_net;
+
+ struct list_head c_map_item;
+ unsigned long c_map_queued;
+@@ -165,13 +165,13 @@ struct rds_connection {
+ static inline
+ struct net *rds_conn_net(struct rds_connection *conn)
+ {
+- return conn->c_net;
++ return read_pnet(&conn->c_net);
+ }
+
+ static inline
+ void rds_conn_net_set(struct rds_connection *conn, struct net *net)
+ {
+- conn->c_net = get_net(net);
++ write_pnet(&conn->c_net, net);
+ }
+
+ #define RDS_FLAG_CONG_BITMAP 0x01
+--- a/net/rds/tcp.c
++++ b/net/rds/tcp.c
+@@ -528,7 +528,7 @@ static void rds_tcp_kill_sock(struct net
+ rds_tcp_listen_stop(lsock, &rtn->rds_tcp_accept_w);
+ spin_lock_irq(&rds_tcp_conn_lock);
+ list_for_each_entry_safe(tc, _tc, &rds_tcp_conn_list, t_tcp_node) {
+- struct net *c_net = tc->t_cpath->cp_conn->c_net;
++ struct net *c_net = read_pnet(&tc->t_cpath->cp_conn->c_net);
+
+ if (net != c_net || !tc->t_sock)
+ continue;
+@@ -587,7 +587,7 @@ static void rds_tcp_sysctl_reset(struct
+
+ spin_lock_irq(&rds_tcp_conn_lock);
+ list_for_each_entry_safe(tc, _tc, &rds_tcp_conn_list, t_tcp_node) {
+- struct net *c_net = tc->t_cpath->cp_conn->c_net;
++ struct net *c_net = read_pnet(&tc->t_cpath->cp_conn->c_net);
+
+ if (net != c_net || !tc->t_sock)
+ continue;
--- /dev/null
+From ef28df55ac27e1e5cd122e19fa311d886d47a756 Mon Sep 17 00:00:00 2001
+From: Paul Moore <paul@paul-moore.com>
+Date: Tue, 28 Nov 2017 18:51:12 -0500
+Subject: selinux: ensure the context is NUL terminated in security_context_to_sid_core()
+
+From: Paul Moore <paul@paul-moore.com>
+
+commit ef28df55ac27e1e5cd122e19fa311d886d47a756 upstream.
+
+The syzbot/syzkaller automated tests found a problem in
+security_context_to_sid_core() during early boot (before we load the
+SELinux policy) where we could potentially feed context strings without
+NUL terminators into the strcmp() function.
+
+We already guard against this during normal operation (after the SELinux
+policy has been loaded) by making a copy of the context strings and
+explicitly adding a NUL terminator to the end. The patch extends this
+protection to the early boot case (no loaded policy) by moving the context
+copy earlier in security_context_to_sid_core().
+
+Reported-by: syzbot <syzkaller@googlegroups.com>
+Signed-off-by: Paul Moore <paul@paul-moore.com>
+Reviewed-By: William Roberts <william.c.roberts@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ security/selinux/ss/services.c | 18 ++++++++----------
+ 1 file changed, 8 insertions(+), 10 deletions(-)
+
+--- a/security/selinux/ss/services.c
++++ b/security/selinux/ss/services.c
+@@ -1413,27 +1413,25 @@ static int security_context_to_sid_core(
+ if (!scontext_len)
+ return -EINVAL;
+
++ /* Copy the string to allow changes and ensure a NUL terminator */
++ scontext2 = kmemdup_nul(scontext, scontext_len, gfp_flags);
++ if (!scontext2)
++ return -ENOMEM;
++
+ if (!ss_initialized) {
+ int i;
+
+ for (i = 1; i < SECINITSID_NUM; i++) {
+- if (!strcmp(initial_sid_to_string[i], scontext)) {
++ if (!strcmp(initial_sid_to_string[i], scontext2)) {
+ *sid = i;
+- return 0;
++ goto out;
+ }
+ }
+ *sid = SECINITSID_KERNEL;
+- return 0;
++ goto out;
+ }
+ *sid = SECSID_NULL;
+
+- /* Copy the string so that we can modify the copy as we parse it. */
+- scontext2 = kmalloc(scontext_len + 1, gfp_flags);
+- if (!scontext2)
+- return -ENOMEM;
+- memcpy(scontext2, scontext, scontext_len);
+- scontext2[scontext_len] = 0;
+-
+ if (force) {
+ /* Save another copy for storing in uninterpreted form */
+ rc = -ENOMEM;
--- /dev/null
+From 4b14752ec4e0d87126e636384cf37c8dd9df157c Mon Sep 17 00:00:00 2001
+From: Paul Moore <paul@paul-moore.com>
+Date: Tue, 5 Dec 2017 17:17:43 -0500
+Subject: selinux: skip bounded transition processing if the policy isn't loaded
+
+From: Paul Moore <paul@paul-moore.com>
+
+commit 4b14752ec4e0d87126e636384cf37c8dd9df157c upstream.
+
+We can't do anything reasonable in security_bounded_transition() if we
+don't have a policy loaded, and in fact we could run into problems
+with some of the code inside expecting a policy. Fix these problems
+like we do many others in security/selinux/ss/services.c by checking
+to see if the policy is loaded (ss_initialized) and returning quickly
+if it isn't.
+
+Reported-by: syzbot <syzkaller-bugs@googlegroups.com>
+Signed-off-by: Paul Moore <paul@paul-moore.com>
+Acked-by: Stephen Smalley <sds@tycho.nsa.gov>
+Reviewed-by: James Morris <james.l.morris@oracle.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ security/selinux/ss/services.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+--- a/security/selinux/ss/services.c
++++ b/security/selinux/ss/services.c
+@@ -867,6 +867,9 @@ int security_bounded_transition(u32 old_
+ int index;
+ int rc;
+
++ if (!ss_initialized)
++ return 0;
++
+ read_lock(&policy_rwlock);
+
+ rc = -EINVAL;
--- /dev/null
+tun-fix-tun_napi_alloc_frags-frag-allocator.patch
+ptr_ring-fail-early-if-queue-occupies-more-than-kmalloc_max_size.patch
+ptr_ring-try-vmalloc-when-kmalloc-fails.patch
+selinux-ensure-the-context-is-nul-terminated-in-security_context_to_sid_core.patch
+selinux-skip-bounded-transition-processing-if-the-policy-isn-t-loaded.patch
+media-pvrusb2-properly-check-endpoint-types.patch
+crypto-x86-twofish-3way-fix-rbp-usage.patch
+staging-android-ion-add-__gfp_nowarn-for-system-contig-heap.patch
+staging-android-ion-switch-from-warn-to-pr_warn.patch
+blk_rq_map_user_iov-fix-error-override.patch
+kvm-x86-fix-escape-of-guest-dr6-to-the-host.patch
+kcov-detect-double-association-with-a-single-task.patch
+netfilter-x_tables-fix-int-overflow-in-xt_alloc_table_info.patch
+netfilter-x_tables-avoid-out-of-bounds-reads-in-xt_request_find_-match-target.patch
+netfilter-ipt_clusterip-fix-out-of-bounds-accesses-in-clusterip_tg_check.patch
+netfilter-on-sockopt-acquire-sock-lock-only-in-the-required-scope.patch
+netfilter-xt_cgroup-initialize-info-priv-in-cgroup_mt_check_v1.patch
+netfilter-xt_rateest-acquire-xt_rateest_mutex-for-hash-insert.patch
+rds-tcp-correctly-sequence-cleanup-on-netns-deletion.patch
+rds-tcp-atomically-purge-entries-from-rds_tcp_conn_list-during-netns-delete.patch
+net-avoid-skb_warn_bad_offload-on-is_err.patch
+net_sched-gen_estimator-fix-lockdep-splat.patch
--- /dev/null
+From 0c75f10312a35b149b2cebb1832316b35c2337ca Mon Sep 17 00:00:00 2001
+From: Laura Abbott <labbott@redhat.com>
+Date: Fri, 5 Jan 2018 11:14:08 -0800
+Subject: staging: android: ion: Add __GFP_NOWARN for system contig heap
+
+From: Laura Abbott <labbott@redhat.com>
+
+commit 0c75f10312a35b149b2cebb1832316b35c2337ca upstream.
+
+syzbot reported a warning from Ion:
+
+ WARNING: CPU: 1 PID: 3485 at mm/page_alloc.c:3926
+
+ ...
+ __alloc_pages_nodemask+0x9fb/0xd80 mm/page_alloc.c:4252
+ alloc_pages_current+0xb6/0x1e0 mm/mempolicy.c:2036
+ alloc_pages include/linux/gfp.h:492 [inline]
+ ion_system_contig_heap_allocate+0x40/0x2c0
+ drivers/staging/android/ion/ion_system_heap.c:374
+ ion_buffer_create drivers/staging/android/ion/ion.c:93 [inline]
+ ion_alloc+0x2c1/0x9e0 drivers/staging/android/ion/ion.c:420
+ ion_ioctl+0x26d/0x380 drivers/staging/android/ion/ion-ioctl.c:84
+ vfs_ioctl fs/ioctl.c:46 [inline]
+ do_vfs_ioctl+0x1b1/0x1520 fs/ioctl.c:686
+ SYSC_ioctl fs/ioctl.c:701 [inline]
+ SyS_ioctl+0x8f/0xc0 fs/ioctl.c:692
+
+This is a warning about attempting to allocate order > MAX_ORDER. This
+is coming from a userspace Ion allocation request. Since userspace is
+free to request however much memory it wants (and the kernel is free to
+deny its allocation), silence the allocation attempt with __GFP_NOWARN
+in case it fails.
+
+Reported-by: syzbot+76e7efc4748495855a4d@syzkaller.appspotmail.com
+Reported-by: syzbot <syzkaller@googlegroups.com>
+Signed-off-by: Laura Abbott <labbott@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/staging/android/ion/ion_system_heap.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/staging/android/ion/ion_system_heap.c
++++ b/drivers/staging/android/ion/ion_system_heap.c
+@@ -371,7 +371,7 @@ static int ion_system_contig_heap_alloca
+ unsigned long i;
+ int ret;
+
+- page = alloc_pages(low_order_gfp_flags, order);
++ page = alloc_pages(low_order_gfp_flags | __GFP_NOWARN, order);
+ if (!page)
+ return -ENOMEM;
+
--- /dev/null
+From e4e179a844f52e907e550f887d0a2171f1508af1 Mon Sep 17 00:00:00 2001
+From: Laura Abbott <labbott@redhat.com>
+Date: Fri, 5 Jan 2018 11:14:09 -0800
+Subject: staging: android: ion: Switch from WARN to pr_warn
+
+From: Laura Abbott <labbott@redhat.com>
+
+commit e4e179a844f52e907e550f887d0a2171f1508af1 upstream.
+
+Syzbot reported a warning with Ion:
+
+WARNING: CPU: 0 PID: 3502 at drivers/staging/android/ion/ion-ioctl.c:73 ion_ioctl+0x2db/0x380 drivers/staging/android/ion/ion-ioctl.c:73
+Kernel panic - not syncing: panic_on_warn set ...
+
+This is a warning that validation of the ioctl fields failed. This was
+deliberately added as a warning to make it very obvious to developers that
+something needed to be fixed. In reality, this is overkill and disturbs
+fuzzing. Switch to pr_warn for a message instead.
+
+Reported-by: syzbot+fa2d5f63ee5904a0115a@syzkaller.appspotmail.com
+Reported-by: syzbot <syzkaller@googlegroups.com>
+Signed-off-by: Laura Abbott <labbott@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/staging/android/ion/ion-ioctl.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+--- a/drivers/staging/android/ion/ion-ioctl.c
++++ b/drivers/staging/android/ion/ion-ioctl.c
+@@ -70,8 +70,10 @@ long ion_ioctl(struct file *filp, unsign
+ return -EFAULT;
+
+ ret = validate_ioctl_arg(cmd, &data);
+- if (WARN_ON_ONCE(ret))
++ if (ret) {
++ pr_warn_once("%s: ioctl validate failed\n", __func__);
+ return ret;
++ }
+
+ if (!(dir & _IOC_WRITE))
+ memset(&data, 0, sizeof(data));
--- /dev/null
+From 43a08e0f58b3f236165029710a4e3b303815253b Mon Sep 17 00:00:00 2001
+From: Eric Dumazet <edumazet@google.com>
+Date: Thu, 15 Feb 2018 14:47:15 -0800
+Subject: tun: fix tun_napi_alloc_frags() frag allocator
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Eric Dumazet <edumazet@google.com>
+
+commit 43a08e0f58b3f236165029710a4e3b303815253b upstream.
+
+<Mark Rutland reported>
+ While fuzzing arm64 v4.16-rc1 with Syzkaller, I've been hitting a
+ misaligned atomic in __skb_clone:
+
+ atomic_inc(&(skb_shinfo(skb)->dataref));
+
+ where dataref doesn't have the required natural alignment, and the
+ atomic operation faults. e.g. i often see it aligned to a single
+ byte boundary rather than a four byte boundary.
+
+ AFAICT, the skb_shared_info is misaligned at the instant it's
+ allocated in __napi_alloc_skb() __napi_alloc_skb()
+</end of report>
+
+Problem is caused by tun_napi_alloc_frags() using
+napi_alloc_frag() with user provided seg sizes,
+leading to other users of this API getting unaligned
+page fragments.
+
+Since we would like to not necessarily add paddings or alignments to
+the frags that tun_napi_alloc_frags() attaches to the skb, switch to
+another page frag allocator.
+
+As a bonus skb_page_frag_refill() can use GFP_KERNEL allocations,
+meaning that we can not deplete memory reserves as easily.
+
+Fixes: 90e33d459407 ("tun: enable napi_gro_frags() for TUN/TAP driver")
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Reported-by: Mark Rutland <mark.rutland@arm.com>
+Tested-by: Mark Rutland <mark.rutland@arm.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/net/tun.c | 16 ++++++----------
+ 1 file changed, 6 insertions(+), 10 deletions(-)
+
+--- a/drivers/net/tun.c
++++ b/drivers/net/tun.c
+@@ -1317,27 +1317,23 @@ static struct sk_buff *tun_napi_alloc_fr
+ skb->truesize += skb->data_len;
+
+ for (i = 1; i < it->nr_segs; i++) {
++ struct page_frag *pfrag = ¤t->task_frag;
+ size_t fragsz = it->iov[i].iov_len;
+- unsigned long offset;
+- struct page *page;
+- void *data;
+
+ if (fragsz == 0 || fragsz > PAGE_SIZE) {
+ err = -EINVAL;
+ goto free;
+ }
+
+- local_bh_disable();
+- data = napi_alloc_frag(fragsz);
+- local_bh_enable();
+- if (!data) {
++ if (!skb_page_frag_refill(fragsz, pfrag, GFP_KERNEL)) {
+ err = -ENOMEM;
+ goto free;
+ }
+
+- page = virt_to_head_page(data);
+- offset = data - page_address(page);
+- skb_fill_page_desc(skb, i - 1, page, offset, fragsz);
++ skb_fill_page_desc(skb, i - 1, pfrag->page,
++ pfrag->offset, fragsz);
++ page_ref_inc(pfrag->page);
++ pfrag->offset += fragsz;
+ }
+
+ return skb;