Netdev List
 help / color / mirror / Atom feed
* Re: [RFC v3 06/22] landlock: Add LSM hooks
From: Thomas Graf @ 2016-10-19 15:19 UTC (permalink / raw)
  To: Mickaël Salaün
  Cc: linux-kernel, Alexei Starovoitov, Andy Lutomirski, Arnd Bergmann,
	Casey Schaufler, Daniel Borkmann, Daniel Mack, David Drysdale,
	David S . Miller, Elena Reshetova, Eric W . Biederman,
	James Morris, Kees Cook, Paul Moore, Sargun Dhillon,
	Serge E . Hallyn, Tejun Heo, Will Drewry, kernel-hardening,
	linux-api, linux-security-module, netdev, cgroups
In-Reply-To: <20160914072415.26021-7-mic@digikod.net>

On 09/14/16 at 09:23am, Mickaël Salaün wrote:
> diff --git a/include/linux/bpf.h b/include/linux/bpf.h
> index 9aa01d9d3d80..36c3e482239c 100644
> --- a/include/linux/bpf.h
> +++ b/include/linux/bpf.h
> @@ -85,6 +85,8 @@ enum bpf_arg_type {
>  
>  	ARG_PTR_TO_CTX,		/* pointer to context */
>  	ARG_ANYTHING,		/* any (initialized) argument is ok */
> +
> +	ARG_PTR_TO_STRUCT_FILE,		/* pointer to struct file */

This should go into patch 7 I guess?

> +void __init landlock_add_hooks(void)
> +{
> +	pr_info("landlock: Becoming ready for sandboxing\n");
> +	security_add_hooks(landlock_hooks, ARRAY_SIZE(landlock_hooks));
> +}

Can we add the hooks when we load the first BPF program for a hook? That
would also allow to not make this conditional on a new config option
which all all distros have to enable anyway.

I would really like to see this patch split into the LSM part which
allows running BPF progs at LSM and your specific sandboxing use case
which requires the new BPF helpers, new reg type, etc.

^ permalink raw reply

* Re: [RFC PATCH net-next] bpf: fix potential percpu map overcopy to user.
From: Daniel Borkmann @ 2016-10-19 10:05 UTC (permalink / raw)
  To: William Tu; +Cc: Alexei Starovoitov, Linux Kernel Network Developers
In-Reply-To: <CALDO+SaebqahYHn2PU=nk6mYOMjRp+F8PKb3cFaGMv4_xjLwZg@mail.gmail.com>

On 10/19/2016 07:31 AM, William Tu wrote:
>> ...
>>> -     if (copy_to_user(uvalue, value, value_size) != 0)
>>> +     if (copy_to_user(uvalue, value, min_t(u32, usize, value_size)) != 0)
>>>                goto free_value;
>>
>> I think such approach won't actually fix anything. User space
>> may lose some of the values and won't have any idea what was lost.
>> I think we need to fix sample code to avoid using sysconf(_SC_NPROCESSORS_CONF)
>> and use /sys/devices/system/cpu/possible instead.
>> I would argue that glibc should be fixed as well since relying on
>> ls -d /sys/devices/system/cpu/cpu[0-9]*|wc -l turned out to be incorrect.
>
> Thanks for the feedback. I think glibc is correct. The
> _SC_NPROCESSORS_CONF presents the number of processors
> configured/populated and is indeed "ls
> /sys/devices/system/cpu/cpu[0-9]*|wc -l". This means the actual number
> of CPUs installed on your system. On the other hand, the

In glibc __get_nprocs_conf() seems to try a number of things, first it
tries equivalent of /sys/devices/system/cpu/cpu[0-9]*|wc -l, if that fails,
depending on the config, it either tries to count cpus in /proc/cpuinfo,
or returns the _SC_NPROCESSORS_ONLN value instead. If /proc/cpuinfo has
some issue, it returns just 1 worst case. _SC_NPROCESSORS_ONLN will parse
/sys/devices/system/cpu/online, if that fails it looks into /proc/stat
for cpuX entries, and if also that fails for some reason, /proc/cpuinfo
is consulted (and returning 1 if unlikely all breaks down).

> num_possible_cpus() includes both the installed CPUs and the empty CPU
> socket/slot, in order to support CPU hotplug.

Correct.

> As a example, one of my dual socket motherboard with 1 CPU installed has
> # /sys/devices/system/cpu/possible
> 0-239
> # /sys/devices/system/cpu/cpu[0-9]*|wc -l
> 12
> Note that these 12 cpus could be online/offline by
> # echo 1/0 > /sys/devices/system/cpu/cpuX/online
> Even if it is offline, the entry is still there.
>
> Thinking about another solution, maybe we should use
> "num_present_cpus()" which means the configured/populated CPUs and the
> value is the same as sysconf(_SC_NPROCESSORS_CONF). Consider:
> 1) cpuX is online/offline: the num_present_cpus() remains the same.
> 2) new cpu is hotplug into the empty socket: the num_present_cpus()
> gets updates, and also the sysconf(_SC_NPROCESSORS_CONF).
>
> +++ b/kernel/bpf/syscall.c
> @@ -297,7 +297,7 @@ static int map_lookup_elem(union bpf_attr *attr)
>
>          if (map->map_type == BPF_MAP_TYPE_PERCPU_HASH ||
>              map->map_type == BPF_MAP_TYPE_PERCPU_ARRAY)
> -               value_size = round_up(map->value_size, 8) * num_possible_cpus();
> +               value_size = round_up(map->value_size, 8) * num_present_cpus();
>          else
>                  value_size = map->value_size;

But as you say in 2) that also has a chance of being racy on CPU hotplug
compared to num_possible_cpus() which is fixed at boot time.

Documentation/cputopology.txt +106 says /sys/devices/system/cpu/possible
outputs cpu_possible_mask. That is the same as in num_possible_cpus(), so
first step would be to fix the buggy example code, imho.

What perhaps could be done in a second step to reduce overhead is an option
for bpf(2) to pass in a cpu mask similarly as for sched_{get,set}affinity()
syscalls, where user space can construct a mask via CPU_SET(3). For the
syscall time, kernel would lock hot plugging via get_online_cpus() and
put_online_cpus(), it would check whether passed CPUs are online to query
and if so then it would copy the values into the user provided buffer. I'd
think this might be useful in a number of ways anyway.

Thanks,
Daniel

^ permalink raw reply

* [PATCH net-next v4 0/3] udp: refactor memory accounting
From: Paolo Abeni @ 2016-10-19 12:46 UTC (permalink / raw)
  To: netdev
  Cc: David S. Miller, James Morris, Trond Myklebust, Alexander Duyck,
	Daniel Borkmann, Eric Dumazet, Tom Herbert, Hannes Frederic Sowa,
	Edward Cree, linux-nfs

This patch series refactor the udp memory accounting, replacing the
generic implementation with a custom one, in order to remove the needs for
locking the socket on the enqueue and dequeue operations. The socket backlog
usage is dropped, as well.

The first patch factor out pieces of some queue and memory management
socket helpers, so that they can later be used by the udp memory accounting
functions.
The second patch adds the memory account helpers, without using them.
The third patch replacse the old rx memory accounting path for udp over ipv4 and
udp over ipv6. In kernel UDP users are updated, as well.

The memory accounting schema is described in detail in the individual patch
commit message.

The performance gain depends on the specific scenario; with few flows (and
little contention in the original code) the differences are in the noise range,
while with several flows contending the same socket, the measured speed-up
is relevant (e.g. even over 100% in case of extreme contention)

v3 -> v4:
 - simplified the locking schema, always use a plain spinlock

v2 -> v3:
 - do not set the now unsed backlog_rcv callback

v1 -> v2:
 - changed slighly the memory accounting schema, we now perform lazy reclaim
 - fixed forward_alloc updating issue
 - fixed memory counter integer overflows

Paolo Abeni (3):
  net/socket: factor out helpers for memory and queue manipulation
  udp: implement memory accounting helpers
  udp: use it's own memory accounting schema

 include/linux/udp.h   |   1 +
 include/net/sock.h    |   4 ++
 include/net/udp.h     |   4 ++
 net/core/datagram.c   |  36 +++++++-----
 net/core/sock.c       |  66 +++++++++++++++-------
 net/ipv4/udp.c        | 153 +++++++++++++++++++++++++++++++++++++++-----------
 net/ipv6/udp.c        |  34 +++--------
 net/sunrpc/svcsock.c  |  20 +++++--
 net/sunrpc/xprtsock.c |   2 +-
 9 files changed, 221 insertions(+), 99 deletions(-)

-- 
1.8.3.1

^ permalink raw reply

* [PATCH net-next v4 2/3] udp: implement memory accounting helpers
From: Paolo Abeni @ 2016-10-19 12:47 UTC (permalink / raw)
  To: netdev
  Cc: David S. Miller, James Morris, Trond Myklebust, Alexander Duyck,
	Daniel Borkmann, Eric Dumazet, Tom Herbert, Hannes Frederic Sowa,
	Edward Cree, linux-nfs
In-Reply-To: <cover.1476877189.git.pabeni@redhat.com>

Avoid using the generic helpers.
Adds a new spinlock_t to the udp_sock structure and use
it to protect the memory accounting operation, both on
enqueue and on dequeue.

On dequeue perform partial memory reclaiming, trying to
leave a quantum of forward allocated memory.

On enqueue use a custom helper, to allow some optimizations:
- use a plain spin_lock() variant instead of the slightly
  costly spin_lock_irqsave(),
- avoid dst_force check, since the calling code has already
  dropped the skb dst

The above needs custom memory reclaiming on shutdown, provided
by the udp_destruct_sock().

v3 -> v4:
  - reworked memory accunting, simplifying the schema
  - provide an helper for both memory scheduling and enqueuing

v1 -> v2:
  - use a udp specific destrctor to perform memory reclaiming
  - remove a couple of helpers, unneeded after the above cleanup
  - do not reclaim memory on dequeue if not under memory
    pressure
  - reworked the fwd accounting schema to avoid potential
    integer overflow

Acked-by: Hannes Frederic Sowa <hannes@stressinduktion.org>
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
---
 include/linux/udp.h |   1 +
 include/net/udp.h   |   4 ++
 net/ipv4/udp.c      | 111 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 116 insertions(+)

diff --git a/include/linux/udp.h b/include/linux/udp.h
index d1fd8cd..8ea7f8b 100644
--- a/include/linux/udp.h
+++ b/include/linux/udp.h
@@ -66,6 +66,7 @@ struct udp_sock {
 #define UDPLITE_RECV_CC  0x4		/* set via udplite setsocktopt        */
 	__u8		 pcflag;        /* marks socket as UDP-Lite if > 0    */
 	__u8		 unused[3];
+	spinlock_t	 mem_lock;	/* protects memory accounting         */
 	/*
 	 * For encapsulation sockets.
 	 */
diff --git a/include/net/udp.h b/include/net/udp.h
index ea53a87..18f1e6b 100644
--- a/include/net/udp.h
+++ b/include/net/udp.h
@@ -246,6 +246,9 @@ static inline __be16 udp_flow_src_port(struct net *net, struct sk_buff *skb,
 }
 
 /* net/ipv4/udp.c */
+void skb_consume_udp(struct sock *sk, struct sk_buff *skb, int len);
+int __udp_enqueue_schedule_skb(struct sock *sk, struct sk_buff *skb);
+
 void udp_v4_early_demux(struct sk_buff *skb);
 int udp_get_port(struct sock *sk, unsigned short snum,
 		 int (*saddr_cmp)(const struct sock *,
@@ -258,6 +261,7 @@ int udp_get_port(struct sock *sk, unsigned short snum,
 void udp4_hwcsum(struct sk_buff *skb, __be32 src, __be32 dst);
 int udp_rcv(struct sk_buff *skb);
 int udp_ioctl(struct sock *sk, int cmd, unsigned long arg);
+int udp_init_sock(struct sock *sk);
 int udp_disconnect(struct sock *sk, int flags);
 unsigned int udp_poll(struct file *file, struct socket *sock, poll_table *wait);
 struct sk_buff *skb_udp_tunnel_segment(struct sk_buff *skb,
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
index 7d96dc2..7047bb3 100644
--- a/net/ipv4/udp.c
+++ b/net/ipv4/udp.c
@@ -1172,6 +1172,117 @@ int udp_sendpage(struct sock *sk, struct page *page, int offset,
 	return ret;
 }
 
+static void udp_rmem_release(struct sock *sk, int size, int partial)
+{
+	struct udp_sock *up = udp_sk(sk);
+	int amt;
+
+	atomic_sub(size, &sk->sk_rmem_alloc);
+
+	spin_lock_bh(&up->mem_lock);
+	sk->sk_forward_alloc += size;
+	amt = (sk->sk_forward_alloc - partial) & ~(SK_MEM_QUANTUM - 1);
+	sk->sk_forward_alloc -= amt;
+	spin_unlock_bh(&up->mem_lock);
+
+	if (amt)
+		__sk_mem_reduce_allocated(sk, amt >> SK_MEM_QUANTUM_SHIFT);
+}
+
+static void udp_rmem_free(struct sk_buff *skb)
+{
+	udp_rmem_release(skb->sk, skb->truesize, 1);
+}
+
+int __udp_enqueue_schedule_skb(struct sock *sk, struct sk_buff *skb)
+{
+	struct sk_buff_head *list = &sk->sk_receive_queue;
+	int rmem, delta, amt, err = -ENOMEM;
+	struct udp_sock *up = udp_sk(sk);
+	int size = skb->truesize;
+
+	/* try to avoid the costly atomic add/sub pair when the receive
+	 * queue is full
+	 */
+	if (atomic_read(&sk->sk_rmem_alloc) + size > sk->sk_rcvbuf)
+		goto drop;
+
+	rmem = atomic_add_return(size, &sk->sk_rmem_alloc);
+	if (rmem > sk->sk_rcvbuf)
+		goto uncharge_drop;
+
+	spin_lock(&up->mem_lock);
+	if (size < sk->sk_forward_alloc)
+		goto unlock;
+
+	amt = sk_mem_pages(size);
+	delta = amt << SK_MEM_QUANTUM_SHIFT;
+	if (!__sk_mem_raise_allocated(sk, delta, amt, SK_MEM_RECV)) {
+		err = -ENOBUFS;
+		spin_unlock(&up->mem_lock);
+		goto uncharge_drop;
+	}
+
+	sk->sk_forward_alloc += delta;
+
+unlock:
+	sk->sk_forward_alloc -= size;
+	spin_unlock(&up->mem_lock);
+
+	/* the skb owner in now the udp socket */
+	skb_orphan(skb);
+	skb->sk = sk;
+	skb->destructor = udp_rmem_free;
+
+	skb->dev = NULL;
+	sock_skb_set_dropcount(sk, skb);
+
+	spin_lock(&list->lock);
+	__skb_queue_tail(list, skb);
+	spin_unlock(&list->lock);
+
+	if (!sock_flag(sk, SOCK_DEAD))
+		sk->sk_data_ready(sk);
+
+	return 0;
+
+uncharge_drop:
+	atomic_sub(skb->truesize, &sk->sk_rmem_alloc);
+
+drop:
+	atomic_inc(&sk->sk_drops);
+	return err;
+}
+EXPORT_SYMBOL_GPL(__udp_enqueue_schedule_skb);
+
+static void udp_destruct_sock(struct sock *sk)
+{
+	/* reclaim completely the forward allocated memory */
+	__skb_queue_purge(&sk->sk_receive_queue);
+	udp_rmem_release(sk, 0, 0);
+	inet_sock_destruct(sk);
+}
+
+int udp_init_sock(struct sock *sk)
+{
+	sk->sk_destruct = udp_destruct_sock;
+	spin_lock_init(&udp_sk(sk)->mem_lock);
+	return 0;
+}
+EXPORT_SYMBOL_GPL(udp_init_sock);
+
+void skb_consume_udp(struct sock *sk, struct sk_buff *skb, int len)
+{
+	if (unlikely(READ_ONCE(sk->sk_peek_off) >= 0)) {
+		bool slow = lock_sock_fast(sk);
+
+		sk_peek_offset_bwd(sk, len);
+		unlock_sock_fast(sk, slow);
+	}
+	consume_skb(skb);
+}
+EXPORT_SYMBOL_GPL(skb_consume_udp);
+
 /**
  *	first_packet_length	- return length of first packet in receive queue
  *	@sk: socket
-- 
1.8.3.1

^ permalink raw reply related

* Re: [RFC PATCH net-next] bpf: fix potential percpu map overcopy to user.
From: Daniel Borkmann @ 2016-10-19 15:15 UTC (permalink / raw)
  To: William Tu; +Cc: Alexei Starovoitov, Linux Kernel Network Developers
In-Reply-To: <CALDO+SaebqahYHn2PU=nk6mYOMjRp+F8PKb3cFaGMv4_xjLwZg@mail.gmail.com>

On 10/19/2016 07:31 AM, William Tu wrote:
>> ...
>>> -     if (copy_to_user(uvalue, value, value_size) != 0)
>>> +     if (copy_to_user(uvalue, value, min_t(u32, usize, value_size)) != 0)
>>>                goto free_value;
>>
>> I think such approach won't actually fix anything. User space
>> may lose some of the values and won't have any idea what was lost.
>> I think we need to fix sample code to avoid using sysconf(_SC_NPROCESSORS_CONF)
>> and use /sys/devices/system/cpu/possible instead.
>> I would argue that glibc should be fixed as well since relying on
>> ls -d /sys/devices/system/cpu/cpu[0-9]*|wc -l turned out to be incorrect.
>
> Thanks for the feedback. I think glibc is correct. The
> _SC_NPROCESSORS_CONF presents the number of processors
> configured/populated and is indeed "ls
> /sys/devices/system/cpu/cpu[0-9]*|wc -l". This means the actual number
> of CPUs installed on your system. On the other hand, the

In glibc __get_nprocs_conf() seems to try a number of things, first it
tries equivalent of /sys/devices/system/cpu/cpu[0-9]*|wc -l, if that fails,
depending on the config, it either tries to count cpus in /proc/cpuinfo,
or returns the _SC_NPROCESSORS_ONLN value instead. If /proc/cpuinfo has
some issue, it returns just 1 worst case. _SC_NPROCESSORS_ONLN will parse
/sys/devices/system/cpu/online, if that fails it looks into /proc/stat
for cpuX entries, and if also that fails for some reason, /proc/cpuinfo
is consulted (and returning 1 if unlikely all breaks down).

> num_possible_cpus() includes both the installed CPUs and the empty CPU
> socket/slot, in order to support CPU hotplug.

Correct.

> As a example, one of my dual socket motherboard with 1 CPU installed has
> # /sys/devices/system/cpu/possible
> 0-239
> # /sys/devices/system/cpu/cpu[0-9]*|wc -l
> 12
> Note that these 12 cpus could be online/offline by
> # echo 1/0 > /sys/devices/system/cpu/cpuX/online
> Even if it is offline, the entry is still there.
>
> Thinking about another solution, maybe we should use
> "num_present_cpus()" which means the configured/populated CPUs and the
> value is the same as sysconf(_SC_NPROCESSORS_CONF). Consider:
> 1) cpuX is online/offline: the num_present_cpus() remains the same.
> 2) new cpu is hotplug into the empty socket: the num_present_cpus()
> gets updates, and also the sysconf(_SC_NPROCESSORS_CONF).
>
> +++ b/kernel/bpf/syscall.c
> @@ -297,7 +297,7 @@ static int map_lookup_elem(union bpf_attr *attr)
>
>          if (map->map_type == BPF_MAP_TYPE_PERCPU_HASH ||
>              map->map_type == BPF_MAP_TYPE_PERCPU_ARRAY)
> -               value_size = round_up(map->value_size, 8) * num_possible_cpus();
> +               value_size = round_up(map->value_size, 8) * num_present_cpus();
>          else
>                  value_size = map->value_size;

But as you say in 2) that also has a chance of being racy on CPU hotplug
compared to num_possible_cpus() which is fixed at boot time.

Documentation/cputopology.txt +106 says /sys/devices/system/cpu/possible
outputs cpu_possible_mask. That is the same as in num_possible_cpus(), so
first step would be to fix the buggy example code, imho.

What perhaps could be done in a second step to reduce overhead is an option
for bpf(2) to pass in a cpu mask similarly as for sched_{get,set}affinity()
syscalls, where user space can construct a mask via CPU_SET(3). For the
syscall time, kernel would lock hot plugging via get_online_cpus() and
put_online_cpus(), it would check whether passed CPUs are online to query
and if so then it would copy the values into the user provided buffer. I'd
think this might be useful in a number of ways anyway.

Thanks,
Daniel

^ permalink raw reply

* Re: [PATCH net] tcp: do not export sysctl_tcp_low_latency
From: David Miller @ 2016-10-19 15:14 UTC (permalink / raw)
  To: eric.dumazet; +Cc: netdev
In-Reply-To: <1476822247.5650.72.camel@edumazet-glaptop3.roam.corp.google.com>

From: Eric Dumazet <eric.dumazet@gmail.com>
Date: Tue, 18 Oct 2016 13:24:07 -0700

> From: Eric Dumazet <edumazet@google.com>
> 
> Since commit b2fb4f54ecd4 ("tcp: uninline tcp_prequeue()") we no longer
> access sysctl_tcp_low_latency from a module.
> 
> Signed-off-by: Eric Dumazet <edumazet@google.com>

Applied, thanks Eric.

^ permalink raw reply

* Re: [RFC v3 04/22] bpf: Set register type according to is_valid_access()
From: Daniel Borkmann @ 2016-10-19 15:10 UTC (permalink / raw)
  To: Thomas Graf, Mickaël Salaün
  Cc: linux-kernel, Alexei Starovoitov, Andy Lutomirski, Arnd Bergmann,
	Casey Schaufler, Daniel Mack, David Drysdale, David S . Miller,
	Elena Reshetova, Eric W . Biederman, James Morris, Kees Cook,
	Paul Moore, Sargun Dhillon, Serge E . Hallyn, Tejun Heo,
	Will Drewry, kernel-hardening, linux-api, linux-security-module,
	netdev, cgroups@
In-Reply-To: <20161019145420.GA22003@pox.localdomain>

On 10/19/2016 04:54 PM, Thomas Graf wrote:
> On 09/14/16 at 09:23am, Mickaël Salaün wrote:
>> This fix a pointer leak when an unprivileged eBPF program read a pointer
>> value from the context. Even if is_valid_access() returns a pointer
>> type, the eBPF verifier replace it with UNKNOWN_VALUE. The register
>> value containing an address is then allowed to leak. Moreover, this
>> prevented unprivileged eBPF programs to use functions with (legitimate)
>> pointer arguments.
>>
>> This bug was not a problem until now because the only unprivileged eBPF
>> program allowed is of type BPF_PROG_TYPE_SOCKET_FILTER and all the types
>> from its context are UNKNOWN_VALUE.
>>
>> Signed-off-by: Mickaël Salaün <mic@digikod.net>
>> Fixes: 969bf05eb3ce ("bpf: direct packet access")
>> Cc: Alexei Starovoitov <ast@kernel.org>
>> Cc: Daniel Borkmann <daniel@iogearbox.net>
>
> Can you post this fix separately? It's valid and needed outside of the
> scope of this series.

Yes, that one was already merged:

https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=1955351da41caa1dbf4139191358fed84909d64b

^ permalink raw reply

* Re: [PATCH net-next] bpf: Detect identical PTR_TO_MAP_VALUE_OR_NULL registers
From: David Miller @ 2016-10-19 15:09 UTC (permalink / raw)
  To: tgraf; +Cc: netdev, alexei.starovoitov, daniel, jbacik
In-Reply-To: <c678e43377187d72c87a030ad27afbcd7748e1e3.1476812715.git.tgraf@suug.ch>

From: Thomas Graf <tgraf@suug.ch>
Date: Tue, 18 Oct 2016 19:51:19 +0200

> A BPF program is required to check the return register of a
> map_elem_lookup() call before accessing memory. The verifier keeps
> track of this by converting the type of the result register from
> PTR_TO_MAP_VALUE_OR_NULL to PTR_TO_MAP_VALUE after a conditional
> jump ensures safety. This check is currently exclusively performed
> for the result register 0.
> 
> In the event the compiler reorders instructions, BPF_MOV64_REG
> instructions may be moved before the conditional jump which causes
> them to keep their type PTR_TO_MAP_VALUE_OR_NULL to which the
> verifier objects when the register is accessed:
> 
> 0: (b7) r1 = 10
> 1: (7b) *(u64 *)(r10 -8) = r1
> 2: (bf) r2 = r10
> 3: (07) r2 += -8
> 4: (18) r1 = 0x59c00000
> 6: (85) call 1
> 7: (bf) r4 = r0
> 8: (15) if r0 == 0x0 goto pc+1
>  R0=map_value(ks=8,vs=8) R4=map_value_or_null(ks=8,vs=8) R10=fp
> 9: (7a) *(u64 *)(r4 +0) = 0
> R4 invalid mem access 'map_value_or_null'
> 
> This commit extends the verifier to keep track of all identical
> PTR_TO_MAP_VALUE_OR_NULL registers after a map_elem_lookup() by
> assigning them an ID and then marking them all when the conditional
> jump is observed.
> 
> Signed-off-by: Thomas Graf <tgraf@suug.ch>
> Reviewed-by: Josef Bacik <jbacik@fb.com>
> Acked-by: Daniel Borkmann <daniel@iogearbox.net>
> Acked-by: Alexei Starovoitov <ast@kernel.org>

Applied, thanks Thomas.

^ permalink raw reply

* Re: [patch net] rtnetlink: Add rtnexthop offload flag to compare mask
From: David Miller @ 2016-10-19 15:08 UTC (permalink / raw)
  To: jiri
  Cc: netdev, idosch, eladr, yotamg, nogahf, ogerlitz, roopa, nikolay,
	linville, andy, f.fainelli, dsa, jhs, vivien.didelot, andrew,
	ivecera, nicolas.dichtel
In-Reply-To: <1476809974-14707-1-git-send-email-jiri@resnulli.us>

From: Jiri Pirko <jiri@resnulli.us>
Date: Tue, 18 Oct 2016 18:59:34 +0200

> From: Jiri Pirko <jiri@mellanox.com>
> 
> The offload flag is a status flag and should not be used by
> FIB semantics for comparison.
> 
> Fixes: 37ed9493699c ("rtnetlink: add RTNH_F_EXTERNAL flag for fib offload")
> Signed-off-by: Jiri Pirko <jiri@mellanox.com>

Ouch, good catch.

Applied and queued up for -stable, thanks!

^ permalink raw reply

* Re: [PATCH] crypto: ccm - avoid scatterlist for MAC encryption
From: Ard Biesheuvel @ 2016-10-19 15:08 UTC (permalink / raw)
  To: Johannes Berg
  Cc: Herbert Xu, Andy Lutomirski, Sergey Senozhatsky,
	<netdev@vger.kernel.org>, David S. Miller,
	<linux-wireless@vger.kernel.org>,
	linux-kernel@vger.kernel.org, Jouni Malinen
In-Reply-To: <1476862995.5927.3.camel@sipsolutions.net>

On 19 October 2016 at 08:43, Johannes Berg <johannes@sipsolutions.net> wrote:
> On Wed, 2016-10-19 at 11:31 +0800, Herbert Xu wrote:
>> On Mon, Oct 17, 2016 at 06:21:14PM +0100, Ard Biesheuvel wrote:
>> >
>> >
>> > Annoyingly, all this complication with scatterlists etc is for
>> > doing
>> > asynchronous crypto via DMA capable crypto accelerators, and the
>> > networking code (ipsec as well as mac80211, afaik) only allow
>> > synchronous in the first place, given that they execute in softirq
>> > context.
>>
>> I'm still thinking about the issue (in particular, whether we
>> should continue to rely on the request context being SG-capable
>> or allow it to be on the stack for AEAD).
>
> :)
>
>> But IPsec definitely supports async crypto.  In fact it was the
>> very first user of async crypto.
>
> Yeah.
>

Ah yes, my bad.

>> mac80211 on the other hand is currently sync-only.
>
> We could probably make mac80211 do that too, but can we guarantee in-
> order processing? Anyway, it's pretty low priority, maybe never
> happening, since hardly anyone really uses "software" crypto, the wifi
> devices mostly have it built in anyway.
>

Indeed. The code is now correct in terms of API requirements, so let's
just wait for someone to complain about any performance regressions.

^ permalink raw reply

* Re: [RFC 2/6] qed: Add iSCSI out of order packet handling.
From: Johannes Thumshirn @ 2016-10-19  9:39 UTC (permalink / raw)
  To: manish.rangankar
  Cc: lduncan, cleech, martin.petersen, jejb, linux-scsi, netdev,
	Yuval.Mintz, QLogic-Storage-Upstream, Yuval Mintz, Arun Easi
In-Reply-To: <1476853273-22960-3-git-send-email-manish.rangankar@cavium.com>

On Wed, Oct 19, 2016 at 01:01:09AM -0400, manish.rangankar@cavium.com wrote:
> From: Yuval Mintz <Yuval.Mintz@qlogic.com>
> 
> This patch adds out of order packet handling for hardware offloaded
> iSCSI. Out of order packet handling requires driver buffer allocation
> and assistance.
> 
> Signed-off-by: Arun Easi <arun.easi@cavium.com>
> Signed-off-by: Yuval Mintz <yuval.mintz@cavium.com>
> ---

[...]

> +		if (IS_ENABLED(CONFIG_QEDI) &&
> +			p_ll2_conn->conn_type == QED_LL2_TYPE_ISCSI_OOO) {

If you're going to implement the qed_is_iscsi_personallity() helper, please
consider a qed_ll2_is_iscsi_oooo() as well.

> +			struct qed_ooo_buffer *p_buffer;

[...]

> +	while (cq_new_idx != cq_old_idx) {
> +		struct core_rx_fast_path_cqe *p_cqe_fp;
> +
> +		cqe = qed_chain_consume(&p_rx->rcq_chain);
> +		cq_old_idx = qed_chain_get_cons_idx(&p_rx->rcq_chain);
> +		cqe_type = cqe->rx_cqe_sp.type;
> +
> +		if (cqe_type != CORE_RX_CQE_TYPE_REGULAR) {
> +			DP_NOTICE(p_hwfn,
> +				  "Got a non-regular LB LL2 completion [type 0x%02x]\n",
> +				  cqe_type);
> +			return -EINVAL;
> +		}
> +		p_cqe_fp = &cqe->rx_cqe_fp;
> +
> +		placement_offset = p_cqe_fp->placement_offset;
> +		parse_flags = le16_to_cpu(p_cqe_fp->parse_flags.flags);
> +		packet_length = le16_to_cpu(p_cqe_fp->packet_length);
> +		vlan = le16_to_cpu(p_cqe_fp->vlan);
> +		iscsi_ooo = (struct ooo_opaque *)&p_cqe_fp->opaque_data;
> +		qed_ooo_save_history_entry(p_hwfn, p_hwfn->p_ooo_info,
> +					   iscsi_ooo);
> +		cid = le32_to_cpu(iscsi_ooo->cid);
> +
> +		/* Process delete isle first */
> +		if (iscsi_ooo->drop_size)
> +			qed_ooo_delete_isles(p_hwfn, p_hwfn->p_ooo_info, cid,
> +					     iscsi_ooo->drop_isle,
> +					     iscsi_ooo->drop_size);
> +
> +		if (iscsi_ooo->ooo_opcode == TCP_EVENT_NOP)
> +			continue;
> +
> +		/* Now process create/add/join isles */
> +		if (list_empty(&p_rx->active_descq)) {
> +			DP_NOTICE(p_hwfn,
> +				  "LL2 OOO RX chain has no submitted buffers\n");
> +			return -EIO;
> +		}
> +
> +		p_pkt = list_first_entry(&p_rx->active_descq,
> +					 struct qed_ll2_rx_packet, list_entry);
> +
> +		if ((iscsi_ooo->ooo_opcode == TCP_EVENT_ADD_NEW_ISLE) ||
> +		    (iscsi_ooo->ooo_opcode == TCP_EVENT_ADD_ISLE_RIGHT) ||
> +		    (iscsi_ooo->ooo_opcode == TCP_EVENT_ADD_ISLE_LEFT) ||
> +		    (iscsi_ooo->ooo_opcode == TCP_EVENT_ADD_PEN) ||
> +		    (iscsi_ooo->ooo_opcode == TCP_EVENT_JOIN)) {
> +			if (!p_pkt) {
> +				DP_NOTICE(p_hwfn,
> +					  "LL2 OOO RX packet is not valid\n");
> +				return -EIO;
> +			}
> +			list_del(&p_pkt->list_entry);
> +			p_buffer = (struct qed_ooo_buffer *)p_pkt->cookie;
> +			p_buffer->packet_length = packet_length;
> +			p_buffer->parse_flags = parse_flags;
> +			p_buffer->vlan = vlan;
> +			p_buffer->placement_offset = placement_offset;
> +			qed_chain_consume(&p_rx->rxq_chain);
> +			list_add_tail(&p_pkt->list_entry, &p_rx->free_descq);
> +
> +			switch (iscsi_ooo->ooo_opcode) {
> +			case TCP_EVENT_ADD_NEW_ISLE:
> +				qed_ooo_add_new_isle(p_hwfn,
> +						     p_hwfn->p_ooo_info,
> +						     cid,
> +						     iscsi_ooo->ooo_isle,
> +						     p_buffer);
> +				break;
> +			case TCP_EVENT_ADD_ISLE_RIGHT:
> +				qed_ooo_add_new_buffer(p_hwfn,
> +						       p_hwfn->p_ooo_info,
> +						       cid,
> +						       iscsi_ooo->ooo_isle,
> +						       p_buffer,
> +						       QED_OOO_RIGHT_BUF);
> +				break;
> +			case TCP_EVENT_ADD_ISLE_LEFT:
> +				qed_ooo_add_new_buffer(p_hwfn,
> +						       p_hwfn->p_ooo_info,
> +						       cid,
> +						       iscsi_ooo->ooo_isle,
> +						       p_buffer,
> +						       QED_OOO_LEFT_BUF);
> +				break;
> +			case TCP_EVENT_JOIN:
> +				qed_ooo_add_new_buffer(p_hwfn,
> +						       p_hwfn->p_ooo_info,
> +						       cid,
> +						       iscsi_ooo->ooo_isle +
> +						       1,
> +						       p_buffer,
> +						       QED_OOO_LEFT_BUF);
> +				qed_ooo_join_isles(p_hwfn,
> +						   p_hwfn->p_ooo_info,
> +						   cid, iscsi_ooo->ooo_isle);
> +				break;
> +			case TCP_EVENT_ADD_PEN:
> +				num_ooo_add_to_peninsula++;
> +				qed_ooo_put_ready_buffer(p_hwfn,
> +							 p_hwfn->p_ooo_info,
> +							 p_buffer, true);
> +				break;
> +			}
> +		} else {
> +			DP_NOTICE(p_hwfn,
> +				  "Unexpected event (%d) TX OOO completion\n",
> +				  iscsi_ooo->ooo_opcode);
> +		}
> +	}

Can you factoror the body of that "while(cq_new_idx != cq_old_idx)" loop into
a own function?

>  
> -		b_last = list_empty(&p_rx->active_descq);
> +	/* Submit RX buffer here */
> +	while ((p_buffer = qed_ooo_get_free_buffer(p_hwfn,
> +						   p_hwfn->p_ooo_info))) {

This could be an opportunity for a qed_for_each_free_buffer() or maybe even a
qed_ooo_submit_rx_buffers() and qed_ooo_submit_tx_buffers() as this is mostly
duplicate code.

> +		rc = qed_ll2_post_rx_buffer(p_hwfn, p_ll2_conn->my_id,
> +					    p_buffer->rx_buffer_phys_addr,
> +					    0, p_buffer, true);
> +		if (rc) {
> +			qed_ooo_put_free_buffer(p_hwfn, p_hwfn->p_ooo_info,
> +						p_buffer);
> +			break;
> +		}
>  	}
> +
> +	/* Submit Tx buffers here */
> +	while ((p_buffer = qed_ooo_get_ready_buffer(p_hwfn,
> +						    p_hwfn->p_ooo_info))) {

Ditto.

[...]
> +
> +	/* Submit Tx buffers here */
> +	while ((p_buffer = qed_ooo_get_ready_buffer(p_hwfn,
> +						    p_hwfn->p_ooo_info))) {


And here

[...]

> +	while ((p_buffer = qed_ooo_get_free_buffer(p_hwfn,
> +						   p_hwfn->p_ooo_info))) {

[..]

> +	while ((p_buffer = qed_ooo_get_free_buffer(p_hwfn,
> +						   p_hwfn->p_ooo_info))) {

[...]

-- 
Johannes Thumshirn                                          Storage
jthumshirn@suse.de                                +49 911 74053 689
SUSE LINUX GmbH, Maxfeldstr. 5, 90409 Nürnberg
GF: Felix Imendörffer, Jane Smithard, Graham Norton
HRB 21284 (AG Nürnberg)
Key fingerprint = EC38 9CAB C2C4 F25D 8600 D0D0 0393 969D 2D76 0850

^ permalink raw reply

* Re: bad commit touching stmmac_ptp.c
From: Richard Cochran @ 2016-10-19  7:54 UTC (permalink / raw)
  To: Nicolas Pitre
  Cc: Giuseppe CAVALLARO, Alexandre TORGUE, Rayagond Kokatanur,
	David S. Miller, netdev
In-Reply-To: <alpine.LFD.2.20.1610182339340.25105@knanqh.ubzr>

On Wed, Oct 19, 2016 at 12:16:09AM -0400, Nicolas Pitre wrote:
> Was this patch actually reviewed?

And please, PLEASE put the PTP maintainer on CC for patches that use the
PTP subsystem!

Thanks,
Richard

^ permalink raw reply

* Re: BUG: KASAN: use-after-free in udp_lib_get_port
From: Baozeng Ding @ 2016-10-19 15:01 UTC (permalink / raw)
  To: Cong Wang; +Cc: network dev, linux-kernel
In-Reply-To: <CAM_iQpVExpqdOXZp0Lw+4Nr2_9W24P2dQFdM=EoYwBkHtwDoPw@mail.gmail.com>

Hello all,
I have got some similar bugs again((on Oct 7 commit d1f5323370fceaed43a7ee38f4c7bfc7e70f28d0):

BUG: KASAN: use-after-free in udp_lib_get_port+0x1573/0x1860 at addr ffff88002f163c60
Write of size 8 by task syz-executor/13510
CPU: 2 PID: 13510 Comm: syz-executor Not tainted 4.8.0+ #41
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.8.2-0-g33fbe13 by qemu-project.org 04/01/2014
 ffff880034ea7a68 ffffffff829f835b ffff88002f488b40 ffff88002f163c40
 ffff88002f164350 ffff88003178154a ffff880034ea7a90 ffffffff8174d3cc
 ffff880034ea7b20 ffff88002f163c00 ffff88002f488b40 ffff880034ea7b10
Call Trace:
 [<ffffffff829f835b>] dump_stack+0xb3/0x118 /lib/dump_stack.c:15
 [<ffffffff8174d3cc>] kasan_object_err+0x1c/0x70 /mm/kasan/report.c:156
 [<     inline     >] print_address_description /mm/kasan/report.c:194
 [<ffffffff8174d666>] kasan_report_error+0x1f6/0x4d0 /mm/kasan/report.c:283
 [<     inline     >] kasan_report /mm/kasan/report.c:303
 [<ffffffff8174db7e>] __asan_report_store8_noabort+0x3e/0x40 /mm/kasan/report.c:329
 [<     inline     >] hlist_add_head_rcu /./include/linux/rculist.h:487
 [<ffffffff850866e3>] udp_lib_get_port+0x1573/0x1860 /net/ipv4/udp.c:345
 [<ffffffff8508b4f9>] udp_v4_get_port+0x139/0x180 /net/ipv4/udp.c:392
 [<ffffffff850b2f7a>] inet_autobind+0xaa/0x180 /net/ipv4/af_inet.c:181
 [<ffffffff850b3181>] inet_dgram_connect+0x131/0x1f0 /net/ipv4/af_inet.c:528
 [<ffffffff84c4959e>] SYSC_connect+0x23e/0x2e0 /net/socket.c:1533
 [<ffffffff84c4bd14>] SyS_connect+0x24/0x30 /net/socket.c:1514
 [<ffffffff85e4d6c5>] entry_SYSCALL_64_fastpath+0x23/0xc6
Object at ffff88002f163c40, in cache UDPv6 size: 1496
Allocated:
PID = 13255
 [ 1773.470431] [<ffffffff811ddcb6>] save_stack_trace+0x16/0x20
 [ 1773.470431] [<ffffffff8174c736>] save_stack+0x46/0xd0
 [ 1773.470431] [<ffffffff8174c9ad>] kasan_kmalloc+0xad/0xe0
 [ 1773.470431] [<ffffffff8174cee2>] kasan_slab_alloc+0x12/0x20
 [ 1773.470431] [<     inline     >] slab_post_alloc_hook /mm/slab.h:417
 [ 1773.470431] [<     inline     >] slab_alloc_node /mm/slub.c:2708
 [ 1773.470431] [<     inline     >] slab_alloc /mm/slub.c:2716
 [ 1773.470431] [<ffffffff817476a8>] kmem_cache_alloc+0xc8/0x2b0 /mm/slub.c:2721
 [ 1773.470431] [<ffffffff84c4f6a9>] sk_prot_alloc+0x69/0x2b0 /net/core/sock.c:1326
 [ 1773.470431] [<ffffffff84c58ac8>] sk_alloc+0x38/0xae0 /net/core/sock.c:1388
 [ 1773.470431] [<ffffffff851ddf77>] inet6_create+0x2d7/0x1000 /net/ipv6/af_inet6.c:182
 [ 1773.470431] [<ffffffff84c4af7b>] __sock_create+0x37b/0x640 /net/socket.c:1153
 [ 1773.470431] [<     inline     >] sock_create /net/socket.c:1193
 [ 1773.470431] [<     inline     >] SYSC_socket /net/socket.c:1223
 [ 1773.470431] [<ffffffff84c4b46f>] SyS_socket+0xef/0x1b0 /net/socket.c:1203
 [ 1773.470431] [<ffffffff85e4d6c5>] entry_SYSCALL_64_fastpath+0x23/0xc6
Freed:
PID = 13261
 [ 1773.470431] [<ffffffff811ddcb6>] save_stack_trace+0x16/0x20
 [ 1773.470431] [<ffffffff8174c736>] save_stack+0x46/0xd0
 [ 1773.470431] [<ffffffff8174cf61>] kasan_slab_free+0x71/0xb0
 [ 1773.470431] [<     inline     >] slab_free_hook /mm/slub.c:1352
 [ 1773.470431] [<     inline     >] slab_free_freelist_hook /mm/slub.c:1374
 [ 1773.470431] [<     inline     >] slab_free /mm/slub.c:2951
 [ 1773.470431] [<ffffffff81748b28>] kmem_cache_free+0xc8/0x330 /mm/slub.c:2973
 [ 1773.470431] [<     inline     >] sk_prot_free /net/core/sock.c:1369
 [ 1773.470431] [<ffffffff84c541eb>] __sk_destruct+0x32b/0x4f0 /net/core/sock.c:1444
 [ 1773.470431] [<ffffffff84c5aca4>] sk_destruct+0x44/0x80 /net/core/sock.c:1452
 [ 1773.470431] [<ffffffff84c5ad33>] __sk_free+0x53/0x220 /net/core/sock.c:1460
 [ 1773.470431] [<ffffffff84c5af23>] sk_free+0x23/0x30 /net/core/sock.c:1471
 [ 1773.470431] [<ffffffff84c5cb6c>] sk_common_release+0x28c/0x3e0 /./include/net/sock.h:1589
 [ 1773.470431] [<ffffffff852569f5>] udp_lib_close+0x15/0x20 /./include/net/udp.h:203
 [ 1773.470431] [<ffffffff850b2dfd>] inet_release+0xed/0x1c0 /net/ipv4/af_inet.c:415
 [ 1773.470431] [<ffffffff851dc5aa>] inet6_release+0x5a/0x80 /net/ipv6/af_inet6.c:424
 [ 1773.470431] [<ffffffff84c4581d>] sock_release+0x8d/0x1d0 /net/socket.c:570
 [ 1773.470431] [<ffffffff84c45976>] sock_close+0x16/0x20 /net/socket.c:1017
 [ 1773.470431] [<ffffffff817a108c>] __fput+0x28c/0x780 /fs/file_table.c:208
 [ 1773.470431] [<ffffffff817a1605>] ____fput+0x15/0x20 /fs/file_table.c:244
 [ 1773.470431] [<ffffffff813774f9>] task_work_run+0xf9/0x170
 [ 1773.470431] [<ffffffff81324aae>] do_exit+0x85e/0x2a00
 [ 1773.470431] [<ffffffff81326dc8>] do_group_exit+0x108/0x330
 [ 1773.470431] [<ffffffff81348cf7>] get_signal+0x617/0x17a0 /kernel/signal.c:2307
 [ 1773.470431] [<ffffffff811b49af>] do_signal+0x7f/0x18f0
 [ 1773.470431] [<ffffffff810039bf>] exit_to_usermode_loop+0xbf/0x150 /arch/x86/entry/common.c:156
 [ 1773.470431] [<     inline     >] prepare_exit_to_usermode /arch/x86/entry/common.c:190
 [ 1773.470431] [<ffffffff81006060>] syscall_return_slowpath+0x1a0/0x1e0 /arch/x86/entry/common.c:259
 [ 1773.470431] [<ffffffff85e4d766>] entry_SYSCALL_64_fastpath+0xc4/0xc6
Memory state around the buggy address:
 ffff88002f163b00: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
 ffff88002f163b80: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
>ffff88002f163c00: fc fc fc fc fc fc fc fc fb fb fb fb fb fb fb fb
                                                       ^
 ffff88002f163c80: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
 ffff88002f163d00: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
==================================================================
Disabling lock debugging due to kernel taint
==================================================================
BUG: KASAN: use-after-free in udp_lib_unhash+0x593/0x660 at addr ffff88002f163c60
Write of size 8 by task syz-executor/13522
CPU: 1 PID: 13522 Comm: syz-executor Tainted: G    B           4.8.0+ #41
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.8.2-0-g33fbe13 by qemu-project.org 04/01/2014
 ffff88002e4e77e0 ffffffff829f835b ffff88002f488b40 ffff88002f163c40
 ffff88002f164350 ffff880031781540 ffff88002e4e7808 ffffffff8174d3cc
 ffff88002e4e7898 ffff88002f163c00 ffff88002f488b40 ffff88002e4e7888
Call Trace:
 [<ffffffff829f835b>] dump_stack+0xb3/0x118 /lib/dump_stack.c:15
 [<ffffffff8174d3cc>] kasan_object_err+0x1c/0x70 /mm/kasan/report.c:156
 [<     inline     >] print_address_description /mm/kasan/report.c:194
 [<ffffffff8174d666>] kasan_report_error+0x1f6/0x4d0 /mm/kasan/report.c:283
 [<     inline     >] kasan_report /mm/kasan/report.c:303
 [<ffffffff8174db7e>] __asan_report_store8_noabort+0x3e/0x40 /mm/kasan/report.c:329
 [<     inline     >] hlist_del_init_rcu /./include/linux/list.h:624
 [<ffffffff85082c83>] udp_lib_unhash+0x593/0x660 /net/ipv4/udp.c:1391
 [<ffffffff84c5c99d>] sk_common_release+0xbd/0x3e0 /net/core/sock.c:2719
 [<ffffffff85083f05>] udp_lib_close+0x15/0x20 /./include/net/udp.h:203
 [<ffffffff850b2dfd>] inet_release+0xed/0x1c0 /net/ipv4/af_inet.c:415
 [<ffffffff84c4581d>] sock_release+0x8d/0x1d0 /net/socket.c:570
 [<ffffffff84c45976>] sock_close+0x16/0x20 /net/socket.c:1017
 [<ffffffff817a108c>] __fput+0x28c/0x780 /fs/file_table.c:208
 [<ffffffff817a1605>] ____fput+0x15/0x20 /fs/file_table.c:244
 [<ffffffff813774f9>] task_work_run+0xf9/0x170
 [<ffffffff81324aae>] do_exit+0x85e/0x2a00
 [<ffffffff81326dc8>] do_group_exit+0x108/0x330
 [<ffffffff81348cf7>] get_signal+0x617/0x17a0 /kernel/signal.c:2307
 [<ffffffff811b49af>] do_signal+0x7f/0x18f0
 [<ffffffff810039bf>] exit_to_usermode_loop+0xbf/0x150 /arch/x86/entry/common.c:156
 [<     inline     >] prepare_exit_to_usermode /arch/x86/entry/common.c:190
 [<ffffffff81006060>] syscall_return_slowpath+0x1a0/0x1e0 /arch/x86/entry/common.c:259
 [<ffffffff85e4d766>] entry_SYSCALL_64_fastpath+0xc4/0xc6
Object at ffff88002f163c40, in cache UDPv6 size: 1496
Allocated:
PID = 13255
 [ 1773.617936] [<ffffffff811ddcb6>] save_stack_trace+0x16/0x20
 [ 1773.617936] [<ffffffff8174c736>] save_stack+0x46/0xd0
 [ 1773.617936] [<ffffffff8174c9ad>] kasan_kmalloc+0xad/0xe0
 [ 1773.617936] [<ffffffff8174cee2>] kasan_slab_alloc+0x12/0x20
 [ 1773.617936] [<     inline     >] slab_post_alloc_hook /mm/slab.h:417
 [ 1773.617936] [<     inline     >] slab_alloc_node /mm/slub.c:2708
 [ 1773.617936] [<     inline     >] slab_alloc /mm/slub.c:2716
 [ 1773.617936] [<ffffffff817476a8>] kmem_cache_alloc+0xc8/0x2b0 /mm/slub.c:2721
 [ 1773.617936] [<ffffffff84c4f6a9>] sk_prot_alloc+0x69/0x2b0 /net/core/sock.c:1326
 [ 1773.617936] [<ffffffff84c58ac8>] sk_alloc+0x38/0xae0 /net/core/sock.c:1388
 [ 1773.617936] [<ffffffff851ddf77>] inet6_create+0x2d7/0x1000 /net/ipv6/af_inet6.c:182
 [ 1773.617936] [<ffffffff84c4af7b>] __sock_create+0x37b/0x640 /net/socket.c:1153
 [ 1773.617936] [<     inline     >] sock_create /net/socket.c:1193
 [ 1773.617936] [<     inline     >] SYSC_socket /net/socket.c:1223
 [ 1773.617936] [<ffffffff84c4b46f>] SyS_socket+0xef/0x1b0 /net/socket.c:1203
 [ 1773.617936] [<ffffffff85e4d6c5>] entry_SYSCALL_64_fastpath+0x23/0xc6
Freed:
PID = 13261
 [ 1773.617936] [<ffffffff811ddcb6>] save_stack_trace+0x16/0x20
 [ 1773.617936] [<ffffffff8174c736>] save_stack+0x46/0xd0
 [ 1773.617936] [<ffffffff8174cf61>] kasan_slab_free+0x71/0xb0
 [ 1773.617936] [<     inline     >] slab_free_hook /mm/slub.c:1352
 [ 1773.617936] [<     inline     >] slab_free_freelist_hook /mm/slub.c:1374
 [ 1773.617936] [<     inline     >] slab_free /mm/slub.c:2951
 [ 1773.617936] [<ffffffff81748b28>] kmem_cache_free+0xc8/0x330 /mm/slub.c:2973
 [ 1773.617936] [<     inline     >] sk_prot_free /net/core/sock.c:1369
 [ 1773.617936] [<ffffffff84c541eb>] __sk_destruct+0x32b/0x4f0 /net/core/sock.c:1444
 [ 1773.617936] [<ffffffff84c5aca4>] sk_destruct+0x44/0x80 /net/core/sock.c:1452
 [ 1773.617936] [<ffffffff84c5ad33>] __sk_free+0x53/0x220 /net/core/sock.c:1460
 [ 1773.617936] [<ffffffff84c5af23>] sk_free+0x23/0x30 /net/core/sock.c:1471
 [ 1773.617936] [<ffffffff84c5cb6c>] sk_common_release+0x28c/0x3e0 /./include/net/sock.h:1589
 [ 1773.617936] [<ffffffff852569f5>] udp_lib_close+0x15/0x20 /./include/net/udp.h:203
 [ 1773.617936] [<ffffffff850b2dfd>] inet_release+0xed/0x1c0 /net/ipv4/af_inet.c:415
 [ 1773.617936] [<ffffffff851dc5aa>] inet6_release+0x5a/0x80 /net/ipv6/af_inet6.c:424
 [ 1773.617936] [<ffffffff84c4581d>] sock_release+0x8d/0x1d0 /net/socket.c:570
 [ 1773.617936] [<ffffffff84c45976>] sock_close+0x16/0x20 /net/socket.c:1017
 [ 1773.617936] [<ffffffff817a108c>] __fput+0x28c/0x780 /fs/file_table.c:208
 [ 1773.617936] [<ffffffff817a1605>] ____fput+0x15/0x20 /fs/file_table.c:244
 [ 1773.617936] [<ffffffff813774f9>] task_work_run+0xf9/0x170
 [ 1773.617936] [<ffffffff81324aae>] do_exit+0x85e/0x2a00
 [ 1773.617936] [<ffffffff81326dc8>] do_group_exit+0x108/0x330
 [ 1773.617936] [<ffffffff81348cf7>] get_signal+0x617/0x17a0 /kernel/signal.c:2307
 [ 1773.617936] [<ffffffff811b49af>] do_signal+0x7f/0x18f0
 [ 1773.617936] [<ffffffff810039bf>] exit_to_usermode_loop+0xbf/0x150 /arch/x86/entry/common.c:156
 [ 1773.617936] [<     inline     >] prepare_exit_to_usermode /arch/x86/entry/common.c:190
 [ 1773.617936] [<ffffffff81006060>] syscall_return_slowpath+0x1a0/0x1e0 /arch/x86/entry/common.c:259
 [ 1773.617936] [<ffffffff85e4d766>] entry_SYSCALL_64_fastpath+0xc4/0xc6
Memory state around the buggy address:
 ffff88002f163b00: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
 ffff88002f163b80: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
>ffff88002f163c00: fc fc fc fc fc fc fc fc fb fb fb fb fb fb fb fb
                                                       ^
 ffff88002f163c80: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
 ffff88002f163d00: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
==================================================================

Best Regards,
Baozeng Ding

On 2016/10/17 3:53, Cong Wang wrote:
> On Sun, Oct 16, 2016 at 6:46 AM, Baozeng Ding <sploving1@gmail.com> wrote:
>> Hello all,
>> While running syzkaller fuzzer I have got the following use-after-free
>> bug in udp_lib_get_port. The kernel version is 4.8.0+ (on Oct 7 commit d1f5323370fceaed43a7ee38f4c7bfc7e70f28d0). Unfortunately I failed to find a reproducer for it.
>>
>> BUG: KASAN: use-after-free in udp_lib_get_port+0x1573/0x1860 at addr ffff88000804cb60
>> Write of size 8 by task syz-executor/31190
>> CPU: 0 PID: 31190 Comm: syz-executor Not tainted 4.8.0+ #39
>> Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.8.2-0-g33fbe13 by qemu-project.org 04/01/2014
>>  ffff880015ac7a48 ffffffff829f835b ffff880032b531c0 ffff88000804cb40
>>  ffff88000804d250 ffff880017415a4a ffff880015ac7a70 ffffffff8174d3cc
>>  ffff880015ac7b00 ffff88000804cb00 ffff880032b531c0 ffff880015ac7af0
>> Call Trace:
>>  [<ffffffff829f835b>] dump_stack+0xb3/0x118 lib/dump_stack.c:15
>>  [<ffffffff8174d3cc>] kasan_object_err+0x1c/0x70 mm/kasan/report.c:156
>>  [<     inline     >] print_address_description mm/kasan/report.c:194
>>  [<ffffffff8174d666>] kasan_report_error+0x1f6/0x4d0 mm/kasan/report.c:283
>>  [<     inline     >] kasan_report mm/kasan/report.c:303
>>  [<ffffffff8174db7e>] __asan_report_store8_noabort+0x3e/0x40 mm/kasan/report.c:329
>>  [<     inline     >] hlist_add_head_rcu ./include/linux/rculist.h:487
>>  [<ffffffff850866e3>] udp_lib_get_port+0x1573/0x1860 net/ipv4/udp.c:345
>>  [<ffffffff8525cc27>] udp_v6_get_port+0xa7/0xd0 net/ipv6/udp.c:106
>>  [<ffffffff851df52c>] inet6_bind+0x89c/0xfb0 net/ipv6/af_inet6.c:384
>>  [<ffffffff84c492fa>] SYSC_bind+0x1ea/0x250 net/socket.c:1367
>>  [<ffffffff84c4ba34>] SyS_bind+0x24/0x30 net/socket.c:1353
>>  [<ffffffff85e4d685>] entry_SYSCALL_64_fastpath+0x23/0xc6
> 
> 
> We should have a reference to this sock via fd and its sock->sk too,
> so I fail to see why it could be freed while we holding this reference.
> Maybe a VFS layer bug?
> 
>> Object at ffff88000804cb40, in cache UDPv6 size: 1496
>> Allocated:
>> PID = 30789
>>  [  378.305168] [<ffffffff811ddcb6>] save_stack_trace+0x16/0x20
>>  [  378.305168] [<ffffffff8174c736>] save_stack+0x46/0xd0
>>  [  378.305168] [<ffffffff8174c9ad>] kasan_kmalloc+0xad/0xe0
>>  [  378.305168] [<ffffffff8174cee2>] kasan_slab_alloc+0x12/0x20
>>  [  378.305168] [<     inline     >] slab_post_alloc_hook mm/slab.h:417
>>  [  378.305168] [<     inline     >] slab_alloc_node mm/slub.c:2708
>>  [  378.305168] [<     inline     >] slab_alloc mm/slub.c:2716
>>  [  378.305168] [<ffffffff817476a8>] kmem_cache_alloc+0xc8/0x2b0 mm/slub.c:2721
>>  [  378.305168] [<ffffffff84c4f6a9>] sk_prot_alloc+0x69/0x2b0 net/core/sock.c:1326
>>  [  378.305168] [<ffffffff84c58ac8>] sk_alloc+0x38/0xae0 net/core/sock.c:1388
>>  [  378.305168] [<ffffffff851ddf67>] inet6_create+0x2d7/0x1000 net/ipv6/af_inet6.c:182
>>  [  378.305168] [<ffffffff84c4af7b>] __sock_create+0x37b/0x640 net/socket.c:1153
>>  [  378.305168] [<     inline     >] sock_create net/socket.c:1193
>>  [  378.305168] [<     inline     >] SYSC_socket net/socket.c:1223
>>  [  378.305168] [<ffffffff84c4b46f>] SyS_socket+0xef/0x1b0 net/socket.c:1203
>>  [  378.305168] [<ffffffff85e4d685>] entry_SYSCALL_64_fastpath+0x23/0xc6
>> Freed:
>> PID = 30789
>>  [  378.305168] [<ffffffff811ddcb6>] save_stack_trace+0x16/0x20
>>  [  378.305168] [<ffffffff8174c736>] save_stack+0x46/0xd0
>>  [  378.305168] [<ffffffff8174cf61>] kasan_slab_free+0x71/0xb0
>>  [  378.305168] [<     inline     >] slab_free_hook mm/slub.c:1352
>>  [  378.305168] [<     inline     >] slab_free_freelist_hook mm/slub.c:1374
>>  [  378.305168] [<     inline     >] slab_free mm/slub.c:2951
>>  [  378.305168] [<ffffffff81748b28>] kmem_cache_free+0xc8/0x330 mm/slub.c:2973
>>  [  378.305168] [<     inline     >] sk_prot_free net/core/sock.c:1369
>>  [  378.305168] [<ffffffff84c541eb>] __sk_destruct+0x32b/0x4f0 net/core/sock.c:1444
>>  [  378.305168] [<ffffffff84c5aca4>] sk_destruct+0x44/0x80 net/core/sock.c:1452
>>  [  378.305168] [<ffffffff84c5ad33>] __sk_free+0x53/0x220 net/core/sock.c:1460
>>  [  378.305168] [<ffffffff84c5af23>] sk_free+0x23/0x30 net/core/sock.c:1471
>>  [  378.305168] [<ffffffff84c5cb6c>] sk_common_release+0x28c/0x3e0 ./include/net/sock.h:1589
>>  [  378.305168] [<ffffffff852569e5>] udp_lib_close+0x15/0x20 ./include/net/udp.h:203
>>  [  378.305168] [<ffffffff850b2dfd>] inet_release+0xed/0x1c0 net/ipv4/af_inet.c:415
>>  [  378.305168] [<ffffffff851dc5a0>] inet6_release+0x50/0x70 net/ipv6/af_inet6.c:422
>>  [  378.305168] [<ffffffff84c4581d>] sock_release+0x8d/0x1d0 net/socket.c:570
>>  [  378.305168] [<ffffffff84c45976>] sock_close+0x16/0x20 net/socket.c:1017
>>  [  378.305168] [<ffffffff817a108c>] __fput+0x28c/0x780 fs/file_table.c:208
>>  [  378.305168] [<ffffffff817a1605>] ____fput+0x15/0x20 fs/file_table.c:244
>>  [  378.305168] [<ffffffff813774f9>] task_work_run+0xf9/0x170
>>  [  378.305168] [<ffffffff81324aae>] do_exit+0x85e/0x2a00
>>  [  378.305168] [<ffffffff81326dc8>] do_group_exit+0x108/0x330
>>  [  378.376437] [<ffffffff81348cf7>] get_signal+0x617/0x17a0 kernel/signal.c:2307
>>  [  378.376437] [<ffffffff811b49af>] do_signal+0x7f/0x18f0
>>  [  378.376437] [<ffffffff810039bf>] exit_to_usermode_loop+0xbf/0x150 arch/x86/entry/common.c:156
>>  [  378.376437] [<     inline     >] prepare_exit_to_usermode arch/x86/entry/common.c:190
>>  [  378.376437] [<ffffffff81006060>] syscall_return_slowpath+0x1a0/0x1e0 arch/x86/entry/common.c:259
>>  [  378.376437] [<ffffffff85e4d726>] entry_SYSCALL_64_fastpath+0xc4/0xc6
>> Memory state around the buggy address:
>>  ffff88000804ca00: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
>>  ffff88000804ca80: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
>>> ffff88000804cb00: fc fc fc fc fc fc fc fc fb fb fb fb fb fb fb fb
>>                                                        ^
>>  ffff88000804cb80: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
>>  ffff88000804cc00: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
>> ==================================================================
>>
>> Thanks && Best Regards,
>> Baozeng Ding

^ permalink raw reply

* Re: [RFC v3 05/22] bpf,landlock: Add eBPF program subtype and is_valid_subtype() verifier
From: Thomas Graf @ 2016-10-19 15:01 UTC (permalink / raw)
  To: Mickaël Salaün
  Cc: linux-kernel, Alexei Starovoitov, Andy Lutomirski, Arnd Bergmann,
	Casey Schaufler, Daniel Borkmann, Daniel Mack, David Drysdale,
	David S . Miller, Elena Reshetova, Eric W . Biederman,
	James Morris, Kees Cook, Paul Moore, Sargun Dhillon,
	Serge E . Hallyn, Tejun Heo, Will Drewry, kernel-hardening,
	linux-api, linux-security-module
In-Reply-To: <20160914072415.26021-6-mic@digikod.net>

On 09/14/16 at 09:23am, Mickaël Salaün wrote:
> @@ -155,6 +163,7 @@ union bpf_attr {
>  		__u32		log_size;	/* size of user buffer */
>  		__aligned_u64	log_buf;	/* user supplied buffer */
>  		__u32		kern_version;	/* checked when prog_type=kprobe */
> +		union bpf_prog_subtype prog_subtype;	/* checked when prog_type=landlock */

The comment seems bogus, this is not landlock specific.

^ permalink raw reply

* Re: [patch net 1/6] switchdev: Execute bridge ndos only for bridge ports
From: David Miller @ 2016-10-19 15:00 UTC (permalink / raw)
  To: jiri
  Cc: netdev, idosch, eladr, yotamg, nogahf, ogerlitz, roopa, nikolay,
	linville, andy, f.fainelli, dsa, jhs, vivien.didelot, andrew,
	ivecera
In-Reply-To: <1476809423-14624-1-git-send-email-jiri@resnulli.us>

From: Jiri Pirko <jiri@resnulli.us>
Date: Tue, 18 Oct 2016 18:50:23 +0200

> From: Ido Schimmel <idosch@mellanox.com>
> 
> We recently got the following warning after setting up a vlan device on
> top of an offloaded bridge and executing 'bridge link':
...
> The problem is that the 8021q module propagates the call to
> ndo_bridge_getlink() via switchdev ops, but the switch driver doesn't
> recognize the netdev, as it's not offloaded.
> 
> While we can ignore calls being made to non-bridge ports inside the
> driver, a better fix would be to push this check up to the switchdev
> layer.
> 
> Note that these ndos can be called for non-bridged netdev, but this only
> happens in certain PF drivers which don't call the corresponding
> switchdev functions anyway.
> 
> Fixes: 99f44bb3527b ("mlxsw: spectrum: Enable L3 interfaces on top of bridge devices")
> Signed-off-by: Ido Schimmel <idosch@mellanox.com>
> Reported-by: Tamir Winetroub <tamirw@mellanox.com>
> Tested-by: Tamir Winetroub <tamirw@mellanox.com>
> Signed-off-by: Jiri Pirko <jiri@mellanox.com>

Applied and queued up for -stable, thanks.

^ permalink raw reply

* Re: [PATCH (net.git)] stmmac: fix and review the ptp registration.
From: Dan Carpenter @ 2016-10-19  7:40 UTC (permalink / raw)
  To: Giuseppe Cavallaro
  Cc: netdev, davem, linux-kernel, Alexandre TORGUE, Rayagond Kokatanur,
	Nicolas Pitre
In-Reply-To: <1476860801-28242-1-git-send-email-peppe.cavallaro@st.com>

Looks good.  This actually fixes my commit where I changed the return
PTR_ERR(NULL) which means success to PTR_ERR(-ESOMETHING).
Unintentionally returning success was the correct behavior.

regards,
dan carpenter

^ permalink raw reply

* [PATCH 0/2] Add ethtool get_ringparam and set_ringparam to cadence
From: Zach Brown @ 2016-10-19 14:56 UTC (permalink / raw)
  To: nicolas.ferre; +Cc: davem, linux-kernel, netdev

There are use cases like RT that would benefit from being able to tune the
macb rx/tx ring sizes. The ethtool set_ringparam function is the standard way
of doing so.

The first patch changes the hardcoded tx/rx ring sizes to variables that are
set to a hardcoded default.

The second patch implements the get_ringparam and set_ringparam fucntions.

Zach Brown (2):
  net: macb: Use variables with defaults for tx/rx ring sizes instead of
    hardcoded values
  net: macb: Add ethtool get_ringparam and set_ringparam functionality

 drivers/net/ethernet/cadence/macb.c | 173 +++++++++++++++++++++++++-----------
 drivers/net/ethernet/cadence/macb.h |   3 +
 2 files changed, 124 insertions(+), 52 deletions(-)

^ permalink raw reply

* [PATCH 2/2] net: macb: Add ethtool get_ringparam and set_ringparam functionality
From: Zach Brown @ 2016-10-19 14:56 UTC (permalink / raw)
  To: nicolas.ferre; +Cc: davem, linux-kernel, netdev
In-Reply-To: <1476889018-8357-1-git-send-email-zach.brown@ni.com>

Some applications want to tune the size of the macb rx/tx ring buffers.
The ethtool set_ringparam function is the standard way of doing it.

Signed-off-by: Zach Brown <zach.brown@ni.com>
---
 drivers/net/ethernet/cadence/macb.c | 59 +++++++++++++++++++++++++++++++++++++
 1 file changed, 59 insertions(+)

diff --git a/drivers/net/ethernet/cadence/macb.c b/drivers/net/ethernet/cadence/macb.c
index 644975d..e1847ce 100644
--- a/drivers/net/ethernet/cadence/macb.c
+++ b/drivers/net/ethernet/cadence/macb.c
@@ -37,11 +37,16 @@

 #define MACB_RX_BUFFER_SIZE	128
 #define RX_BUFFER_MULTIPLE	64  /* bytes */
+
 #define DEFAULT_RX_RING_SIZE	512 /* must be power of 2 */
+#define MIN_RX_RING_SIZE	64
+#define MAX_RX_RING_SIZE	8192
 #define RX_RING_BYTES(bp)	(sizeof(struct macb_dma_desc)	\
 				 * (bp)->rx_ring_size)

 #define DEFAULT_TX_RING_SIZE	512 /* must be power of 2 */
+#define MIN_TX_RING_SIZE	64
+#define MAX_TX_RING_SIZE	4096
 #define TX_RING_BYTES(bp)	(sizeof(struct macb_dma_desc)	\
 				 * (bp)->tx_ring_size)

@@ -2211,6 +2216,56 @@ static int macb_set_wol(struct net_device *netdev, struct ethtool_wolinfo *wol)
 	return 0;
 }

+static void macb_get_ringparam(struct net_device *netdev,
+			       struct ethtool_ringparam *ring)
+{
+	struct macb *bp = netdev_priv(netdev);
+
+	ring->rx_max_pending = MAX_RX_RING_SIZE;
+	ring->tx_max_pending = MAX_TX_RING_SIZE;
+
+	ring->rx_pending = bp->rx_ring_size;
+	ring->tx_pending = bp->tx_ring_size;
+}
+
+static int macb_set_ringparam(struct net_device *netdev,
+			      struct ethtool_ringparam *ring)
+{
+	struct macb *bp = netdev_priv(netdev);
+	u32 new_rx_size, new_tx_size;
+	unsigned int reset = 0;
+
+	if ((ring->rx_mini_pending) || (ring->rx_jumbo_pending))
+		return -EINVAL;
+
+	new_rx_size = clamp_t(u32, ring->rx_pending,
+			      MIN_RX_RING_SIZE, MAX_RX_RING_SIZE);
+	new_rx_size = roundup_pow_of_two(new_rx_size);
+
+	new_tx_size = clamp_t(u32, ring->tx_pending,
+			      MIN_TX_RING_SIZE, MAX_TX_RING_SIZE);
+	new_tx_size = roundup_pow_of_two(new_tx_size);
+
+	if ((new_tx_size == bp->tx_ring_size) &&
+	    (new_rx_size == bp->rx_ring_size)) {
+		/* nothing to do */
+		return 0;
+	}
+
+	if (netif_running(bp->dev)) {
+		reset = 1;
+		macb_close(bp->dev);
+	}
+
+	bp->rx_ring_size = new_rx_size;
+	bp->tx_ring_size = new_tx_size;
+
+	if (reset)
+		macb_open(bp->dev);
+
+	return 0;
+}
+
 static const struct ethtool_ops macb_ethtool_ops = {
 	.get_regs_len		= macb_get_regs_len,
 	.get_regs		= macb_get_regs,
@@ -2220,6 +2275,8 @@ static const struct ethtool_ops macb_ethtool_ops = {
 	.set_wol		= macb_set_wol,
 	.get_link_ksettings     = phy_ethtool_get_link_ksettings,
 	.set_link_ksettings     = phy_ethtool_set_link_ksettings,
+	.get_ringparam		= macb_get_ringparam,
+	.set_ringparam		= macb_set_ringparam,
 };

 static const struct ethtool_ops gem_ethtool_ops = {
@@ -2232,6 +2289,8 @@ static const struct ethtool_ops gem_ethtool_ops = {
 	.get_sset_count		= gem_get_sset_count,
 	.get_link_ksettings     = phy_ethtool_get_link_ksettings,
 	.set_link_ksettings     = phy_ethtool_set_link_ksettings,
+	.get_ringparam		= macb_get_ringparam,
+	.set_ringparam		= macb_set_ringparam,
 };

 static int macb_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
--
2.7.4

^ permalink raw reply related

* [PATCH 1/2] net: macb: Use variables with defaults for tx/rx ring sizes instead of hardcoded values
From: Zach Brown @ 2016-10-19 14:56 UTC (permalink / raw)
  To: nicolas.ferre; +Cc: davem, linux-kernel, netdev
In-Reply-To: <1476889018-8357-1-git-send-email-zach.brown@ni.com>

The macb driver hardcoded the tx/rx ring sizes. This made it
impossible to change the sizes at run time.

Add tx_ring_size, and rx_ring_size variables to macb object, which
are initilized with default vales during macb_init. Change all
references to RX_RING_SIZE and TX_RING_SIZE to their respective
replacements.

Signed-off-by: Zach Brown <zach.brown@ni.com>
---
 drivers/net/ethernet/cadence/macb.c | 114 ++++++++++++++++++++----------------
 drivers/net/ethernet/cadence/macb.h |   3 +
 2 files changed, 65 insertions(+), 52 deletions(-)

diff --git a/drivers/net/ethernet/cadence/macb.c b/drivers/net/ethernet/cadence/macb.c
index e83781a..644975d 100644
--- a/drivers/net/ethernet/cadence/macb.c
+++ b/drivers/net/ethernet/cadence/macb.c
@@ -37,14 +37,16 @@
 
 #define MACB_RX_BUFFER_SIZE	128
 #define RX_BUFFER_MULTIPLE	64  /* bytes */
-#define RX_RING_SIZE		512 /* must be power of 2 */
-#define RX_RING_BYTES		(sizeof(struct macb_dma_desc) * RX_RING_SIZE)
+#define DEFAULT_RX_RING_SIZE	512 /* must be power of 2 */
+#define RX_RING_BYTES(bp)	(sizeof(struct macb_dma_desc)	\
+				 * (bp)->rx_ring_size)
 
-#define TX_RING_SIZE		128 /* must be power of 2 */
-#define TX_RING_BYTES		(sizeof(struct macb_dma_desc) * TX_RING_SIZE)
+#define DEFAULT_TX_RING_SIZE	512 /* must be power of 2 */
+#define TX_RING_BYTES(bp)	(sizeof(struct macb_dma_desc)	\
+				 * (bp)->tx_ring_size)
 
 /* level of occupied TX descriptors under which we wake up TX process */
-#define MACB_TX_WAKEUP_THRESH	(3 * TX_RING_SIZE / 4)
+#define MACB_TX_WAKEUP_THRESH(bp)	(3 * (bp)->tx_ring_size / 4)
 
 #define MACB_RX_INT_FLAGS	(MACB_BIT(RCOMP) | MACB_BIT(RXUBR)	\
 				 | MACB_BIT(ISR_ROVR))
@@ -67,45 +69,47 @@
 #define MACB_HALT_TIMEOUT	1230
 
 /* Ring buffer accessors */
-static unsigned int macb_tx_ring_wrap(unsigned int index)
+static unsigned int macb_tx_ring_wrap(struct macb *bp, unsigned int index)
 {
-	return index & (TX_RING_SIZE - 1);
+	return index & (bp->tx_ring_size - 1);
 }
 
 static struct macb_dma_desc *macb_tx_desc(struct macb_queue *queue,
 					  unsigned int index)
 {
-	return &queue->tx_ring[macb_tx_ring_wrap(index)];
+	return &queue->tx_ring[macb_tx_ring_wrap(queue->bp, index)];
 }
 
 static struct macb_tx_skb *macb_tx_skb(struct macb_queue *queue,
 				       unsigned int index)
 {
-	return &queue->tx_skb[macb_tx_ring_wrap(index)];
+	return &queue->tx_skb[macb_tx_ring_wrap(queue->bp, index)];
 }
 
 static dma_addr_t macb_tx_dma(struct macb_queue *queue, unsigned int index)
 {
 	dma_addr_t offset;
 
-	offset = macb_tx_ring_wrap(index) * sizeof(struct macb_dma_desc);
+	offset = macb_tx_ring_wrap(queue->bp, index) *
+		 sizeof(struct macb_dma_desc);
 
 	return queue->tx_ring_dma + offset;
 }
 
-static unsigned int macb_rx_ring_wrap(unsigned int index)
+static unsigned int macb_rx_ring_wrap(struct macb *bp, unsigned int index)
 {
-	return index & (RX_RING_SIZE - 1);
+	return index & (bp->rx_ring_size - 1);
 }
 
 static struct macb_dma_desc *macb_rx_desc(struct macb *bp, unsigned int index)
 {
-	return &bp->rx_ring[macb_rx_ring_wrap(index)];
+	return &bp->rx_ring[macb_rx_ring_wrap(bp, index)];
 }
 
 static void *macb_rx_buffer(struct macb *bp, unsigned int index)
 {
-	return bp->rx_buffers + bp->rx_buffer_size * macb_rx_ring_wrap(index);
+	return bp->rx_buffers + bp->rx_buffer_size *
+	       macb_rx_ring_wrap(bp, index);
 }
 
 /* I/O accessors */
@@ -608,7 +612,8 @@ static void macb_tx_error_task(struct work_struct *work)
 			 */
 			if (!(ctrl & MACB_BIT(TX_BUF_EXHAUSTED))) {
 				netdev_vdbg(bp->dev, "txerr skb %u (data %p) TX complete\n",
-					    macb_tx_ring_wrap(tail), skb->data);
+					    macb_tx_ring_wrap(bp, tail),
+					    skb->data);
 				bp->stats.tx_packets++;
 				bp->stats.tx_bytes += skb->len;
 			}
@@ -700,7 +705,8 @@ static void macb_tx_interrupt(struct macb_queue *queue)
 			/* First, update TX stats if needed */
 			if (skb) {
 				netdev_vdbg(bp->dev, "skb %u (data %p) TX complete\n",
-					    macb_tx_ring_wrap(tail), skb->data);
+					    macb_tx_ring_wrap(bp, tail),
+					    skb->data);
 				bp->stats.tx_packets++;
 				bp->stats.tx_bytes += skb->len;
 			}
@@ -720,7 +726,7 @@ static void macb_tx_interrupt(struct macb_queue *queue)
 	queue->tx_tail = tail;
 	if (__netif_subqueue_stopped(bp->dev, queue_index) &&
 	    CIRC_CNT(queue->tx_head, queue->tx_tail,
-		     TX_RING_SIZE) <= MACB_TX_WAKEUP_THRESH)
+		     bp->tx_ring_size) <= MACB_TX_WAKEUP_THRESH(bp))
 		netif_wake_subqueue(bp->dev, queue_index);
 }
 
@@ -731,8 +737,8 @@ static void gem_rx_refill(struct macb *bp)
 	dma_addr_t		paddr;
 
 	while (CIRC_SPACE(bp->rx_prepared_head, bp->rx_tail,
-			  RX_RING_SIZE) > 0) {
-		entry = macb_rx_ring_wrap(bp->rx_prepared_head);
+			  bp->rx_ring_size) > 0) {
+		entry = macb_rx_ring_wrap(bp, bp->rx_prepared_head);
 
 		/* Make hw descriptor updates visible to CPU */
 		rmb();
@@ -759,7 +765,7 @@ static void gem_rx_refill(struct macb *bp)
 
 			bp->rx_skbuff[entry] = skb;
 
-			if (entry == RX_RING_SIZE - 1)
+			if (entry == bp->rx_ring_size - 1)
 				paddr |= MACB_BIT(RX_WRAP);
 			macb_set_addr(&(bp->rx_ring[entry]), paddr);
 			bp->rx_ring[entry].ctrl = 0;
@@ -813,7 +819,7 @@ static int gem_rx(struct macb *bp, int budget)
 		dma_addr_t addr;
 		bool rxused;
 
-		entry = macb_rx_ring_wrap(bp->rx_tail);
+		entry = macb_rx_ring_wrap(bp, bp->rx_tail);
 		desc = &bp->rx_ring[entry];
 
 		/* Make hw descriptor updates visible to CPU */
@@ -895,8 +901,8 @@ static int macb_rx_frame(struct macb *bp, unsigned int first_frag,
 	len = desc->ctrl & bp->rx_frm_len_mask;
 
 	netdev_vdbg(bp->dev, "macb_rx_frame frags %u - %u (len %u)\n",
-		    macb_rx_ring_wrap(first_frag),
-		    macb_rx_ring_wrap(last_frag), len);
+		macb_rx_ring_wrap(bp, first_frag),
+		macb_rx_ring_wrap(bp, last_frag), len);
 
 	/* The ethernet header starts NET_IP_ALIGN bytes into the
 	 * first buffer. Since the header is 14 bytes, this makes the
@@ -969,12 +975,12 @@ static inline void macb_init_rx_ring(struct macb *bp)
 	int i;
 
 	addr = bp->rx_buffers_dma;
-	for (i = 0; i < RX_RING_SIZE; i++) {
+	for (i = 0; i < bp->rx_ring_size; i++) {
 		bp->rx_ring[i].addr = addr;
 		bp->rx_ring[i].ctrl = 0;
 		addr += bp->rx_buffer_size;
 	}
-	bp->rx_ring[RX_RING_SIZE - 1].addr |= MACB_BIT(RX_WRAP);
+	bp->rx_ring[bp->rx_ring_size - 1].addr |= MACB_BIT(RX_WRAP);
 }
 
 static int macb_rx(struct macb *bp, int budget)
@@ -1228,7 +1234,7 @@ static unsigned int macb_tx_map(struct macb *bp,
 	offset = 0;
 	while (len) {
 		size = min(len, bp->max_tx_length);
-		entry = macb_tx_ring_wrap(tx_head);
+		entry = macb_tx_ring_wrap(bp, tx_head);
 		tx_skb = &queue->tx_skb[entry];
 
 		mapping = dma_map_single(&bp->pdev->dev,
@@ -1257,7 +1263,7 @@ static unsigned int macb_tx_map(struct macb *bp,
 		offset = 0;
 		while (len) {
 			size = min(len, bp->max_tx_length);
-			entry = macb_tx_ring_wrap(tx_head);
+			entry = macb_tx_ring_wrap(bp, tx_head);
 			tx_skb = &queue->tx_skb[entry];
 
 			mapping = skb_frag_dma_map(&bp->pdev->dev, frag,
@@ -1295,14 +1301,14 @@ static unsigned int macb_tx_map(struct macb *bp,
 	 * to set the end of TX queue
 	 */
 	i = tx_head;
-	entry = macb_tx_ring_wrap(i);
+	entry = macb_tx_ring_wrap(bp, i);
 	ctrl = MACB_BIT(TX_USED);
 	desc = &queue->tx_ring[entry];
 	desc->ctrl = ctrl;
 
 	do {
 		i--;
-		entry = macb_tx_ring_wrap(i);
+		entry = macb_tx_ring_wrap(bp, i);
 		tx_skb = &queue->tx_skb[entry];
 		desc = &queue->tx_ring[entry];
 
@@ -1311,7 +1317,7 @@ static unsigned int macb_tx_map(struct macb *bp,
 			ctrl |= MACB_BIT(TX_LAST);
 			eof = 0;
 		}
-		if (unlikely(entry == (TX_RING_SIZE - 1)))
+		if (unlikely(entry == (bp->tx_ring_size - 1)))
 			ctrl |= MACB_BIT(TX_WRAP);
 
 		/* Set TX buffer descriptor */
@@ -1388,7 +1394,8 @@ static int macb_start_xmit(struct sk_buff *skb, struct net_device *dev)
 	spin_lock_irqsave(&bp->lock, flags);
 
 	/* This is a hard error, log it. */
-	if (CIRC_SPACE(queue->tx_head, queue->tx_tail, TX_RING_SIZE) < count) {
+	if (CIRC_SPACE(queue->tx_head, queue->tx_tail,
+		       bp->tx_ring_size) < count) {
 		netif_stop_subqueue(dev, queue_index);
 		spin_unlock_irqrestore(&bp->lock, flags);
 		netdev_dbg(bp->dev, "tx_head = %u, tx_tail = %u\n",
@@ -1414,7 +1421,7 @@ static int macb_start_xmit(struct sk_buff *skb, struct net_device *dev)
 
 	macb_writel(bp, NCR, macb_readl(bp, NCR) | MACB_BIT(TSTART));
 
-	if (CIRC_SPACE(queue->tx_head, queue->tx_tail, TX_RING_SIZE) < 1)
+	if (CIRC_SPACE(queue->tx_head, queue->tx_tail, bp->tx_ring_size) < 1)
 		netif_stop_subqueue(dev, queue_index);
 
 unlock:
@@ -1453,7 +1460,7 @@ static void gem_free_rx_buffers(struct macb *bp)
 	if (!bp->rx_skbuff)
 		return;
 
-	for (i = 0; i < RX_RING_SIZE; i++) {
+	for (i = 0; i < bp->rx_ring_size; i++) {
 		skb = bp->rx_skbuff[i];
 
 		if (!skb)
@@ -1478,7 +1485,7 @@ static void macb_free_rx_buffers(struct macb *bp)
 {
 	if (bp->rx_buffers) {
 		dma_free_coherent(&bp->pdev->dev,
-				  RX_RING_SIZE * bp->rx_buffer_size,
+				  bp->rx_ring_size * bp->rx_buffer_size,
 				  bp->rx_buffers, bp->rx_buffers_dma);
 		bp->rx_buffers = NULL;
 	}
@@ -1491,7 +1498,7 @@ static void macb_free_consistent(struct macb *bp)
 
 	bp->macbgem_ops.mog_free_rx_buffers(bp);
 	if (bp->rx_ring) {
-		dma_free_coherent(&bp->pdev->dev, RX_RING_BYTES,
+		dma_free_coherent(&bp->pdev->dev, RX_RING_BYTES(bp),
 				  bp->rx_ring, bp->rx_ring_dma);
 		bp->rx_ring = NULL;
 	}
@@ -1500,7 +1507,7 @@ static void macb_free_consistent(struct macb *bp)
 		kfree(queue->tx_skb);
 		queue->tx_skb = NULL;
 		if (queue->tx_ring) {
-			dma_free_coherent(&bp->pdev->dev, TX_RING_BYTES,
+			dma_free_coherent(&bp->pdev->dev, TX_RING_BYTES(bp),
 					  queue->tx_ring, queue->tx_ring_dma);
 			queue->tx_ring = NULL;
 		}
@@ -1511,14 +1518,14 @@ static int gem_alloc_rx_buffers(struct macb *bp)
 {
 	int size;
 
-	size = RX_RING_SIZE * sizeof(struct sk_buff *);
+	size = bp->rx_ring_size * sizeof(struct sk_buff *);
 	bp->rx_skbuff = kzalloc(size, GFP_KERNEL);
 	if (!bp->rx_skbuff)
 		return -ENOMEM;
-
-	netdev_dbg(bp->dev,
-		   "Allocated %d RX struct sk_buff entries at %p\n",
-		   RX_RING_SIZE, bp->rx_skbuff);
+	else
+		netdev_dbg(bp->dev,
+			   "Allocated %d RX struct sk_buff entries at %p\n",
+			   bp->rx_ring_size, bp->rx_skbuff);
 	return 0;
 }
 
@@ -1526,7 +1533,7 @@ static int macb_alloc_rx_buffers(struct macb *bp)
 {
 	int size;
 
-	size = RX_RING_SIZE * bp->rx_buffer_size;
+	size = bp->rx_ring_size * bp->rx_buffer_size;
 	bp->rx_buffers = dma_alloc_coherent(&bp->pdev->dev, size,
 					    &bp->rx_buffers_dma, GFP_KERNEL);
 	if (!bp->rx_buffers)
@@ -1545,7 +1552,7 @@ static int macb_alloc_consistent(struct macb *bp)
 	int size;
 
 	for (q = 0, queue = bp->queues; q < bp->num_queues; ++q, ++queue) {
-		size = TX_RING_BYTES;
+		size = TX_RING_BYTES(bp);
 		queue->tx_ring = dma_alloc_coherent(&bp->pdev->dev, size,
 						    &queue->tx_ring_dma,
 						    GFP_KERNEL);
@@ -1556,13 +1563,13 @@ static int macb_alloc_consistent(struct macb *bp)
 			   q, size, (unsigned long)queue->tx_ring_dma,
 			   queue->tx_ring);
 
-		size = TX_RING_SIZE * sizeof(struct macb_tx_skb);
+		size = bp->tx_ring_size * sizeof(struct macb_tx_skb);
 		queue->tx_skb = kmalloc(size, GFP_KERNEL);
 		if (!queue->tx_skb)
 			goto out_err;
 	}
 
-	size = RX_RING_BYTES;
+	size = RX_RING_BYTES(bp);
 	bp->rx_ring = dma_alloc_coherent(&bp->pdev->dev, size,
 					 &bp->rx_ring_dma, GFP_KERNEL);
 	if (!bp->rx_ring)
@@ -1588,11 +1595,11 @@ static void gem_init_rings(struct macb *bp)
 	int i;
 
 	for (q = 0, queue = bp->queues; q < bp->num_queues; ++q, ++queue) {
-		for (i = 0; i < TX_RING_SIZE; i++) {
-			macb_set_addr(&(queue->tx_ring[i]), 0);
+		for (i = 0; i < bp->tx_ring_size; i++) {
+			queue->tx_ring[i].addr = 0;
 			queue->tx_ring[i].ctrl = MACB_BIT(TX_USED);
 		}
-		queue->tx_ring[TX_RING_SIZE - 1].ctrl |= MACB_BIT(TX_WRAP);
+		queue->tx_ring[bp->tx_ring_size - 1].ctrl |= MACB_BIT(TX_WRAP);
 		queue->tx_head = 0;
 		queue->tx_tail = 0;
 	}
@@ -1609,13 +1616,13 @@ static void macb_init_rings(struct macb *bp)
 
 	macb_init_rx_ring(bp);
 
-	for (i = 0; i < TX_RING_SIZE; i++) {
+	for (i = 0; i < bp->tx_ring_size; i++) {
 		bp->queues[0].tx_ring[i].addr = 0;
 		bp->queues[0].tx_ring[i].ctrl = MACB_BIT(TX_USED);
 	}
 	bp->queues[0].tx_head = 0;
 	bp->queues[0].tx_tail = 0;
-	bp->queues[0].tx_ring[TX_RING_SIZE - 1].ctrl |= MACB_BIT(TX_WRAP);
+	bp->queues[0].tx_ring[bp->tx_ring_size - 1].ctrl |= MACB_BIT(TX_WRAP);
 
 	bp->rx_tail = 0;
 }
@@ -2148,8 +2155,8 @@ static void macb_get_regs(struct net_device *dev, struct ethtool_regs *regs,
 	regs->version = (macb_readl(bp, MID) & ((1 << MACB_REV_SIZE) - 1))
 			| MACB_GREGS_VERSION;
 
-	tail = macb_tx_ring_wrap(bp->queues[0].tx_tail);
-	head = macb_tx_ring_wrap(bp->queues[0].tx_head);
+	tail = macb_tx_ring_wrap(bp, bp->queues[0].tx_tail);
+	head = macb_tx_ring_wrap(bp, bp->queues[0].tx_head);
 
 	regs_buff[0]  = macb_readl(bp, NCR);
 	regs_buff[1]  = macb_or_gem_readl(bp, NCFGR);
@@ -2419,6 +2426,9 @@ static int macb_init(struct platform_device *pdev)
 	int err;
 	u32 val;
 
+	bp->tx_ring_size = DEFAULT_TX_RING_SIZE;
+	bp->rx_ring_size = DEFAULT_RX_RING_SIZE;
+
 	/* set the queue register mapping once for all: queue0 has a special
 	 * register mapping but we don't want to test the queue index then
 	 * compute the corresponding register offset at run time.
diff --git a/drivers/net/ethernet/cadence/macb.h b/drivers/net/ethernet/cadence/macb.h
index 8bed4b5..1216950 100644
--- a/drivers/net/ethernet/cadence/macb.h
+++ b/drivers/net/ethernet/cadence/macb.h
@@ -811,6 +811,9 @@ struct macb {
 	void			*rx_buffers;
 	size_t			rx_buffer_size;
 
+	unsigned int		rx_ring_size;
+	unsigned int		tx_ring_size;
+
 	unsigned int		num_queues;
 	unsigned int		queue_mask;
 	struct macb_queue	queues[MACB_MAX_QUEUES];
-- 
2.7.4

^ permalink raw reply related

* Re: [RFC v3 04/22] bpf: Set register type according to is_valid_access()
From: Thomas Graf @ 2016-10-19 14:54 UTC (permalink / raw)
  To: Mickaël Salaün
  Cc: linux-kernel, Alexei Starovoitov, Andy Lutomirski, Arnd Bergmann,
	Casey Schaufler, Daniel Borkmann, Daniel Mack, David Drysdale,
	David S . Miller, Elena Reshetova, Eric W . Biederman,
	James Morris, Kees Cook, Paul Moore, Sargun Dhillon,
	Serge E . Hallyn, Tejun Heo, Will Drewry, kernel-hardening,
	linux-api, linux-security-module
In-Reply-To: <20160914072415.26021-5-mic@digikod.net>

On 09/14/16 at 09:23am, Mickaël Salaün wrote:
> This fix a pointer leak when an unprivileged eBPF program read a pointer
> value from the context. Even if is_valid_access() returns a pointer
> type, the eBPF verifier replace it with UNKNOWN_VALUE. The register
> value containing an address is then allowed to leak. Moreover, this
> prevented unprivileged eBPF programs to use functions with (legitimate)
> pointer arguments.
> 
> This bug was not a problem until now because the only unprivileged eBPF
> program allowed is of type BPF_PROG_TYPE_SOCKET_FILTER and all the types
> from its context are UNKNOWN_VALUE.
> 
> Signed-off-by: Mickaël Salaün <mic@digikod.net>
> Fixes: 969bf05eb3ce ("bpf: direct packet access")
> Cc: Alexei Starovoitov <ast@kernel.org>
> Cc: Daniel Borkmann <daniel@iogearbox.net>

Can you post this fix separately? It's valid and needed outside of the
scope of this series.

^ permalink raw reply

* Re: net/l2tp:BUG: KASAN: use-after-free in l2tp_ip6_close
From: Baozeng Ding @ 2016-10-19 14:52 UTC (permalink / raw)
  To: Cong Wang; +Cc: Linux Kernel Network Developers
In-Reply-To: <CAM_iQpWpf--gXPy7zD7ax4vt-foMCh_dw8Pbb3=y_gSgegeF3Q@mail.gmail.com>

This use-after-free seems to be triggered by some race. I use stress tool for this: 
https://github.com/golang/tools/blob/master/cmd/stress/stress.go 
If you have Go toolchain installed, then the following will do: 
$ go get golang.org/x/tools/cmd/stress 
$ stress ./a.out

=========================================================================
#include <unistd.h>
#include <stdint.h>
#include <pthread.h>
#include <stdio.h>
#include <sys/socket.h>
#include <linux/l2tp.h>

int fd;
struct sockaddr_l2tpip sock_addr = {
        .l2tp_family = AF_INET,
        .l2tp_unused = 0,
        .l2tp_addr = 0,
        .l2tp_conn_id = 8,
        .__pad = 0

};

void *thr(void *arg)
{
        switch ((long)arg) {
        case 0:
                fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_L2TP);
                break;
        case 1:
                bind(fd, (struct sockaddr*) &sock_addr, 0x10ul);
                break;
        case 2:
                bind(fd, (struct sockaddr*)&sock_addr, 0x10ul);
                break;
        case 3:
                connect(fd, (struct sockaddr*)&sock_addr, 0x10ul);
                break;
        }
        return 0;
}

int main()
{
        long i;
        pthread_t th[4];
        int n;
        for (i = 0; i < 4; i++) {
               pthread_create(&th[i], 0, thr, (void*)i);
               usleep(10000);
        }
        for (i = 0; i < 4; i++) {
               pthread_create(&th[i], 0, thr, (void*)i);
               if (i%2==0)
                        usleep(10000);
        }
        usleep(100000);
        return 0;
}

On 2016/10/17 3:50, Cong Wang wrote:
> On Sun, Oct 16, 2016 at 8:07 AM, Baozeng Ding <sploving1@gmail.com> wrote:
>> Hello,
>> While running syzkaller fuzzer I have got the following use-after-free
>> bug in l2tp_ip6_close. The kernel version is 4.8.0+ (on Oct 7 commit d1f5323370fceaed43a7ee38f4c7bfc7e70f28d0).
>>
>> BUG: KASAN: use-after-free in l2tp_ip6_close+0x22e/0x290 at addr ffff8800081b0ed8
>> Write of size 8 by task syz-executor/10987
>> CPU: 0 PID: 10987 Comm: syz-executor Not tainted 4.8.0+ #39
>> Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.8.2-0-g33fbe13 by qemu-project.org 04/01/2014
>>  ffff880031d97838 ffffffff829f835b ffff88001b5a1640 ffff8800081b0ec0
>>  ffff8800081b15a0 ffff8800081b6d20 ffff880031d97860 ffffffff8174d3cc
>>  ffff880031d978f0 ffff8800081b0e80 ffff88001b5a1640 ffff880031d978e0
>> Call Trace:
>>  [<ffffffff829f835b>] dump_stack+0xb3/0x118 lib/dump_stack.c:15
>>  [<ffffffff8174d3cc>] kasan_object_err+0x1c/0x70 mm/kasan/report.c:156
>>  [<     inline     >] print_address_description mm/kasan/report.c:194
>>  [<ffffffff8174d666>] kasan_report_error+0x1f6/0x4d0 mm/kasan/report.c:283
>>  [<     inline     >] kasan_report mm/kasan/report.c:303
>>  [<ffffffff8174db7e>] __asan_report_store8_noabort+0x3e/0x40 mm/kasan/report.c:329
>>  [<     inline     >] __write_once_size ./include/linux/compiler.h:249
>>  [<     inline     >] __hlist_del ./include/linux/list.h:622
>>  [<     inline     >] hlist_del_init ./include/linux/list.h:637
>>  [<ffffffff8579047e>] l2tp_ip6_close+0x22e/0x290 net/l2tp/l2tp_ip6.c:239
> 
> 
> This one looks pretty interesting, how the hell could we call ____fput() twice
> on the same fd...
> 
> 
>>  [<ffffffff850b2dfd>] inet_release+0xed/0x1c0 net/ipv4/af_inet.c:415
>>  [<ffffffff851dc5a0>] inet6_release+0x50/0x70 net/ipv6/af_inet6.c:422
>>  [<ffffffff84c4581d>] sock_release+0x8d/0x1d0 net/socket.c:570
>>  [<ffffffff84c45976>] sock_close+0x16/0x20 net/socket.c:1017
>>  [<ffffffff817a108c>] __fput+0x28c/0x780 fs/file_table.c:208
>>  [<ffffffff817a1605>] ____fput+0x15/0x20 fs/file_table.c:244
>>  [<ffffffff813774f9>] task_work_run+0xf9/0x170
>>  [<ffffffff81324aae>] do_exit+0x85e/0x2a00
>>  [<ffffffff81326dc8>] do_group_exit+0x108/0x330
>>  [<ffffffff81348cf7>] get_signal+0x617/0x17a0 kernel/signal.c:2307
>>  [<ffffffff811b49af>] do_signal+0x7f/0x18f0
>>  [<ffffffff810039bf>] exit_to_usermode_loop+0xbf/0x150 arch/x86/entry/common.c:156
>>  [<     inline     >] prepare_exit_to_usermode arch/x86/entry/common.c:190
>>  [<ffffffff81006060>] syscall_return_slowpath+0x1a0/0x1e0 arch/x86/entry/common.c:259
>>  [<ffffffff85e4d726>] entry_SYSCALL_64_fastpath+0xc4/0xc6
>> Object at ffff8800081b0ec0, in cache L2TP/IPv6 size: 1448
>> Allocated:
>> PID = 10987
>>  [ 1116.897025] [<ffffffff811ddcb6>] save_stack_trace+0x16/0x20
>>  [ 1116.897025] [<ffffffff8174c736>] save_stack+0x46/0xd0
>>  [ 1116.897025] [<ffffffff8174c9ad>] kasan_kmalloc+0xad/0xe0
>>  [ 1116.897025] [<ffffffff8174cee2>] kasan_slab_alloc+0x12/0x20
>>  [ 1116.897025] [<     inline     >] slab_post_alloc_hook mm/slab.h:417
>>  [ 1116.897025] [<     inline     >] slab_alloc_node mm/slub.c:2708
>>  [ 1116.897025] [<     inline     >] slab_alloc mm/slub.c:2716
>>  [ 1116.897025] [<ffffffff817476a8>] kmem_cache_alloc+0xc8/0x2b0 mm/slub.c:2721
>>  [ 1116.897025] [<ffffffff84c4f6a9>] sk_prot_alloc+0x69/0x2b0 net/core/sock.c:1326
>>  [ 1116.897025] [<ffffffff84c58ac8>] sk_alloc+0x38/0xae0 net/core/sock.c:1388
>>  [ 1116.897025] [<ffffffff851ddf67>] inet6_create+0x2d7/0x1000 net/ipv6/af_inet6.c:182
>>  [ 1116.897025] [<ffffffff84c4af7b>] __sock_create+0x37b/0x640 net/socket.c:1153
>>  [ 1116.897025] [<     inline     >] sock_create net/socket.c:1193
>>  [ 1116.897025] [<     inline     >] SYSC_socket net/socket.c:1223
>>  [ 1116.897025] [<ffffffff84c4b46f>] SyS_socket+0xef/0x1b0 net/socket.c:1203
>>  [ 1116.897025] [<ffffffff85e4d685>] entry_SYSCALL_64_fastpath+0x23/0xc6
>> Freed:
>> PID = 10987
>>  [ 1116.897025] [<ffffffff811ddcb6>] save_stack_trace+0x16/0x20
>>  [ 1116.897025] [<ffffffff8174c736>] save_stack+0x46/0xd0
>>  [ 1116.897025] [<ffffffff8174cf61>] kasan_slab_free+0x71/0xb0
>>  [ 1116.897025] [<     inline     >] slab_free_hook mm/slub.c:1352
>>  [ 1116.897025] [<     inline     >] slab_free_freelist_hook mm/slub.c:1374
>>  [ 1116.897025] [<     inline     >] slab_free mm/slub.c:2951
>>  [ 1116.897025] [<ffffffff81748b28>] kmem_cache_free+0xc8/0x330 mm/slub.c:2973
>>  [ 1116.897025] [<     inline     >] sk_prot_free net/core/sock.c:1369
>>  [ 1116.897025] [<ffffffff84c541eb>] __sk_destruct+0x32b/0x4f0 net/core/sock.c:1444
>>  [ 1116.897025] [<ffffffff84c5aca4>] sk_destruct+0x44/0x80 net/core/sock.c:1452
>>  [ 1116.897025] [<ffffffff84c5ad33>] __sk_free+0x53/0x220 net/core/sock.c:1460
>>  [ 1116.897025] [<ffffffff84c5af23>] sk_free+0x23/0x30 net/core/sock.c:1471
>>  [ 1116.897025] [<ffffffff84c5cb6c>] sk_common_release+0x28c/0x3e0 ./include/net/sock.h:1589
>>  [ 1116.897025] [<ffffffff8579044e>] l2tp_ip6_close+0x1fe/0x290 net/l2tp/l2tp_ip6.c:243
>>  [ 1116.897025] [<ffffffff850b2dfd>] inet_release+0xed/0x1c0 net/ipv4/af_inet.c:415
>>  [ 1116.897025] [<ffffffff851dc5a0>] inet6_release+0x50/0x70 net/ipv6/af_inet6.c:422
>>  [ 1116.897025] [<ffffffff84c4581d>] sock_release+0x8d/0x1d0 net/socket.c:570
>>  [ 1116.897025] [<ffffffff84c45976>] sock_close+0x16/0x20 net/socket.c:1017
>>  [ 1116.897025] [<ffffffff817a108c>] __fput+0x28c/0x780 fs/file_table.c:208
>>  [ 1116.897025] [<ffffffff817a1605>] ____fput+0x15/0x20 fs/file_table.c:244
>>  [ 1116.897025] [<ffffffff813774f9>] task_work_run+0xf9/0x170
>>  [ 1116.897025] [<ffffffff81324aae>] do_exit+0x85e/0x2a00
>>  [ 1116.897025] [<ffffffff81326dc8>] do_group_exit+0x108/0x330
>>  [ 1116.897025] [<ffffffff81348cf7>] get_signal+0x617/0x17a0 kernel/signal.c:2307
>>  [ 1116.897025] [<ffffffff811b49af>] do_signal+0x7f/0x18f0
>>  [ 1116.897025] [<ffffffff810039bf>] exit_to_usermode_loop+0xbf/0x150 arch/x86/entry/common.c:156
>>  [ 1116.897025] [<     inline     >] prepare_exit_to_usermode arch/x86/entry/common.c:190
>>  [ 1116.897025] [<ffffffff81006060>] syscall_return_slowpath+0x1a0/0x1e0 arch/x86/entry/common.c:259
>>  [ 1116.897025] [<ffffffff85e4d726>] entry_SYSCALL_64_fastpath+0xc4/0xc6
>> Memory state around the buggy address:
>>  ffff8800081b0d80: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
>>  ffff8800081b0e00: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
>>> ffff8800081b0e80: fc fc fc fc fc fc fc fc fb fb fb fb fb fb fb fb
>>                                                     ^
>>  ffff8800081b0f00: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
>>  ffff8800081b0f80: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
>> ==================================================================
>>
>> Best Regards,
>> Baozeng Ding

^ permalink raw reply

* Re: [PATCH net-next 4/6] net: use core MTU range checking in core net infra
From: Jarod Wilson @ 2016-10-19 14:51 UTC (permalink / raw)
  To: Jiri Benc
  Cc: linux-kernel, netdev, Nicolas Dichtel, Hannes Frederic Sowa,
	Tom Herbert, Daniel Borkmann, Alexander Duyck, Paolo Abeni,
	WANG Cong, Roopa Prabhu, Pravin B Shelar, Sabrina Dubroca,
	Patrick McHardy, Stephen Hemminger, Pravin Shelar
In-Reply-To: <20161019141703.01ff8850@griffin>

On Wed, Oct 19, 2016 at 02:17:03PM +0200, Jiri Benc wrote:
> On Tue, 18 Oct 2016 22:33:31 -0400, Jarod Wilson wrote:
> > --- a/drivers/net/vxlan.c
> > +++ b/drivers/net/vxlan.c
> > @@ -2367,43 +2367,31 @@ static void vxlan_set_multicast_list(struct net_device *dev)
> >  {
> >  }
> >  
> > -static int __vxlan_change_mtu(struct net_device *dev,
> > -			      struct net_device *lowerdev,
> > -			      struct vxlan_rdst *dst, int new_mtu, bool strict)
> > +static int vxlan_change_mtu(struct net_device *dev, int new_mtu)
> >  {
> > -	int max_mtu = IP_MAX_MTU;
> > -
> > -	if (lowerdev)
> > -		max_mtu = lowerdev->mtu;
> > +	struct vxlan_dev *vxlan = netdev_priv(dev);
> > +	struct vxlan_rdst *dst = &vxlan->default_dst;
> > +	struct net_device *lowerdev = __dev_get_by_index(vxlan->net,
> > +							 dst->remote_ifindex);
> > +	bool use_ipv6 = false;
> >  
> >  	if (dst->remote_ip.sa.sa_family == AF_INET6)
> > -		max_mtu -= VXLAN6_HEADROOM;
> > -	else
> > -		max_mtu -= VXLAN_HEADROOM;
> > -
> > -	if (new_mtu < 68)
> > -		return -EINVAL;
> > +		use_ipv6 = true;
> >  
> > -	if (new_mtu > max_mtu) {
> > -		if (strict)
> > +	/* We re-check this, because users *could* alter the mtu of the
> > +	 * lower device after we've initialized dev->max_mtu.
> > +	 */
> > +	if (lowerdev) {
> > +		dev->max_mtu = lowerdev->mtu -
> > +			       (use_ipv6 ? VXLAN6_HEADROOM : VXLAN_HEADROOM);
> > +		if (new_mtu > dev->max_mtu)
> >  			return -EINVAL;
> > -
> > -		new_mtu = max_mtu;
> >  	}
> >  
> >  	dev->mtu = new_mtu;
> >  	return 0;
> >  }
> 
> Sorry for the silly question, how does the min_mtu and max_mtu stuff
> works? I noticed your patches but haven't looked in depth into them.
> 
> When the ndo_change_mtu callback is defined, is the dev->min_mtu and
> dev->max_mtu checked first and if the desired mtu is not within range,
> ndo_change_mtu is not called?
> 
> Or does ndo_change_mtu override the checks?

The former. If the new value is outside min/max, ndo_change_mtu doesn't
get called, which is exactly the chicken and egg problem I introduced by
setting max_mtu to 1500 in ether_setup before having all drivers that call
ether_setup set a more appropriate max_mtu first. :\

> In either case, the code does not look correct. In the first case,
> increasing of lowerdev MTU wouldn't allow increasing of vxlan MTU
> without deleting and recreating the vxlan interface. In the second
> case, you're missing check against the min_mtu.

Okay, this sounds like a similar case to bridge that Sabrina pointed out.
Looks like virtual devices will need to just set no max_mtu directly (or
IP_MAX_MTU), and do dynamic checks in their ndo_change_mtu if they need to
compare against underlying devices on the fly.

...
> > @@ -2847,9 +2842,14 @@ static int vxlan_dev_configure(struct net *src_net, struct net_device *dev,
> >  	}
> >  
> >  	if (conf->mtu) {
> > -		err = __vxlan_change_mtu(dev, lowerdev, dst, conf->mtu, false);
> > -		if (err)
> > -			return err;
> > +		if (lowerdev)
> > +			dev->max_mtu = lowerdev->mtu;
> > +		dev->max_mtu -= (use_ipv6 ? VXLAN6_HEADROOM : VXLAN_HEADROOM);
> > +
> > +		dev->mtu = conf->mtu;
> > +
> > +		if (conf->mtu > dev->max_mtu)
> > +			dev->mtu = dev->max_mtu;
> >  	}
> 
> You removed the check for min_mtu but it's needed here. The conf->mtu
> value comes from the user space and can be anything.

Hm. Not sure why I did that... Will put it back now...

-- 
Jarod Wilson
jarod@redhat.com

^ permalink raw reply

* Re: [PATCH (net.git)] stmmac: fix and review the ptp registration.
From: Nicolas Pitre @ 2016-10-19 14:47 UTC (permalink / raw)
  To: Giuseppe Cavallaro
  Cc: netdev, davem, linux-kernel, Alexandre TORGUE, Rayagond Kokatanur,
	Dan Carpenter, Richard Cochran
In-Reply-To: <1476860801-28242-1-git-send-email-peppe.cavallaro@st.com>

[ added Richard to CC ]

On Wed, 19 Oct 2016, Giuseppe Cavallaro wrote:

> The commit commit 7086605a6ab5 ("stmmac: fix error check when init ptp")
> breaks the procedure added by the
> commit efee95f42b5d ("ptp_clock: future-proofing drivers against PTP
> subsystem becoming optional")
> 
> So this patch tries to re-import the logic added by the latest
> commit above: it makes sense to have the stmmac_ptp_register
> as void function and, inside the main, the stmmac_init_ptp can fails
> in case of the capability cannot be supported by the HW.
> 
> Signed-off-by: Giuseppe Cavallaro <peppe.cavallaro@st.com>
> Cc: Alexandre TORGUE <alexandre.torgue@st.com>
> Cc: Rayagond Kokatanur <rayagond@vayavyalabs.com>
> Cc: Dan Carpenter <dan.carpenter@oracle.com>
> Cc: Nicolas Pitre <nico@linaro.org>

Acked-by: Nicolas Pitre <nico@linaro.org>

> ---
>  drivers/net/ethernet/stmicro/stmmac/stmmac.h      |  2 +-
>  drivers/net/ethernet/stmicro/stmmac/stmmac_main.c |  6 ++++--
>  drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.c  | 15 ++++-----------
>  3 files changed, 9 insertions(+), 14 deletions(-)
> 
> diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac.h b/drivers/net/ethernet/stmicro/stmmac/stmmac.h
> index 8dc9056..b15fc55 100644
> --- a/drivers/net/ethernet/stmicro/stmmac/stmmac.h
> +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac.h
> @@ -145,7 +145,7 @@ int stmmac_mdio_register(struct net_device *ndev);
>  int stmmac_mdio_reset(struct mii_bus *mii);
>  void stmmac_set_ethtool_ops(struct net_device *netdev);
>  
> -int stmmac_ptp_register(struct stmmac_priv *priv);
> +void stmmac_ptp_register(struct stmmac_priv *priv);
>  void stmmac_ptp_unregister(struct stmmac_priv *priv);
>  int stmmac_resume(struct device *dev);
>  int stmmac_suspend(struct device *dev);
> diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
> index 6c85b61..48e71fa 100644
> --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
> +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
> @@ -676,7 +676,9 @@ static int stmmac_init_ptp(struct stmmac_priv *priv)
>  	priv->hwts_tx_en = 0;
>  	priv->hwts_rx_en = 0;
>  
> -	return stmmac_ptp_register(priv);
> +	stmmac_ptp_register(priv);
> +
> +	return 0;
>  }
>  
>  static void stmmac_release_ptp(struct stmmac_priv *priv)
> @@ -1710,7 +1712,7 @@ static int stmmac_hw_setup(struct net_device *dev, bool init_ptp)
>  	if (init_ptp) {
>  		ret = stmmac_init_ptp(priv);
>  		if (ret)
> -			netdev_warn(priv->dev, "PTP support cannot init.\n");
> +			netdev_warn(priv->dev, "fail to init PTP.\n");
>  	}
>  
>  #ifdef CONFIG_DEBUG_FS
> diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.c
> index 5d61fb2..1477471 100644
> --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.c
> +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.c
> @@ -177,7 +177,7 @@ static struct ptp_clock_info stmmac_ptp_clock_ops = {
>   * Description: this function will register the ptp clock driver
>   * to kernel. It also does some house keeping work.
>   */
> -int stmmac_ptp_register(struct stmmac_priv *priv)
> +void stmmac_ptp_register(struct stmmac_priv *priv)
>  {
>  	spin_lock_init(&priv->ptp_lock);
>  	priv->ptp_clock_ops = stmmac_ptp_clock_ops;
> @@ -185,17 +185,10 @@ int stmmac_ptp_register(struct stmmac_priv *priv)
>  	priv->ptp_clock = ptp_clock_register(&priv->ptp_clock_ops,
>  					     priv->device);
>  	if (IS_ERR(priv->ptp_clock)) {
> -		int ret = PTR_ERR(priv->ptp_clock);
> -
> +		netdev_err(priv->dev, "ptp_clock_register failed\n");
>  		priv->ptp_clock = NULL;
> -		return ret;
> -	}
> -
> -	spin_lock_init(&priv->ptp_lock);
> -
> -	netdev_dbg(priv->dev, "Added PTP HW clock successfully\n");
> -
> -	return 0;
> +	} else if (priv->ptp_clock)
> +		netdev_info(priv->dev, "registered PTP clock\n");
>  }
>  
>  /**
> -- 
> 2.7.4
> 
> 

^ permalink raw reply

* [PATCH -next] net: arc_emac: use dev_kfree_skb_any instead of dev_kfree_skb
From: Wei Yongjun @ 2016-10-19 13:47 UTC (permalink / raw)
  To: Caesar Wang, David S. Miller, Alexander Kochetkov,
	Philippe Reynes, Peter Chen, Wei Yongjun
  Cc: Wei Yongjun, netdev

From: Wei Yongjun <weiyongjun1@huawei.com>

Replace dev_kfree_skb with dev_kfree_skb_any in arc_emac_tx()
which can be called from hard irq context (netpoll) and from
other contexts. arc_emac_tx() only frees skbs that it has
dropped.

This is detected by Coccinelle semantic patch.

Signed-off-by: Wei Yongjun <weiyongjun1@huawei.com>
---
 drivers/net/ethernet/arc/emac_main.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/arc/emac_main.c b/drivers/net/ethernet/arc/emac_main.c
index b0da969..95d8b3e 100644
--- a/drivers/net/ethernet/arc/emac_main.c
+++ b/drivers/net/ethernet/arc/emac_main.c
@@ -633,7 +633,7 @@ static int arc_emac_tx(struct sk_buff *skb, struct net_device *ndev)
 	if (unlikely(dma_mapping_error(&ndev->dev, addr))) {
 		stats->tx_dropped++;
 		stats->tx_errors++;
-		dev_kfree_skb(skb);
+		dev_kfree_skb_any(skb);
 		return NETDEV_TX_OK;
 	}
 	dma_unmap_addr_set(&priv->tx_buff[*txbd_curr], addr, addr);

^ permalink raw reply related

* Re: [PATCH net-next 4/6] net: use core MTU range checking in core net infra
From: Jiri Benc @ 2016-10-19 12:17 UTC (permalink / raw)
  To: Jarod Wilson
  Cc: linux-kernel, netdev, Nicolas Dichtel, Hannes Frederic Sowa,
	Tom Herbert, Daniel Borkmann, Alexander Duyck, Paolo Abeni,
	WANG Cong, Roopa Prabhu, Pravin B Shelar, Sabrina Dubroca,
	Patrick McHardy, Stephen Hemminger, Pravin Shelar
In-Reply-To: <20161019023333.15760-5-jarod@redhat.com>

On Tue, 18 Oct 2016 22:33:31 -0400, Jarod Wilson wrote:
> --- a/drivers/net/vxlan.c
> +++ b/drivers/net/vxlan.c
> @@ -2367,43 +2367,31 @@ static void vxlan_set_multicast_list(struct net_device *dev)
>  {
>  }
>  
> -static int __vxlan_change_mtu(struct net_device *dev,
> -			      struct net_device *lowerdev,
> -			      struct vxlan_rdst *dst, int new_mtu, bool strict)
> +static int vxlan_change_mtu(struct net_device *dev, int new_mtu)
>  {
> -	int max_mtu = IP_MAX_MTU;
> -
> -	if (lowerdev)
> -		max_mtu = lowerdev->mtu;
> +	struct vxlan_dev *vxlan = netdev_priv(dev);
> +	struct vxlan_rdst *dst = &vxlan->default_dst;
> +	struct net_device *lowerdev = __dev_get_by_index(vxlan->net,
> +							 dst->remote_ifindex);
> +	bool use_ipv6 = false;
>  
>  	if (dst->remote_ip.sa.sa_family == AF_INET6)
> -		max_mtu -= VXLAN6_HEADROOM;
> -	else
> -		max_mtu -= VXLAN_HEADROOM;
> -
> -	if (new_mtu < 68)
> -		return -EINVAL;
> +		use_ipv6 = true;
>  
> -	if (new_mtu > max_mtu) {
> -		if (strict)
> +	/* We re-check this, because users *could* alter the mtu of the
> +	 * lower device after we've initialized dev->max_mtu.
> +	 */
> +	if (lowerdev) {
> +		dev->max_mtu = lowerdev->mtu -
> +			       (use_ipv6 ? VXLAN6_HEADROOM : VXLAN_HEADROOM);
> +		if (new_mtu > dev->max_mtu)
>  			return -EINVAL;
> -
> -		new_mtu = max_mtu;
>  	}
>  
>  	dev->mtu = new_mtu;
>  	return 0;
>  }

Sorry for the silly question, how does the min_mtu and max_mtu stuff
works? I noticed your patches but haven't looked in depth into them.

When the ndo_change_mtu callback is defined, is the dev->min_mtu and
dev->max_mtu checked first and if the desired mtu is not within range,
ndo_change_mtu is not called?

Or does ndo_change_mtu override the checks?

In either case, the code does not look correct. In the first case,
increasing of lowerdev MTU wouldn't allow increasing of vxlan MTU
without deleting and recreating the vxlan interface. In the second
case, you're missing check against the min_mtu.

>  
> -static int vxlan_change_mtu(struct net_device *dev, int new_mtu)
> -{
> -	struct vxlan_dev *vxlan = netdev_priv(dev);
> -	struct vxlan_rdst *dst = &vxlan->default_dst;
> -	struct net_device *lowerdev = __dev_get_by_index(vxlan->net,
> -							 dst->remote_ifindex);
> -	return __vxlan_change_mtu(dev, lowerdev, dst, new_mtu, true);
> -}
> -
>  static int vxlan_fill_metadata_dst(struct net_device *dev, struct sk_buff *skb)
>  {
>  	struct vxlan_dev *vxlan = netdev_priv(dev);
> @@ -2795,6 +2783,10 @@ static int vxlan_dev_configure(struct net *src_net, struct net_device *dev,
>  		vxlan_ether_setup(dev);
>  	}
>  
> +	/* MTU range: 68 - 65535 */
> +	dev->min_mtu = 68;
> +	dev->max_mtu = IP_MAX_MTU;
> +
>  	vxlan->net = src_net;
>  
>  	dst->remote_vni = conf->vni;
> @@ -2837,8 +2829,11 @@ static int vxlan_dev_configure(struct net *src_net, struct net_device *dev,
>  		}
>  #endif
>  
> -		if (!conf->mtu)
> -			dev->mtu = lowerdev->mtu - (use_ipv6 ? VXLAN6_HEADROOM : VXLAN_HEADROOM);
> +		if (!conf->mtu) {
> +			dev->mtu = lowerdev->mtu -
> +				   (use_ipv6 ? VXLAN6_HEADROOM : VXLAN_HEADROOM);
> +			dev->max_mtu = dev->mtu;
> +		}
>  
>  		needed_headroom = lowerdev->hard_header_len;
>  	} else if (vxlan_addr_multicast(&dst->remote_ip)) {
> @@ -2847,9 +2842,14 @@ static int vxlan_dev_configure(struct net *src_net, struct net_device *dev,
>  	}
>  
>  	if (conf->mtu) {
> -		err = __vxlan_change_mtu(dev, lowerdev, dst, conf->mtu, false);
> -		if (err)
> -			return err;
> +		if (lowerdev)
> +			dev->max_mtu = lowerdev->mtu;
> +		dev->max_mtu -= (use_ipv6 ? VXLAN6_HEADROOM : VXLAN_HEADROOM);
> +
> +		dev->mtu = conf->mtu;
> +
> +		if (conf->mtu > dev->max_mtu)
> +			dev->mtu = dev->max_mtu;
>  	}

You removed the check for min_mtu but it's needed here. The conf->mtu
value comes from the user space and can be anything.

>  
>  	if (use_ipv6 || conf->flags & VXLAN_F_COLLECT_METADATA)

 Jiri

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox