Netdev List
 help / color / mirror / Atom feed
* Re: [PATCH net] ipv4: initialize flowi4_flags before calling fib_lookup()
From: David Ahern @ 2016-03-22 18:29 UTC (permalink / raw)
  To: Lance Richardson, netdev
In-Reply-To: <1458660679-7279-1-git-send-email-lrichard@redhat.com>

On 3/22/16 9:31 AM, Lance Richardson wrote:
> Field fl4.flowi4_flags is not initialized in fib_compute_spec_dst()
> before calling fib_lookup(), which means fib_table_lookup() is
> using non-deterministic data at this line:
>
> 	if (!(flp->flowi4_flags & FLOWI_FLAG_SKIP_NH_OIF)) {
>
> Fix by initializing fl4.flowi4_flags to zero.
>
> Signed-off-by: Lance Richardson <lrichard@redhat.com>
> ---
>   net/ipv4/fib_frontend.c | 1 +
>   1 file changed, 1 insertion(+)
>
> diff --git a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c
> index 21add55..896844a 100644
> --- a/net/ipv4/fib_frontend.c
> +++ b/net/ipv4/fib_frontend.c
> @@ -304,6 +304,7 @@ __be32 fib_compute_spec_dst(struct sk_buff *skb)
>   		fl4.flowi4_scope = scope;
>   		fl4.flowi4_mark = IN_DEV_SRC_VMARK(in_dev) ? skb->mark : 0;
>   		fl4.flowi4_tun_key.tun_id = 0;
> +		fl4.flowi4_flags = 0;
>   		if (!fib_lookup(net, &fl4, &res, 0))
>   			return FIB_RES_PREFSRC(net, res);
>   	} else {
>

Fixes: 58189ca7b2741 ("net: Fix vti use case with oif in dst lookups")

I think a more robust solution is to move fl4 to this if case and init 
when it is declared:

	struct flowi4 fl4 = {
		.flowi4_iif = LOOPBACK_IFINDEX,
		.daddr = ip_hdr(skb)->saddr,
		.flowi4_tos = RT_TOS(ip_hdr(skb)->tos),
		.flowi4_scope = scope,
		.flowi4_mark = IN_DEV_SRC_VMARK(in_dev) ? skb->mark : 0,
	};

^ permalink raw reply

* Re: [PATCH] ipv6: Fix the pmtu path for connected UDP socket
From: Cong Wang @ 2016-03-22 18:19 UTC (permalink / raw)
  To: Martin KaFai Lau
  Cc: Wei Wang, Wei Wang, Eric Dumazet, David Miller, Eric Dumazet,
	Linux Kernel Network Developers
In-Reply-To: <20160322173939.GA53936@kafai-mba.local>

On Tue, Mar 22, 2016 at 10:39 AM, Martin KaFai Lau <kafai@fb.com> wrote:
> On Tue, Mar 22, 2016 at 09:53:35AM -0700, Cong Wang wrote:
>> On Mon, Mar 21, 2016 at 11:02 PM, Martin KaFai Lau <kafai@fb.com> wrote:
>> > In term of difference, AFAICT, the current patch is an optimization in the
>> > sense that the update_pmtu() code path does not have to do a dst_check to
>> > discover its sk->sk_dst_cache is invalid, and then do a relookup to find out
>> > that the just created RTF_CACHE clone should be used.  To get this, it may
>> > make more sense to remove all the relookup code together during update_pmtu().
>> > Even if this slow path was to be optimized, should it be put in a
>> > separate patch where net-next is a better candidate?
>> >
>>
>> Speaking of RTF_CACHE, I am curious why you didn't use FIB next hop exception
>> as what ipv4 does to cache exceptions? This makes IPv6 has more gap with IPv4.
>> This is (almost) irrelevant to this patch.
> There are a few differences between IPv6 and IPv4.  Both in terms of
> data structure and functionality.  The last 'RTF_CACHE on exception' patchset is one
> step toward this direction. More patches are needed and are welcomed ;)

Sure, I will take a look at this once net-next is re-open.


>
>>
>>
>> > I think fixing it in __udp6_lib_err() or what Cong Wang is suggesting makes
>> > more sense for a net branch fix.  If there is logic specific to connected-udp,
>> > I would do it in the __udp6_lib_err() instead.  After looking at
>> > udpv6_sendmsg() and how it calls ip6_dst_store(), may also need to be careful
>> > what daddr and saddr should be passed to ip6_dst_store(), or at least a commit
>> > message.  The first patch is essentially passing NULL to daddr and saddr
>> > while the second patch seems passing something else.
>>
>> Raw socket needs to fix too, we can't just fix __udp6_lib_err(), this is also
>> why fixing ip6_sk_update_pmtu() is better, its call path is better.
> I don't see rawv6 socket is storing the dst.  I probably have overlooked it.  Can
> you point it out?


I thought sk->sk_dst_cache is generic to all sockets, but it is up to
each kind of
socket to decide to use it or not, and you are right, raw socket doesn't seem to
care about it even though it calls *_sk_update_pmtu().

^ permalink raw reply

* Re: [PATCH] ipv6: Fix the pmtu path for connected UDP socket
From: Martin KaFai Lau @ 2016-03-22 18:16 UTC (permalink / raw)
  To: Wei Wang
  Cc: Cong Wang, Wei Wang, Eric Dumazet, David Miller, Eric Dumazet,
	Linux Kernel Network Developers
In-Reply-To: <CAC15z3jDRvJR4uZ97mC+beaMaPQvAvTHB9OLKCdQ4hcwRu07vw@mail.gmail.com>

On Tue, Mar 22, 2016 at 11:03:29AM -0700, Wei Wang wrote:
> But one thing here, we will have to generate the same flowi6 in both
> ip6_sk_update_pmtu() as well as ip6_update_pmtu(). Is this considered
> as a not clean enough fix?
If they share common codes to build flowi6, can the common codes
be factored out?

^ permalink raw reply

* Re: [PATCH] ipv6: Fix the pmtu path for connected UDP socket
From: Wei Wang @ 2016-03-22 18:03 UTC (permalink / raw)
  To: Martin KaFai Lau
  Cc: Cong Wang, Wei Wang, Eric Dumazet, David Miller, Eric Dumazet,
	Linux Kernel Network Developers
In-Reply-To: <20160322173939.GA53936@kafai-mba.local>

Thanks Martin and Cong.

I guess then we are going with the following fix in ip6_sk_update_pmtu():
1. call ip6_upate_pmtu() as it is
2. do a dst_check()
3. re-lookup() if it is invalid
4. and then do a ip6_dst_store()/dst_set

But one thing here, we will have to generate the same flowi6 in both
ip6_sk_update_pmtu() as well as ip6_update_pmtu(). Is this considered
as a not clean enough fix?


On Tue, Mar 22, 2016 at 10:39 AM, Martin KaFai Lau <kafai@fb.com> wrote:
> On Tue, Mar 22, 2016 at 09:53:35AM -0700, Cong Wang wrote:
>> On Mon, Mar 21, 2016 at 11:02 PM, Martin KaFai Lau <kafai@fb.com> wrote:
>> > In term of difference, AFAICT, the current patch is an optimization in the
>> > sense that the update_pmtu() code path does not have to do a dst_check to
>> > discover its sk->sk_dst_cache is invalid, and then do a relookup to find out
>> > that the just created RTF_CACHE clone should be used.  To get this, it may
>> > make more sense to remove all the relookup code together during update_pmtu().
>> > Even if this slow path was to be optimized, should it be put in a
>> > separate patch where net-next is a better candidate?
>> >
>>
>> Speaking of RTF_CACHE, I am curious why you didn't use FIB next hop exception
>> as what ipv4 does to cache exceptions? This makes IPv6 has more gap with IPv4.
>> This is (almost) irrelevant to this patch.
> There are a few differences between IPv6 and IPv4.  Both in terms of
> data structure and functionality.  The last 'RTF_CACHE on exception' patchset is one
> step toward this direction. More patches are needed and are welcomed ;)
>
>>
>>
>> > I think fixing it in __udp6_lib_err() or what Cong Wang is suggesting makes
>> > more sense for a net branch fix.  If there is logic specific to connected-udp,
>> > I would do it in the __udp6_lib_err() instead.  After looking at
>> > udpv6_sendmsg() and how it calls ip6_dst_store(), may also need to be careful
>> > what daddr and saddr should be passed to ip6_dst_store(), or at least a commit
>> > message.  The first patch is essentially passing NULL to daddr and saddr
>> > while the second patch seems passing something else.
>>
>> Raw socket needs to fix too, we can't just fix __udp6_lib_err(), this is also
>> why fixing ip6_sk_update_pmtu() is better, its call path is better.
> I don't see rawv6 socket is storing the dst.  I probably have overlooked it.  Can
> you point it out?
>
> Having said that, I don't feel strongly on any of the two places.  I think only
> implementation can tell.

^ permalink raw reply

* Re: [RFC PATCH 7/9] GSO: Support partial segmentation offload
From: Alexander Duyck @ 2016-03-22 17:47 UTC (permalink / raw)
  To: Edward Cree; +Cc: Alexander Duyck, Netdev, David Miller, Tom Herbert
In-Reply-To: <56F17A13.8090701@solarflare.com>

On Tue, Mar 22, 2016 at 10:00 AM, Edward Cree <ecree@solarflare.com> wrote:
> On 18/03/16 23:25, Alexander Duyck wrote:
>> This patch adds support for something I am referring to as GSO partial.
>> The basic idea is that we can support a broader range of devices for
>> segmentation if we use fixed outer headers and have the hardware only
>> really deal with segmenting the inner header.  The idea behind the naming
>> is due to the fact that everything before csum_start will be fixed headers,
>> and everything after will be the region that is handled by hardware.
>>
>> With the current implementation it allows us to add support for the
>> following GSO types with an inner TSO or TSO6 offload:
>> NETIF_F_GSO_GRE
>> NETIF_F_GSO_GRE_CSUM
>> NETIF_F_UDP_TUNNEL
>> NETIF_F_UDP_TUNNEL_CSUM
>>
>> Signed-off-by: Alexander Duyck <aduyck@mirantis.com>
>> ---
> If I'm correctly understanding what you're doing, you're building a large
> TCP segment, feeding it through the encapsulation drivers as normal, then
> at GSO time you're fixing up length fields, checksums etc. in the headers.
> I think we can do this more simply, by making it so that at the time when
> we _generate_ the TCP segment, we give it headers saying it's one MSS big,
> but have several MSS of data.  Similarly when adding the encap headers,
> they all need to get their lengths from what the layer below tells them,
> rather than the current length of data in the SKB.  Then at GSO time all
> the headers already have the right things in, and you don't need to call
> any per-protocol GSO callbacks for them.

One issue I have to deal with here is that we have no way of knowing
what the underlying hardware can support at the time of segment being
created.  You have to keep in mind that what we have access to is the
tunnel dev in many cases, not the underlying dev so we don't know if
things can be offloaded to hardware or not.  By pushing this logic
into the GSO code we can actually implement it without much overhead
since we either segment it into an MSS multiple, or into single MSS
sized chunks.  This way we defer the decision until the very last
moment when we actually know if we can offload some portion of this in
hardware or not.

> Any protocol that noticed it was putting something non-copyable in its
> headers (e.g. GRE with the Counter field, or an outer IP layer without DF
> set needing real IPIDs) would set a flag in the SKB to indicate that we
> really do need to call through the per-protocol GSO stuff.  (Ideally, if
> we had a separate skb->gso_start field rather than piggybacking on
> csum_start, we could reset it to point just before us, so that any further
> headers outside us still can be copied rather than taking callbacks.  But
> I'm not sure whether that's worth using up sk_buff real estate for.)

The idea behind piggybacking on csum_start was due to the fact that we
cannot perform GSO/TSO unless CHECKSUM_PARTIAL is set.  As far as I
know in the case of TCP offloads this always ends up being the
inner-most L4 header so it works out in that it actually reduces code
path as we were having to deal with all the skb->encapsulation checks.
It was a relationship that already existed, I just decided to make use
of it since it simplifies things pretty significantly.

As far as retreating I don't really see how that would work. In most
cases it is an all-or-nothing proposition to setup these outer
headers.  Either we can segment the frame with the outer headers
replicated or we cannot.  I suspect it would end up being a common
case where the hardware will update the outer IP and inner TCP
headers, but I think the outer L4 and inner IP headers will be the
ones that most likely always end up being static.  Also we already
have code paths in place in the GRE driver for instance that prevent
us from using GSO in the case of TUNNEL_SEQ being enabled.

> (It might still be necessary to put the true length in the TCP header, if
> hardware is using that as an input to segmentation.  I think sfc hardware
> just uses 'total length of all payload DMA descriptors', but others might
> behave differently.)

That is what most drivers do.  The way I kind of retained that is that
the TCP header doesn't include an actual length field, but I left the
pseudo-header using the full length of all data.  My thought was to
end up using something like the ixgbe approach for most devices.  What
I did there was replicate the tunnel headers and inner IPv4 or IPv6
header.  In the case of ixgbe and i40e I can throw away the checksum
and length values for the outer IP header, one thing I was curious
about is if I really needed to retain the full packet size for those.

> However, I haven't yet had the time to attempt to implement this, so there
> might be some obvious reason I'm missing why this is impossible.
> Also, it's possible that I've completely misunderstood your patch and it's
> orthogonal to and can coexist with what I'm suggesting.

The one piece I could really use would be an understanding of what
inputs your hardware is expecting in order for us to extend TSO to
support this kind of approach.  Then I could start tailoring the
output generated so that we had something that would work with more
devices.  I was thinking the approach I have taken is fairly generic
since essentially it allows us to get away with TSO as long as we are
allowed to provide the offsets for the IP header and the TCP header.
>From what I can tell it looks like the Solarflare drivers do something
similar so you might even try making changes similar to what I did for
ixgbe to see if you can get a proof of concept working for sfc.

- Alex

^ permalink raw reply

* Re: [PATCH] ipv6: Fix the pmtu path for connected UDP socket
From: Martin KaFai Lau @ 2016-03-22 17:39 UTC (permalink / raw)
  To: Cong Wang
  Cc: Wei Wang, Wei Wang, Eric Dumazet, David Miller, Eric Dumazet,
	Linux Kernel Network Developers
In-Reply-To: <CAM_iQpVfofoThoUS8UYkh-2KR_Co42tfxz00mCXx+JMWpwgg8A@mail.gmail.com>

On Tue, Mar 22, 2016 at 09:53:35AM -0700, Cong Wang wrote:
> On Mon, Mar 21, 2016 at 11:02 PM, Martin KaFai Lau <kafai@fb.com> wrote:
> > In term of difference, AFAICT, the current patch is an optimization in the
> > sense that the update_pmtu() code path does not have to do a dst_check to
> > discover its sk->sk_dst_cache is invalid, and then do a relookup to find out
> > that the just created RTF_CACHE clone should be used.  To get this, it may
> > make more sense to remove all the relookup code together during update_pmtu().
> > Even if this slow path was to be optimized, should it be put in a
> > separate patch where net-next is a better candidate?
> >
>
> Speaking of RTF_CACHE, I am curious why you didn't use FIB next hop exception
> as what ipv4 does to cache exceptions? This makes IPv6 has more gap with IPv4.
> This is (almost) irrelevant to this patch.
There are a few differences between IPv6 and IPv4.  Both in terms of
data structure and functionality.  The last 'RTF_CACHE on exception' patchset is one
step toward this direction. More patches are needed and are welcomed ;)

>
>
> > I think fixing it in __udp6_lib_err() or what Cong Wang is suggesting makes
> > more sense for a net branch fix.  If there is logic specific to connected-udp,
> > I would do it in the __udp6_lib_err() instead.  After looking at
> > udpv6_sendmsg() and how it calls ip6_dst_store(), may also need to be careful
> > what daddr and saddr should be passed to ip6_dst_store(), or at least a commit
> > message.  The first patch is essentially passing NULL to daddr and saddr
> > while the second patch seems passing something else.
>
> Raw socket needs to fix too, we can't just fix __udp6_lib_err(), this is also
> why fixing ip6_sk_update_pmtu() is better, its call path is better.
I don't see rawv6 socket is storing the dst.  I probably have overlooked it.  Can
you point it out?

Having said that, I don't feel strongly on any of the two places.  I think only
implementation can tell.

^ permalink raw reply

* Re: [PATCH] ath9k: fix checkpatch.pl identation and sapce errors.
From: Joe Perches @ 2016-03-22 17:36 UTC (permalink / raw)
  To: Ashwini Singh, ath9k-devel, kvalo
  Cc: linux-wireless, ath9k-devel, netdev, linux-kernel, Rajeev_Kumar
In-Reply-To: <1458629628-6264-1-git-send-email-Ashwini_Singh@mentor.com>

On Tue, 2016-03-22 at 12:23 +0530, Ashwini Singh wrote:
> Signed-off-by: Ashwini Singh <Ashwini_Singh@mentor.com>

It might be better to break this into a few different patches.

o Remove trailing whitespace
o Fix vertical line / brace location
o Multi-line statement parenthesis alignment
o Space to tab conversions
o Whitespace addition / removal

^ permalink raw reply

* Re: ip-token: unable to remove a token & multi-token handling & concurrent use w/ EUI64/privacy
From: Daniel Borkmann @ 2016-03-22 17:03 UTC (permalink / raw)
  To: Robin H. Johnson; +Cc: netdev, hannes
In-Reply-To: <robbat2-20160319T175636-156562343Z@orbis-terrarum.net>

Hi Robin,

On 03/19/2016 07:53 PM, Robin H. Johnson wrote:
[...]
> Playing around with IPv6 tokens, I ran into a problem:
> Once you have a token set on an interface, it's impossible to remove it!
>
> # ip token set :: dev eth0
> RTNETLINK answers: Invalid argument

I'll have a look into a fix, I think this was intentional, but I currently
fail to recall a reason why (should have put a note into the commit log). ;)
The draft is pretty terse in any case, it seems as we only invalidate other
tokenized addresses, it should be okay to just remove it.

> This is a side-effect of rejecting ipv6_addr_any in inet6_set_iftoken.
>
> While this gets fixed, I have two related feature requests for this:
> - Please make it possible to configure multiple tokens on an interface:
>    Use case: Deploying local services on well-known addresses inside a
>    network without explicit prefix configuration.
> - Adding a token causes other address generation methods to be disabled,
>    this is problematic if you wish to prefer privacy addresses for
>    outbound connections.
>
> Design suggestion:
> Convert from using a single token to using a list of tokens, with an
> explicit default IPv6-any-addr (::) in the list, to represent that
> other address generation should ALSO take place (EUI64/privacy).
> Deletion of the any-addr from the list should disable EUI64/privacy
> addresses.

Seems you already have some patches, please feel free to send them. ;)

Thanks for the feedback!
Daniel

^ permalink raw reply

* Re: [RFC PATCH 7/9] GSO: Support partial segmentation offload
From: Edward Cree @ 2016-03-22 17:00 UTC (permalink / raw)
  To: Alexander Duyck, netdev, davem, alexander.duyck, tom
In-Reply-To: <20160318232522.14955.13475.stgit@localhost.localdomain>

On 18/03/16 23:25, Alexander Duyck wrote:
> This patch adds support for something I am referring to as GSO partial.
> The basic idea is that we can support a broader range of devices for
> segmentation if we use fixed outer headers and have the hardware only
> really deal with segmenting the inner header.  The idea behind the naming
> is due to the fact that everything before csum_start will be fixed headers,
> and everything after will be the region that is handled by hardware.
>
> With the current implementation it allows us to add support for the
> following GSO types with an inner TSO or TSO6 offload:
> NETIF_F_GSO_GRE
> NETIF_F_GSO_GRE_CSUM
> NETIF_F_UDP_TUNNEL
> NETIF_F_UDP_TUNNEL_CSUM
>
> Signed-off-by: Alexander Duyck <aduyck@mirantis.com>
> ---
If I'm correctly understanding what you're doing, you're building a large
TCP segment, feeding it through the encapsulation drivers as normal, then
at GSO time you're fixing up length fields, checksums etc. in the headers.
I think we can do this more simply, by making it so that at the time when
we _generate_ the TCP segment, we give it headers saying it's one MSS big,
but have several MSS of data.  Similarly when adding the encap headers,
they all need to get their lengths from what the layer below tells them,
rather than the current length of data in the SKB.  Then at GSO time all
the headers already have the right things in, and you don't need to call
any per-protocol GSO callbacks for them.
Any protocol that noticed it was putting something non-copyable in its
headers (e.g. GRE with the Counter field, or an outer IP layer without DF
set needing real IPIDs) would set a flag in the SKB to indicate that we
really do need to call through the per-protocol GSO stuff.  (Ideally, if
we had a separate skb->gso_start field rather than piggybacking on
csum_start, we could reset it to point just before us, so that any further
headers outside us still can be copied rather than taking callbacks.  But
I'm not sure whether that's worth using up sk_buff real estate for.)
(It might still be necessary to put the true length in the TCP header, if
hardware is using that as an input to segmentation.  I think sfc hardware
just uses 'total length of all payload DMA descriptors', but others might
behave differently.)
However, I haven't yet had the time to attempt to implement this, so there
might be some obvious reason I'm missing why this is impossible.
Also, it's possible that I've completely misunderstood your patch and it's
orthogonal to and can coexist with what I'm suggesting.
-Ed

^ permalink raw reply

* Re: [PATCH 3/3] libceph: use KMEM_CACHE macro
From: Ilya Dryomov @ 2016-03-22 16:58 UTC (permalink / raw)
  To: Geliang Tang
  Cc: Yan, Zheng, Sage Weil, David S. Miller, Ceph Development, netdev,
	linux-kernel@vger.kernel.org
In-Reply-To: <a9c3e96ba6bf321ca13d9445d2770781fb7033cd.1457853190.git.geliangtang@163.com>

On Sun, Mar 13, 2016 at 8:18 AM, Geliang Tang <geliangtang@163.com> wrote:
> Use KMEM_CACHE() instead of kmem_cache_create() to simplify the code.
>
> Signed-off-by: Geliang Tang <geliangtang@163.com>
> ---
>  net/ceph/messenger.c  | 10 ++--------
>  net/ceph/osd_client.c |  5 +----
>  2 files changed, 3 insertions(+), 12 deletions(-)
>
> diff --git a/net/ceph/messenger.c b/net/ceph/messenger.c
> index 9382619..32c997e 100644
> --- a/net/ceph/messenger.c
> +++ b/net/ceph/messenger.c
> @@ -235,18 +235,12 @@ static struct workqueue_struct *ceph_msgr_wq;
>  static int ceph_msgr_slab_init(void)
>  {
>         BUG_ON(ceph_msg_cache);
> -       ceph_msg_cache = kmem_cache_create("ceph_msg",
> -                                       sizeof (struct ceph_msg),
> -                                       __alignof__(struct ceph_msg), 0, NULL);
> -
> +       ceph_msg_cache = KMEM_CACHE(ceph_msg, 0);
>         if (!ceph_msg_cache)
>                 return -ENOMEM;
>
>         BUG_ON(ceph_msg_data_cache);
> -       ceph_msg_data_cache = kmem_cache_create("ceph_msg_data",
> -                                       sizeof (struct ceph_msg_data),
> -                                       __alignof__(struct ceph_msg_data),
> -                                       0, NULL);
> +       ceph_msg_data_cache = KMEM_CACHE(ceph_msg_data, 0);
>         if (ceph_msg_data_cache)
>                 return 0;
>
> diff --git a/net/ceph/osd_client.c b/net/ceph/osd_client.c
> index 5bc0537..7558855 100644
> --- a/net/ceph/osd_client.c
> +++ b/net/ceph/osd_client.c
> @@ -2783,10 +2783,7 @@ EXPORT_SYMBOL(ceph_osdc_writepages);
>  int ceph_osdc_setup(void)
>  {
>         BUG_ON(ceph_osd_request_cache);
> -       ceph_osd_request_cache = kmem_cache_create("ceph_osd_request",
> -                                       sizeof (struct ceph_osd_request),
> -                                       __alignof__(struct ceph_osd_request),
> -                                       0, NULL);
> +       ceph_osd_request_cache = KMEM_CACHE(ceph_osd_request, 0);
>
>         return ceph_osd_request_cache ? 0 : -ENOMEM;
>  }

Applied, with osd_client.c hunk dropped.  ceph_osd_request cache
objects are not longer sizeof(struct ceph_osd_request).

Thanks,

                Ilya

^ permalink raw reply

* Re: [PATCH] ipv6: Fix the pmtu path for connected UDP socket
From: Cong Wang @ 2016-03-22 16:53 UTC (permalink / raw)
  To: Martin KaFai Lau
  Cc: Wei Wang, Wei Wang, Eric Dumazet, David Miller, Eric Dumazet,
	Linux Kernel Network Developers
In-Reply-To: <20160322060220.GA50824@kafai-mba.local>

On Mon, Mar 21, 2016 at 11:02 PM, Martin KaFai Lau <kafai@fb.com> wrote:
> I think Cong Wang is suggesting, in ip6_sk_update_pmtu():
> 1. call ip6_upate_pmtu() as it is
> 2. do a dst_check()
> 3. re-lookup() if it is invalid
> 4. and then do a ip6_dst_store()/dst_set
>
> The above is exactly what inet6_csk_update_pmtu(), which was also used in the
> first patch, is doing.

Well, the reasons why I suggest to fix ip6_sk_update_pmtu() instead of anything
else (no matter __udp6_lib_err() in v1 or ip6_update_pmtu() in v2) are that:

1) Catch up with ipv4 part, which is ipv4_sk_update_pmtu()
2) Straight-forward, (ideally) no need to bother other irrelevant
callers like xfrm.

Functionally all the solutions should work to fix Wei's problem, we just need to
find which one is more elegant.


>
> In term of difference, AFAICT, the current patch is an optimization in the
> sense that the update_pmtu() code path does not have to do a dst_check to
> discover its sk->sk_dst_cache is invalid, and then do a relookup to find out
> that the just created RTF_CACHE clone should be used.  To get this, it may
> make more sense to remove all the relookup code together during update_pmtu().
> Even if this slow path was to be optimized, should it be put in a
> separate patch where net-next is a better candidate?
>

Speaking of RTF_CACHE, I am curious why you didn't use FIB next hop exception
as what ipv4 does to cache exceptions? This makes IPv6 has more gap with IPv4.
This is (almost) irrelevant to this patch.


> I think fixing it in __udp6_lib_err() or what Cong Wang is suggesting makes
> more sense for a net branch fix.  If there is logic specific to connected-udp,
> I would do it in the __udp6_lib_err() instead.  After looking at
> udpv6_sendmsg() and how it calls ip6_dst_store(), may also need to be careful
> what daddr and saddr should be passed to ip6_dst_store(), or at least a commit
> message.  The first patch is essentially passing NULL to daddr and saddr
> while the second patch seems passing something else.

Raw socket needs to fix too, we can't just fix __udp6_lib_err(), this is also
why fixing ip6_sk_update_pmtu() is better, its call path is better.

^ permalink raw reply

* Re: [PATCH v5 2/4] Documentation: Bindings: Add STM32 DWMAC glue
From: Chen-Yu Tsai @ 2016-03-22 16:27 UTC (permalink / raw)
  To: Giuseppe CAVALLARO
  Cc: Alexandre Torgue, Chen-Yu Tsai, Maxime Coquelin, netdev,
	devicetree, Joachim Eastwood, linux-kernel, linux-arm-kernel
In-Reply-To: <56EFFEEC.1010407-qxv4g6HH51o@public.gmane.org>

On Mon, Mar 21, 2016 at 10:02 PM, Giuseppe CAVALLARO
<peppe.cavallaro-qxv4g6HH51o@public.gmane.org> wrote:
> On 3/21/2016 11:45 AM, Alexandre Torgue wrote:
>>
>> Hi,
>>
>> 2016-03-18 17:00 GMT+01:00 Chen-Yu Tsai <wens-jdAy2FN1RRM@public.gmane.org>:
>>>
>>> Hi,
>>>
>>> On Fri, Mar 18, 2016 at 11:37 PM, Alexandre TORGUE
>>> <alexandre.torgue-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:
>>>>
>>>> Signed-off-by: Alexandre TORGUE <alexandre.torgue-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
>>>>
>>>> diff --git a/Documentation/devicetree/bindings/net/stm32-dwmac.txt
>>>> b/Documentation/devicetree/bindings/net/stm32-dwmac.txt
>>>> new file mode 100644
>>>> index 0000000..ada2aa4
>>>> --- /dev/null
>>>> +++ b/Documentation/devicetree/bindings/net/stm32-dwmac.txt
>>>> @@ -0,0 +1,32 @@
>>>> +STMicroelectronics STM32 / MCU DWMAC glue layer controller
>>>> +
>>>> +This file documents platform glue layer for stmmac.
>>>> +Please see stmmac.txt for the other unchanged properties.
>>>> +
>>>> +The device node has following properties.
>>>> +
>>>> +Required properties:
>>>> +- compatible:  Should be "st,stm32-dwmac" to select glue, and
>>>> +              "snps,dwmac-3.50a" to select IP vesrion.
>
>
> Almost all the synp gmac chips have the HW capability register that is
> used for setting all the parameters at probe time.
> This will override fields passed from DT. In theory, it is not
> necessary to pass: "snps,dwmac-3.50a" from device tree at least there
> is either no HW cap reg or the glue has some w/a for a specific chip
> revision.
> To be honest, I like to see the "snps,dwmac-3.50a" as compatibility
> to also have a better readability (that's my personal view ;-) ).

I agree having the versioned strings is good for informational purposes,
and to signal hardware capability. It is not so good for directly
binding drivers in the implementation though.

Unfortunately, as Joachim pointed out, exynos5440 uses it so we cannot
change it.

ChenYu

> Peppe
>
>
>>>
>>> If you need have sort of hardware glue, then it is not compatible.
>>>
>>
>> We could have the case where the glue is set by a bootloader.
>> In this case, we will select IP version in compatible and we will use
>> generic dwmac glue to probe stmmac driver.
>>
>> Regards
>>
>> Alex.
>>
>>> ChenYu
>>>
>>>> +- clocks: Must contain a phandle for each entry in clock-names.
>>>> +- clock-names: Should be "stmmaceth" for the host clock.
>>>> +              Should be "tx-clk" for the MAC TX clock.
>>>> +              Should be "rx-clk" for the MAC RX clock.
>>>> +- st,syscon : Should be phandle/offset pair. The phandle to the syscon
>>>> node which
>>>> +             encompases the glue register, and the offset of the
>>>> control register.
>>>> +Example:
>>>> +
>>>> +               ethernet0: dwmac@40028000 {
>>>> +                       compatible = "st,stm32-dwmac",
>>>> "snps,dwmac-3.50a";
>>>> +                       status = "disabled";
>>>> +                       reg = <0x40028000 0x8000>;
>>>> +                       reg-names = "stmmaceth";
>>>> +                       interrupts = <0 61 0>, <0 62 0>;
>>>> +                       interrupt-names = "macirq", "eth_wake_irq";
>>>> +                       clock-names = "stmmaceth", "tx-clk", "rx-clk";
>>>> +                       clocks = <&rcc 0 25>, <&rcc 0 26>, <&rcc 0 27>;
>>>> +                       st,syscon = <&syscfg 0x4>;
>>>> +                       snps,pbl = <8>;
>>>> +                       snps,mixed-burst;
>>>> +                       dma-ranges;
>>>> +               };
>>>> --
>>>> 1.9.1
>>>>
>>>>
>>>> _______________________________________________
>>>> linux-arm-kernel mailing list
>>>> linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org
>>>> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
>>
>>
>>
>
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* Re: [PATCH v5 2/4] Documentation: Bindings: Add STM32 DWMAC glue
From: Alexandre Torgue @ 2016-03-22 16:11 UTC (permalink / raw)
  To: Joachim Eastwood
  Cc: Rob Herring, Chen-Yu Tsai, Maxime Coquelin, Giuseppe Cavallaro,
	netdev, devicetree, linux-kernel, linux-arm-kernel
In-Reply-To: <CAGhQ9VwS=YwgfeUuK+LzGjy3f9btVGV7bN=TATGHwQs+JW+iGA-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>

Hi guys,

I will fix typo issues (s/vesrion/version and ethernet @).

Concerning compatible string. For sure "snps,dwmac-3.50a" string is
not used inside glue driver.
I perfere to keep it for information but if you really want that I
remove it I will not block ;)

2016-03-21 16:36 GMT+01:00 Joachim  Eastwood <manabian-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>:
> On 21 March 2016 at 13:40, Rob Herring <robh-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org> wrote:
>> On Sat, Mar 19, 2016 at 12:00:22AM +0800, Chen-Yu Tsai wrote:
>>> Hi,
>>>
>>> On Fri, Mar 18, 2016 at 11:37 PM, Alexandre TORGUE
>>> <alexandre.torgue-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:
>>> > +- clocks: Must contain a phandle for each entry in clock-names.
>>> > +- clock-names: Should be "stmmaceth" for the host clock.
>>
We can remove host clock (stmmac eth) entry here and refer to
stmmac.txt binding for common entry

>> This doesn't sound like the clock input signal name...
>>
>>> > +              Should be "tx-clk" for the MAC TX clock.
>>> > +              Should be "rx-clk" for the MAC RX clock.
>>
>> How can other DWMAC blocks not have these clocks? The glue can't really
>> add these clocks. It could combine them into one or a new version of
>> DWMAC could have a different number of clock inputs. So if there is
>> variation here, then some of the bindings are probably wrong. I guess
>> the only change I'm suggesting is possibly moving these into common
>> binding doc.
>
> The LPC18xx implementation probably have these clocks as well but the
> LPC1850 user manual only documents the main clock. Someone with access
> to the IP block doc from Synopsys should be able to check which clocks
> the MAC really needs.
>
> Rockchip bindings have two clocks named "mac_clk_rx" and "mac_clk_tx".
> These are probably the same as stm32 needs so maybe use these names
> and move them into the main doc and update the rockchip binding.
>
I think we can use same name. But I have a doubt on moving it in a
common bindings (maybe I don't well understood). When you say "common
binding file" is it "stmmac.txt" binding ? If yes does it mean that we
have to control it inside stmmac driver (no more in glue) ? In this
case those clocks will become "required" for stm32 and rockship but
not for others chip. It could create confusion?

Best regards

Alex

>
> regards,
> Joachim Eastwood
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* [PATCH v3 2/2] AF_VSOCK: Shrink the area influenced by prepare_to_wait
From: Claudio Imbrenda @ 2016-03-22 16:05 UTC (permalink / raw)
  To: davem; +Cc: labbott, netdev, linux-kernel
In-Reply-To: <1458662752-2415-1-git-send-email-imbrenda@linux.vnet.ibm.com>

When a thread is prepared for waiting by calling prepare_to_wait, sleeping
is not allowed until either the wait has taken place or finish_wait has
been called.  The existing code in af_vsock imposed unnecessary no-sleep
assumptions to a broad list of backend functions.
This patch shrinks the influence of prepare_to_wait to the area where it
is strictly needed, therefore relaxing the no-sleep restriction there.

Signed-off-by: Claudio Imbrenda <imbrenda@linux.vnet.ibm.com>
---
 net/vmw_vsock/af_vsock.c | 158 +++++++++++++++++++++++++----------------------
 1 file changed, 85 insertions(+), 73 deletions(-)

diff --git a/net/vmw_vsock/af_vsock.c b/net/vmw_vsock/af_vsock.c
index 7fd1220..3dce53e 100644
--- a/net/vmw_vsock/af_vsock.c
+++ b/net/vmw_vsock/af_vsock.c
@@ -1209,10 +1209,14 @@ static int vsock_stream_connect(struct socket *sock, struct sockaddr *addr,
 
 		if (signal_pending(current)) {
 			err = sock_intr_errno(timeout);
-			goto out_wait_error;
+			sk->sk_state = SS_UNCONNECTED;
+			sock->state = SS_UNCONNECTED;
+			goto out_wait;
 		} else if (timeout == 0) {
 			err = -ETIMEDOUT;
-			goto out_wait_error;
+			sk->sk_state = SS_UNCONNECTED;
+			sock->state = SS_UNCONNECTED;
+			goto out_wait;
 		}
 
 		prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE);
@@ -1220,20 +1224,17 @@ static int vsock_stream_connect(struct socket *sock, struct sockaddr *addr,
 
 	if (sk->sk_err) {
 		err = -sk->sk_err;
-		goto out_wait_error;
-	} else
+		sk->sk_state = SS_UNCONNECTED;
+		sock->state = SS_UNCONNECTED;
+	} else {
 		err = 0;
+	}
 
 out_wait:
 	finish_wait(sk_sleep(sk), &wait);
 out:
 	release_sock(sk);
 	return err;
-
-out_wait_error:
-	sk->sk_state = SS_UNCONNECTED;
-	sock->state = SS_UNCONNECTED;
-	goto out_wait;
 }
 
 static int vsock_accept(struct socket *sock, struct socket *newsock, int flags)
@@ -1270,18 +1271,20 @@ static int vsock_accept(struct socket *sock, struct socket *newsock, int flags)
 	       listener->sk_err == 0) {
 		release_sock(listener);
 		timeout = schedule_timeout(timeout);
+		finish_wait(sk_sleep(listener), &wait);
 		lock_sock(listener);
 
 		if (signal_pending(current)) {
 			err = sock_intr_errno(timeout);
-			goto out_wait;
+			goto out;
 		} else if (timeout == 0) {
 			err = -EAGAIN;
-			goto out_wait;
+			goto out;
 		}
 
 		prepare_to_wait(sk_sleep(listener), &wait, TASK_INTERRUPTIBLE);
 	}
+	finish_wait(sk_sleep(listener), &wait);
 
 	if (listener->sk_err)
 		err = -listener->sk_err;
@@ -1301,19 +1304,15 @@ static int vsock_accept(struct socket *sock, struct socket *newsock, int flags)
 		 */
 		if (err) {
 			vconnected->rejected = true;
-			release_sock(connected);
-			sock_put(connected);
-			goto out_wait;
+		} else {
+			newsock->state = SS_CONNECTED;
+			sock_graft(connected, newsock);
 		}
 
-		newsock->state = SS_CONNECTED;
-		sock_graft(connected, newsock);
 		release_sock(connected);
 		sock_put(connected);
 	}
 
-out_wait:
-	finish_wait(sk_sleep(listener), &wait);
 out:
 	release_sock(listener);
 	return err;
@@ -1557,11 +1556,11 @@ static int vsock_stream_sendmsg(struct socket *sock, struct msghdr *msg,
 	if (err < 0)
 		goto out;
 
-	prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE);
 
 	while (total_written < len) {
 		ssize_t written;
 
+		prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE);
 		while (vsock_stream_has_space(vsk) == 0 &&
 		       sk->sk_err == 0 &&
 		       !(sk->sk_shutdown & SEND_SHUTDOWN) &&
@@ -1570,27 +1569,33 @@ static int vsock_stream_sendmsg(struct socket *sock, struct msghdr *msg,
 			/* Don't wait for non-blocking sockets. */
 			if (timeout == 0) {
 				err = -EAGAIN;
-				goto out_wait;
+				finish_wait(sk_sleep(sk), &wait);
+				goto out_err;
 			}
 
 			err = transport->notify_send_pre_block(vsk, &send_data);
-			if (err < 0)
-				goto out_wait;
+			if (err < 0) {
+				finish_wait(sk_sleep(sk), &wait);
+				goto out_err;
+			}
 
 			release_sock(sk);
 			timeout = schedule_timeout(timeout);
 			lock_sock(sk);
 			if (signal_pending(current)) {
 				err = sock_intr_errno(timeout);
-				goto out_wait;
+				finish_wait(sk_sleep(sk), &wait);
+				goto out_err;
 			} else if (timeout == 0) {
 				err = -EAGAIN;
-				goto out_wait;
+				finish_wait(sk_sleep(sk), &wait);
+				goto out_err;
 			}
 
 			prepare_to_wait(sk_sleep(sk), &wait,
 					TASK_INTERRUPTIBLE);
 		}
+		finish_wait(sk_sleep(sk), &wait);
 
 		/* These checks occur both as part of and after the loop
 		 * conditional since we need to check before and after
@@ -1598,16 +1603,16 @@ static int vsock_stream_sendmsg(struct socket *sock, struct msghdr *msg,
 		 */
 		if (sk->sk_err) {
 			err = -sk->sk_err;
-			goto out_wait;
+			goto out_err;
 		} else if ((sk->sk_shutdown & SEND_SHUTDOWN) ||
 			   (vsk->peer_shutdown & RCV_SHUTDOWN)) {
 			err = -EPIPE;
-			goto out_wait;
+			goto out_err;
 		}
 
 		err = transport->notify_send_pre_enqueue(vsk, &send_data);
 		if (err < 0)
-			goto out_wait;
+			goto out_err;
 
 		/* Note that enqueue will only write as many bytes as are free
 		 * in the produce queue, so we don't need to ensure len is
@@ -1620,7 +1625,7 @@ static int vsock_stream_sendmsg(struct socket *sock, struct msghdr *msg,
 				len - total_written);
 		if (written < 0) {
 			err = -ENOMEM;
-			goto out_wait;
+			goto out_err;
 		}
 
 		total_written += written;
@@ -1628,14 +1633,13 @@ static int vsock_stream_sendmsg(struct socket *sock, struct msghdr *msg,
 		err = transport->notify_send_post_enqueue(
 				vsk, written, &send_data);
 		if (err < 0)
-			goto out_wait;
+			goto out_err;
 
 	}
 
-out_wait:
+out_err:
 	if (total_written > 0)
 		err = total_written;
-	finish_wait(sk_sleep(sk), &wait);
 out:
 	release_sock(sk);
 	return err;
@@ -1716,21 +1720,61 @@ vsock_stream_recvmsg(struct socket *sock, struct msghdr *msg, size_t len,
 	if (err < 0)
 		goto out;
 
-	prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE);
 
 	while (1) {
-		s64 ready = vsock_stream_has_data(vsk);
+		s64 ready;
 
-		if (ready < 0) {
-			/* Invalid queue pair content. XXX This should be
-			 * changed to a connection reset in a later change.
-			 */
+		prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE);
+		ready = vsock_stream_has_data(vsk);
 
-			err = -ENOMEM;
-			goto out_wait;
-		} else if (ready > 0) {
+		if (ready == 0) {
+			if (sk->sk_err != 0 ||
+			    (sk->sk_shutdown & RCV_SHUTDOWN) ||
+			    (vsk->peer_shutdown & SEND_SHUTDOWN)) {
+				finish_wait(sk_sleep(sk), &wait);
+				break;
+			}
+			/* Don't wait for non-blocking sockets. */
+			if (timeout == 0) {
+				err = -EAGAIN;
+				finish_wait(sk_sleep(sk), &wait);
+				break;
+			}
+
+			err = transport->notify_recv_pre_block(
+					vsk, target, &recv_data);
+			if (err < 0) {
+				finish_wait(sk_sleep(sk), &wait);
+				break;
+			}
+			release_sock(sk);
+			timeout = schedule_timeout(timeout);
+			lock_sock(sk);
+
+			if (signal_pending(current)) {
+				err = sock_intr_errno(timeout);
+				finish_wait(sk_sleep(sk), &wait);
+				break;
+			} else if (timeout == 0) {
+				err = -EAGAIN;
+				finish_wait(sk_sleep(sk), &wait);
+				break;
+			}
+		} else {
 			ssize_t read;
 
+			finish_wait(sk_sleep(sk), &wait);
+
+			if (ready < 0) {
+				/* Invalid queue pair content. XXX This should
+				* be changed to a connection reset in a later
+				* change.
+				*/
+
+				err = -ENOMEM;
+				goto out;
+			}
+
 			err = transport->notify_recv_pre_dequeue(
 					vsk, target, &recv_data);
 			if (err < 0)
@@ -1750,42 +1794,12 @@ vsock_stream_recvmsg(struct socket *sock, struct msghdr *msg, size_t len,
 					vsk, target, read,
 					!(flags & MSG_PEEK), &recv_data);
 			if (err < 0)
-				goto out_wait;
+				goto out;
 
 			if (read >= target || flags & MSG_PEEK)
 				break;
 
 			target -= read;
-		} else {
-			if (sk->sk_err != 0 || (sk->sk_shutdown & RCV_SHUTDOWN)
-			    || (vsk->peer_shutdown & SEND_SHUTDOWN)) {
-				break;
-			}
-			/* Don't wait for non-blocking sockets. */
-			if (timeout == 0) {
-				err = -EAGAIN;
-				break;
-			}
-
-			err = transport->notify_recv_pre_block(
-					vsk, target, &recv_data);
-			if (err < 0)
-				break;
-
-			release_sock(sk);
-			timeout = schedule_timeout(timeout);
-			lock_sock(sk);
-
-			if (signal_pending(current)) {
-				err = sock_intr_errno(timeout);
-				break;
-			} else if (timeout == 0) {
-				err = -EAGAIN;
-				break;
-			}
-
-			prepare_to_wait(sk_sleep(sk), &wait,
-					TASK_INTERRUPTIBLE);
 		}
 	}
 
@@ -1816,8 +1830,6 @@ vsock_stream_recvmsg(struct socket *sock, struct msghdr *msg, size_t len,
 		err = copied;
 	}
 
-out_wait:
-	finish_wait(sk_sleep(sk), &wait);
 out:
 	release_sock(sk);
 	return err;
-- 
1.9.1

^ permalink raw reply related

* [PATCH v3 1/2] Revert "vsock: Fix blocking ops call in prepare_to_wait"
From: Claudio Imbrenda @ 2016-03-22 16:05 UTC (permalink / raw)
  To: davem; +Cc: labbott, netdev, linux-kernel
In-Reply-To: <1458662752-2415-1-git-send-email-imbrenda@linux.vnet.ibm.com>

This reverts commit 5988818008257ca42010d6b43a3e0e48afec9898 ("vsock: Fix
blocking ops call in prepare_to_wait")

The commit reverted with this patch caused us to potentially miss wakeups.
Since the condition is not checked between the prepare_to_wait and the
schedule(), if a wakeup happens after the condition is checked but before
the sleep happens, we will miss it. ( A description of the problem can be
found here: http://www.makelinux.net/ldd3/chp-6-sect-2 ).

By reverting the patch, the behaviour is still incorrect (since we
shouldn't sleep between the prepare_to_wait and the schedule) but at least
it will not miss wakeups.

The next patch in the series actually fixes the behaviour.

Signed-off-by: Claudio Imbrenda <imbrenda@linux.vnet.ibm.com>
---
 net/vmw_vsock/af_vsock.c | 19 +++++++++++++------
 1 file changed, 13 insertions(+), 6 deletions(-)

diff --git a/net/vmw_vsock/af_vsock.c b/net/vmw_vsock/af_vsock.c
index bbe65dc..7fd1220 100644
--- a/net/vmw_vsock/af_vsock.c
+++ b/net/vmw_vsock/af_vsock.c
@@ -1557,6 +1557,8 @@ static int vsock_stream_sendmsg(struct socket *sock, struct msghdr *msg,
 	if (err < 0)
 		goto out;
 
+	prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE);
+
 	while (total_written < len) {
 		ssize_t written;
 
@@ -1576,9 +1578,7 @@ static int vsock_stream_sendmsg(struct socket *sock, struct msghdr *msg,
 				goto out_wait;
 
 			release_sock(sk);
-			prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE);
 			timeout = schedule_timeout(timeout);
-			finish_wait(sk_sleep(sk), &wait);
 			lock_sock(sk);
 			if (signal_pending(current)) {
 				err = sock_intr_errno(timeout);
@@ -1588,6 +1588,8 @@ static int vsock_stream_sendmsg(struct socket *sock, struct msghdr *msg,
 				goto out_wait;
 			}
 
+			prepare_to_wait(sk_sleep(sk), &wait,
+					TASK_INTERRUPTIBLE);
 		}
 
 		/* These checks occur both as part of and after the loop
@@ -1633,6 +1635,7 @@ static int vsock_stream_sendmsg(struct socket *sock, struct msghdr *msg,
 out_wait:
 	if (total_written > 0)
 		err = total_written;
+	finish_wait(sk_sleep(sk), &wait);
 out:
 	release_sock(sk);
 	return err;
@@ -1713,6 +1716,7 @@ vsock_stream_recvmsg(struct socket *sock, struct msghdr *msg, size_t len,
 	if (err < 0)
 		goto out;
 
+	prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE);
 
 	while (1) {
 		s64 ready = vsock_stream_has_data(vsk);
@@ -1723,7 +1727,7 @@ vsock_stream_recvmsg(struct socket *sock, struct msghdr *msg, size_t len,
 			 */
 
 			err = -ENOMEM;
-			goto out;
+			goto out_wait;
 		} else if (ready > 0) {
 			ssize_t read;
 
@@ -1746,7 +1750,7 @@ vsock_stream_recvmsg(struct socket *sock, struct msghdr *msg, size_t len,
 					vsk, target, read,
 					!(flags & MSG_PEEK), &recv_data);
 			if (err < 0)
-				goto out;
+				goto out_wait;
 
 			if (read >= target || flags & MSG_PEEK)
 				break;
@@ -1769,9 +1773,7 @@ vsock_stream_recvmsg(struct socket *sock, struct msghdr *msg, size_t len,
 				break;
 
 			release_sock(sk);
-			prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE);
 			timeout = schedule_timeout(timeout);
-			finish_wait(sk_sleep(sk), &wait);
 			lock_sock(sk);
 
 			if (signal_pending(current)) {
@@ -1781,6 +1783,9 @@ vsock_stream_recvmsg(struct socket *sock, struct msghdr *msg, size_t len,
 				err = -EAGAIN;
 				break;
 			}
+
+			prepare_to_wait(sk_sleep(sk), &wait,
+					TASK_INTERRUPTIBLE);
 		}
 	}
 
@@ -1811,6 +1816,8 @@ vsock_stream_recvmsg(struct socket *sock, struct msghdr *msg, size_t len,
 		err = copied;
 	}
 
+out_wait:
+	finish_wait(sk_sleep(sk), &wait);
 out:
 	release_sock(sk);
 	return err;
-- 
1.9.1

^ permalink raw reply related

* [PATCH v3 0/2] AF_VSOCK: Shrink the area influenced by prepare_to_wait
From: Claudio Imbrenda @ 2016-03-22 16:05 UTC (permalink / raw)
  To: davem; +Cc: labbott, netdev, linux-kernel

This patchset applies on net-next.

I think I found a problem with the patch submitted by Laura Abbott
( https://lkml.org/lkml/2016/2/4/711 ): we might miss wakeups.
Since the condition is not checked between the prepare_to_wait and the
schedule(), if a wakeup happens after the condition is checked but before
the sleep happens, and we miss it. ( A description of the problem can be
found here: http://www.makelinux.net/ldd3/chp-6-sect-2 ).

The first patch reverts the previous broken patch, while the second patch
properly fixes the sleep-while-waiting issue.


Claudio Imbrenda (2):
  Revert "vsock: Fix blocking ops call in prepare_to_wait"
  AF_VSOCK: Shrink the area influenced by prepare_to_wait

 net/vmw_vsock/af_vsock.c | 155 ++++++++++++++++++++++++++---------------------
 1 file changed, 87 insertions(+), 68 deletions(-)

-- 
1.9.1

^ permalink raw reply

* [iproute PATCH v3] Use ARRAY_SIZE macro everywhere
From: Phil Sutter @ 2016-03-22 15:52 UTC (permalink / raw)
  To: Stephen Hemminger; +Cc: netdev
In-Reply-To: <20160321115905.78a2b3e1@xeon-e3>

This patch was generated by the following semantic patch (a trimmed down
version of what is shipped with Linux sources):

@@
type T;
T[] E;
@@
(
- (sizeof(E)/sizeof(*E))
+ ARRAY_SIZE(E)
|
- (sizeof(E)/sizeof(E[...]))
+ ARRAY_SIZE(E)
|
- (sizeof(E)/sizeof(T))
+ ARRAY_SIZE(E)
)

The only manual adjustment was to include utils.h in misc/nstat.c to make
the macro known there.

Signed-off-by: Phil Sutter <phil@nwl.cc>
---
Changes since v1:
- Rebased onto current master to avoid merge conflicts.

Changes since v2:
- Patch recreated from scratch.
---
 bridge/link.c | 2 +-
 misc/nstat.c  | 2 +-
 misc/ss.c     | 2 +-
 3 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/bridge/link.c b/bridge/link.c
index 353e1c3da45db..b347040ccf91d 100644
--- a/bridge/link.c
+++ b/bridge/link.c
@@ -319,7 +319,7 @@ static int brlink_modify(int argc, char **argv)
 		} else if (strcmp(*argv, "state") == 0) {
 			NEXT_ARG();
 			char *endptr;
-			size_t nstates = sizeof(port_states) / sizeof(*port_states);
+			size_t nstates = ARRAY_SIZE(port_states);
 
 			state = strtol(*argv, &endptr, 10);
 			if (!(**argv != '\0' && *endptr == '\0')) {
diff --git a/misc/nstat.c b/misc/nstat.c
index a9e0f20789e3c..4f3863ff99121 100644
--- a/misc/nstat.c
+++ b/misc/nstat.c
@@ -95,7 +95,7 @@ static int useless_number(const char *id)
 {
 	int i;
 
-	for (i = 0; i < sizeof(useless_numbers)/sizeof(*useless_numbers); i++)
+	for (i = 0; i < ARRAY_SIZE(useless_numbers); i++)
 		if (strcmp(id, useless_numbers[i]) == 0)
 			return 1;
 	return 0;
diff --git a/misc/ss.c b/misc/ss.c
index 192389cc82371..449c391579af1 100644
--- a/misc/ss.c
+++ b/misc/ss.c
@@ -666,7 +666,7 @@ static int get_slabstat(struct slabstat *s)
 	while (fgets(buf, sizeof(buf), fp) != NULL) {
 		int i;
 
-		for (i = 0; i < sizeof(slabstat_ids)/sizeof(slabstat_ids[0]); i++) {
+		for (i = 0; i < ARRAY_SIZE(slabstat_ids); i++) {
 			if (memcmp(buf, slabstat_ids[i], strlen(slabstat_ids[i])) == 0) {
 				sscanf(buf, "%*s%d", ((int *)s) + i);
 				cnt--;
-- 
2.7.2

^ permalink raw reply related

* [PATCH net] ipv4: initialize flowi4_flags before calling fib_lookup()
From: Lance Richardson @ 2016-03-22 15:31 UTC (permalink / raw)
  To: netdev

Field fl4.flowi4_flags is not initialized in fib_compute_spec_dst()
before calling fib_lookup(), which means fib_table_lookup() is
using non-deterministic data at this line:

	if (!(flp->flowi4_flags & FLOWI_FLAG_SKIP_NH_OIF)) {

Fix by initializing fl4.flowi4_flags to zero.

Signed-off-by: Lance Richardson <lrichard@redhat.com>
---
 net/ipv4/fib_frontend.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c
index 21add55..896844a 100644
--- a/net/ipv4/fib_frontend.c
+++ b/net/ipv4/fib_frontend.c
@@ -304,6 +304,7 @@ __be32 fib_compute_spec_dst(struct sk_buff *skb)
 		fl4.flowi4_scope = scope;
 		fl4.flowi4_mark = IN_DEV_SRC_VMARK(in_dev) ? skb->mark : 0;
 		fl4.flowi4_tun_key.tun_id = 0;
+		fl4.flowi4_flags = 0;
 		if (!fib_lookup(net, &fl4, &res, 0))
 			return FIB_RES_PREFSRC(net, res);
 	} else {
-- 
2.5.0

^ permalink raw reply related

* Re: [PATCH] lan78xx: Protect runtime_auto check by #ifdef CONFIG_PM
From: Oliver Neukum @ 2016-03-22 15:29 UTC (permalink / raw)
  To: Alan Stern
  Cc: David S. Miller, Geert Uytterhoeven,
	Microchip Linux Driver Support, Woojung Huh, Rafael J. Wysocki,
	Guenter Roeck, linux-kernel, linux-pm, linux-usb, netdev
In-Reply-To: <Pine.LNX.4.44L0.1603221111040.1793-100000@iolanthe.rowland.org>

On Tue, 2016-03-22 at 11:13 -0400, Alan Stern wrote:
> > Indeed. In that case the point is moot. But it is correct to ask
> > the core whether the device is autosuspended at that point rather
> > than keep a private flag if you can.
> 
> That's why we have pm_runtime_status_suspended().

I guess we are in violent agreement though we were unaware of being
in that state.

	Regards
		Oliver

^ permalink raw reply

* Re: net/sctp: stack-out-of-bounds in sctp_getsockopt
From: Marcelo Ricardo Leitner @ 2016-03-22 15:28 UTC (permalink / raw)
  To: Eric Dumazet
  Cc: Baozeng Ding, vyasevich, nhorman, davem, linux-sctp, netdev,
	linux-kernel
In-Reply-To: <1458660088.10868.19.camel@edumazet-glaptop3.roam.corp.google.com>

On Tue, Mar 22, 2016 at 08:21:28AM -0700, Eric Dumazet wrote:
> On Tue, 2016-03-22 at 23:08 +0800, Baozeng Ding wrote:
> > Hi all,
> > 
> > The following program triggers an out-of-bounds bug in
> > sctp_getsockopt. The kernel version is 4.5 (on Mar 16
> > commit 09fd671ccb2475436bd5f597f751ca4a7d177aea). 
> > 
> > ==================================================================
> > BUG: KASAN: stack-out-of-bounds in string+0x1ef/0x200 at addr
> > ffff88003ae679e0
> > Read of size 1 by task syz-executor/19753
> > page:ffffea0000eb99c0 count:0 mapcount:0 mapping:          (null)
> > index:0x0
> > flags: 0x1fffc0000000000()
> > page dumped because: kasan: bad access detected
> > CPU: 3 PID: 19753 Comm: syz-executor Not tainted 4.5.0+ #8
> > Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS
> > rel-1.8.2-0-g33fbe13 by qemu-project.org 04/01/2014
> >  0000000000000003 ffff88003ae67578 ffffffff82945051 ffff88003ae67608
> >  ffff88003ae679e0 0000000000000096 dffffc0000000000 ffff88003ae675f8
> >  ffffffff81709f88 000000000000030d 0000000000000000 0000000000000286
> > Call Trace:
> >  [<     inline     >] __dump_stack lib/dump_stack.c:15
> >  [<ffffffff82945051>] dump_stack+0xb3/0x112 lib/dump_stack.c:51
> >  [<     inline     >] print_address_description mm/kasan/report.c:150
> >  [<ffffffff81709f88>] kasan_report_error+0x4f8/0x530 mm/kasan/report.c:236
> >  [<ffffffff8140785b>] ? __lock_acquire+0x15fb/0x5dd0 kernel/locking/lockdep.c:3226
> >  [<     inline     >] kasan_report mm/kasan/report.c:259
> >  [<ffffffff81709ffe>] __asan_report_load1_noabort+0x3e/0x40 mm/kasan/report.c:277
> >  [<ffffffff8296613f>] ? string+0x1ef/0x200 lib/vsprintf.c:591
> >  [<ffffffff8296613f>] string+0x1ef/0x200 lib/vsprintf.c:591
> >  [<ffffffff8296f103>] vsnprintf+0xb83/0x1900 lib/vsprintf.c:2049
> >  [<ffffffff8296e580>] ? pointer+0xab0/0xab0 lib/vsprintf.c:1584
> >  [<ffffffff813456f2>] __request_module+0x132/0x6b0 kernel/kmod.c:146
> >  [<ffffffff814056b0>] ? mark_held_locks+0xd0/0x130 kernel/locking/lockdep.c:2552
> >  [<ffffffff813455c0>] ? call_usermodehelper_setup+0x2b0/0x2b0 kernel/kmod.c:530
> >  [<ffffffff85da47b0>] ? mutex_lock_interruptible_nested+0x980/0x980
> >  [<ffffffff8168fed4>] ? __might_fault+0xe4/0x1d0 mm/memory.c:3833
> >  [<ffffffff8538f74c>] find_inlist_lock.constprop.17+0x10c/0x210 net/bridge/netfilter/ebtables.c:347
> >  [<     inline     >] find_table_lock net/bridge/netfilter/ebtables.c:356
> >  [<ffffffff853904ab>] do_ebt_get_ctl+0x13b/0x540 net/bridge/netfilter/ebtables.c:1524
> >  [<ffffffff85390370>] ? copy_everything_to_user+0x600/0x600 net/bridge/netfilter/ebtables.c:1455
> >  [<     inline     >] ? __mutex_unlock_common_slowpath kernel/locking/mutex.c:751
> >  [<ffffffff85da6799>] ? __mutex_unlock_slowpath+0x239/0x3f0 kernel/locking/mutex.c:762
> >  [<ffffffff85da6959>] ? mutex_unlock+0x9/0x10 kernel/locking/mutex.c:437
> >  [<ffffffff84dea126>] ? nf_sockopt_find+0x1a6/0x220 net/netfilter/nf_sockopt.c:87
> >  [<     inline     >] nf_sockopt net/netfilter/nf_sockopt.c:103
> >  [<ffffffff84dea20d>] nf_getsockopt+0x6d/0xc0 net/netfilter/nf_sockopt.c:121
> >  [<ffffffff84fadf05>] ip_getsockopt+0x135/0x190 net/ipv4/ip_sockglue.c:1523
> >  [<ffffffff84faddd0>] ? do_ip_getsockopt+0x1520/0x1520 net/ipv4/ip_sockglue.c:1353
> >  [<     inline     >] ? wake_up_process kernel/sched/core.c:2024
> >  [<ffffffff8138bcc2>] ? wake_up_q+0x82/0xe0 kernel/sched/core.c:416
> >  [<     inline     >] ? atomic_dec_and_test /arch/x86/include/asm/atomic.h:117
> >  [<     inline     >] ? mmdrop include/linux/sched.h:2611
> >  [<ffffffff814a3310>] ? drop_futex_key_refs.isra.13+0x70/0xe0 kernel/futex.c:444
> >  [<ffffffff8583a4dd>] sctp_getsockopt+0x18d/0x3f40 net/sctp/socket.c:5964
> >  [<ffffffff8140785b>] ? __lock_acquire+0x15fb/0x5dd0 kernel/locking/lockdep.c:3226
> >  [<ffffffff8583a350>] ? sctp_do_peeloff+0x2b0/0x2b0 net/sctp/socket.c:4434
> >  [<ffffffff81406260>] ? debug_check_no_locks_freed+0x290/0x290 kernel/locking/lockdep.c:4104
> >  [<     inline     >] ? rcu_read_unlock include/linux/rcupdate.h:922
> >  [<ffffffff817b398c>] ? __fget+0x20c/0x3b0 fs/file.c:712
> >  [<     inline     >] ? rcu_lock_release include/linux/rcupdate.h:491
> >  [<     inline     >] ? rcu_read_unlock include/linux/rcupdate.h:926
> >  [<ffffffff817b39b5>] ? __fget+0x235/0x3b0 fs/file.c:712
> >  [<ffffffff817b37c7>] ? __fget+0x47/0x3b0 fs/file.c:696
> >  [<ffffffff817b3c11>] ? __fget_light+0xa1/0x1f0 fs/file.c:759
> >  [<ffffffff84c3a695>] sock_common_getsockopt+0x95/0xd0 net/core/sock.c:2579
> >  [<     inline     >] SYSC_getsockopt net/socket.c:1783
> >  [<ffffffff84c37e12>] SyS_getsockopt+0x142/0x230 net/socket.c:1765
> >  [<ffffffff84c37cd0>] ? SyS_setsockopt+0x240/0x240 net/socket.c:1752
> >  [<ffffffff85dab922>] ? entry_SYSCALL_64_fastpath+0x5/0xc1 arch/x86/entry/entry_64.S:191
> >  [<ffffffff81003017>] ? trace_hardirqs_on_thunk+0x17/0x19 arch/x86/entry/thunk_64.S:39
> >  [<ffffffff85dab940>] entry_SYSCALL_64_fastpath+0x23/0xc1 arch/x86/entry/entry_64.S:207
> > Memory state around the buggy address:
> >  ffff88003ae67880: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
> >  ffff88003ae67900: 00 f1 f1 f1 f1 04 f4 f4 f4 f2 f2 f2 f2 00 00 00
> > >ffff88003ae67980: 00 00 00 00 00 00 00 00 00 00 00 00 f4 f3 f3 f3
> >                                                        ^
> >  ffff88003ae67a00: f3 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
> >  ffff88003ae67a80: f1 f1 f1 f1 04 f4 f4 f4 f3 f3 f3 f3 00 00 00 00
> > ==================================================================
> > 
> > #include <unistd.h>
> > #include <sys/syscall.h>
> > #include <netinet/in.h>
> > #include <string.h>
> > #include <stdint.h>
> > #include <sys/mman.h>
> > #include <sys/socket.h>
> > 
> > int main()
> > {
> >         int sock = 0;
> >         int sock_dup = 0;
> >         mmap((void *)0x20000000ul, 0x5000ul, PROT_READ|PROT_WRITE,
> > MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0);
> >         sock = socket(AF_INET, SOCK_STREAM, IPPROTO_SCTP);
> >         sock_dup = dup(sock);
> >         memcpy((void*)0x20000bf3,"\xac\x71\x93\x68\x02\xb3\xd1\x86\x52\xf1\xf0\x18\x09\x56\xc6\x98\x6f\x8e\x74\xb7\x17\xd4\x3a\x64\x51\x68\x13\x2d\x25\xba\x6d\x3f\x74\x68\x84\x89\x04\xd1\xa6\xe2\x7d\xaf\xfa\xd9\xce\x52\xbe\x6f\xb6\xe3\xff\x92\x35\xa1\x88\x4a\x68\x27\xaa\x25\xf8\xc1\xd5\x3b\xe5\x69\x11\x4f\x75\x4c\xe9\xff\x8b\x86\x53\x20\xb7\x10\xa2\x62\xcc\xc3\x06\x85\xde\x3e\x1c\x5a\x62\x3a\x2d\x0d\x0b\x0c\xb2\xac\x75\x42\x4d\x82\x3f\x7b\xf7\x28\xea\x2d\xff\x42\xa8\xdf\xb3\x49\x1a\xfd\xae\x2c\xd4\x35\x8e\x96\xb3\xe1\x0a\x92\x56\xb7\xde\xe8\x9e\xc3\x9e\x88\x79\xc4\x71\x46\x27\xf4\x9e\x85\xf4\x8f\x1f\x9a\xe5\x7e\x02\x09\x34\x80\x1e\x87\xa8\x9a\xce\xac\xfb\x43\x07\xdf\x15\xe8\x71\x9a\xa3\x80\x18\x1b\x15\xbd\x57\xb6\xc1\x73\x6e\xb1\x28\x3a\x01\xd5\x8e\x15\x85\xbd\x52\xdf\xfa\x64\xaa\x13\x
 0e\x2f\x64\x05\x11\xce\x79\x8b\xa8\x02\x29\x7f\x72\x0f\x37\x89\xb4\x54\x0b\x09\x02\x75\xc2\x8e\xd7\xcd\x7e\xfb\x4f\x72\xf1\x47\xea\xa2\x2a\xc3\xc4\xe9\x70\xfe\xa5\x80\x88\x21\x33\xcf\x13\x66\!
>  x98\x23\x
>  10\x5c\xa4\xbd\xee\xc0\xb4\xdd\xfb\xff\xf2\x38\xab\xca\x36\x62\x35\x84\xe4\x73\x5c\xc7\x3e\x72\x2e\x17\x43\x6f\x85\x45\x4f\x82\x62\x0d\x77\xae\xcb\xe1\x8f\xe8\xf0\x84\x3e\x62\x8b\x70\x2b\x55\xb5\xa7\x13\xcf\xa1\x78\x77\x82\xe2\xb7\x1c\x65\x7f\xb5\x79\x73\x01\x07\xd1\x9f\x45\x6a\xbb\x3d\xbf\xc8\x71\x5b\x9f\x30\xc7\xb9\xb8\x53\x9f\xe1\xba\xb6\x78\x9e\x05\x75\xa3\x55\xb1\x26\x96\xa9\xb2\x82\xce\x81\x5c\x8a\x18\xb3\x4b\x0c\x18\x8c\xf2\x7c\x09\xde\xcb\xcf\x78\x22\x58\xf6\x15\xf6\xf7\x48\xda\x08\x75\xd4\xc1\x20\xc3\x18\x2e\x89\xe8\x5b\x48\xd9\xbc\x1f\xbb\xed\x31\xaf\x12\x4d\xcd\x46\x60\xa0\xef\x0e\x2e\x21\x1d\x2b\x68\x75\xb9\x42\x5e\xd7\xae\x35\x46\xe9\x06\x63\x1d\x3c\xd6\x9c\x14\x3b\x09\x29\x49\x70\xb9\xe1\xe0\x09\x45\x41\x62\x0c\xff\x5a\x77\xbe\x31\xa6\x03\x94\x92\xde\x41\x99\xfa\x68\x99\x7
 4\xbb\x0a\x3d\xac\x9c\x7e\x00\x6b\xcd\xc1\x83\xa7\xc5\x63\xdd\x10\xea\x59\x27\xdc\x02\x98\xd6\x43\x20\x24\x4e\xc0\xdc\xa2\x98\xdf\x3e\xaf\x61\x35\xa0\x95\x3f\x9a\xaa\x7d\xe9\xe9\x0d\xe5\x97\x!
>  66\x1a\x9
>  f\xbf\x56\xc8\x37\x84\x18\x2b\xd2\xcd\xd6\xb3\x19\xd8\x4a\x30\x6e\xcb\x99\x1c\xe9\x0f\xdb\xca\x30\xe1\xe2\x90\xba\xb9\x61\x00\xbf\xeb\xad\x6a\xc8\x52\xea\x1a\x92\x05\x0c\x3b\x78\x82\x01\xac\xfd\x88\x6c\xca\xe2\xfb\xe7\x0f\xcc\x75\x9c\x98\x12\x26\xcf\xa6\x80\x02\x35\xdf\x6e\xe1\x11\x1d\xa7\x30\x17\x38\x41\xd9\x81\x55\x1a\x1e\xd1\xfe\x60\xbf\xef\x09\x25\xc0\xdb\x9f\xc4\xc6\x54\x1a\x85\x36\x85\x05\xb3\x9f\x2c\xc5\xcd\x12\x51\xef\xbe\x10\x79\xbf\x11\x00\x47\x0d\x9c\x14\x43\x1a\x46\xea\xd1\x34\x2e\x10\x6b\xa4\x3c\x25\x21\xe3\xb9\x15\x78\x6c\x40\x87\x90\xf7\x93\x5a\x66\x5f\x0a\x76\xff\xc2\xe2\x14\x35\x88\x47\xa1\x33\x5b\x8f\x3d\xc5\x89\xb7\xf9\x8a\x40\xf0\x1e\xc9\x30\xcd\xd8\x96\x41\x78\x58\x97\x49\xc8\x50\x61\x36\x8f\x7e\x44\x41\xc0\x84\xbb\x35\xf0\x63\xa9\xc2\x2a\xbd\xcc\x4b\xab\x8b\x16\x33
 \xc0\x66\xbf\x47\x62\x9b\xc4\x47\x2d\x68\x83\xca\xe3\x52\x79\xd7\xe0\x61\x80\x15\xf1\x90\x83\xa2\xbb\x4c\xe5\x8b\x50\xc8\x1b\x68\x7b\xee\x57\xdc\x54\xfa\x90\xf1\xf5\xec\x7d\x93\xe0\x80\x74\x0!
>  6\xbe\xac
>  \xc8\x85\x4d\xe8\xbf\xd3\xdd\x34\x55\xc4\xbf\x2f\x24\x19\xad\x86\x1e\x69\x2b\x6c\x3f\x00\xe8\x4b\xbb\x99\xcf\x17\x99\x00\x9d\x6c\x70\x57\xcc\x35\xee\x07\x87\x25\x8c\x0c\x8b\x9b\x38\x15\xcc\x05\x6f\xf8\x16\x78\x0b\x41\xfa\x23\x96\xc0\x79\xf8\xb7\xf0\x2b\x60\x7e\x98\xe3\x7b\xab\x80\x1f\x0d\xbf\xf6\x7e\x37\x06\xf1\x11\x42\x38\x2a\x70\xdf\xa4\xca\xf5\xf3\xf4\x7d\xca\x10\x0c\xd5\xe2\x90\xa0\x15\xde\xc2\x61\xa2\x88\xea\x32\x37\x97\x83\xd0\x4c\xad\xe2\xae\x9b\x53\xa2\xc2\x54\x0c\xbd\xe1\x50\x3b\x15\xd4\xb1\xa9\x41\x6e\x18\x2e\x30\x3f\x91\x03\x81\x86\x8c\x5c\x1f\x76\x51\x92\xf5\xb5\xb2\xc3\x16\x01\xef\xe3\x9e\xb1\x92\x0e\x0e\xcb\x20\x7f\x10\x29\x08\x6e\x15\x3d\x1e\x7c\x70\xf5\xb5\x3c\x56\x15\x3c\x59\xe6\xe7\x9e\x16\xcd\xfc\x8e\xfa\x12\x99\xbb\x07\xaa\xd7\x1c\xd0\xae\x93\x4c\xba\x16\x5d\x0c\xed\
 x1d\x02\x87\xcd\x38\x31\xc6\x10\x42\xe1\x46\x4e\xa3\xae\xb6\xda\xb6\xb0\x49\x55\x89\x57\xe6\xac\xe3\xbf\xb5\x5c\x59\x93\x0d\x21\x35\xdd\x57\x8c\x04\x15\x91\x05\x69\x4a\xdb\x5e\xcb\x4d\xa3\x5d!
>  \xa8\x7e\
>  x95\x9e\x9d\x95\x61\xc9\x1c\xdd\x66\x0a\x76\x18\xbb\x59\x6a\xa5\xc0\xf2\xb8\x2f\xa9\x4c\xa8\xb3\x2b\xa3\x8a\xbf\x5c\xe8\x18\x3d\x7f\x0e\x2f\xe9\x06\xf9\xb6\xcc\x60\xcc\x38\x6c\x9a\x78\xa7\x7c\x61",
> > 1037);
> >         getsockopt(sock_dup, IPPROTO_IP, 0x81,  (void *)0x20000bf3ul,
> > (socklen_t *)0x20003000ul);        
> >         return 0;
> > }
> > 
> > Best Regards,
> > 
> > Baozeng Ding
> 
> More likely a netfilter bug in net/bridge/netfilter/ebtables.c

+1. sctp diverted it as the option level is IPPROTO_IP and not
SOL_SCTP.

^ permalink raw reply

* Re: net/sctp: stack-out-of-bounds in sctp_getsockopt
From: Eric Dumazet @ 2016-03-22 15:27 UTC (permalink / raw)
  To: Baozeng Ding, netfilter-devel
  Cc: vyasevich, nhorman, davem, linux-sctp, netdev, linux-kernel
In-Reply-To: <1458660088.10868.19.camel@edumazet-glaptop3.roam.corp.google.com>

On Tue, 2016-03-22 at 08:21 -0700, Eric Dumazet wrote:
> On Tue, 2016-03-22 at 23:08 +0800, Baozeng Ding wrote:
> > Hi all,
> > 
> > The following program triggers an out-of-bounds bug in
> > sctp_getsockopt. The kernel version is 4.5 (on Mar 16
> > commit 09fd671ccb2475436bd5f597f751ca4a7d177aea). 
> > 
> > ==================================================================
> > BUG: KASAN: stack-out-of-bounds in string+0x1ef/0x200 at addr
> > ffff88003ae679e0
> > Read of size 1 by task syz-executor/19753
> > page:ffffea0000eb99c0 count:0 mapcount:0 mapping:          (null)
> > index:0x0
> > flags: 0x1fffc0000000000()
> > page dumped because: kasan: bad access detected
> > CPU: 3 PID: 19753 Comm: syz-executor Not tainted 4.5.0+ #8
> > Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS
> > rel-1.8.2-0-g33fbe13 by qemu-project.org 04/01/2014
> >  0000000000000003 ffff88003ae67578 ffffffff82945051 ffff88003ae67608
> >  ffff88003ae679e0 0000000000000096 dffffc0000000000 ffff88003ae675f8
> >  ffffffff81709f88 000000000000030d 0000000000000000 0000000000000286
> > Call Trace:
> >  [<     inline     >] __dump_stack lib/dump_stack.c:15
> >  [<ffffffff82945051>] dump_stack+0xb3/0x112 lib/dump_stack.c:51
> >  [<     inline     >] print_address_description mm/kasan/report.c:150
> >  [<ffffffff81709f88>] kasan_report_error+0x4f8/0x530 mm/kasan/report.c:236
> >  [<ffffffff8140785b>] ? __lock_acquire+0x15fb/0x5dd0 kernel/locking/lockdep.c:3226
> >  [<     inline     >] kasan_report mm/kasan/report.c:259
> >  [<ffffffff81709ffe>] __asan_report_load1_noabort+0x3e/0x40 mm/kasan/report.c:277
> >  [<ffffffff8296613f>] ? string+0x1ef/0x200 lib/vsprintf.c:591
> >  [<ffffffff8296613f>] string+0x1ef/0x200 lib/vsprintf.c:591
> >  [<ffffffff8296f103>] vsnprintf+0xb83/0x1900 lib/vsprintf.c:2049
> >  [<ffffffff8296e580>] ? pointer+0xab0/0xab0 lib/vsprintf.c:1584
> >  [<ffffffff813456f2>] __request_module+0x132/0x6b0 kernel/kmod.c:146
> >  [<ffffffff814056b0>] ? mark_held_locks+0xd0/0x130 kernel/locking/lockdep.c:2552
> >  [<ffffffff813455c0>] ? call_usermodehelper_setup+0x2b0/0x2b0 kernel/kmod.c:530
> >  [<ffffffff85da47b0>] ? mutex_lock_interruptible_nested+0x980/0x980
> >  [<ffffffff8168fed4>] ? __might_fault+0xe4/0x1d0 mm/memory.c:3833
> >  [<ffffffff8538f74c>] find_inlist_lock.constprop.17+0x10c/0x210 net/bridge/netfilter/ebtables.c:347
> >  [<     inline     >] find_table_lock net/bridge/netfilter/ebtables.c:356
> >  [<ffffffff853904ab>] do_ebt_get_ctl+0x13b/0x540 net/bridge/netfilter/ebtables.c:1524
> >  [<ffffffff85390370>] ? copy_everything_to_user+0x600/0x600 net/bridge/netfilter/ebtables.c:1455
> >  [<     inline     >] ? __mutex_unlock_common_slowpath kernel/locking/mutex.c:751
> >  [<ffffffff85da6799>] ? __mutex_unlock_slowpath+0x239/0x3f0 kernel/locking/mutex.c:762
> >  [<ffffffff85da6959>] ? mutex_unlock+0x9/0x10 kernel/locking/mutex.c:437
> >  [<ffffffff84dea126>] ? nf_sockopt_find+0x1a6/0x220 net/netfilter/nf_sockopt.c:87
> >  [<     inline     >] nf_sockopt net/netfilter/nf_sockopt.c:103
> >  [<ffffffff84dea20d>] nf_getsockopt+0x6d/0xc0 net/netfilter/nf_sockopt.c:121
> >  [<ffffffff84fadf05>] ip_getsockopt+0x135/0x190 net/ipv4/ip_sockglue.c:1523
> >  [<ffffffff84faddd0>] ? do_ip_getsockopt+0x1520/0x1520 net/ipv4/ip_sockglue.c:1353
> >  [<     inline     >] ? wake_up_process kernel/sched/core.c:2024
> >  [<ffffffff8138bcc2>] ? wake_up_q+0x82/0xe0 kernel/sched/core.c:416
> >  [<     inline     >] ? atomic_dec_and_test /arch/x86/include/asm/atomic.h:117
> >  [<     inline     >] ? mmdrop include/linux/sched.h:2611
> >  [<ffffffff814a3310>] ? drop_futex_key_refs.isra.13+0x70/0xe0 kernel/futex.c:444
> >  [<ffffffff8583a4dd>] sctp_getsockopt+0x18d/0x3f40 net/sctp/socket.c:5964
> >  [<ffffffff8140785b>] ? __lock_acquire+0x15fb/0x5dd0 kernel/locking/lockdep.c:3226
> >  [<ffffffff8583a350>] ? sctp_do_peeloff+0x2b0/0x2b0 net/sctp/socket.c:4434
> >  [<ffffffff81406260>] ? debug_check_no_locks_freed+0x290/0x290 kernel/locking/lockdep.c:4104
> >  [<     inline     >] ? rcu_read_unlock include/linux/rcupdate.h:922
> >  [<ffffffff817b398c>] ? __fget+0x20c/0x3b0 fs/file.c:712
> >  [<     inline     >] ? rcu_lock_release include/linux/rcupdate.h:491
> >  [<     inline     >] ? rcu_read_unlock include/linux/rcupdate.h:926
> >  [<ffffffff817b39b5>] ? __fget+0x235/0x3b0 fs/file.c:712
> >  [<ffffffff817b37c7>] ? __fget+0x47/0x3b0 fs/file.c:696
> >  [<ffffffff817b3c11>] ? __fget_light+0xa1/0x1f0 fs/file.c:759
> >  [<ffffffff84c3a695>] sock_common_getsockopt+0x95/0xd0 net/core/sock.c:2579
> >  [<     inline     >] SYSC_getsockopt net/socket.c:1783
> >  [<ffffffff84c37e12>] SyS_getsockopt+0x142/0x230 net/socket.c:1765
> >  [<ffffffff84c37cd0>] ? SyS_setsockopt+0x240/0x240 net/socket.c:1752
> >  [<ffffffff85dab922>] ? entry_SYSCALL_64_fastpath+0x5/0xc1 arch/x86/entry/entry_64.S:191
> >  [<ffffffff81003017>] ? trace_hardirqs_on_thunk+0x17/0x19 arch/x86/entry/thunk_64.S:39
> >  [<ffffffff85dab940>] entry_SYSCALL_64_fastpath+0x23/0xc1 arch/x86/entry/entry_64.S:207
> > Memory state around the buggy address:
> >  ffff88003ae67880: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
> >  ffff88003ae67900: 00 f1 f1 f1 f1 04 f4 f4 f4 f2 f2 f2 f2 00 00 00
> > >ffff88003ae67980: 00 00 00 00 00 00 00 00 00 00 00 00 f4 f3 f3 f3
> >                                                        ^
> >  ffff88003ae67a00: f3 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
> >  ffff88003ae67a80: f1 f1 f1 f1 04 f4 f4 f4 f3 f3 f3 f3 00 00 00 00
> > ==================================================================
> > 
> > #include <unistd.h>
> > #include <sys/syscall.h>
> > #include <netinet/in.h>
> > #include <string.h>
> > #include <stdint.h>
> > #include <sys/mman.h>
> > #include <sys/socket.h>
> > 
> > int main()
> > {
> >         int sock = 0;
> >         int sock_dup = 0;
> >         mmap((void *)0x20000000ul, 0x5000ul, PROT_READ|PROT_WRITE,
> > MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0);
> >         sock = socket(AF_INET, SOCK_STREAM, IPPROTO_SCTP);
> >         sock_dup = dup(sock);
> >         memcpy((void*)0x20000bf3,"\xac\x71\x93\x68\x02\xb3\xd1\x86\x52\xf1\xf0\x18\x09\x56\xc6\x98\x6f\x8e\x74\xb7\x17\xd4\x3a\x64\x51\x68\x13\x2d\x25\xba\x6d\x3f\x74\x68\x84\x89\x04\xd1\xa6\xe2\x7d\xaf\xfa\xd9\xce\x52\xbe\x6f\xb6\xe3\xff\x92\x35\xa1\x88\x4a\x68\x27\xaa\x25\xf8\xc1\xd5\x3b\xe5\x69\x11\x4f\x75\x4c\xe9\xff\x8b\x86\x53\x20\xb7\x10\xa2\x62\xcc\xc3\x06\x85\xde\x3e\x1c\x5a\x62\x3a\x2d\x0d\x0b\x0c\xb2\xac\x75\x42\x4d\x82\x3f\x7b\xf7\x28\xea\x2d\xff\x42\xa8\xdf\xb3\x49\x1a\xfd\xae\x2c\xd4\x35\x8e\x96\xb3\xe1\x0a\x92\x56\xb7\xde\xe8\x9e\xc3\x9e\x88\x79\xc4\x71\x46\x27\xf4\x9e\x85\xf4\x8f\x1f\x9a\xe5\x7e\x02\x09\x34\x80\x1e\x87\xa8\x9a\xce\xac\xfb\x43\x07\xdf\x15\xe8\x71\x9a\xa3\x80\x18\x1b\x15\xbd\x57\xb6\xc1\x73\x6e\xb1\x28\x3a\x01\xd5\x8e\x15\x85\xbd\x52\xdf\xfa\x64\xaa\x13\x
 0e\x2f\x64\x05\x11\xce\x79\x8b\xa8\x02\x29\x7f\x72\x0f\x37\x89\xb4\x54\x0b\x09\x02\x75\xc2\x8e\xd7\xcd\x7e\xfb\x4f\x72\xf1\x47\xea\xa2\x2a\xc3\xc4\xe9\x70\xfe\xa5\x80\x88\x21\x33\xcf\x13\x66\x98\x23\x10\x5c\xa4\xbd\xee\xc0\xb4\xdd\xfb\xff\xf2\x38\xab\xca\x36\x62\x35\x84\xe4\x73\x5c\xc7\x3e\x72\x2e\x17\x43\x6f\x85\x45\x4f\x82\x62\x0d\x77\xae\xcb\xe1\x8f\xe8\xf0\x84\x3e\x62\x8b\x70\x2b\x55\xb5\xa7\x13\xcf\xa1\x78\x77\x82\xe2\xb7\x1c\x65\x7f\xb5\x79\x73\x01\x07\xd1\x9f\x45\x6a\xbb\x3d\xbf\xc8\x71\x5b\x9f\x30\xc7\xb9\xb8\x53\x9f\xe1\xba\xb6\x78\x9e\x05\x75\xa3\x55\xb1\x26\x96\xa9\xb2\x82\xce\x81\x5c\x8a\x18\xb3\x4b\x0c\x18\x8c\xf2\x7c\x09\xde\xcb\xcf\x78\x22\x58\xf6\x15\xf6\xf7\x48\xda\x08\x75\xd4\xc1\x20\xc3\x18\x2e\x89\xe8\x5b\x48\xd9\xbc\x1f\xbb\xed\x31\xaf\x12\x4d\xcd\x46\x60\xa0\xef\x0e
 \x2e\x21\x1d\x2b\x68\x75\xb9\x42\x5e\xd7\xae\x35\x46\xe9\x06\x63\x1d\x3c\xd6\x9c\x14\x3b\x09\x29\x49\x70\xb9\xe1\xe0\x09\x45\x41\x62\x0c\xff\x5a\x77\xbe\x31\xa6\x03\x94\x92\xde\x41\x99\xfa\x68\x99\x74\xbb\x0a\x3d\xac\x9c\x7e\x00\x6b\xcd\xc1\x83\xa7\xc5\x63\xdd\x10\xea\x59\x27\xdc\x02\x98\xd6\x43\x20\x24\x4e\xc0\xdc\xa2\x98\xdf\x3e\xaf\x61\x35\xa0\x95\x3f\x9a\xaa\x7d\xe9\xe9\x0d\xe5\x97\x66\x1a\x9f\xbf\x56\xc8\x37\x84\x18\x2b\xd2\xcd\xd6\xb3\x19\xd8\x4a\x30\x6e\xcb\x99\x1c\xe9\x0f\xdb\xca\x30\xe1\xe2\x90\xba\xb9\x61\x00\xbf\xeb\xad\x6a\xc8\x52\xea\x1a\x92\x05\x0c\x3b\x78\x82\x01\xac\xfd\x88\x6c\xca\xe2\xfb\xe7\x0f\xcc\x75\x9c\x98\x12\x26\xcf\xa6\x80\x02\x35\xdf\x6e\xe1\x11\x1d\xa7\x30\x17\x38\x41\xd9\x81\x55\x1a\x1e\xd1\xfe\x60\xbf\xef\x09\x25\xc0\xdb\x9f\xc4\xc6\x54\x1a\x85\x36\x85\x05\x
 b3\x9f\x2c\xc5\xcd\x12\x51\xef\xbe\x10\x79\xbf\x11\x00\x47\x0d\x9c\x14\x43\x1a\x46\xea\xd1\x34\x2e\x10\x6b\xa4\x3c\x25\x21\xe3\xb9\x15\x78\x6c\x40\x87\x90\xf7\x93\x5a\x66\x5f\x0a\x76\xff\xc2\xe2\x14\x35\x88\x47\xa1\x33\x5b\x8f\x3d\xc5\x89\xb7\xf9\x8a\x40\xf0\x1e\xc9\x30\xcd\xd8\x96\x41\x78\x58\x97\x49\xc8\x50\x61\x36\x8f\x7e\x44\x41\xc0\x84\xbb\x35\xf0\x63\xa9\xc2\x2a\xbd\xcc\x4b\xab\x8b\x16\x33\xc0\x66\xbf\x47\x62\x9b\xc4\x47\x2d\x68\x83\xca\xe3\x52\x79\xd7\xe0\x61\x80\x15\xf1\x90\x83\xa2\xbb\x4c\xe5\x8b\x50\xc8\x1b\x68\x7b\xee\x57\xdc\x54\xfa\x90\xf1\xf5\xec\x7d\x93\xe0\x80\x74\x06\xbe\xac\xc8\x85\x4d\xe8\xbf\xd3\xdd\x34\x55\xc4\xbf\x2f\x24\x19\xad\x86\x1e\x69\x2b\x6c\x3f\x00\xe8\x4b\xbb\x99\xcf\x17\x99\x00\x9d\x6c\x70\x57\xcc\x35\xee\x07\x87\x25\x8c\x0c\x8b\x9b\x38\x15\xcc\x05\x6f\xf8
 \x16\x78\x0b\x41\xfa\x23\x96\xc0\x79\xf8\xb7\xf0\x2b\x60\x7e\x98\xe3\x7b\xab\x80\x1f\x0d\xbf\xf6\x7e\x37\x06\xf1\x11\x42\x38\x2a\x70\xdf\xa4\xca\xf5\xf3\xf4\x7d\xca\x10\x0c\xd5\xe2\x90\xa0\x15\xde\xc2\x61\xa2\x88\xea\x32\x37\x97\x83\xd0\x4c\xad\xe2\xae\x9b\x53\xa2\xc2\x54\x0c\xbd\xe1\x50\x3b\x15\xd4\xb1\xa9\x41\x6e\x18\x2e\x30\x3f\x91\x03\x81\x86\x8c\x5c\x1f\x76\x51\x92\xf5\xb5\xb2\xc3\x16\x01\xef\xe3\x9e\xb1\x92\x0e\x0e\xcb\x20\x7f\x10\x29\x08\x6e\x15\x3d\x1e\x7c\x70\xf5\xb5\x3c\x56\x15\x3c\x59\xe6\xe7\x9e\x16\xcd\xfc\x8e\xfa\x12\x99\xbb\x07\xaa\xd7\x1c\xd0\xae\x93\x4c\xba\x16\x5d\x0c\xed\x1d\x02\x87\xcd\x38\x31\xc6\x10\x42\xe1\x46\x4e\xa3\xae\xb6\xda\xb6\xb0\x49\x55\x89\x57\xe6\xac\xe3\xbf\xb5\x5c\x59\x93\x0d\x21\x35\xdd\x57\x8c\x04\x15\x91\x05\x69\x4a\xdb\x5e\xcb\x4d\xa3\x5d\xa8\x7e\x
 95\x9e\x9d\x95\x61\xc9\x1c\xdd\x66\x0a\x76\x18\xbb\x59\x6a\xa5\xc0\xf2\xb8\x2f\xa9\x4c\xa8\xb3\x2b\xa3\x8a\xbf\x5c\xe8\x18\x3d\x7f\x0e\x2f\xe9\x06\xf9\xb6\xcc\x60\xcc\x38\x6c\x9a\x78\xa7\x7c\x61",
> > 1037);
> >         getsockopt(sock_dup, IPPROTO_IP, 0x81,  (void *)0x20000bf3ul,
> > (socklen_t *)0x20003000ul);        
> >         return 0;
> > }
> > 
> > Best Regards,
> > 
> > Baozeng Ding
> 
> More likely a netfilter bug in net/bridge/netfilter/ebtables.c
> 

Untested patch would be :

diff --git a/net/bridge/netfilter/ebtables.c b/net/bridge/netfilter/ebtables.c
index 67b2e27999aa..fceb7354d169 100644
--- a/net/bridge/netfilter/ebtables.c
+++ b/net/bridge/netfilter/ebtables.c
@@ -346,7 +346,7 @@ find_inlist_lock(struct list_head *head, const char *name, const char *prefix,
 {
 	return try_then_request_module(
 			find_inlist_lock_noload(head, name, error, mutex),
-			"%s%s", prefix, name);
+			"%.*s%s", EBT_TABLE_MAXNAMELEN, prefix, name);
 }
 
 static inline struct ebt_table *




^ permalink raw reply related

* [PATCH v8 net-next] ravb: Add dma queue interrupt support
From: Yoshihiro Kaneko @ 2016-03-22 15:22 UTC (permalink / raw)
  To: netdev
  Cc: David S. Miller, Sergei Shtylyov, Simon Horman, Magnus Damm,
	linux-renesas-soc

From: Kazuya Mizuguchi <kazuya.mizuguchi.ks@renesas.com>

This patch supports the following interrupts.

- One interrupt for multiple (timestamp, error, gPTP)
- One interrupt for emac
- Four interrupts for dma queue (best effort rx/tx, network control rx/tx)

This patch improve efficiency of the interrupt handler by adding the
interrupt handler corresponding to each interrupt source described
above. Additionally, it reduces the number of times of the access to
EthernetAVB IF.
Also this patch prevent this driver depends on the whim of a boot loader.

[ykaneko0929@gmail.com: define bit names of registers]
[ykaneko0929@gmail.com: add comment for gen3 only registers]
[ykaneko0929@gmail.com: fix coding style]
[ykaneko0929@gmail.com: update changelog]
[ykaneko0929@gmail.com: gen3: fix initialization of interrupts]
[ykaneko0929@gmail.com: gen3: fix clearing interrupts]
[ykaneko0929@gmail.com: gen3: add helper function for request_irq()]
[ykaneko0929@gmail.com: gen3: remove IRQF_SHARED flag for request_irq()]
[ykaneko0929@gmail.com: revert ravb_close() and ravb_ptp_stop()]
[ykaneko0929@gmail.com: avoid calling free_irq() to non-hooked interrupts]
[ykaneko0929@gmail.com: make NC/BE interrupt handler a function]
[ykaneko0929@gmail.com: make timestamp interrupt handler a function]
[ykaneko0929@gmail.com: timestamp interrupt is handled in multiple
 interrupt handler instead of dma queue interrupt handler]
Signed-off-by: Kazuya Mizuguchi <kazuya.mizuguchi.ks@renesas.com>
Signed-off-by: Yoshihiro Kaneko <ykaneko0929@gmail.com>
---

This patch is based on the master branch of David Miller's next networking
tree.

v8 [Yoshihiro Kaneko]
  - rebased

v7 [Yoshihiro Kaneko]
  drivers/net/ethernet/renesas/ravb_main.c:
  - read TIS in ravb_timestamp_interrupt()
  - avoid overwriting the 'result' by a return value of ravb_ptp_interrupt()
* As suggested by Sergei Shtylyov
  drivers/net/ethernet/renesas/ravb_main.c:
  - read RIS, RIC, TIS and TIC in ravb_queue_interrupt()
  - rename ravb_rx_tx_interrupt to ravb_dma_interrupt
  - shorten argument ravb_queue of ravb_dma_interrupt()

v6 [Yoshihiro Kaneko]
* As suggested by Sergei Shtylyov
  drivers/net/ethernet/renesas/ravb_main.c:
    - rename ravb_nc_be_interrupt to ravb_queue_interrupt, change the type
       of return value to 'bool', rename ravb_queue to 'q'
    - stop use of 'for' loop for queue interrupt in ravb_interrupt()
    - fix comment for ravb_multi_interrupt()
    - rename ravb_dmaq_interrupt to ravb_rx_tx_interrupt
    - move timestamp interrupt handler into ravb_multi_interrupt()
    - make timestamp interrupt handler a funtion
    - rename out_free_irq2 label to out_free_irq_nc_tx
    - remove IRQF_SHARED flag for request_irq()
  drivers/net/ethernet/renesas/ravb_ptp.c:
    - fix coding style

v5 [Yoshihiro Kaneko]
* As suggested by Sergei Shtylyov
  drivers/net/ethernet/renesas/ravb_main.c:
    - stop copying ravb_queue parameter in ravb_dmaq_interrupt()
    - clear TFUF instead of disabling
    - factored out NC/BE interrupt handler
    - rename hook_irq() in ravb_hook_irq()
    - add calling free_irq() for the EMAC IRQ
    - stop using a loop for free_irq() to avoid calling free_irq() for
      non-hooked interrupt handlers
    - add test for failure of devm_kasprintf in ravb_hook_irq()
    - update changelog

v4 [Yoshihiro Kaneko]
* compile tested only
* As suggested by Sergei Shtylyov
  drivers/net/ethernet/renesas/ravb.h:
    - make two lines of comment into one line.
    - remove unused definition of xxx_ALL.
  drivers/net/ethernet/renesas/ravb_main.c:
    - remove unrelated change (fix indentation).
    - output warning messages when napi_schedule_prep() fails in ravb_dmaq_
      interrupt() like ravb_interrupt().
    - change the function name from req_irq to hook_irq.
    - fix programming error in hook_irq().
    - do free_irq() for rx_irqs[] and tx_irqs[] for only gen3 in out_free_
      irq label in ravb_open().

v3 [Yoshihiro Kaneko]
* compile tested only
* As suggested by Sergei Shtylyov
  - update changelog
  drivers/net/ethernet/renesas/ravb.h:
    - add comments to the additional registers like CIE
  drivers/net/ethernet/renesas/ravb_main.c:
    - fix the initialization of the interrupt in ravb_dmac_init()
    - revert ravb_error_interrupt() because gen3 code is wrong
    - change the comment "Management" in ravb_multi_interrupt()
    - add a helper function for request_irq() in ravb_open()
    - revert ravb_close() because atomicity is not necessary here
  drivers/net/ethernet/renesas/ravb_ptp.c:
    - revert ravb_ptp_stop() because atomicity is not necessary here

v2 [Yoshihiro Kaneko]
* compile tested only
* As suggested by Sergei Shtylyov
  - add comment to CIE
  - remove comments from CIE bits
  - fix value of TIx_ALL
  - define each bits for CIE, GIE, GID, RIE0, RID0, RIE2, RID2, TIE, TID
  - reversed Christmas tree declaration ordered
  - rename _ravb_emac_interrupt() to ravb_emac_interrupt_unlocked()
  - remove unnecessary clearing of CIE
  - use a bit name corresponding to the target register, RIE0, RIE2, TIE,
    TID, RID2, GID, GIE

 drivers/net/ethernet/renesas/ravb.h      | 204 ++++++++++++++++++++++++
 drivers/net/ethernet/renesas/ravb_main.c | 266 +++++++++++++++++++++++++------
 drivers/net/ethernet/renesas/ravb_ptp.c  |  17 +-
 3 files changed, 439 insertions(+), 48 deletions(-)

diff --git a/drivers/net/ethernet/renesas/ravb.h b/drivers/net/ethernet/renesas/ravb.h
index b2160d1..5c16241 100644
--- a/drivers/net/ethernet/renesas/ravb.h
+++ b/drivers/net/ethernet/renesas/ravb.h
@@ -157,6 +157,7 @@ enum ravb_reg {
 	TIC	= 0x0378,
 	TIS	= 0x037C,
 	ISS	= 0x0380,
+	CIE	= 0x0384,	/* R-Car Gen3 only */
 	GCCR	= 0x0390,
 	GMTT	= 0x0394,
 	GPTC	= 0x0398,
@@ -170,6 +171,15 @@ enum ravb_reg {
 	GCT0	= 0x03B8,
 	GCT1	= 0x03BC,
 	GCT2	= 0x03C0,
+	GIE	= 0x03CC,	/* R-Car Gen3 only */
+	GID	= 0x03D0,	/* R-Car Gen3 only */
+	DIL	= 0x0440,	/* R-Car Gen3 only */
+	RIE0	= 0x0460,	/* R-Car Gen3 only */
+	RID0	= 0x0464,	/* R-Car Gen3 only */
+	RIE2	= 0x0470,	/* R-Car Gen3 only */
+	RID2	= 0x0474,	/* R-Car Gen3 only */
+	TIE	= 0x0478,	/* R-Car Gen3 only */
+	TID	= 0x047c,	/* R-Car Gen3 only */
 
 	/* E-MAC registers */
 	ECMR	= 0x0500,
@@ -556,6 +566,16 @@ enum ISS_BIT {
 	ISS_DPS15	= 0x80000000,
 };
 
+/* CIE (R-Car Gen3 only) */
+enum CIE_BIT {
+	CIE_CRIE	= 0x00000001,
+	CIE_CTIE	= 0x00000100,
+	CIE_RQFM	= 0x00010000,
+	CIE_CL0M	= 0x00020000,
+	CIE_RFWL	= 0x00040000,
+	CIE_RFFL	= 0x00080000,
+};
+
 /* GCCR */
 enum GCCR_BIT {
 	GCCR_TCR	= 0x00000003,
@@ -592,6 +612,188 @@ enum GIS_BIT {
 	GIS_PTMF	= 0x00000004,
 };
 
+/* GIE (R-Car Gen3 only) */
+enum GIE_BIT {
+	GIE_PTCS	= 0x00000001,
+	GIE_PTOS	= 0x00000002,
+	GIE_PTMS0	= 0x00000004,
+	GIE_PTMS1	= 0x00000008,
+	GIE_PTMS2	= 0x00000010,
+	GIE_PTMS3	= 0x00000020,
+	GIE_PTMS4	= 0x00000040,
+	GIE_PTMS5	= 0x00000080,
+	GIE_PTMS6	= 0x00000100,
+	GIE_PTMS7	= 0x00000200,
+	GIE_ATCS0	= 0x00010000,
+	GIE_ATCS1	= 0x00020000,
+	GIE_ATCS2	= 0x00040000,
+	GIE_ATCS3	= 0x00080000,
+	GIE_ATCS4	= 0x00100000,
+	GIE_ATCS5	= 0x00200000,
+	GIE_ATCS6	= 0x00400000,
+	GIE_ATCS7	= 0x00800000,
+	GIE_ATCS8	= 0x01000000,
+	GIE_ATCS9	= 0x02000000,
+	GIE_ATCS10	= 0x04000000,
+	GIE_ATCS11	= 0x08000000,
+	GIE_ATCS12	= 0x10000000,
+	GIE_ATCS13	= 0x20000000,
+	GIE_ATCS14	= 0x40000000,
+	GIE_ATCS15	= 0x80000000,
+};
+
+/* GID (R-Car Gen3 only) */
+enum GID_BIT {
+	GID_PTCD	= 0x00000001,
+	GID_PTOD	= 0x00000002,
+	GID_PTMD0	= 0x00000004,
+	GID_PTMD1	= 0x00000008,
+	GID_PTMD2	= 0x00000010,
+	GID_PTMD3	= 0x00000020,
+	GID_PTMD4	= 0x00000040,
+	GID_PTMD5	= 0x00000080,
+	GID_PTMD6	= 0x00000100,
+	GID_PTMD7	= 0x00000200,
+	GID_ATCD0	= 0x00010000,
+	GID_ATCD1	= 0x00020000,
+	GID_ATCD2	= 0x00040000,
+	GID_ATCD3	= 0x00080000,
+	GID_ATCD4	= 0x00100000,
+	GID_ATCD5	= 0x00200000,
+	GID_ATCD6	= 0x00400000,
+	GID_ATCD7	= 0x00800000,
+	GID_ATCD8	= 0x01000000,
+	GID_ATCD9	= 0x02000000,
+	GID_ATCD10	= 0x04000000,
+	GID_ATCD11	= 0x08000000,
+	GID_ATCD12	= 0x10000000,
+	GID_ATCD13	= 0x20000000,
+	GID_ATCD14	= 0x40000000,
+	GID_ATCD15	= 0x80000000,
+};
+
+/* RIE0 (R-Car Gen3 only) */
+enum RIE0_BIT {
+	RIE0_FRS0	= 0x00000001,
+	RIE0_FRS1	= 0x00000002,
+	RIE0_FRS2	= 0x00000004,
+	RIE0_FRS3	= 0x00000008,
+	RIE0_FRS4	= 0x00000010,
+	RIE0_FRS5	= 0x00000020,
+	RIE0_FRS6	= 0x00000040,
+	RIE0_FRS7	= 0x00000080,
+	RIE0_FRS8	= 0x00000100,
+	RIE0_FRS9	= 0x00000200,
+	RIE0_FRS10	= 0x00000400,
+	RIE0_FRS11	= 0x00000800,
+	RIE0_FRS12	= 0x00001000,
+	RIE0_FRS13	= 0x00002000,
+	RIE0_FRS14	= 0x00004000,
+	RIE0_FRS15	= 0x00008000,
+	RIE0_FRS16	= 0x00010000,
+	RIE0_FRS17	= 0x00020000,
+};
+
+/* RID0 (R-Car Gen3 only) */
+enum RID0_BIT {
+	RID0_FRD0	= 0x00000001,
+	RID0_FRD1	= 0x00000002,
+	RID0_FRD2	= 0x00000004,
+	RID0_FRD3	= 0x00000008,
+	RID0_FRD4	= 0x00000010,
+	RID0_FRD5	= 0x00000020,
+	RID0_FRD6	= 0x00000040,
+	RID0_FRD7	= 0x00000080,
+	RID0_FRD8	= 0x00000100,
+	RID0_FRD9	= 0x00000200,
+	RID0_FRD10	= 0x00000400,
+	RID0_FRD11	= 0x00000800,
+	RID0_FRD12	= 0x00001000,
+	RID0_FRD13	= 0x00002000,
+	RID0_FRD14	= 0x00004000,
+	RID0_FRD15	= 0x00008000,
+	RID0_FRD16	= 0x00010000,
+	RID0_FRD17	= 0x00020000,
+};
+
+/* RIE2 (R-Car Gen3 only) */
+enum RIE2_BIT {
+	RIE2_QFS0	= 0x00000001,
+	RIE2_QFS1	= 0x00000002,
+	RIE2_QFS2	= 0x00000004,
+	RIE2_QFS3	= 0x00000008,
+	RIE2_QFS4	= 0x00000010,
+	RIE2_QFS5	= 0x00000020,
+	RIE2_QFS6	= 0x00000040,
+	RIE2_QFS7	= 0x00000080,
+	RIE2_QFS8	= 0x00000100,
+	RIE2_QFS9	= 0x00000200,
+	RIE2_QFS10	= 0x00000400,
+	RIE2_QFS11	= 0x00000800,
+	RIE2_QFS12	= 0x00001000,
+	RIE2_QFS13	= 0x00002000,
+	RIE2_QFS14	= 0x00004000,
+	RIE2_QFS15	= 0x00008000,
+	RIE2_QFS16	= 0x00010000,
+	RIE2_QFS17	= 0x00020000,
+	RIE2_RFFS	= 0x80000000,
+};
+
+/* RID2 (R-Car Gen3 only) */
+enum RID2_BIT {
+	RID2_QFD0	= 0x00000001,
+	RID2_QFD1	= 0x00000002,
+	RID2_QFD2	= 0x00000004,
+	RID2_QFD3	= 0x00000008,
+	RID2_QFD4	= 0x00000010,
+	RID2_QFD5	= 0x00000020,
+	RID2_QFD6	= 0x00000040,
+	RID2_QFD7	= 0x00000080,
+	RID2_QFD8	= 0x00000100,
+	RID2_QFD9	= 0x00000200,
+	RID2_QFD10	= 0x00000400,
+	RID2_QFD11	= 0x00000800,
+	RID2_QFD12	= 0x00001000,
+	RID2_QFD13	= 0x00002000,
+	RID2_QFD14	= 0x00004000,
+	RID2_QFD15	= 0x00008000,
+	RID2_QFD16	= 0x00010000,
+	RID2_QFD17	= 0x00020000,
+	RID2_RFFD	= 0x80000000,
+};
+
+/* TIE (R-Car Gen3 only) */
+enum TIE_BIT {
+	TIE_FTS0	= 0x00000001,
+	TIE_FTS1	= 0x00000002,
+	TIE_FTS2	= 0x00000004,
+	TIE_FTS3	= 0x00000008,
+	TIE_TFUS	= 0x00000100,
+	TIE_TFWS	= 0x00000200,
+	TIE_MFUS	= 0x00000400,
+	TIE_MFWS	= 0x00000800,
+	TIE_TDPS0	= 0x00010000,
+	TIE_TDPS1	= 0x00020000,
+	TIE_TDPS2	= 0x00040000,
+	TIE_TDPS3	= 0x00080000,
+};
+
+/* TID (R-Car Gen3 only) */
+enum TID_BIT {
+	TID_FTD0	= 0x00000001,
+	TID_FTD1	= 0x00000002,
+	TID_FTD2	= 0x00000004,
+	TID_FTD3	= 0x00000008,
+	TID_TFUD	= 0x00000100,
+	TID_TFWD	= 0x00000200,
+	TID_MFUD	= 0x00000400,
+	TID_MFWD	= 0x00000800,
+	TID_TDPD0	= 0x00010000,
+	TID_TDPD1	= 0x00020000,
+	TID_TDPD2	= 0x00040000,
+	TID_TDPD3	= 0x00080000,
+};
+
 /* ECMR */
 enum ECMR_BIT {
 	ECMR_PRM	= 0x00000001,
@@ -817,6 +1019,8 @@ struct ravb_private {
 	int duplex;
 	int emac_irq;
 	enum ravb_chip_id chip_id;
+	int rx_irqs[NUM_RX_QUEUE];
+	int tx_irqs[NUM_TX_QUEUE];
 
 	unsigned no_avb_link:1;
 	unsigned avb_link_active_low:1;
diff --git a/drivers/net/ethernet/renesas/ravb_main.c b/drivers/net/ethernet/renesas/ravb_main.c
index 4e1a7db..8fa8ffe 100644
--- a/drivers/net/ethernet/renesas/ravb_main.c
+++ b/drivers/net/ethernet/renesas/ravb_main.c
@@ -42,6 +42,16 @@
 		 NETIF_MSG_RX_ERR | \
 		 NETIF_MSG_TX_ERR)
 
+static const char *ravb_rx_irqs[NUM_RX_QUEUE] = {
+	"ch0", /* RAVB_BE */
+	"ch1", /* RAVB_NC */
+};
+
+static const char *ravb_tx_irqs[NUM_TX_QUEUE] = {
+	"ch18", /* RAVB_BE */
+	"ch19", /* RAVB_NC */
+};
+
 void ravb_modify(struct net_device *ndev, enum ravb_reg reg, u32 clear,
 		 u32 set)
 {
@@ -365,6 +375,7 @@ static void ravb_emac_init(struct net_device *ndev)
 /* Device init function for Ethernet AVB */
 static int ravb_dmac_init(struct net_device *ndev)
 {
+	struct ravb_private *priv = netdev_priv(ndev);
 	int error;
 
 	/* Set CONFIG mode */
@@ -401,6 +412,12 @@ static int ravb_dmac_init(struct net_device *ndev)
 	ravb_write(ndev, TCCR_TFEN, TCCR);
 
 	/* Interrupt init: */
+	if (priv->chip_id == RCAR_GEN3) {
+		/* Clear DIL.DPLx */
+		ravb_write(ndev, 0, DIL);
+		/* Set queue specific interrupt */
+		ravb_write(ndev, CIE_CRIE | CIE_CTIE | CIE_CL0M, CIE);
+	}
 	/* Frame receive */
 	ravb_write(ndev, RIC0_FRE0 | RIC0_FRE1, RIC0);
 	/* Disable FIFO full warning */
@@ -643,7 +660,7 @@ static int ravb_stop_dma(struct net_device *ndev)
 }
 
 /* E-MAC interrupt handler */
-static void ravb_emac_interrupt(struct net_device *ndev)
+static void ravb_emac_interrupt_unlocked(struct net_device *ndev)
 {
 	struct ravb_private *priv = netdev_priv(ndev);
 	u32 ecsr, psr;
@@ -669,6 +686,18 @@ static void ravb_emac_interrupt(struct net_device *ndev)
 	}
 }
 
+static irqreturn_t ravb_emac_interrupt(int irq, void *dev_id)
+{
+	struct net_device *ndev = dev_id;
+	struct ravb_private *priv = netdev_priv(ndev);
+
+	spin_lock(&priv->lock);
+	ravb_emac_interrupt_unlocked(ndev);
+	mmiowb();
+	spin_unlock(&priv->lock);
+	return IRQ_HANDLED;
+}
+
 /* Error interrupt handler */
 static void ravb_error_interrupt(struct net_device *ndev)
 {
@@ -695,6 +724,50 @@ static void ravb_error_interrupt(struct net_device *ndev)
 	}
 }
 
+static bool ravb_queue_interrupt(struct net_device *ndev, int q)
+{
+	struct ravb_private *priv = netdev_priv(ndev);
+	u32 ris0 = ravb_read(ndev, RIS0);
+	u32 ric0 = ravb_read(ndev, RIC0);
+	u32 tis  = ravb_read(ndev, TIS);
+	u32 tic  = ravb_read(ndev, TIC);
+
+	if (((ris0 & ric0) & BIT(q)) || ((tis  & tic)  & BIT(q))) {
+		if (napi_schedule_prep(&priv->napi[q])) {
+			/* Mask RX and TX interrupts */
+			if (priv->chip_id == RCAR_GEN2) {
+				ravb_write(ndev, ric0 & ~BIT(q), RIC0);
+				ravb_write(ndev, tic & ~BIT(q), TIC);
+			} else {
+				ravb_write(ndev, BIT(q), RID0);
+				ravb_write(ndev, BIT(q), TID);
+			}
+			__napi_schedule(&priv->napi[q]);
+		} else {
+			netdev_warn(ndev,
+				    "ignoring interrupt, rx status 0x%08x, rx mask 0x%08x,\n",
+				    ris0, ric0);
+			netdev_warn(ndev,
+				    "                    tx status 0x%08x, tx mask 0x%08x.\n",
+				    tis, tic);
+		}
+		return true;
+	}
+	return false;
+}
+
+static bool ravb_timestamp_interrupt(struct net_device *ndev)
+{
+	u32 tis = ravb_read(ndev, TIS);
+
+	if (tis & TIS_TFUF) {
+		ravb_write(ndev, ~TIS_TFUF, TIS);
+		ravb_get_tx_tstamp(ndev);
+		return true;
+	}
+	return false;
+}
+
 static irqreturn_t ravb_interrupt(int irq, void *dev_id)
 {
 	struct net_device *ndev = dev_id;
@@ -708,46 +781,22 @@ static irqreturn_t ravb_interrupt(int irq, void *dev_id)
 
 	/* Received and transmitted interrupts */
 	if (iss & (ISS_FRS | ISS_FTS | ISS_TFUS)) {
-		u32 ris0 = ravb_read(ndev, RIS0);
-		u32 ric0 = ravb_read(ndev, RIC0);
-		u32 tis  = ravb_read(ndev, TIS);
-		u32 tic  = ravb_read(ndev, TIC);
 		int q;
 
 		/* Timestamp updated */
-		if (tis & TIS_TFUF) {
-			ravb_write(ndev, ~TIS_TFUF, TIS);
-			ravb_get_tx_tstamp(ndev);
+		if (ravb_timestamp_interrupt(ndev))
 			result = IRQ_HANDLED;
-		}
 
 		/* Network control and best effort queue RX/TX */
 		for (q = RAVB_NC; q >= RAVB_BE; q--) {
-			if (((ris0 & ric0) & BIT(q)) ||
-			    ((tis  & tic)  & BIT(q))) {
-				if (napi_schedule_prep(&priv->napi[q])) {
-					/* Mask RX and TX interrupts */
-					ric0 &= ~BIT(q);
-					tic &= ~BIT(q);
-					ravb_write(ndev, ric0, RIC0);
-					ravb_write(ndev, tic, TIC);
-					__napi_schedule(&priv->napi[q]);
-				} else {
-					netdev_warn(ndev,
-						    "ignoring interrupt, rx status 0x%08x, rx mask 0x%08x,\n",
-						    ris0, ric0);
-					netdev_warn(ndev,
-						    "                    tx status 0x%08x, tx mask 0x%08x.\n",
-						    tis, tic);
-				}
+			if (ravb_queue_interrupt(ndev, q))
 				result = IRQ_HANDLED;
-			}
 		}
 	}
 
 	/* E-MAC status summary */
 	if (iss & ISS_MS) {
-		ravb_emac_interrupt(ndev);
+		ravb_emac_interrupt_unlocked(ndev);
 		result = IRQ_HANDLED;
 	}
 
@@ -757,6 +806,7 @@ static irqreturn_t ravb_interrupt(int irq, void *dev_id)
 		result = IRQ_HANDLED;
 	}
 
+	/* gPTP interrupt status summary */
 	if ((iss & ISS_CGIS) && ravb_ptp_interrupt(ndev) == IRQ_HANDLED)
 		result = IRQ_HANDLED;
 
@@ -765,6 +815,64 @@ static irqreturn_t ravb_interrupt(int irq, void *dev_id)
 	return result;
 }
 
+/* Timestamp/Error/gPTP interrupt handler */
+static irqreturn_t ravb_multi_interrupt(int irq, void *dev_id)
+{
+	struct net_device *ndev = dev_id;
+	struct ravb_private *priv = netdev_priv(ndev);
+	irqreturn_t result = IRQ_NONE;
+	u32 iss;
+
+	spin_lock(&priv->lock);
+	/* Get interrupt status */
+	iss = ravb_read(ndev, ISS);
+
+	/* Timestamp updated */
+	if ((iss & ISS_TFUS) && ravb_timestamp_interrupt(ndev))
+		result = IRQ_HANDLED;
+
+	/* Error status summary */
+	if (iss & ISS_ES) {
+		ravb_error_interrupt(ndev);
+		result = IRQ_HANDLED;
+	}
+
+	/* gPTP interrupt status summary */
+	if ((iss & ISS_CGIS) && ravb_ptp_interrupt(ndev) == IRQ_HANDLED)
+		result = IRQ_HANDLED;
+
+	mmiowb();
+	spin_unlock(&priv->lock);
+	return result;
+}
+
+static irqreturn_t ravb_dma_interrupt(int irq, void *dev_id, int q)
+{
+	struct net_device *ndev = dev_id;
+	struct ravb_private *priv = netdev_priv(ndev);
+	irqreturn_t result = IRQ_NONE;
+
+	spin_lock(&priv->lock);
+
+	/* Network control/Best effort queue RX/TX */
+	if (ravb_queue_interrupt(ndev, q))
+		result = IRQ_HANDLED;
+
+	mmiowb();
+	spin_unlock(&priv->lock);
+	return result;
+}
+
+static irqreturn_t ravb_be_interrupt(int irq, void *dev_id)
+{
+	return ravb_dma_interrupt(irq, dev_id, RAVB_BE);
+}
+
+static irqreturn_t ravb_nc_interrupt(int irq, void *dev_id)
+{
+	return ravb_dma_interrupt(irq, dev_id, RAVB_NC);
+}
+
 static int ravb_poll(struct napi_struct *napi, int budget)
 {
 	struct net_device *ndev = napi->dev;
@@ -804,8 +912,13 @@ static int ravb_poll(struct napi_struct *napi, int budget)
 
 	/* Re-enable RX/TX interrupts */
 	spin_lock_irqsave(&priv->lock, flags);
-	ravb_modify(ndev, RIC0, mask, mask);
-	ravb_modify(ndev, TIC,  mask, mask);
+	if (priv->chip_id == RCAR_GEN2) {
+		ravb_modify(ndev, RIC0, mask, mask);
+		ravb_modify(ndev, TIC,  mask, mask);
+	} else {
+		ravb_write(ndev, mask, RIE0);
+		ravb_write(ndev, mask, TIE);
+	}
 	mmiowb();
 	spin_unlock_irqrestore(&priv->lock, flags);
 
@@ -1208,35 +1321,72 @@ static const struct ethtool_ops ravb_ethtool_ops = {
 	.get_ts_info		= ravb_get_ts_info,
 };
 
+static inline int ravb_hook_irq(unsigned int irq, irq_handler_t handler,
+				struct net_device *ndev, struct device *dev,
+				const char *ch)
+{
+	char *name;
+	int error;
+
+	name = devm_kasprintf(dev, GFP_KERNEL, "%s:%s", ndev->name, ch);
+	if (!name)
+		return -ENOMEM;
+	error = request_irq(irq, handler, 0, name, ndev);
+	if (error)
+		netdev_err(ndev, "cannot request IRQ %s\n", name);
+
+	return error;
+}
+
 /* Network device open function for Ethernet AVB */
 static int ravb_open(struct net_device *ndev)
 {
 	struct ravb_private *priv = netdev_priv(ndev);
+	struct platform_device *pdev = priv->pdev;
+	struct device *dev = &pdev->dev;
 	int error;
 
 	napi_enable(&priv->napi[RAVB_BE]);
 	napi_enable(&priv->napi[RAVB_NC]);
 
-	error = request_irq(ndev->irq, ravb_interrupt, IRQF_SHARED, ndev->name,
-			    ndev);
-	if (error) {
-		netdev_err(ndev, "cannot request IRQ\n");
-		goto out_napi_off;
-	}
-
-	if (priv->chip_id == RCAR_GEN3) {
-		error = request_irq(priv->emac_irq, ravb_interrupt,
-				    IRQF_SHARED, ndev->name, ndev);
+	if (priv->chip_id == RCAR_GEN2) {
+		error = request_irq(ndev->irq, ravb_interrupt, IRQF_SHARED,
+				    ndev->name, ndev);
 		if (error) {
 			netdev_err(ndev, "cannot request IRQ\n");
-			goto out_free_irq;
+			goto out_napi_off;
 		}
+	} else {
+		error = ravb_hook_irq(ndev->irq, ravb_multi_interrupt, ndev,
+				      dev, "ch22:multi");
+		if (error)
+			goto out_napi_off;
+		error = ravb_hook_irq(priv->emac_irq, ravb_emac_interrupt, ndev,
+				      dev, "ch24:emac");
+		if (error)
+			goto out_free_irq;
+		error = ravb_hook_irq(priv->rx_irqs[RAVB_BE], ravb_be_interrupt,
+				      ndev, dev, "ch0:rx_be");
+		if (error)
+			goto out_free_irq_emac;
+		error = ravb_hook_irq(priv->tx_irqs[RAVB_BE], ravb_be_interrupt,
+				      ndev, dev, "ch18:tx_be");
+		if (error)
+			goto out_free_irq_be_rx;
+		error = ravb_hook_irq(priv->rx_irqs[RAVB_NC], ravb_nc_interrupt,
+				      ndev, dev, "ch1:rx_nc");
+		if (error)
+			goto out_free_irq_be_tx;
+		error = ravb_hook_irq(priv->tx_irqs[RAVB_NC], ravb_nc_interrupt,
+				      ndev, dev, "ch19:tx_nc");
+		if (error)
+			goto out_free_irq_nc_rx;
 	}
 
 	/* Device init */
 	error = ravb_dmac_init(ndev);
 	if (error)
-		goto out_free_irq2;
+		goto out_free_irq_nc_tx;
 	ravb_emac_init(ndev);
 
 	/* Initialise PTP Clock driver */
@@ -1256,9 +1406,18 @@ out_ptp_stop:
 	/* Stop PTP Clock driver */
 	if (priv->chip_id == RCAR_GEN2)
 		ravb_ptp_stop(ndev);
-out_free_irq2:
-	if (priv->chip_id == RCAR_GEN3)
-		free_irq(priv->emac_irq, ndev);
+out_free_irq_nc_tx:
+	if (priv->chip_id == RCAR_GEN2)
+		goto out_free_irq;
+	free_irq(priv->tx_irqs[RAVB_NC], ndev);
+out_free_irq_nc_rx:
+	free_irq(priv->rx_irqs[RAVB_NC], ndev);
+out_free_irq_be_tx:
+	free_irq(priv->tx_irqs[RAVB_BE], ndev);
+out_free_irq_be_rx:
+	free_irq(priv->rx_irqs[RAVB_BE], ndev);
+out_free_irq_emac:
+	free_irq(priv->emac_irq, ndev);
 out_free_irq:
 	free_irq(ndev->irq, ndev);
 out_napi_off:
@@ -1713,6 +1872,7 @@ static int ravb_probe(struct platform_device *pdev)
 	struct net_device *ndev;
 	int error, irq, q;
 	struct resource *res;
+	int i;
 
 	if (!np) {
 		dev_err(&pdev->dev,
@@ -1782,6 +1942,22 @@ static int ravb_probe(struct platform_device *pdev)
 			goto out_release;
 		}
 		priv->emac_irq = irq;
+		for (i = 0; i < NUM_RX_QUEUE; i++) {
+			irq = platform_get_irq_byname(pdev, ravb_rx_irqs[i]);
+			if (irq < 0) {
+				error = irq;
+				goto out_release;
+			}
+			priv->rx_irqs[i] = irq;
+		}
+		for (i = 0; i < NUM_TX_QUEUE; i++) {
+			irq = platform_get_irq_byname(pdev, ravb_tx_irqs[i]);
+			if (irq < 0) {
+				error = irq;
+				goto out_release;
+			}
+			priv->tx_irqs[i] = irq;
+		}
 	}
 
 	priv->chip_id = chip_id;
diff --git a/drivers/net/ethernet/renesas/ravb_ptp.c b/drivers/net/ethernet/renesas/ravb_ptp.c
index 57992cc..f1b2cbb 100644
--- a/drivers/net/ethernet/renesas/ravb_ptp.c
+++ b/drivers/net/ethernet/renesas/ravb_ptp.c
@@ -194,7 +194,12 @@ static int ravb_ptp_extts(struct ptp_clock_info *ptp,
 	priv->ptp.extts[req->index] = on;
 
 	spin_lock_irqsave(&priv->lock, flags);
-	ravb_modify(ndev, GIC, GIC_PTCE, on ? GIC_PTCE : 0);
+	if (priv->chip_id == RCAR_GEN2)
+		ravb_modify(ndev, GIC, GIC_PTCE, on ? GIC_PTCE : 0);
+	else if (on)
+		ravb_write(ndev, GIE_PTCS, GIE);
+	else
+		ravb_write(ndev, GID_PTCD, GID);
 	mmiowb();
 	spin_unlock_irqrestore(&priv->lock, flags);
 
@@ -241,7 +246,10 @@ static int ravb_ptp_perout(struct ptp_clock_info *ptp,
 		error = ravb_ptp_update_compare(priv, (u32)start_ns);
 		if (!error) {
 			/* Unmask interrupt */
-			ravb_modify(ndev, GIC, GIC_PTME, GIC_PTME);
+			if (priv->chip_id == RCAR_GEN2)
+				ravb_modify(ndev, GIC, GIC_PTME, GIC_PTME);
+			else
+				ravb_write(ndev, GIE_PTMS0, GIE);
 		}
 	} else	{
 		spin_lock_irqsave(&priv->lock, flags);
@@ -250,7 +258,10 @@ static int ravb_ptp_perout(struct ptp_clock_info *ptp,
 		perout->period = 0;
 
 		/* Mask interrupt */
-		ravb_modify(ndev, GIC, GIC_PTME, 0);
+		if (priv->chip_id == RCAR_GEN2)
+			ravb_modify(ndev, GIC, GIC_PTME, 0);
+		else
+			ravb_write(ndev, GID_PTMD0, GID);
 	}
 	mmiowb();
 	spin_unlock_irqrestore(&priv->lock, flags);
-- 
1.9.1

^ permalink raw reply related

* Re: net/sctp: stack-out-of-bounds in sctp_getsockopt
From: Eric Dumazet @ 2016-03-22 15:21 UTC (permalink / raw)
  To: Baozeng Ding; +Cc: vyasevich, nhorman, davem, linux-sctp, netdev, linux-kernel
In-Reply-To: <56f16034.890c620a.e04dc.ffffc770@mx.google.com>

On Tue, 2016-03-22 at 23:08 +0800, Baozeng Ding wrote:
> Hi all,
> 
> The following program triggers an out-of-bounds bug in
> sctp_getsockopt. The kernel version is 4.5 (on Mar 16
> commit 09fd671ccb2475436bd5f597f751ca4a7d177aea). 
> 
> ==================================================================
> BUG: KASAN: stack-out-of-bounds in string+0x1ef/0x200 at addr
> ffff88003ae679e0
> Read of size 1 by task syz-executor/19753
> page:ffffea0000eb99c0 count:0 mapcount:0 mapping:          (null)
> index:0x0
> flags: 0x1fffc0000000000()
> page dumped because: kasan: bad access detected
> CPU: 3 PID: 19753 Comm: syz-executor Not tainted 4.5.0+ #8
> Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS
> rel-1.8.2-0-g33fbe13 by qemu-project.org 04/01/2014
>  0000000000000003 ffff88003ae67578 ffffffff82945051 ffff88003ae67608
>  ffff88003ae679e0 0000000000000096 dffffc0000000000 ffff88003ae675f8
>  ffffffff81709f88 000000000000030d 0000000000000000 0000000000000286
> Call Trace:
>  [<     inline     >] __dump_stack lib/dump_stack.c:15
>  [<ffffffff82945051>] dump_stack+0xb3/0x112 lib/dump_stack.c:51
>  [<     inline     >] print_address_description mm/kasan/report.c:150
>  [<ffffffff81709f88>] kasan_report_error+0x4f8/0x530 mm/kasan/report.c:236
>  [<ffffffff8140785b>] ? __lock_acquire+0x15fb/0x5dd0 kernel/locking/lockdep.c:3226
>  [<     inline     >] kasan_report mm/kasan/report.c:259
>  [<ffffffff81709ffe>] __asan_report_load1_noabort+0x3e/0x40 mm/kasan/report.c:277
>  [<ffffffff8296613f>] ? string+0x1ef/0x200 lib/vsprintf.c:591
>  [<ffffffff8296613f>] string+0x1ef/0x200 lib/vsprintf.c:591
>  [<ffffffff8296f103>] vsnprintf+0xb83/0x1900 lib/vsprintf.c:2049
>  [<ffffffff8296e580>] ? pointer+0xab0/0xab0 lib/vsprintf.c:1584
>  [<ffffffff813456f2>] __request_module+0x132/0x6b0 kernel/kmod.c:146
>  [<ffffffff814056b0>] ? mark_held_locks+0xd0/0x130 kernel/locking/lockdep.c:2552
>  [<ffffffff813455c0>] ? call_usermodehelper_setup+0x2b0/0x2b0 kernel/kmod.c:530
>  [<ffffffff85da47b0>] ? mutex_lock_interruptible_nested+0x980/0x980
>  [<ffffffff8168fed4>] ? __might_fault+0xe4/0x1d0 mm/memory.c:3833
>  [<ffffffff8538f74c>] find_inlist_lock.constprop.17+0x10c/0x210 net/bridge/netfilter/ebtables.c:347
>  [<     inline     >] find_table_lock net/bridge/netfilter/ebtables.c:356
>  [<ffffffff853904ab>] do_ebt_get_ctl+0x13b/0x540 net/bridge/netfilter/ebtables.c:1524
>  [<ffffffff85390370>] ? copy_everything_to_user+0x600/0x600 net/bridge/netfilter/ebtables.c:1455
>  [<     inline     >] ? __mutex_unlock_common_slowpath kernel/locking/mutex.c:751
>  [<ffffffff85da6799>] ? __mutex_unlock_slowpath+0x239/0x3f0 kernel/locking/mutex.c:762
>  [<ffffffff85da6959>] ? mutex_unlock+0x9/0x10 kernel/locking/mutex.c:437
>  [<ffffffff84dea126>] ? nf_sockopt_find+0x1a6/0x220 net/netfilter/nf_sockopt.c:87
>  [<     inline     >] nf_sockopt net/netfilter/nf_sockopt.c:103
>  [<ffffffff84dea20d>] nf_getsockopt+0x6d/0xc0 net/netfilter/nf_sockopt.c:121
>  [<ffffffff84fadf05>] ip_getsockopt+0x135/0x190 net/ipv4/ip_sockglue.c:1523
>  [<ffffffff84faddd0>] ? do_ip_getsockopt+0x1520/0x1520 net/ipv4/ip_sockglue.c:1353
>  [<     inline     >] ? wake_up_process kernel/sched/core.c:2024
>  [<ffffffff8138bcc2>] ? wake_up_q+0x82/0xe0 kernel/sched/core.c:416
>  [<     inline     >] ? atomic_dec_and_test /arch/x86/include/asm/atomic.h:117
>  [<     inline     >] ? mmdrop include/linux/sched.h:2611
>  [<ffffffff814a3310>] ? drop_futex_key_refs.isra.13+0x70/0xe0 kernel/futex.c:444
>  [<ffffffff8583a4dd>] sctp_getsockopt+0x18d/0x3f40 net/sctp/socket.c:5964
>  [<ffffffff8140785b>] ? __lock_acquire+0x15fb/0x5dd0 kernel/locking/lockdep.c:3226
>  [<ffffffff8583a350>] ? sctp_do_peeloff+0x2b0/0x2b0 net/sctp/socket.c:4434
>  [<ffffffff81406260>] ? debug_check_no_locks_freed+0x290/0x290 kernel/locking/lockdep.c:4104
>  [<     inline     >] ? rcu_read_unlock include/linux/rcupdate.h:922
>  [<ffffffff817b398c>] ? __fget+0x20c/0x3b0 fs/file.c:712
>  [<     inline     >] ? rcu_lock_release include/linux/rcupdate.h:491
>  [<     inline     >] ? rcu_read_unlock include/linux/rcupdate.h:926
>  [<ffffffff817b39b5>] ? __fget+0x235/0x3b0 fs/file.c:712
>  [<ffffffff817b37c7>] ? __fget+0x47/0x3b0 fs/file.c:696
>  [<ffffffff817b3c11>] ? __fget_light+0xa1/0x1f0 fs/file.c:759
>  [<ffffffff84c3a695>] sock_common_getsockopt+0x95/0xd0 net/core/sock.c:2579
>  [<     inline     >] SYSC_getsockopt net/socket.c:1783
>  [<ffffffff84c37e12>] SyS_getsockopt+0x142/0x230 net/socket.c:1765
>  [<ffffffff84c37cd0>] ? SyS_setsockopt+0x240/0x240 net/socket.c:1752
>  [<ffffffff85dab922>] ? entry_SYSCALL_64_fastpath+0x5/0xc1 arch/x86/entry/entry_64.S:191
>  [<ffffffff81003017>] ? trace_hardirqs_on_thunk+0x17/0x19 arch/x86/entry/thunk_64.S:39
>  [<ffffffff85dab940>] entry_SYSCALL_64_fastpath+0x23/0xc1 arch/x86/entry/entry_64.S:207
> Memory state around the buggy address:
>  ffff88003ae67880: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
>  ffff88003ae67900: 00 f1 f1 f1 f1 04 f4 f4 f4 f2 f2 f2 f2 00 00 00
> >ffff88003ae67980: 00 00 00 00 00 00 00 00 00 00 00 00 f4 f3 f3 f3
>                                                        ^
>  ffff88003ae67a00: f3 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
>  ffff88003ae67a80: f1 f1 f1 f1 04 f4 f4 f4 f3 f3 f3 f3 00 00 00 00
> ==================================================================
> 
> #include <unistd.h>
> #include <sys/syscall.h>
> #include <netinet/in.h>
> #include <string.h>
> #include <stdint.h>
> #include <sys/mman.h>
> #include <sys/socket.h>
> 
> int main()
> {
>         int sock = 0;
>         int sock_dup = 0;
>         mmap((void *)0x20000000ul, 0x5000ul, PROT_READ|PROT_WRITE,
> MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0);
>         sock = socket(AF_INET, SOCK_STREAM, IPPROTO_SCTP);
>         sock_dup = dup(sock);
>         memcpy((void*)0x20000bf3,"\xac\x71\x93\x68\x02\xb3\xd1\x86\x52\xf1\xf0\x18\x09\x56\xc6\x98\x6f\x8e\x74\xb7\x17\xd4\x3a\x64\x51\x68\x13\x2d\x25\xba\x6d\x3f\x74\x68\x84\x89\x04\xd1\xa6\xe2\x7d\xaf\xfa\xd9\xce\x52\xbe\x6f\xb6\xe3\xff\x92\x35\xa1\x88\x4a\x68\x27\xaa\x25\xf8\xc1\xd5\x3b\xe5\x69\x11\x4f\x75\x4c\xe9\xff\x8b\x86\x53\x20\xb7\x10\xa2\x62\xcc\xc3\x06\x85\xde\x3e\x1c\x5a\x62\x3a\x2d\x0d\x0b\x0c\xb2\xac\x75\x42\x4d\x82\x3f\x7b\xf7\x28\xea\x2d\xff\x42\xa8\xdf\xb3\x49\x1a\xfd\xae\x2c\xd4\x35\x8e\x96\xb3\xe1\x0a\x92\x56\xb7\xde\xe8\x9e\xc3\x9e\x88\x79\xc4\x71\x46\x27\xf4\x9e\x85\xf4\x8f\x1f\x9a\xe5\x7e\x02\x09\x34\x80\x1e\x87\xa8\x9a\xce\xac\xfb\x43\x07\xdf\x15\xe8\x71\x9a\xa3\x80\x18\x1b\x15\xbd\x57\xb6\xc1\x73\x6e\xb1\x28\x3a\x01\xd5\x8e\x15\x85\xbd\x52\xdf\xfa\x64\xaa\x13\x0e
 \x2f\x64\x05\x11\xce\x79\x8b\xa8\x02\x29\x7f\x72\x0f\x37\x89\xb4\x54\x0b\x09\x02\x75\xc2\x8e\xd7\xcd\x7e\xfb\x4f\x72\xf1\x47\xea\xa2\x2a\xc3\xc4\xe9\x70\xfe\xa5\x80\x88\x21\x33\xcf\x13\x66\x98\x23\x10\x5c\xa4\xbd\xee\xc0\xb4\xdd\xfb\xff\xf2\x38\xab\xca\x36\x62\x35\x84\xe4\x73\x5c\xc7\x3e\x72\x2e\x17\x43\x6f\x85\x45\x4f\x82\x62\x0d\x77\xae\xcb\xe1\x8f\xe8\xf0\x84\x3e\x62\x8b\x70\x2b\x55\xb5\xa7\x13\xcf\xa1\x78\x77\x82\xe2\xb7\x1c\x65\x7f\xb5\x79\x73\x01\x07\xd1\x9f\x45\x6a\xbb\x3d\xbf\xc8\x71\x5b\x9f\x30\xc7\xb9\xb8\x53\x9f\xe1\xba\xb6\x78\x9e\x05\x75\xa3\x55\xb1\x26\x96\xa9\xb2\x82\xce\x81\x5c\x8a\x18\xb3\x4b\x0c\x18\x8c\xf2\x7c\x09\xde\xcb\xcf\x78\x22\x58\xf6\x15\xf6\xf7\x48\xda\x08\x75\xd4\xc1\x20\xc3\x18\x2e\x89\xe8\x5b\x48\xd9\xbc\x1f\xbb\xed\x31\xaf\x12\x4d\xcd\x46\x60\xa0\xef\x0e\x
 2e\x21\x1d\x2b\x68\x75\xb9\x42\x5e\xd7\xae\x35\x46\xe9\x06\x63\x1d\x3c\xd6\x9c\x14\x3b\x09\x29\x49\x70\xb9\xe1\xe0\x09\x45\x41\x62\x0c\xff\x5a\x77\xbe\x31\xa6\x03\x94\x92\xde\x41\x99\xfa\x68\x99\x74\xbb\x0a\x3d\xac\x9c\x7e\x00\x6b\xcd\xc1\x83\xa7\xc5\x63\xdd\x10\xea\x59\x27\xdc\x02\x98\xd6\x43\x20\x24\x4e\xc0\xdc\xa2\x98\xdf\x3e\xaf\x61\x35\xa0\x95\x3f\x9a\xaa\x7d\xe9\xe9\x0d\xe5\x97\x66\x1a\x9f\xbf\x56\xc8\x37\x84\x18\x2b\xd2\xcd\xd6\xb3\x19\xd8\x4a\x30\x6e\xcb\x99\x1c\xe9\x0f\xdb\xca\x30\xe1\xe2\x90\xba\xb9\x61\x00\xbf\xeb\xad\x6a\xc8\x52\xea\x1a\x92\x05\x0c\x3b\x78\x82\x01\xac\xfd\x88\x6c\xca\xe2\xfb\xe7\x0f\xcc\x75\x9c\x98\x12\x26\xcf\xa6\x80\x02\x35\xdf\x6e\xe1\x11\x1d\xa7\x30\x17\x38\x41\xd9\x81\x55\x1a\x1e\xd1\xfe\x60\xbf\xef\x09\x25\xc0\xdb\x9f\xc4\xc6\x54\x1a\x85\x36\x85\x05\xb3
 \x9f\x2c\xc5\xcd\x12\x51\xef\xbe\x10\x79\xbf\x11\x00\x47\x0d\x9c\x14\x43\x1a\x46\xea\xd1\x34\x2e\x10\x6b\xa4\x3c\x25\x21\xe3\xb9\x15\x78\x6c\x40\x87\x90\xf7\x93\x5a\x66\x5f\x0a\x76\xff\xc2\xe2\x14\x35\x88\x47\xa1\x33\x5b\x8f\x3d\xc5\x89\xb7\xf9\x8a\x40\xf0\x1e\xc9\x30\xcd\xd8\x96\x41\x78\x58\x97\x49\xc8\x50\x61\x36\x8f\x7e\x44\x41\xc0\x84\xbb\x35\xf0\x63\xa9\xc2\x2a\xbd\xcc\x4b\xab\x8b\x16\x33\xc0\x66\xbf\x47\x62\x9b\xc4\x47\x2d\x68\x83\xca\xe3\x52\x79\xd7\xe0\x61\x80\x15\xf1\x90\x83\xa2\xbb\x4c\xe5\x8b\x50\xc8\x1b\x68\x7b\xee\x57\xdc\x54\xfa\x90\xf1\xf5\xec\x7d\x93\xe0\x80\x74\x06\xbe\xac\xc8\x85\x4d\xe8\xbf\xd3\xdd\x34\x55\xc4\xbf\x2f\x24\x19\xad\x86\x1e\x69\x2b\x6c\x3f\x00\xe8\x4b\xbb\x99\xcf\x17\x99\x00\x9d\x6c\x70\x57\xcc\x35\xee\x07\x87\x25\x8c\x0c\x8b\x9b\x38\x15\xcc\x05\x6f\xf8\x
 16\x78\x0b\x41\xfa\x23\x96\xc0\x79\xf8\xb7\xf0\x2b\x60\x7e\x98\xe3\x7b\xab\x80\x1f\x0d\xbf\xf6\x7e\x37\x06\xf1\x11\x42\x38\x2a\x70\xdf\xa4\xca\xf5\xf3\xf4\x7d\xca\x10\x0c\xd5\xe2\x90\xa0\x15\xde\xc2\x61\xa2\x88\xea\x32\x37\x97\x83\xd0\x4c\xad\xe2\xae\x9b\x53\xa2\xc2\x54\x0c\xbd\xe1\x50\x3b\x15\xd4\xb1\xa9\x41\x6e\x18\x2e\x30\x3f\x91\x03\x81\x86\x8c\x5c\x1f\x76\x51\x92\xf5\xb5\xb2\xc3\x16\x01\xef\xe3\x9e\xb1\x92\x0e\x0e\xcb\x20\x7f\x10\x29\x08\x6e\x15\x3d\x1e\x7c\x70\xf5\xb5\x3c\x56\x15\x3c\x59\xe6\xe7\x9e\x16\xcd\xfc\x8e\xfa\x12\x99\xbb\x07\xaa\xd7\x1c\xd0\xae\x93\x4c\xba\x16\x5d\x0c\xed\x1d\x02\x87\xcd\x38\x31\xc6\x10\x42\xe1\x46\x4e\xa3\xae\xb6\xda\xb6\xb0\x49\x55\x89\x57\xe6\xac\xe3\xbf\xb5\x5c\x59\x93\x0d\x21\x35\xdd\x57\x8c\x04\x15\x91\x05\x69\x4a\xdb\x5e\xcb\x4d\xa3\x5d\xa8\x7e\x95
 \x9e\x9d\x95\x61\xc9\x1c\xdd\x66\x0a\x76\x18\xbb\x59\x6a\xa5\xc0\xf2\xb8\x2f\xa9\x4c\xa8\xb3\x2b\xa3\x8a\xbf\x5c\xe8\x18\x3d\x7f\x0e\x2f\xe9\x06\xf9\xb6\xcc\x60\xcc\x38\x6c\x9a\x78\xa7\x7c\x61",
> 1037);
>         getsockopt(sock_dup, IPPROTO_IP, 0x81,  (void *)0x20000bf3ul,
> (socklen_t *)0x20003000ul);        
>         return 0;
> }
> 
> Best Regards,
> 
> Baozeng Ding

More likely a netfilter bug in net/bridge/netfilter/ebtables.c

^ permalink raw reply

* Re: [PATCH] lan78xx: Protect runtime_auto check by #ifdef CONFIG_PM
From: Alan Stern @ 2016-03-22 15:13 UTC (permalink / raw)
  To: Oliver Neukum
  Cc: David S. Miller, Geert Uytterhoeven,
	Microchip Linux Driver Support, Woojung Huh, Rafael J. Wysocki,
	Guenter Roeck, linux-kernel, linux-pm, linux-usb, netdev
In-Reply-To: <1458656903.1990.12.camel@suse.com>

On Tue, 22 Mar 2016, Oliver Neukum wrote:

> On Tue, 2016-03-22 at 10:21 -0400, Alan Stern wrote:
> > I don't see any point in resuming the device just in order to collect 
> > operating statistics.  If it was already suspended then it wasn't 
> > operating, so there will be no statistics to collect.
> 
> Indeed. In that case the point is moot. But it is correct to ask
> the core whether the device is autosuspended at that point rather
> than keep a private flag if you can.

That's why we have pm_runtime_status_suspended().

> All that is relevant only if the upper layers ask for information
> that the driver cannot provide without resuming the device.
> Those are fundamentally different issues.

Of course.

Alan Stern


^ permalink raw reply

* net/sctp: stack-out-of-bounds in sctp_getsockopt
From: Baozeng Ding @ 2016-03-22 15:08 UTC (permalink / raw)
  To: vyasevich, nhorman, davem; +Cc: linux-sctp, netdev, linux-kernel

Hi all,

The following program triggers an out-of-bounds bug in
sctp_getsockopt. The kernel version is 4.5 (on Mar 16
commit 09fd671ccb2475436bd5f597f751ca4a7d177aea). 

==================================================================
BUG: KASAN: stack-out-of-bounds in string+0x1ef/0x200 at addr
ffff88003ae679e0
Read of size 1 by task syz-executor/19753
page:ffffea0000eb99c0 count:0 mapcount:0 mapping:          (null)
index:0x0
flags: 0x1fffc0000000000()
page dumped because: kasan: bad access detected
CPU: 3 PID: 19753 Comm: syz-executor Not tainted 4.5.0+ #8
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS
rel-1.8.2-0-g33fbe13 by qemu-project.org 04/01/2014
 0000000000000003 ffff88003ae67578 ffffffff82945051 ffff88003ae67608
 ffff88003ae679e0 0000000000000096 dffffc0000000000 ffff88003ae675f8
 ffffffff81709f88 000000000000030d 0000000000000000 0000000000000286
Call Trace:
 [<     inline     >] __dump_stack lib/dump_stack.c:15
 [<ffffffff82945051>] dump_stack+0xb3/0x112 lib/dump_stack.c:51
 [<     inline     >] print_address_description mm/kasan/report.c:150
 [<ffffffff81709f88>] kasan_report_error+0x4f8/0x530 mm/kasan/report.c:236
 [<ffffffff8140785b>] ? __lock_acquire+0x15fb/0x5dd0 kernel/locking/lockdep.c:3226
 [<     inline     >] kasan_report mm/kasan/report.c:259
 [<ffffffff81709ffe>] __asan_report_load1_noabort+0x3e/0x40 mm/kasan/report.c:277
 [<ffffffff8296613f>] ? string+0x1ef/0x200 lib/vsprintf.c:591
 [<ffffffff8296613f>] string+0x1ef/0x200 lib/vsprintf.c:591
 [<ffffffff8296f103>] vsnprintf+0xb83/0x1900 lib/vsprintf.c:2049
 [<ffffffff8296e580>] ? pointer+0xab0/0xab0 lib/vsprintf.c:1584
 [<ffffffff813456f2>] __request_module+0x132/0x6b0 kernel/kmod.c:146
 [<ffffffff814056b0>] ? mark_held_locks+0xd0/0x130 kernel/locking/lockdep.c:2552
 [<ffffffff813455c0>] ? call_usermodehelper_setup+0x2b0/0x2b0 kernel/kmod.c:530
 [<ffffffff85da47b0>] ? mutex_lock_interruptible_nested+0x980/0x980
 [<ffffffff8168fed4>] ? __might_fault+0xe4/0x1d0 mm/memory.c:3833
 [<ffffffff8538f74c>] find_inlist_lock.constprop.17+0x10c/0x210 net/bridge/netfilter/ebtables.c:347
 [<     inline     >] find_table_lock net/bridge/netfilter/ebtables.c:356
 [<ffffffff853904ab>] do_ebt_get_ctl+0x13b/0x540 net/bridge/netfilter/ebtables.c:1524
 [<ffffffff85390370>] ? copy_everything_to_user+0x600/0x600 net/bridge/netfilter/ebtables.c:1455
 [<     inline     >] ? __mutex_unlock_common_slowpath kernel/locking/mutex.c:751
 [<ffffffff85da6799>] ? __mutex_unlock_slowpath+0x239/0x3f0 kernel/locking/mutex.c:762
 [<ffffffff85da6959>] ? mutex_unlock+0x9/0x10 kernel/locking/mutex.c:437
 [<ffffffff84dea126>] ? nf_sockopt_find+0x1a6/0x220 net/netfilter/nf_sockopt.c:87
 [<     inline     >] nf_sockopt net/netfilter/nf_sockopt.c:103
 [<ffffffff84dea20d>] nf_getsockopt+0x6d/0xc0 net/netfilter/nf_sockopt.c:121
 [<ffffffff84fadf05>] ip_getsockopt+0x135/0x190 net/ipv4/ip_sockglue.c:1523
 [<ffffffff84faddd0>] ? do_ip_getsockopt+0x1520/0x1520 net/ipv4/ip_sockglue.c:1353
 [<     inline     >] ? wake_up_process kernel/sched/core.c:2024
 [<ffffffff8138bcc2>] ? wake_up_q+0x82/0xe0 kernel/sched/core.c:416
 [<     inline     >] ? atomic_dec_and_test /arch/x86/include/asm/atomic.h:117
 [<     inline     >] ? mmdrop include/linux/sched.h:2611
 [<ffffffff814a3310>] ? drop_futex_key_refs.isra.13+0x70/0xe0 kernel/futex.c:444
 [<ffffffff8583a4dd>] sctp_getsockopt+0x18d/0x3f40 net/sctp/socket.c:5964
 [<ffffffff8140785b>] ? __lock_acquire+0x15fb/0x5dd0 kernel/locking/lockdep.c:3226
 [<ffffffff8583a350>] ? sctp_do_peeloff+0x2b0/0x2b0 net/sctp/socket.c:4434
 [<ffffffff81406260>] ? debug_check_no_locks_freed+0x290/0x290 kernel/locking/lockdep.c:4104
 [<     inline     >] ? rcu_read_unlock include/linux/rcupdate.h:922
 [<ffffffff817b398c>] ? __fget+0x20c/0x3b0 fs/file.c:712
 [<     inline     >] ? rcu_lock_release include/linux/rcupdate.h:491
 [<     inline     >] ? rcu_read_unlock include/linux/rcupdate.h:926
 [<ffffffff817b39b5>] ? __fget+0x235/0x3b0 fs/file.c:712
 [<ffffffff817b37c7>] ? __fget+0x47/0x3b0 fs/file.c:696
 [<ffffffff817b3c11>] ? __fget_light+0xa1/0x1f0 fs/file.c:759
 [<ffffffff84c3a695>] sock_common_getsockopt+0x95/0xd0 net/core/sock.c:2579
 [<     inline     >] SYSC_getsockopt net/socket.c:1783
 [<ffffffff84c37e12>] SyS_getsockopt+0x142/0x230 net/socket.c:1765
 [<ffffffff84c37cd0>] ? SyS_setsockopt+0x240/0x240 net/socket.c:1752
 [<ffffffff85dab922>] ? entry_SYSCALL_64_fastpath+0x5/0xc1 arch/x86/entry/entry_64.S:191
 [<ffffffff81003017>] ? trace_hardirqs_on_thunk+0x17/0x19 arch/x86/entry/thunk_64.S:39
 [<ffffffff85dab940>] entry_SYSCALL_64_fastpath+0x23/0xc1 arch/x86/entry/entry_64.S:207
Memory state around the buggy address:
 ffff88003ae67880: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
 ffff88003ae67900: 00 f1 f1 f1 f1 04 f4 f4 f4 f2 f2 f2 f2 00 00 00
>ffff88003ae67980: 00 00 00 00 00 00 00 00 00 00 00 00 f4 f3 f3 f3
                                                       ^
 ffff88003ae67a00: f3 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
 ffff88003ae67a80: f1 f1 f1 f1 04 f4 f4 f4 f3 f3 f3 f3 00 00 00 00
==================================================================

#include <unistd.h>
#include <sys/syscall.h>
#include <netinet/in.h>
#include <string.h>
#include <stdint.h>
#include <sys/mman.h>
#include <sys/socket.h>

int main()
{
        int sock = 0;
        int sock_dup = 0;
        mmap((void *)0x20000000ul, 0x5000ul, PROT_READ|PROT_WRITE,
MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0);
        sock = socket(AF_INET, SOCK_STREAM, IPPROTO_SCTP);
        sock_dup = dup(sock);
        memcpy((void*)0x20000bf3,"\xac\x71\x93\x68\x02\xb3\xd1\x86\x52\xf1\xf0\x18\x09\x56\xc6\x98\x6f\x8e\x74\xb7\x17\xd4\x3a\x64\x51\x68\x13\x2d\x25\xba\x6d\x3f\x74\x68\x84\x89\x04\xd1\xa6\xe2\x7d\xaf\xfa\xd9\xce\x52\xbe\x6f\xb6\xe3\xff\x92\x35\xa1\x88\x4a\x68\x27\xaa\x25\xf8\xc1\xd5\x3b\xe5\x69\x11\x4f\x75\x4c\xe9\xff\x8b\x86\x53\x20\xb7\x10\xa2\x62\xcc\xc3\x06\x85\xde\x3e\x1c\x5a\x62\x3a\x2d\x0d\x0b\x0c\xb2\xac\x75\x42\x4d\x82\x3f\x7b\xf7\x28\xea\x2d\xff\x42\xa8\xdf\xb3\x49\x1a\xfd\xae\x2c\xd4\x35\x8e\x96\xb3\xe1\x0a\x92\x56\xb7\xde\xe8\x9e\xc3\x9e\x88\x79\xc4\x71\x46\x27\xf4\x9e\x85\xf4\x8f\x1f\x9a\xe5\x7e\x02\x09\x34\x80\x1e\x87\xa8\x9a\xce\xac\xfb\x43\x07\xdf\x15\xe8\x71\x9a\xa3\x80\x18\x1b\x15\xbd\x57\xb6\xc1\x73\x6e\xb1\x28\x3a\x01\xd5\x8e\x15\x85\xbd\x52\xdf\xfa\x64\xaa\x13\x0e\x
 2f\x64\x05\x11\xce\x79\x8b\xa8\x02\x29\x7f\x72\x0f\x37\x89\xb4\x54\x0b\x09\x02\x75\xc2\x8e\xd7\xcd\x7e\xfb\x4f\x72\xf1\x47\xea\xa2\x2a\xc3\xc4\xe9\x70\xfe\xa5\x80\x88\x21\x33\xcf\x13\x66\x98\x23\x10\x5c\xa4\xbd\xee\xc0\xb4\xdd\xfb\xff\xf2\x38\xab\xca\x36\x62\x35\x84\xe4\x73\x5c\xc7\x3e\x72\x2e\x17\x43\x6f\x85\x45\x4f\x82\x62\x0d\x77\xae\xcb\xe1\x8f\xe8\xf0\x84\x3e\x62\x8b\x70\x2b\x55\xb5\xa7\x13\xcf\xa1\x78\x77\x82\xe2\xb7\x1c\x65\x7f\xb5\x79\x73\x01\x07\xd1\x9f\x45\x6a\xbb\x3d\xbf\xc8\x71\x5b\x9f\x30\xc7\xb9\xb8\x53\x9f\xe1\xba\xb6\x78\x9e\x05\x75\xa3\x55\xb1\x26\x96\xa9\xb2\x82\xce\x81\x5c\x8a\x18\xb3\x4b\x0c\x18\x8c\xf2\x7c\x09\xde\xcb\xcf\x78\x22\x58\xf6\x15\xf6\xf7\x48\xda\x08\x75\xd4\xc1\x20\xc3\x18\x2e\x89\xe8\x5b\x48\xd9\xbc\x1f\xbb\xed\x31\xaf\x12\x4d\xcd\x46\x60\xa0\xef\x0e\x2e
 \x21\x1d\x2b\x68\x75\xb9\x42\x5e\xd7\xae\x35\x46\xe9\x06\x63\x1d\x3c\xd6\x9c\x14\x3b\x09\x29\x49\x70\xb9\xe1\xe0\x09\x45\x41\x62\x0c\xff\x5a\x77\xbe\x31\xa6\x03\x94\x92\xde\x41\x99\xfa\x68\x99\x74\xbb\x0a\x3d\xac\x9c\x7e\x00\x6b\xcd\xc1\x83\xa7\xc5\x63\xdd\x10\xea\x59\x27\xdc\x02\x98\xd6\x43\x20\x24\x4e\xc0\xdc\xa2\x98\xdf\x3e\xaf\x61\x35\xa0\x95\x3f\x9a\xaa\x7d\xe9\xe9\x0d\xe5\x97\x66\x1a\x9f\xbf\x56\xc8\x37\x84\x18\x2b\xd2\xcd\xd6\xb3\x19\xd8\x4a\x30\x6e\xcb\x99\x1c\xe9\x0f\xdb\xca\x30\xe1\xe2\x90\xba\xb9\x61\x00\xbf\xeb\xad\x6a\xc8\x52\xea\x1a\x92\x05\x0c\x3b\x78\x82\x01\xac\xfd\x88\x6c\xca\xe2\xfb\xe7\x0f\xcc\x75\x9c\x98\x12\x26\xcf\xa6\x80\x02\x35\xdf\x6e\xe1\x11\x1d\xa7\x30\x17\x38\x41\xd9\x81\x55\x1a\x1e\xd1\xfe\x60\xbf\xef\x09\x25\xc0\xdb\x9f\xc4\xc6\x54\x1a\x85\x36\x85\x05\xb3\x
 9f\x2c\xc5\xcd\x12\x51\xef\xbe\x10\x79\xbf\x11\x00\x47\x0d\x9c\x14\x43\x1a\x46\xea\xd1\x34\x2e\x10\x6b\xa4\x3c\x25\x21\xe3\xb9\x15\x78\x6c\x40\x87\x90\xf7\x93\x5a\x66\x5f\x0a\x76\xff\xc2\xe2\x14\x35\x88\x47\xa1\x33\x5b\x8f\x3d\xc5\x89\xb7\xf9\x8a\x40\xf0\x1e\xc9\x30\xcd\xd8\x96\x41\x78\x58\x97\x49\xc8\x50\x61\x36\x8f\x7e\x44\x41\xc0\x84\xbb\x35\xf0\x63\xa9\xc2\x2a\xbd\xcc\x4b\xab\x8b\x16\x33\xc0\x66\xbf\x47\x62\x9b\xc4\x47\x2d\x68\x83\xca\xe3\x52\x79\xd7\xe0\x61\x80\x15\xf1\x90\x83\xa2\xbb\x4c\xe5\x8b\x50\xc8\x1b\x68\x7b\xee\x57\xdc\x54\xfa\x90\xf1\xf5\xec\x7d\x93\xe0\x80\x74\x06\xbe\xac\xc8\x85\x4d\xe8\xbf\xd3\xdd\x34\x55\xc4\xbf\x2f\x24\x19\xad\x86\x1e\x69\x2b\x6c\x3f\x00\xe8\x4b\xbb\x99\xcf\x17\x99\x00\x9d\x6c\x70\x57\xcc\x35\xee\x07\x87\x25\x8c\x0c\x8b\x9b\x38\x15\xcc\x05\x6f\xf8\x16
 \x78\x0b\x41\xfa\x23\x96\xc0\x79\xf8\xb7\xf0\x2b\x60\x7e\x98\xe3\x7b\xab\x80\x1f\x0d\xbf\xf6\x7e\x37\x06\xf1\x11\x42\x38\x2a\x70\xdf\xa4\xca\xf5\xf3\xf4\x7d\xca\x10\x0c\xd5\xe2\x90\xa0\x15\xde\xc2\x61\xa2\x88\xea\x32\x37\x97\x83\xd0\x4c\xad\xe2\xae\x9b\x53\xa2\xc2\x54\x0c\xbd\xe1\x50\x3b\x15\xd4\xb1\xa9\x41\x6e\x18\x2e\x30\x3f\x91\x03\x81\x86\x8c\x5c\x1f\x76\x51\x92\xf5\xb5\xb2\xc3\x16\x01\xef\xe3\x9e\xb1\x92\x0e\x0e\xcb\x20\x7f\x10\x29\x08\x6e\x15\x3d\x1e\x7c\x70\xf5\xb5\x3c\x56\x15\x3c\x59\xe6\xe7\x9e\x16\xcd\xfc\x8e\xfa\x12\x99\xbb\x07\xaa\xd7\x1c\xd0\xae\x93\x4c\xba\x16\x5d\x0c\xed\x1d\x02\x87\xcd\x38\x31\xc6\x10\x42\xe1\x46\x4e\xa3\xae\xb6\xda\xb6\xb0\x49\x55\x89\x57\xe6\xac\xe3\xbf\xb5\x5c\x59\x93\x0d\x21\x35\xdd\x57\x8c\x04\x15\x91\x05\x69\x4a\xdb\x5e\xcb\x4d\xa3\x5d\xa8\x7e\x95\x
 9e\x9d\x95\x61\xc9\x1c\xdd\x66\x0a\x76\x18\xbb\x59\x6a\xa5\xc0\xf2\xb8\x2f\xa9\x4c\xa8\xb3\x2b\xa3\x8a\xbf\x5c\xe8\x18\x3d\x7f\x0e\x2f\xe9\x06\xf9\xb6\xcc\x60\xcc\x38\x6c\x9a\x78\xa7\x7c\x61",
1037);
        getsockopt(sock_dup, IPPROTO_IP, 0x81,  (void *)0x20000bf3ul,
(socklen_t *)0x20003000ul);        
        return 0;
}

Best Regards,

Baozeng Ding

^ 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