commit:     ba8283a81206007982898ff1867ce119c3c8bba6
Author:     Mike Pagano <mpagano <AT> gentoo <DOT> org>
AuthorDate: Thu Dec 15 23:41:14 2016 +0000
Commit:     Mike Pagano <mpagano <AT> gentoo <DOT> org>
CommitDate: Thu Dec 15 23:41:14 2016 +0000
URL:        https://gitweb.gentoo.org/proj/linux-patches.git/commit/?id=ba8283a8

Linux patch 4.4.39

 0000_README             |   4 +
 1038_linux-4.4.39.patch | 513 ++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 517 insertions(+)

diff --git a/0000_README b/0000_README
index 5f96436..27da679 100644
--- a/0000_README
+++ b/0000_README
@@ -195,6 +195,10 @@ Patch:  1037_linux-4.4.38.patch
 From:   http://www.kernel.org
 Desc:   Linux 4.4.38
 
+Patch:  1038_linux-4.4.39.patch
+From:   http://www.kernel.org
+Desc:   Linux 4.4.39
+
 Patch:  1500_XATTR_USER_PREFIX.patch
 From:   https://bugs.gentoo.org/show_bug.cgi?id=470644
 Desc:   Support for namespace user.pax.* on tmpfs.

diff --git a/1038_linux-4.4.39.patch b/1038_linux-4.4.39.patch
new file mode 100644
index 0000000..5b3ea9d
--- /dev/null
+++ b/1038_linux-4.4.39.patch
@@ -0,0 +1,513 @@
+diff --git a/Makefile b/Makefile
+index 6876efe0d735..88d26a632bef 100644
+--- a/Makefile
++++ b/Makefile
+@@ -1,6 +1,6 @@
+ VERSION = 4
+ PATCHLEVEL = 4
+-SUBLEVEL = 38
++SUBLEVEL = 39
+ EXTRAVERSION =
+ NAME = Blurry Fish Butt
+ 
+diff --git a/arch/arm64/include/asm/futex.h b/arch/arm64/include/asm/futex.h
+index 007a69fc4f40..5f3ab8c1db55 100644
+--- a/arch/arm64/include/asm/futex.h
++++ b/arch/arm64/include/asm/futex.h
+@@ -121,6 +121,7 @@ futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr,
+               return -EFAULT;
+ 
+       asm volatile("// futex_atomic_cmpxchg_inatomic\n"
++ALTERNATIVE("nop", SET_PSTATE_PAN(0), ARM64_HAS_PAN, CONFIG_ARM64_PAN)
+ "     prfm    pstl1strm, %2\n"
+ "1:   ldxr    %w1, %2\n"
+ "     sub     %w3, %w1, %w4\n"
+@@ -137,6 +138,7 @@ futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr,
+ "     .align  3\n"
+ "     .quad   1b, 4b, 2b, 4b\n"
+ "     .popsection\n"
++ALTERNATIVE("nop", SET_PSTATE_PAN(1), ARM64_HAS_PAN, CONFIG_ARM64_PAN)
+       : "+r" (ret), "=&r" (val), "+Q" (*uaddr), "=&r" (tmp)
+       : "r" (oldval), "r" (newval), "Ir" (-EFAULT)
+       : "memory");
+diff --git a/arch/m68k/include/asm/delay.h b/arch/m68k/include/asm/delay.h
+index d28fa8fe26fe..c598d847d56b 100644
+--- a/arch/m68k/include/asm/delay.h
++++ b/arch/m68k/include/asm/delay.h
+@@ -114,6 +114,6 @@ static inline void __udelay(unsigned long usecs)
+  */
+ #define       HZSCALE         (268435456 / (1000000 / HZ))
+ 
+-#define ndelay(n) __delay(DIV_ROUND_UP((n) * ((((HZSCALE) >> 11) * 
(loops_per_jiffy >> 11)) >> 6), 1000));
++#define ndelay(n) __delay(DIV_ROUND_UP((n) * ((((HZSCALE) >> 11) * 
(loops_per_jiffy >> 11)) >> 6), 1000))
+ 
+ #endif /* defined(_M68K_DELAY_H) */
+diff --git a/arch/parisc/include/asm/pgtable.h 
b/arch/parisc/include/asm/pgtable.h
+index c2c43f714684..3a4ed9f91d57 100644
+--- a/arch/parisc/include/asm/pgtable.h
++++ b/arch/parisc/include/asm/pgtable.h
+@@ -65,9 +65,9 @@ static inline void purge_tlb_entries(struct mm_struct *mm, 
unsigned long addr)
+               unsigned long flags;                            \
+               spin_lock_irqsave(&pa_tlb_lock, flags);         \
+               old_pte = *ptep;                                \
+-              set_pte(ptep, pteval);                          \
+               if (pte_inserted(old_pte))                      \
+                       purge_tlb_entries(mm, addr);            \
++              set_pte(ptep, pteval);                          \
+               spin_unlock_irqrestore(&pa_tlb_lock, flags);    \
+       } while (0)
+ 
+@@ -478,8 +478,8 @@ static inline int ptep_test_and_clear_young(struct 
vm_area_struct *vma, unsigned
+               spin_unlock_irqrestore(&pa_tlb_lock, flags);
+               return 0;
+       }
+-      set_pte(ptep, pte_mkold(pte));
+       purge_tlb_entries(vma->vm_mm, addr);
++      set_pte(ptep, pte_mkold(pte));
+       spin_unlock_irqrestore(&pa_tlb_lock, flags);
+       return 1;
+ }
+@@ -492,9 +492,9 @@ static inline pte_t ptep_get_and_clear(struct mm_struct 
*mm, unsigned long addr,
+ 
+       spin_lock_irqsave(&pa_tlb_lock, flags);
+       old_pte = *ptep;
+-      set_pte(ptep, __pte(0));
+       if (pte_inserted(old_pte))
+               purge_tlb_entries(mm, addr);
++      set_pte(ptep, __pte(0));
+       spin_unlock_irqrestore(&pa_tlb_lock, flags);
+ 
+       return old_pte;
+@@ -504,8 +504,8 @@ static inline void ptep_set_wrprotect(struct mm_struct 
*mm, unsigned long addr,
+ {
+       unsigned long flags;
+       spin_lock_irqsave(&pa_tlb_lock, flags);
+-      set_pte(ptep, pte_wrprotect(*ptep));
+       purge_tlb_entries(mm, addr);
++      set_pte(ptep, pte_wrprotect(*ptep));
+       spin_unlock_irqrestore(&pa_tlb_lock, flags);
+ }
+ 
+diff --git a/arch/parisc/kernel/cache.c b/arch/parisc/kernel/cache.c
+index fd5979f28ada..6857a104b2f9 100644
+--- a/arch/parisc/kernel/cache.c
++++ b/arch/parisc/kernel/cache.c
+@@ -375,6 +375,15 @@ void __init parisc_setup_cache_timing(void)
+ 
+       /* calculate TLB flush threshold */
+ 
++      /* On SMP machines, skip the TLB measure of kernel text which
++       * has been mapped as huge pages. */
++      if (num_online_cpus() > 1 && !parisc_requires_coherency()) {
++              threshold = max(cache_info.it_size, cache_info.dt_size);
++              threshold *= PAGE_SIZE;
++              threshold /= num_online_cpus();
++              goto set_tlb_threshold;
++      }
++
+       alltime = mfctl(16);
+       flush_tlb_all();
+       alltime = mfctl(16) - alltime;
+@@ -393,6 +402,8 @@ void __init parisc_setup_cache_timing(void)
+               alltime, size, rangetime);
+ 
+       threshold = PAGE_ALIGN(num_online_cpus() * size * alltime / rangetime);
++
++set_tlb_threshold:
+       if (threshold)
+               parisc_tlb_flush_threshold = threshold;
+       printk(KERN_INFO "TLB flush threshold set to %lu KiB\n",
+diff --git a/arch/parisc/kernel/pacache.S b/arch/parisc/kernel/pacache.S
+index 675521919229..a4761b772406 100644
+--- a/arch/parisc/kernel/pacache.S
++++ b/arch/parisc/kernel/pacache.S
+@@ -886,19 +886,10 @@ ENTRY(flush_dcache_page_asm)
+       fdc,m           r31(%r28)
+       fdc,m           r31(%r28)
+       fdc,m           r31(%r28)
+-      cmpb,COND(<<)           %r28, %r25,1b
++      cmpb,COND(<<)   %r28, %r25,1b
+       fdc,m           r31(%r28)
+ 
+       sync
+-
+-#ifdef CONFIG_PA20
+-      pdtlb,l         %r0(%r25)
+-#else
+-      tlb_lock        %r20,%r21,%r22
+-      pdtlb           %r0(%r25)
+-      tlb_unlock      %r20,%r21,%r22
+-#endif
+-
+       bv              %r0(%r2)
+       nop
+       .exit
+@@ -973,17 +964,6 @@ ENTRY(flush_icache_page_asm)
+       fic,m           %r31(%sr4,%r28)
+ 
+       sync
+-
+-#ifdef CONFIG_PA20
+-      pdtlb,l         %r0(%r28)
+-      pitlb,l         %r0(%sr4,%r25)
+-#else
+-      tlb_lock        %r20,%r21,%r22
+-      pdtlb           %r0(%r28)
+-      pitlb           %r0(%sr4,%r25)
+-      tlb_unlock      %r20,%r21,%r22
+-#endif
+-
+       bv              %r0(%r2)
+       nop
+       .exit
+diff --git a/arch/powerpc/kernel/eeh_driver.c 
b/arch/powerpc/kernel/eeh_driver.c
+index c07bfb52275e..300382e5a2cc 100644
+--- a/arch/powerpc/kernel/eeh_driver.c
++++ b/arch/powerpc/kernel/eeh_driver.c
+@@ -612,8 +612,10 @@ static int eeh_reset_device(struct eeh_pe *pe, struct 
pci_bus *bus)
+ 
+       /* Clear frozen state */
+       rc = eeh_clear_pe_frozen_state(pe, false);
+-      if (rc)
++      if (rc) {
++              pci_unlock_rescan_remove();
+               return rc;
++      }
+ 
+       /* Give the system 5 seconds to finish running the user-space
+        * hotplug shutdown scripts, e.g. ifdown for ethernet.  Yes,
+diff --git a/arch/x86/kernel/cpu/perf_event.c 
b/arch/x86/kernel/cpu/perf_event.c
+index a3aeb2cc361e..1a8256dd6729 100644
+--- a/arch/x86/kernel/cpu/perf_event.c
++++ b/arch/x86/kernel/cpu/perf_event.c
+@@ -67,7 +67,7 @@ u64 x86_perf_event_update(struct perf_event *event)
+       int shift = 64 - x86_pmu.cntval_bits;
+       u64 prev_raw_count, new_raw_count;
+       int idx = hwc->idx;
+-      s64 delta;
++      u64 delta;
+ 
+       if (idx == INTEL_PMC_IDX_FIXED_BTS)
+               return 0;
+diff --git a/arch/x86/kernel/cpu/perf_event_intel.c 
b/arch/x86/kernel/cpu/perf_event_intel.c
+index 5f82cd59f0e5..5cc2242d77c6 100644
+--- a/arch/x86/kernel/cpu/perf_event_intel.c
++++ b/arch/x86/kernel/cpu/perf_event_intel.c
+@@ -3636,7 +3636,7 @@ __init int intel_pmu_init(void)
+ 
+       /* Support full width counters using alternative MSR range */
+       if (x86_pmu.intel_cap.full_width_write) {
+-              x86_pmu.max_period = x86_pmu.cntval_mask;
++              x86_pmu.max_period = x86_pmu.cntval_mask >> 1;
+               x86_pmu.perfctr = MSR_IA32_PMC0;
+               pr_cont("full-width counters, ");
+       }
+diff --git a/crypto/Makefile b/crypto/Makefile
+index f7aba923458d..82fbff180ad3 100644
+--- a/crypto/Makefile
++++ b/crypto/Makefile
+@@ -33,6 +33,7 @@ obj-$(CONFIG_CRYPTO_AKCIPHER2) += akcipher.o
+ 
+ $(obj)/rsapubkey-asn1.o: $(obj)/rsapubkey-asn1.c $(obj)/rsapubkey-asn1.h
+ $(obj)/rsaprivkey-asn1.o: $(obj)/rsaprivkey-asn1.c $(obj)/rsaprivkey-asn1.h
++$(obj)/rsa_helper.o: $(obj)/rsapubkey-asn1.h $(obj)/rsaprivkey-asn1.h
+ clean-files += rsapubkey-asn1.c rsapubkey-asn1.h
+ clean-files += rsaprivkey-asn1.c rsaprivkey-asn1.h
+ 
+diff --git a/crypto/mcryptd.c b/crypto/mcryptd.c
+index fe5b495a434d..a0ceb41d5ccc 100644
+--- a/crypto/mcryptd.c
++++ b/crypto/mcryptd.c
+@@ -258,18 +258,22 @@ out_free_inst:
+       goto out;
+ }
+ 
+-static inline void mcryptd_check_internal(struct rtattr **tb, u32 *type,
++static inline bool mcryptd_check_internal(struct rtattr **tb, u32 *type,
+                                         u32 *mask)
+ {
+       struct crypto_attr_type *algt;
+ 
+       algt = crypto_get_attr_type(tb);
+       if (IS_ERR(algt))
+-              return;
+-      if ((algt->type & CRYPTO_ALG_INTERNAL))
+-              *type |= CRYPTO_ALG_INTERNAL;
+-      if ((algt->mask & CRYPTO_ALG_INTERNAL))
+-              *mask |= CRYPTO_ALG_INTERNAL;
++              return false;
++
++      *type |= algt->type & CRYPTO_ALG_INTERNAL;
++      *mask |= algt->mask & CRYPTO_ALG_INTERNAL;
++
++      if (*type & *mask & CRYPTO_ALG_INTERNAL)
++              return true;
++      else
++              return false;
+ }
+ 
+ static int mcryptd_hash_init_tfm(struct crypto_tfm *tfm)
+@@ -498,7 +502,8 @@ static int mcryptd_create_hash(struct crypto_template 
*tmpl, struct rtattr **tb,
+       u32 mask = 0;
+       int err;
+ 
+-      mcryptd_check_internal(tb, &type, &mask);
++      if (!mcryptd_check_internal(tb, &type, &mask))
++              return -EINVAL;
+ 
+       salg = shash_attr_alg(tb[1], type, mask);
+       if (IS_ERR(salg))
+diff --git a/drivers/block/zram/zram_drv.c b/drivers/block/zram/zram_drv.c
+index 1770c455dfdd..1648de80e230 100644
+--- a/drivers/block/zram/zram_drv.c
++++ b/drivers/block/zram/zram_drv.c
+@@ -1378,8 +1378,14 @@ static ssize_t hot_remove_store(struct class *class,
+       return ret ? ret : count;
+ }
+ 
++/*
++ * NOTE: hot_add attribute is not the usual read-only sysfs attribute. In a
++ * sense that reading from this file does alter the state of your system -- it
++ * creates a new un-initialized zram device and returns back this device's
++ * device_id (or an error code if it fails to create a new device).
++ */
+ static struct class_attribute zram_control_class_attrs[] = {
+-      __ATTR_RO(hot_add),
++      __ATTR(hot_add, 0400, hot_add_show, NULL),
+       __ATTR_WO(hot_remove),
+       __ATTR_NULL,
+ };
+diff --git a/drivers/net/can/usb/peak_usb/pcan_usb_core.c 
b/drivers/net/can/usb/peak_usb/pcan_usb_core.c
+index 5a2e341a6d1e..91be4575b524 100644
+--- a/drivers/net/can/usb/peak_usb/pcan_usb_core.c
++++ b/drivers/net/can/usb/peak_usb/pcan_usb_core.c
+@@ -872,23 +872,25 @@ lbl_free_candev:
+ static void peak_usb_disconnect(struct usb_interface *intf)
+ {
+       struct peak_usb_device *dev;
++      struct peak_usb_device *dev_prev_siblings;
+ 
+       /* unregister as many netdev devices as siblings */
+-      for (dev = usb_get_intfdata(intf); dev; dev = dev->prev_siblings) {
++      for (dev = usb_get_intfdata(intf); dev; dev = dev_prev_siblings) {
+               struct net_device *netdev = dev->netdev;
+               char name[IFNAMSIZ];
+ 
++              dev_prev_siblings = dev->prev_siblings;
+               dev->state &= ~PCAN_USB_STATE_CONNECTED;
+               strncpy(name, netdev->name, IFNAMSIZ);
+ 
+               unregister_netdev(netdev);
+-              free_candev(netdev);
+ 
+               kfree(dev->cmd_buf);
+               dev->next_siblings = NULL;
+               if (dev->adapter->dev_free)
+                       dev->adapter->dev_free(dev);
+ 
++              free_candev(netdev);
+               dev_info(&intf->dev, "%s removed\n", name);
+       }
+ 
+diff --git a/include/linux/cpu.h b/include/linux/cpu.h
+index d2ca8c38f9c4..3ea9aae2387d 100644
+--- a/include/linux/cpu.h
++++ b/include/linux/cpu.h
+@@ -131,22 +131,16 @@ enum {
+               { .notifier_call = fn, .priority = pri };       \
+       __register_cpu_notifier(&fn##_nb);                      \
+ }
+-#else /* #if defined(CONFIG_HOTPLUG_CPU) || !defined(MODULE) */
+-#define cpu_notifier(fn, pri) do { (void)(fn); } while (0)
+-#define __cpu_notifier(fn, pri)       do { (void)(fn); } while (0)
+-#endif /* #else #if defined(CONFIG_HOTPLUG_CPU) || !defined(MODULE) */
+ 
+-#ifdef CONFIG_HOTPLUG_CPU
+ extern int register_cpu_notifier(struct notifier_block *nb);
+ extern int __register_cpu_notifier(struct notifier_block *nb);
+ extern void unregister_cpu_notifier(struct notifier_block *nb);
+ extern void __unregister_cpu_notifier(struct notifier_block *nb);
+-#else
+ 
+-#ifndef MODULE
+-extern int register_cpu_notifier(struct notifier_block *nb);
+-extern int __register_cpu_notifier(struct notifier_block *nb);
+-#else
++#else /* #if defined(CONFIG_HOTPLUG_CPU) || !defined(MODULE) */
++#define cpu_notifier(fn, pri) do { (void)(fn); } while (0)
++#define __cpu_notifier(fn, pri)       do { (void)(fn); } while (0)
++
+ static inline int register_cpu_notifier(struct notifier_block *nb)
+ {
+       return 0;
+@@ -156,7 +150,6 @@ static inline int __register_cpu_notifier(struct 
notifier_block *nb)
+ {
+       return 0;
+ }
+-#endif
+ 
+ static inline void unregister_cpu_notifier(struct notifier_block *nb)
+ {
+diff --git a/include/uapi/linux/can.h b/include/uapi/linux/can.h
+index 9692cda5f8fc..c48d93a28d1a 100644
+--- a/include/uapi/linux/can.h
++++ b/include/uapi/linux/can.h
+@@ -196,5 +196,6 @@ struct can_filter {
+ };
+ 
+ #define CAN_INV_FILTER 0x20000000U /* to be set in can_filter.can_id */
++#define CAN_RAW_FILTER_MAX 512 /* maximum number of can_filter set via 
setsockopt() */
+ 
+ #endif /* !_UAPI_CAN_H */
+diff --git a/kernel/cpu.c b/kernel/cpu.c
+index 85ff5e26e23b..cd6d1258554e 100644
+--- a/kernel/cpu.c
++++ b/kernel/cpu.c
+@@ -223,8 +223,6 @@ static int cpu_notify(unsigned long val, void *v)
+       return __cpu_notify(val, v, -1, NULL);
+ }
+ 
+-#ifdef CONFIG_HOTPLUG_CPU
+-
+ static void cpu_notify_nofail(unsigned long val, void *v)
+ {
+       BUG_ON(cpu_notify(val, v));
+@@ -246,6 +244,7 @@ void __unregister_cpu_notifier(struct notifier_block *nb)
+ }
+ EXPORT_SYMBOL(__unregister_cpu_notifier);
+ 
++#ifdef CONFIG_HOTPLUG_CPU
+ /**
+  * clear_tasks_mm_cpumask - Safely clear tasks' mm_cpumask for a CPU
+  * @cpu: a CPU id
+diff --git a/kernel/locking/rtmutex.c b/kernel/locking/rtmutex.c
+index 8251e75dd9c0..b066724d7a5b 100644
+--- a/kernel/locking/rtmutex.c
++++ b/kernel/locking/rtmutex.c
+@@ -65,8 +65,72 @@ static inline void clear_rt_mutex_waiters(struct rt_mutex 
*lock)
+ 
+ static void fixup_rt_mutex_waiters(struct rt_mutex *lock)
+ {
+-      if (!rt_mutex_has_waiters(lock))
+-              clear_rt_mutex_waiters(lock);
++      unsigned long owner, *p = (unsigned long *) &lock->owner;
++
++      if (rt_mutex_has_waiters(lock))
++              return;
++
++      /*
++       * The rbtree has no waiters enqueued, now make sure that the
++       * lock->owner still has the waiters bit set, otherwise the
++       * following can happen:
++       *
++       * CPU 0        CPU 1           CPU2
++       * l->owner=T1
++       *              rt_mutex_lock(l)
++       *              lock(l->lock)
++       *              l->owner = T1 | HAS_WAITERS;
++       *              enqueue(T2)
++       *              boost()
++       *                unlock(l->lock)
++       *              block()
++       *
++       *                              rt_mutex_lock(l)
++       *                              lock(l->lock)
++       *                              l->owner = T1 | HAS_WAITERS;
++       *                              enqueue(T3)
++       *                              boost()
++       *                                unlock(l->lock)
++       *                              block()
++       *              signal(->T2)    signal(->T3)
++       *              lock(l->lock)
++       *              dequeue(T2)
++       *              deboost()
++       *                unlock(l->lock)
++       *                              lock(l->lock)
++       *                              dequeue(T3)
++       *                               ==> wait list is empty
++       *                              deboost()
++       *                               unlock(l->lock)
++       *              lock(l->lock)
++       *              fixup_rt_mutex_waiters()
++       *                if (wait_list_empty(l) {
++       *                  l->owner = owner
++       *                  owner = l->owner & ~HAS_WAITERS;
++       *                    ==> l->owner = T1
++       *                }
++       *                              lock(l->lock)
++       * rt_mutex_unlock(l)           fixup_rt_mutex_waiters()
++       *                                if (wait_list_empty(l) {
++       *                                  owner = l->owner & ~HAS_WAITERS;
++       * cmpxchg(l->owner, T1, NULL)
++       *  ===> Success (l->owner = NULL)
++       *
++       *                                  l->owner = owner
++       *                                    ==> l->owner = T1
++       *                                }
++       *
++       * With the check for the waiter bit in place T3 on CPU2 will not
++       * overwrite. All tasks fiddling with the waiters bit are
++       * serialized by l->lock, so nothing else can modify the waiters
++       * bit. If the bit is set then nothing can change l->owner either
++       * so the simple RMW is safe. The cmpxchg() will simply fail if it
++       * happens in the middle of the RMW because the waiters bit is
++       * still set.
++       */
++      owner = READ_ONCE(*p);
++      if (owner & RT_MUTEX_HAS_WAITERS)
++              WRITE_ONCE(*p, owner & ~RT_MUTEX_HAS_WAITERS);
+ }
+ 
+ /*
+diff --git a/kernel/locking/rtmutex_common.h b/kernel/locking/rtmutex_common.h
+index 4f5f83c7d2d3..e317e1cbb3eb 100644
+--- a/kernel/locking/rtmutex_common.h
++++ b/kernel/locking/rtmutex_common.h
+@@ -75,8 +75,9 @@ task_top_pi_waiter(struct task_struct *p)
+ 
+ static inline struct task_struct *rt_mutex_owner(struct rt_mutex *lock)
+ {
+-      return (struct task_struct *)
+-              ((unsigned long)lock->owner & ~RT_MUTEX_OWNER_MASKALL);
++      unsigned long owner = (unsigned long) READ_ONCE(lock->owner);
++
++      return (struct task_struct *) (owner & ~RT_MUTEX_OWNER_MASKALL);
+ }
+ 
+ /*
+diff --git a/net/batman-adv/translation-table.c 
b/net/batman-adv/translation-table.c
+index 83b0ca27a45e..f2079acb555d 100644
+--- a/net/batman-adv/translation-table.c
++++ b/net/batman-adv/translation-table.c
+@@ -2764,7 +2764,7 @@ static bool batadv_send_my_tt_response(struct 
batadv_priv *bat_priv,
+                                                            &tvlv_tt_data,
+                                                            &tt_change,
+                                                            &tt_len);
+-              if (!tt_len)
++              if (!tt_len || !tvlv_len)
+                       goto unlock;
+ 
+               /* Copy the last orig_node's OGM buffer */
+@@ -2782,7 +2782,7 @@ static bool batadv_send_my_tt_response(struct 
batadv_priv *bat_priv,
+                                                            &tvlv_tt_data,
+                                                            &tt_change,
+                                                            &tt_len);
+-              if (!tt_len)
++              if (!tt_len || !tvlv_len)
+                       goto out;
+ 
+               /* fill the rest of the tvlv with the real TT entries */
+diff --git a/net/can/raw.c b/net/can/raw.c
+index 2e67b1423cd3..56af689ca999 100644
+--- a/net/can/raw.c
++++ b/net/can/raw.c
+@@ -499,6 +499,9 @@ static int raw_setsockopt(struct socket *sock, int level, 
int optname,
+               if (optlen % sizeof(struct can_filter) != 0)
+                       return -EINVAL;
+ 
++              if (optlen > CAN_RAW_FILTER_MAX * sizeof(struct can_filter))
++                      return -EINVAL;
++
+               count = optlen / sizeof(struct can_filter);
+ 
+               if (count > 1) {

Reply via email to