* RE: [PATCH net-next 06/10] net/mlx4_core: Dynamically allocate structs at mlx4_slave_cap
From: David Laight @ 2016-11-28 15:28 UTC (permalink / raw)
To: 'Tariq Toukan', David S. Miller
Cc: netdev@vger.kernel.org, Eran Ben Elisha, Tal Alon
In-Reply-To: <1480261877-19720-7-git-send-email-tariqt@mellanox.com>
From: Tariq Toukan
> Sent: 27 November 2016 15:51
> From: Eran Ben Elisha <eranbe@mellanox.com>
>
> In order to avoid temporary large structs on the stack,
> allocate them dynamically.
>
> Signed-off-by: Eran Ben Elisha <eranbe@mellanox.com>
> Signed-off-by: Tal Alon <talal@mellanox.com>
> Signed-off-by: Tariq Toukan <tariqt@mellanox.com>
> ---
> drivers/net/ethernet/mellanox/mlx4/main.c | 244 +++++++++++++++++-------------
> 1 file changed, 142 insertions(+), 102 deletions(-)
>
> diff --git a/drivers/net/ethernet/mellanox/mlx4/main.c b/drivers/net/ethernet/mellanox/mlx4/main.c
> index 4a9497e9778d..65502df9fd96 100644
> --- a/drivers/net/ethernet/mellanox/mlx4/main.c
> +++ b/drivers/net/ethernet/mellanox/mlx4/main.c
> @@ -799,40 +799,117 @@ static void slave_adjust_steering_mode(struct mlx4_dev *dev,
...
> +static int mlx4_slave_special_qp_cap(struct mlx4_dev *dev)
> +{
> + struct mlx4_func_cap *func_cap = NULL;
> + int i, err = 0;
> +
> + func_cap = kzalloc(sizeof(*func_cap), GFP_KERNEL);
> + dev->caps.qp0_qkey = kcalloc(dev->caps.num_ports,
> + sizeof(u32), GFP_KERNEL);
> + dev->caps.qp0_tunnel = kcalloc(dev->caps.num_ports,
> + sizeof(u32), GFP_KERNEL);
> + dev->caps.qp0_proxy = kcalloc(dev->caps.num_ports,
> + sizeof(u32), GFP_KERNEL);
> + dev->caps.qp1_tunnel = kcalloc(dev->caps.num_ports,
> + sizeof(u32), GFP_KERNEL);
> + dev->caps.qp1_proxy = kcalloc(dev->caps.num_ports,
> + sizeof(u32), GFP_KERNEL);
...
It has to be better to allocate a single piece of memory.
Potentially using a structure something like:
struct fubar {
struct mlx4_func_cap func_cap;
struct {
u32 qp0_qkey;
u32 qp0_tunnel;
u32 qp0_proxy;
u32 qp1_tunnel;
u32 qp1_proxy;
} port_info[];
};
David
^ permalink raw reply
* Re: [PATCH net-next] virtio-net: enable multiqueue by default
From: Neil Horman @ 2016-11-28 15:26 UTC (permalink / raw)
To: Jason Wang
Cc: virtualization, netdev, linux-kernel, Hannes Frederic Sowa,
Michael S . Tsirkin, Jeremy Eder, Marko Myllynen, Maxime Coquelin
In-Reply-To: <1480048646-17536-1-git-send-email-jasowang@redhat.com>
On Fri, Nov 25, 2016 at 12:37:26PM +0800, Jason Wang wrote:
> We use single queue even if multiqueue is enabled and let admin to
> enable it through ethtool later. This is used to avoid possible
> regression (small packet TCP stream transmission). But looks like an
> overkill since:
>
> - single queue user can disable multiqueue when launching qemu
> - brings extra troubles for the management since it needs extra admin
> tool in guest to enable multiqueue
> - multiqueue performs much better than single queue in most of the
> cases
>
> So this patch enables multiqueue by default: if #queues is less than or
> equal to #vcpu, enable as much as queue pairs; if #queues is greater
> than #vcpu, enable #vcpu queue pairs.
>
> Cc: Hannes Frederic Sowa <hannes@redhat.com>
> Cc: Michael S. Tsirkin <mst@redhat.com>
> Cc: Neil Horman <nhorman@redhat.com>
> Cc: Jeremy Eder <jeder@redhat.com>
> Cc: Marko Myllynen <myllynen@redhat.com>
> Cc: Maxime Coquelin <maxime.coquelin@redhat.com>
> Signed-off-by: Jason Wang <jasowang@redhat.com>
> ---
> drivers/net/virtio_net.c | 9 +++++++--
> 1 file changed, 7 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
> index d4ac7a6..a21d93a 100644
> --- a/drivers/net/virtio_net.c
> +++ b/drivers/net/virtio_net.c
> @@ -1886,8 +1886,11 @@ static int virtnet_probe(struct virtio_device *vdev)
> if (vi->any_header_sg)
> dev->needed_headroom = vi->hdr_len;
>
> - /* Use single tx/rx queue pair as default */
> - vi->curr_queue_pairs = 1;
> + /* Enable multiqueue by default */
> + if (num_online_cpus() >= max_queue_pairs)
> + vi->curr_queue_pairs = max_queue_pairs;
> + else
> + vi->curr_queue_pairs = num_online_cpus();
> vi->max_queue_pairs = max_queue_pairs;
>
> /* Allocate/initialize the rx/tx queues, and invoke find_vqs */
> @@ -1918,6 +1921,8 @@ static int virtnet_probe(struct virtio_device *vdev)
> goto free_unregister_netdev;
> }
>
> + virtnet_set_affinity(vi);
> +
> /* Assume link up if device can't report link status,
> otherwise get link status from config. */
> if (virtio_has_feature(vi->vdev, VIRTIO_NET_F_STATUS)) {
> --
> 2.7.4
>
Acked-by: Neil Horman <nhorman@tuxdriver.com>
^ permalink raw reply
* Re: [PATCH] cpsw: ethtool: add support for nway reset
From: Yegor Yefremov @ 2016-11-28 15:25 UTC (permalink / raw)
To: netdev
Cc: linux-omap@vger.kernel.org, Grygorii Strashko, N, Mugunthan V,
David Miller, Yegor Yefremov
In-Reply-To: <1480326472-5849-1-git-send-email-yegorslists@googlemail.com>
On Mon, Nov 28, 2016 at 10:47 AM, <yegorslists@googlemail.com> wrote:
> From: Yegor Yefremov <yegorslists@googlemail.com>
>
> This patch adds support for ethtool's '-r' command. Restarting
> N-WAY negotiation can be useful to activate newly changed EEE
> settings etc.
>
> Signed-off-by: Yegor Yefremov <yegorslists@googlemail.com>
This patch applies on top of
http://marc.info/?l=linux-netdev&m=148032251729251&w=2
Yegor
^ permalink raw reply
* Re: [PATCH] stmmac: reduce code duplication getting basic descriptors
From: kbuild test robot @ 2016-11-28 15:25 UTC (permalink / raw)
To: Pavel Machek
Cc: kbuild-all, David Miller, Andrew Morton, alexandre.torgue,
peppe.cavallaro, netdev, linux-kernel
In-Reply-To: <20161128121736.GD15034@amd>
[-- Attachment #1: Type: text/plain, Size: 1828 bytes --]
Hi Pavel,
[auto build test WARNING on net-next/master]
[also build test WARNING on v4.9-rc7 next-20161128]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]
url: https://github.com/0day-ci/linux/commits/Pavel-Machek/stmmac-reduce-code-duplication-getting-basic-descriptors/20161128-204339
config: x86_64-randconfig-s1-11282147 (attached as .config)
compiler: gcc-4.4 (Debian 4.4.7-8) 4.4.7
reproduce:
# save the attached .config to linux build tree
make ARCH=x86_64
All warnings (new ones prefixed by >>):
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c: In function 'dma_free_tx_skbufs':
>> drivers/net/ethernet/stmicro/stmmac/stmmac_main.c:1137: warning: unused variable 'p'
drivers/net/ethernet/stmicro/stmmac/stmmac_main.o: warning: objtool: stmmac_resume()+0x125: function has unreachable instruction
vim +/p +1137 drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
1121 return ret;
1122 }
1123
1124 static void dma_free_rx_skbufs(struct stmmac_priv *priv)
1125 {
1126 int i;
1127
1128 for (i = 0; i < DMA_RX_SIZE; i++)
1129 stmmac_free_rx_buffers(priv, i);
1130 }
1131
1132 static void dma_free_tx_skbufs(struct stmmac_priv *priv)
1133 {
1134 int i;
1135
1136 for (i = 0; i < DMA_TX_SIZE; i++) {
> 1137 struct dma_desc *p = stmmac_tx_desc(priv, i);
1138
1139 if (priv->tx_skbuff_dma[i].buf) {
1140 if (priv->tx_skbuff_dma[i].map_as_page)
1141 dma_unmap_page(priv->device,
1142 priv->tx_skbuff_dma[i].buf,
1143 priv->tx_skbuff_dma[i].len,
1144 DMA_TO_DEVICE);
1145 else
---
0-DAY kernel test infrastructure Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all Intel Corporation
[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 31122 bytes --]
^ permalink raw reply
* Re: [PATCH net-next] virtio-net: enable multiqueue by default
From: Neil Horman @ 2016-11-28 15:25 UTC (permalink / raw)
To: Michael S. Tsirkin
Cc: Jason Wang, virtualization, netdev, linux-kernel,
Hannes Frederic Sowa, Jeremy Eder, Marko Myllynen,
Maxime Coquelin
In-Reply-To: <20161125064201-mutt-send-email-mst@kernel.org>
On Fri, Nov 25, 2016 at 06:43:08AM +0200, Michael S. Tsirkin wrote:
> On Fri, Nov 25, 2016 at 12:37:26PM +0800, Jason Wang wrote:
> > We use single queue even if multiqueue is enabled and let admin to
> > enable it through ethtool later. This is used to avoid possible
> > regression (small packet TCP stream transmission). But looks like an
> > overkill since:
> >
> > - single queue user can disable multiqueue when launching qemu
> > - brings extra troubles for the management since it needs extra admin
> > tool in guest to enable multiqueue
> > - multiqueue performs much better than single queue in most of the
> > cases
> >
> > So this patch enables multiqueue by default: if #queues is less than or
> > equal to #vcpu, enable as much as queue pairs; if #queues is greater
> > than #vcpu, enable #vcpu queue pairs.
> >
> > Cc: Hannes Frederic Sowa <hannes@redhat.com>
> > Cc: Michael S. Tsirkin <mst@redhat.com>
> > Cc: Neil Horman <nhorman@redhat.com>
> > Cc: Jeremy Eder <jeder@redhat.com>
> > Cc: Marko Myllynen <myllynen@redhat.com>
> > Cc: Maxime Coquelin <maxime.coquelin@redhat.com>
> > Signed-off-by: Jason Wang <jasowang@redhat.com>
>
> OK at some level but all uses of num_online_cpus()
> like this are racy versus hotplug.
> I know we already have this bug but shouldn't we fix it
> before we add more?
>
Isn't the fix orthogonal to this use though? That is to say, you shoudl
register a hotplug notifier first, and use the handler to adjust the number of
queues on hotplug add/remove?
Neil
>
> > ---
> > drivers/net/virtio_net.c | 9 +++++++--
> > 1 file changed, 7 insertions(+), 2 deletions(-)
> >
> > diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
> > index d4ac7a6..a21d93a 100644
> > --- a/drivers/net/virtio_net.c
> > +++ b/drivers/net/virtio_net.c
> > @@ -1886,8 +1886,11 @@ static int virtnet_probe(struct virtio_device *vdev)
> > if (vi->any_header_sg)
> > dev->needed_headroom = vi->hdr_len;
> >
> > - /* Use single tx/rx queue pair as default */
> > - vi->curr_queue_pairs = 1;
> > + /* Enable multiqueue by default */
> > + if (num_online_cpus() >= max_queue_pairs)
> > + vi->curr_queue_pairs = max_queue_pairs;
> > + else
> > + vi->curr_queue_pairs = num_online_cpus();
> > vi->max_queue_pairs = max_queue_pairs;
> >
> > /* Allocate/initialize the rx/tx queues, and invoke find_vqs */
> > @@ -1918,6 +1921,8 @@ static int virtnet_probe(struct virtio_device *vdev)
> > goto free_unregister_netdev;
> > }
> >
> > + virtnet_set_affinity(vi);
> > +
> > /* Assume link up if device can't report link status,
> > otherwise get link status from config. */
> > if (virtio_has_feature(vi->vdev, VIRTIO_NET_F_STATUS)) {
> > --
> > 2.7.4
^ permalink raw reply
* Re: [PATCH net] net/dccp: fix use-after-free in dccp_invalid_packet
From: Eric Dumazet @ 2016-11-28 15:20 UTC (permalink / raw)
To: Arnaldo Carvalho de Melo, Alexander Duyck
Cc: Arnaldo Carvalho de Melo, Andrey Konovalov, Gerrit Renker,
David S. Miller, dccp, netdev, LKML, Dmitry Vyukov,
Kostya Serebryany, Eric Dumazet, syzkaller
In-Reply-To: <20161128150518.GA17913@kernel.org>
On Mon, 2016-11-28 at 12:05 -0300, Arnaldo Carvalho de Melo wrote:
> Em Mon, Nov 28, 2016 at 06:47:14AM -0800, Eric Dumazet escreveu:
> > On Mon, 2016-11-28 at 11:40 -0300, Arnaldo Carvalho de Melo wrote:
> > > Em Mon, Nov 28, 2016 at 06:26:49AM -0800, Eric Dumazet escreveu:
> > > > From: Eric Dumazet <edumazet@google.com>
> > > >
> > > > pskb_may_pull() can reallocate skb->head, we need to reload dh pointer
> > > > in dccp_invalid_packet() or risk use after free.
> > > >
> > > > Bug found by Andrey Konovalov using syzkaller.
> > > >
> > > > Signed-off-by: Eric Dumazet <edumazet@google.com>
> > > > Reported-by: Andrey Konovalov <andreyknvl@google.com>
> > >
> > > Acked-by: Arnaldo Carvalho de Melo <acme@redhat.com>
> > >
> > > I was about to send exactly this patch, and while looking at it I think
> > > the patch below needs to go in as well, no? To follow the advice of that
> > > Warning line there :-)
> > >
> > > From: Arnaldo Carvalho de Melo <acme@redhat.com>
> > >
> > > pskb_may_pull() can reallocate skb->head, so we can't access
> > > iph->frag_off or risk use after free, save it to a variable and us that
> > > later.
> > >
> > > Cc: Andrey Konovalov <andreyknvl@google.com>
> > > Cc: Eric Dumazet <edumazet@google.com>
> > > Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
> > >
> > > diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c
> > > index 5ddf5cda07f4..9462070561a3 100644
> > > --- a/net/ipv4/af_inet.c
> > > +++ b/net/ipv4/af_inet.c
> > > @@ -1198,6 +1198,7 @@ struct sk_buff *inet_gso_segment(struct sk_buff *skb,
> > > struct iphdr *iph;
> > > int proto, tot_len;
> > > int nhoff;
> > > + u16 frag_off;
> > > int ihl;
> > > int id;
> > >
> > > @@ -1213,6 +1214,7 @@ struct sk_buff *inet_gso_segment(struct sk_buff *skb,
> > >
> > > id = ntohs(iph->id);
> > > proto = iph->protocol;
> > > + frag_off = iph->frag_off;
> > >
> > > /* Warning: after this point, iph might be no longer valid */
> > > if (unlikely(!pskb_may_pull(skb, ihl)))
> > > @@ -1233,7 +1235,7 @@ struct sk_buff *inet_gso_segment(struct sk_buff *skb,
> > > fixedid = !!(skb_shinfo(skb)->gso_type & SKB_GSO_TCP_FIXEDID);
> > >
> > > /* fixed ID is invalid if DF bit is not set */
> > > - if (fixedid && !(iph->frag_off & htons(IP_DF)))
> > > + if (fixedid && !(frag_off & htons(IP_DF)))
> > > goto out;
> > > }
> > >
> >
> >
> > I do not see why this patch would be needed ?
>
> Where is iph being reloaded after that pskb_may_pull() and thus at line 1236 we
> could use after free? The warning at line 1217?
>
> 1209 iph = ip_hdr(skb);
> 1210 ihl = iph->ihl * 4;
> 1211 if (ihl < sizeof(*iph))
> 1212 goto out;
> 1213
> 1214 id = ntohs(iph->id);
> 1215 proto = iph->protocol;
> 1216
> 1217 /* Warning: after this point, iph might be no longer valid */
> 1218 if (unlikely(!pskb_may_pull(skb, ihl)))
> 1219 goto out;
> 1220 __skb_pull(skb, ihl);
> 1221
> 1222 encap = SKB_GSO_CB(skb)->encap_level > 0;
> 1223 if (encap)
> 1224 features &= skb->dev->hw_enc_features;
> 1225 SKB_GSO_CB(skb)->encap_level += ihl;
> 1226
> 1227 skb_reset_transport_header(skb);
> 1228
> 1229 segs = ERR_PTR(-EPROTONOSUPPORT);
> 1230
> 1231 if (!skb->encapsulation || encap) {
> 1232 udpfrag = !!(skb_shinfo(skb)->gso_type & SKB_GSO_UDP);
> 1233 fixedid = !!(skb_shinfo(skb)->gso_type & SKB_GSO_TCP_FIXEDID);
> 1234
> 1235 /* fixed ID is invalid if DF bit is not set */
> 1236 if (fixedid && !(iph->frag_off & htons(IP_DF)))
> 1237 goto out;
> 1238 }
>
Arg, I was looking at an old tree.
Please then add
Fixes: cbc53e08a793b ("GSO: Add GSO type for fixed IPv4 ID")
To ease stable backports.
Also, it looks comments are not read, we might kill this one and reload
iph.
( Saving 3 fields is now more expensive than simply reloading iph )
Thanks.
^ permalink raw reply
* Re: [patch net] sched: cls_flower: remove from hashtable only in case skip sw flag is not set
From: Amir Vadai" @ 2016-11-28 15:16 UTC (permalink / raw)
To: Jiri Pirko; +Cc: netdev, davem, jhs, idosch, eladr, ogerlitz, hadarh
In-Reply-To: <1480344013-4812-1-git-send-email-jiri@resnulli.us>
On Mon, Nov 28, 2016 at 03:40:13PM +0100, Jiri Pirko wrote:
> From: Jiri Pirko <jiri@mellanox.com>
>
> Be symmetric to hashtable insert and remove filter from hashtable only
> in case skip sw flag is not set.
>
> Fixes: e69985c67c33 ("net/sched: cls_flower: Introduce support in SKIP SW flag")
> Signed-off-by: Jiri Pirko <jiri@mellanox.com>
> ---
Reviewed-by: Amir Vadai <amir@vadai.me>
^ permalink raw reply
* Re: net/sctp: vmalloc allocation failure in sctp_setsockopt/xt_alloc_table_info
From: Marcelo Ricardo Leitner @ 2016-11-28 15:13 UTC (permalink / raw)
To: Neil Horman
Cc: Andrey Konovalov, Vlad Yasevich, linux-sctp, netdev, LKML,
Pablo Neira Ayuso, Patrick McHardy, Jozsef Kadlecsik,
David S. Miller, netfilter-devel, coreteam, Dmitry Vyukov,
Kostya Serebryany, Eric Dumazet, syzkaller
In-Reply-To: <20161128143931.GB29839@hmsreliant.think-freely.org>
On Mon, Nov 28, 2016 at 09:39:31AM -0500, Neil Horman wrote:
> On Mon, Nov 28, 2016 at 03:33:40PM +0100, Andrey Konovalov wrote:
> > On Mon, Nov 28, 2016 at 3:13 PM, Neil Horman <nhorman@tuxdriver.com> wrote:
> > > On Mon, Nov 28, 2016 at 02:00:19PM +0100, Andrey Konovalov wrote:
> > >> Hi!
> > >>
> > >> I've got the following error report while running the syzkaller fuzzer.
> > >>
> > >> On commit d8e435f3ab6fea2ea324dce72b51dd7761747523 (Nov 26).
> > >>
> > >> A reproducer is attached.
> > >>
> > >> a.out: vmalloc: allocation failure, allocated 823562240 of 1427091456
> > >> bytes, mode:0x24000c2(GFP_KERNEL|__GFP_HIGHMEM)
> > >>
> > > How much total ram do you have in this system? The call appears to be
> > > attempting to allocate 1.3 Gb of data. Even using vmalloc to allow
> > > discontiguous allocation, thats alot of memory, and if enough is in use already,
> > > I could make the argument that this might be expected behavior.
> >
> > Hi Neail,
> >
> > I have 2 Gb.
> >
> That would be why. Allocating 65% of the available system memory will almost
> certainly lead to OOM failures quickly.
>
> > Just tested with 4 Gb, everything seems to be working fine.
> > So I guess this is not actually a bug and allocating 1.3 Gb is OK.
Still we probably should avoid the warn triggered by an userspace
application: (untested)
--8<--
diff --git a/net/netfilter/x_tables.c b/net/netfilter/x_tables.c
index fc4977456c30..b56a0e128fc3 100644
--- a/net/netfilter/x_tables.c
+++ b/net/netfilter/x_tables.c
@@ -958,7 +958,8 @@ struct xt_table_info *xt_alloc_table_info(unsigned int size)
if (sz <= (PAGE_SIZE << PAGE_ALLOC_COSTLY_ORDER))
info = kmalloc(sz, GFP_KERNEL | __GFP_NOWARN | __GFP_NORETRY);
if (!info) {
- info = vmalloc(sz);
+ info = __vmalloc(sz, GFP_KERNEL | __GFP_NOWARN | __GFP_HIGHMEM,
+ PAGE_KERNEL);
if (!info)
return NULL;
}
^ permalink raw reply related
* Re: [PATCH net] net/dccp: fix use-after-free in dccp_invalid_packet
From: Arnaldo Carvalho de Melo @ 2016-11-28 15:05 UTC (permalink / raw)
To: Eric Dumazet
Cc: Arnaldo Carvalho de Melo, Andrey Konovalov, Gerrit Renker,
David S. Miller, dccp, netdev, LKML, Dmitry Vyukov,
Kostya Serebryany, Eric Dumazet, syzkaller
In-Reply-To: <1480344434.18162.51.camel@edumazet-glaptop3.roam.corp.google.com>
Em Mon, Nov 28, 2016 at 06:47:14AM -0800, Eric Dumazet escreveu:
> On Mon, 2016-11-28 at 11:40 -0300, Arnaldo Carvalho de Melo wrote:
> > Em Mon, Nov 28, 2016 at 06:26:49AM -0800, Eric Dumazet escreveu:
> > > From: Eric Dumazet <edumazet@google.com>
> > >
> > > pskb_may_pull() can reallocate skb->head, we need to reload dh pointer
> > > in dccp_invalid_packet() or risk use after free.
> > >
> > > Bug found by Andrey Konovalov using syzkaller.
> > >
> > > Signed-off-by: Eric Dumazet <edumazet@google.com>
> > > Reported-by: Andrey Konovalov <andreyknvl@google.com>
> >
> > Acked-by: Arnaldo Carvalho de Melo <acme@redhat.com>
> >
> > I was about to send exactly this patch, and while looking at it I think
> > the patch below needs to go in as well, no? To follow the advice of that
> > Warning line there :-)
> >
> > From: Arnaldo Carvalho de Melo <acme@redhat.com>
> >
> > pskb_may_pull() can reallocate skb->head, so we can't access
> > iph->frag_off or risk use after free, save it to a variable and us that
> > later.
> >
> > Cc: Andrey Konovalov <andreyknvl@google.com>
> > Cc: Eric Dumazet <edumazet@google.com>
> > Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
> >
> > diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c
> > index 5ddf5cda07f4..9462070561a3 100644
> > --- a/net/ipv4/af_inet.c
> > +++ b/net/ipv4/af_inet.c
> > @@ -1198,6 +1198,7 @@ struct sk_buff *inet_gso_segment(struct sk_buff *skb,
> > struct iphdr *iph;
> > int proto, tot_len;
> > int nhoff;
> > + u16 frag_off;
> > int ihl;
> > int id;
> >
> > @@ -1213,6 +1214,7 @@ struct sk_buff *inet_gso_segment(struct sk_buff *skb,
> >
> > id = ntohs(iph->id);
> > proto = iph->protocol;
> > + frag_off = iph->frag_off;
> >
> > /* Warning: after this point, iph might be no longer valid */
> > if (unlikely(!pskb_may_pull(skb, ihl)))
> > @@ -1233,7 +1235,7 @@ struct sk_buff *inet_gso_segment(struct sk_buff *skb,
> > fixedid = !!(skb_shinfo(skb)->gso_type & SKB_GSO_TCP_FIXEDID);
> >
> > /* fixed ID is invalid if DF bit is not set */
> > - if (fixedid && !(iph->frag_off & htons(IP_DF)))
> > + if (fixedid && !(frag_off & htons(IP_DF)))
> > goto out;
> > }
> >
>
>
> I do not see why this patch would be needed ?
Where is iph being reloaded after that pskb_may_pull() and thus at line 1236 we
could use after free? The warning at line 1217?
1209 iph = ip_hdr(skb);
1210 ihl = iph->ihl * 4;
1211 if (ihl < sizeof(*iph))
1212 goto out;
1213
1214 id = ntohs(iph->id);
1215 proto = iph->protocol;
1216
1217 /* Warning: after this point, iph might be no longer valid */
1218 if (unlikely(!pskb_may_pull(skb, ihl)))
1219 goto out;
1220 __skb_pull(skb, ihl);
1221
1222 encap = SKB_GSO_CB(skb)->encap_level > 0;
1223 if (encap)
1224 features &= skb->dev->hw_enc_features;
1225 SKB_GSO_CB(skb)->encap_level += ihl;
1226
1227 skb_reset_transport_header(skb);
1228
1229 segs = ERR_PTR(-EPROTONOSUPPORT);
1230
1231 if (!skb->encapsulation || encap) {
1232 udpfrag = !!(skb_shinfo(skb)->gso_type & SKB_GSO_UDP);
1233 fixedid = !!(skb_shinfo(skb)->gso_type & SKB_GSO_TCP_FIXEDID);
1234
1235 /* fixed ID is invalid if DF bit is not set */
1236 if (fixedid && !(iph->frag_off & htons(IP_DF)))
1237 goto out;
1238 }
^ permalink raw reply
* Re: stmmac ethernet in kernel 4.4: coalescing related pauses?
From: David Miller @ 2016-11-28 14:54 UTC (permalink / raw)
To: lsanfil; +Cc: pavel, peppe.cavallaro, netdev, linux-kernel
In-Reply-To: <f14255ee-7fa8-afef-23ec-fc4f9a74eec8@marvell.com>
From: Lino Sanfilippo <lsanfil@marvell.com>
Date: Mon, 28 Nov 2016 14:07:51 +0100
> Calling skb_orphan() in the xmit handler made this issue disappear.
This is not the way to handle this problem.
The solution is to free the SKBs in a timely manner after the
chip has transmitted the frame.
^ permalink raw reply
* Re: [PATCH net] net/dccp: fix use-after-free in dccp_invalid_packet
From: Eric Dumazet @ 2016-11-28 14:47 UTC (permalink / raw)
To: Arnaldo Carvalho de Melo
Cc: Andrey Konovalov, Gerrit Renker, David S. Miller, dccp, netdev,
LKML, Dmitry Vyukov, Kostya Serebryany, Eric Dumazet, syzkaller
In-Reply-To: <20161128144001.GE16426@kernel.org>
On Mon, 2016-11-28 at 11:40 -0300, Arnaldo Carvalho de Melo wrote:
> Em Mon, Nov 28, 2016 at 06:26:49AM -0800, Eric Dumazet escreveu:
> > From: Eric Dumazet <edumazet@google.com>
> >
> > pskb_may_pull() can reallocate skb->head, we need to reload dh pointer
> > in dccp_invalid_packet() or risk use after free.
> >
> > Bug found by Andrey Konovalov using syzkaller.
> >
> > Signed-off-by: Eric Dumazet <edumazet@google.com>
> > Reported-by: Andrey Konovalov <andreyknvl@google.com>
>
> Acked-by: Arnaldo Carvalho de Melo <acme@redhat.com>
>
> I was about to send exactly this patch, and while looking at it I think
> the patch below needs to go in as well, no? To follow the advice of that
> Warning line there :-)
>
> From: Arnaldo Carvalho de Melo <acme@redhat.com>
>
> pskb_may_pull() can reallocate skb->head, so we can't access
> iph->frag_off or risk use after free, save it to a variable and us that
> later.
>
> Cc: Andrey Konovalov <andreyknvl@google.com>
> Cc: Eric Dumazet <edumazet@google.com>
> Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
>
> diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c
> index 5ddf5cda07f4..9462070561a3 100644
> --- a/net/ipv4/af_inet.c
> +++ b/net/ipv4/af_inet.c
> @@ -1198,6 +1198,7 @@ struct sk_buff *inet_gso_segment(struct sk_buff *skb,
> struct iphdr *iph;
> int proto, tot_len;
> int nhoff;
> + u16 frag_off;
> int ihl;
> int id;
>
> @@ -1213,6 +1214,7 @@ struct sk_buff *inet_gso_segment(struct sk_buff *skb,
>
> id = ntohs(iph->id);
> proto = iph->protocol;
> + frag_off = iph->frag_off;
>
> /* Warning: after this point, iph might be no longer valid */
> if (unlikely(!pskb_may_pull(skb, ihl)))
> @@ -1233,7 +1235,7 @@ struct sk_buff *inet_gso_segment(struct sk_buff *skb,
> fixedid = !!(skb_shinfo(skb)->gso_type & SKB_GSO_TCP_FIXEDID);
>
> /* fixed ID is invalid if DF bit is not set */
> - if (fixedid && !(iph->frag_off & htons(IP_DF)))
> + if (fixedid && !(frag_off & htons(IP_DF)))
> goto out;
> }
>
I do not see why this patch would be needed ?
^ permalink raw reply
* [patch net] sched: cls_flower: remove from hashtable only in case skip sw flag is not set
From: Jiri Pirko @ 2016-11-28 14:40 UTC (permalink / raw)
To: netdev; +Cc: davem, jhs, idosch, eladr, ogerlitz, hadarh, amir
From: Jiri Pirko <jiri@mellanox.com>
Be symmetric to hashtable insert and remove filter from hashtable only
in case skip sw flag is not set.
Fixes: e69985c67c33 ("net/sched: cls_flower: Introduce support in SKIP SW flag")
Signed-off-by: Jiri Pirko <jiri@mellanox.com>
---
net/sched/cls_flower.c | 10 ++++++----
1 file changed, 6 insertions(+), 4 deletions(-)
diff --git a/net/sched/cls_flower.c b/net/sched/cls_flower.c
index f6f40fb..641c44c 100644
--- a/net/sched/cls_flower.c
+++ b/net/sched/cls_flower.c
@@ -711,8 +711,9 @@ static int fl_change(struct net *net, struct sk_buff *in_skb,
goto errout;
if (fold) {
- rhashtable_remove_fast(&head->ht, &fold->ht_node,
- head->ht_params);
+ if (!tc_skip_sw(fold->flags))
+ rhashtable_remove_fast(&head->ht, &fold->ht_node,
+ head->ht_params);
fl_hw_destroy_filter(tp, (unsigned long)fold);
}
@@ -739,8 +740,9 @@ static int fl_delete(struct tcf_proto *tp, unsigned long arg)
struct cls_fl_head *head = rtnl_dereference(tp->root);
struct cls_fl_filter *f = (struct cls_fl_filter *) arg;
- rhashtable_remove_fast(&head->ht, &f->ht_node,
- head->ht_params);
+ if (!tc_skip_sw(f->flags))
+ rhashtable_remove_fast(&head->ht, &f->ht_node,
+ head->ht_params);
list_del_rcu(&f->list);
fl_hw_destroy_filter(tp, (unsigned long)f);
tcf_unbind_filter(tp, &f->res);
--
2.7.4
^ permalink raw reply related
* Re: [PATCH net] net/dccp: fix use-after-free in dccp_invalid_packet
From: Arnaldo Carvalho de Melo @ 2016-11-28 14:40 UTC (permalink / raw)
To: Eric Dumazet
Cc: Andrey Konovalov, Gerrit Renker, David S. Miller, dccp, netdev,
LKML, Dmitry Vyukov, Kostya Serebryany, Eric Dumazet, syzkaller
In-Reply-To: <1480343209.18162.50.camel@edumazet-glaptop3.roam.corp.google.com>
Em Mon, Nov 28, 2016 at 06:26:49AM -0800, Eric Dumazet escreveu:
> From: Eric Dumazet <edumazet@google.com>
>
> pskb_may_pull() can reallocate skb->head, we need to reload dh pointer
> in dccp_invalid_packet() or risk use after free.
>
> Bug found by Andrey Konovalov using syzkaller.
>
> Signed-off-by: Eric Dumazet <edumazet@google.com>
> Reported-by: Andrey Konovalov <andreyknvl@google.com>
Acked-by: Arnaldo Carvalho de Melo <acme@redhat.com>
I was about to send exactly this patch, and while looking at it I think
the patch below needs to go in as well, no? To follow the advice of that
Warning line there :-)
From: Arnaldo Carvalho de Melo <acme@redhat.com>
pskb_may_pull() can reallocate skb->head, so we can't access
iph->frag_off or risk use after free, save it to a variable and us that
later.
Cc: Andrey Konovalov <andreyknvl@google.com>
Cc: Eric Dumazet <edumazet@google.com>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c
index 5ddf5cda07f4..9462070561a3 100644
--- a/net/ipv4/af_inet.c
+++ b/net/ipv4/af_inet.c
@@ -1198,6 +1198,7 @@ struct sk_buff *inet_gso_segment(struct sk_buff *skb,
struct iphdr *iph;
int proto, tot_len;
int nhoff;
+ u16 frag_off;
int ihl;
int id;
@@ -1213,6 +1214,7 @@ struct sk_buff *inet_gso_segment(struct sk_buff *skb,
id = ntohs(iph->id);
proto = iph->protocol;
+ frag_off = iph->frag_off;
/* Warning: after this point, iph might be no longer valid */
if (unlikely(!pskb_may_pull(skb, ihl)))
@@ -1233,7 +1235,7 @@ struct sk_buff *inet_gso_segment(struct sk_buff *skb,
fixedid = !!(skb_shinfo(skb)->gso_type & SKB_GSO_TCP_FIXEDID);
/* fixed ID is invalid if DF bit is not set */
- if (fixedid && !(iph->frag_off & htons(IP_DF)))
+ if (fixedid && !(frag_off & htons(IP_DF)))
goto out;
}
^ permalink raw reply related
* Re: net/sctp: vmalloc allocation failure in sctp_setsockopt/xt_alloc_table_info
From: Neil Horman @ 2016-11-28 14:39 UTC (permalink / raw)
To: Andrey Konovalov
Cc: Vlad Yasevich, linux-sctp, netdev, LKML, Pablo Neira Ayuso,
Patrick McHardy, Jozsef Kadlecsik, David S. Miller,
netfilter-devel, coreteam, Dmitry Vyukov, Kostya Serebryany,
Eric Dumazet, syzkaller
In-Reply-To: <CAAeHK+xJmwF6hddS-sO-y3HQkRicwQN=ZceFWTZT2M_0h4E2hQ@mail.gmail.com>
On Mon, Nov 28, 2016 at 03:33:40PM +0100, Andrey Konovalov wrote:
> On Mon, Nov 28, 2016 at 3:13 PM, Neil Horman <nhorman@tuxdriver.com> wrote:
> > On Mon, Nov 28, 2016 at 02:00:19PM +0100, Andrey Konovalov wrote:
> >> Hi!
> >>
> >> I've got the following error report while running the syzkaller fuzzer.
> >>
> >> On commit d8e435f3ab6fea2ea324dce72b51dd7761747523 (Nov 26).
> >>
> >> A reproducer is attached.
> >>
> >> a.out: vmalloc: allocation failure, allocated 823562240 of 1427091456
> >> bytes, mode:0x24000c2(GFP_KERNEL|__GFP_HIGHMEM)
> >>
> > How much total ram do you have in this system? The call appears to be
> > attempting to allocate 1.3 Gb of data. Even using vmalloc to allow
> > discontiguous allocation, thats alot of memory, and if enough is in use already,
> > I could make the argument that this might be expected behavior.
>
> Hi Neail,
>
> I have 2 Gb.
>
That would be why. Allocating 65% of the available system memory will almost
certainly lead to OOM failures quickly.
> Just tested with 4 Gb, everything seems to be working fine.
> So I guess this is not actually a bug and allocating 1.3 Gb is OK.
>
> Thanks!
>
No problem.
Neil
> >
> > Neil
> >
> >> oom_reaper: reaped process 3810 (a.out), now anon-rss:0kB,
> >> file-rss:0kB, shmem-rss:0kB
> >> a.out invoked oom-killer:
> >> gfp_mask=0x24002c2(GFP_KERNEL|__GFP_HIGHMEM|__GFP_NOWARN), nodemask=0,
> >> order=0, oom_score_adj=0
> >> a.out cpuset=/ mems_allowed=0
> >> CPU: 0 PID: 3814 Comm: a.out Not tainted 4.9.0-rc6+ #457
> >> Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Bochs 01/01/2011
> >> ffff880068667380 ffffffff81c73b14 ffff880068667710 ffff88006b469018
> >> ffff880068667718 0000000000000000 ffff880068667400 ffffffff81641a87
> >> 0000000000000000 0000000000000000 0000000000000297 ffffffff84d37280
> >> Call Trace:
> >> [< inline >] __dump_stack lib/dump_stack.c:15
> >> [<ffffffff81c73b14>] dump_stack+0xb3/0x10f lib/dump_stack.c:51
> >> [<ffffffff81641a87>] dump_header.isra.21+0x16f/0x5f5 mm/oom_kill.c:416
> >> [<ffffffff8154bad8>] oom_kill_process+0x4d8/0xab0 mm/oom_kill.c:835
> >> [<ffffffff8154c77c>] out_of_memory+0x2dc/0x1790 mm/oom_kill.c:1044
> >> [< inline >] __alloc_pages_may_oom mm/page_alloc.c:3086
> >> [<ffffffff8155afb6>] __alloc_pages_slowpath+0x1886/0x1bf0 mm/page_alloc.c:3683
> >> [<ffffffff8155b8e2>] __alloc_pages_nodemask+0x5c2/0x710 mm/page_alloc.c:3781
> >> [<ffffffff816236a4>] alloc_pages_current+0xf4/0x400 mm/mempolicy.c:2072
> >> [< inline >] alloc_pages ./include/linux/gfp.h:469
> >> [< inline >] __vmalloc_area_node mm/vmalloc.c:1631
> >> [<ffffffff815f8eab>] __vmalloc_node_range+0x33b/0x690 mm/vmalloc.c:1691
> >> [< inline >] __vmalloc_node mm/vmalloc.c:1734
> >> [< inline >] __vmalloc_node_flags mm/vmalloc.c:1748
> >> [<ffffffff815f92cb>] vmalloc+0x5b/0x70 mm/vmalloc.c:1763
> >> [<ffffffff82fd0893>] xt_alloc_table_info+0x83/0x120
> >> net/netfilter/x_tables.c:961
> >> [< inline >] do_replace net/ipv4/netfilter/ip_tables.c:1140
> >> [<ffffffff8335b420>] do_ipt_set_ctl+0x210/0x420
> >> net/ipv4/netfilter/ip_tables.c:1687
> >> [< inline >] nf_sockopt net/netfilter/nf_sockopt.c:105
> >> [<ffffffff82efdab7>] nf_setsockopt+0x67/0xc0 net/netfilter/nf_sockopt.c:114
> >> [<ffffffff831be741>] ip_setsockopt+0xa1/0xb0 net/ipv4/ip_sockglue.c:1231
> >> [<ffffffff832700d5>] udp_setsockopt+0x45/0x80 net/ipv4/udp.c:2085
> >> [<ffffffff8346b31f>] ipv6_setsockopt+0x11f/0x140 net/ipv6/ipv6_sockglue.c:892
> >> [<ffffffff83a6cd5d>] sctp_setsockopt+0x15d/0x3d70 net/sctp/socket.c:3788
> >> [<ffffffff82ca40e6>] sock_common_setsockopt+0x96/0xd0 net/core/sock.c:2690
> >> [< inline >] SYSC_setsockopt net/socket.c:1757
> >> [<ffffffff82ca10c4>] SyS_setsockopt+0x154/0x240 net/socket.c:1736
> >> [<ffffffff840f2c41>] entry_SYSCALL_64_fastpath+0x1f/0xc2
> >> arch/x86/entry/entry_64.S:209
> >> CPU: 1 PID: 3810 Comm: a.out Not tainted 4.9.0-rc6+ #457
> >> Mem-Info:
> >> active_anon:1938 inactive_anon:75 isolated_anon:0
> >> active_file:14 inactive_file:30 isolated_file:4
> >> unevictable:0 dirty:0 writeback:0 unstable:0
> >> slab_reclaimable:3316 slab_unreclaimable:9767
> >> mapped:21 shmem:81 pagetables:309 bounce:0
> >> free:1 free_pcp:75 free_cma:0
> >> Node 0 active_anon:7752kB inactive_anon:300kB active_file:56kB
> >> inactive_file:120kB unevictable:0kB isolated(anon):0kB
> >> isolated(file):16kB mapped:84kB dirty:0kB writeback:0kB shmem:324kB
> >> writeback_tmp:0kB unstable:0kB pages_scanned:134 all_unreclaimable? no
> >> Node 0 DMA free:4kB min:48kB low:60kB high:72kB active_anon:0kB
> >> inactive_anon:0kB active_file:0kB inactive_file:0kB unevictable:0kB
> >> writepending:0kB present:15992kB managed:15908kB mlocked:0kB
> >> slab_reclaimable:0kB slab_unreclaimable:8kB kernel_stack:0kB
> >> pagetables:0kB bounce:0kB free_pcp:0kB local_pcp:0kB free_cma:0kB
> >> lowmem_reserve[]: 0 1641 1641 1641
> >> Node 0 DMA32 free:0kB min:5156kB low:6836kB high:8516kB
> >> active_anon:7752kB inactive_anon:300kB active_file:56kB
> >> inactive_file:120kB unevictable:0kB writepending:0kB present:2080760kB
> >> managed:1684640kB mlocked:0kB slab_reclaimable:13264kB
> >> slab_unreclaimable:39060kB kernel_stack:2944kB pagetables:1236kB
> >> bounce:0kB free_pcp:300kB local_pcp:120kB free_cma:0kB
> >> lowmem_reserve[]: 0 0 0 0
> >> Node 0 DMA: 0*4kB 0*8kB 0*16kB 0*32kB 0*64kB 0*128kB 0*256kB 0*512kB
> >> 0*1024kB 0*2048kB 0*4096kB = 0kB
> >> Node 0 DMA32: 0*4kB 0*8kB 0*16kB 0*32kB 0*64kB 0*128kB 0*256kB 0*512kB
> >> 0*1024kB 0*2048kB 0*4096kB = 0kB
> >> Node 0 hugepages_total=0 hugepages_free=0 hugepages_surp=0 hugepages_size=2048kB
> >> 148 total pagecache pages
> >> 0 pages in swap cache
> >> Swap cache stats: add 0, delete 0, find 0/0
> >> Free swap = 0kB
> >> Total swap = 0kB
> >> 524188 pages RAM
> >> 0 pages HighMem/MovableOnly
> >> 99051 pages reserved
> >> [ pid ] uid tgid total_vm rss nr_ptes nr_pmds swapents
> >> oom_score_adj name
> >> 0 1767 5346 133 16 3 0 -1000 udevd
> >> 0 1876 5315 122 15 3 0 -1000 udevd
> >> 0 1877 5315 122 15 3 0 -1000 udevd
> >> 0 3541 2493 573 8 3 0 0 dhclient
> >> 0 3676 13231 171 22 3 0 0 rsyslogd
> >> 0 3725 4725 52 15 3 0 0 cron
> >> 0 3751 12490 155 28 3 0 -1000 sshd
> >> 0 3775 3694 43 13 3 0 0 getty
> >> 0 3776 3694 43 13 3 0 0 getty
> >> 0 3777 3694 42 13 3 0 0 getty
> >> 0 3778 3694 41 13 3 0 0 getty
> >> 0 3779 3694 44 13 3 0 0 getty
> >> 0 3780 3694 43 13 3 0 0 getty
> >> 0 3785 3649 44 12 3 0 0 getty
> >> 0 3797 17818 205 39 3 0 0 sshd
> >> 0 3800 4474 126 15 3 0 0 bash
> >> 0 3804 2053 22 9 3 0 0 a.out
> >> 0 3805 2053 26 9 3 0 0 a.out
> >> 0 3806 18488 0 18 3 0 0 a.out
> >
> >> // autogenerated by syzkaller (http://github.com/google/syzkaller)
> >>
> >> #ifndef __NR_mmap
> >> #define __NR_mmap 9
> >> #endif
> >> #ifndef __NR_setsockopt
> >> #define __NR_setsockopt 54
> >> #endif
> >> #ifndef __NR_syz_fuse_mount
> >> #define __NR_syz_fuse_mount 1000004
> >> #endif
> >> #ifndef __NR_socket
> >> #define __NR_socket 41
> >> #endif
> >> #ifndef __NR_syz_emit_ethernet
> >> #define __NR_syz_emit_ethernet 1000006
> >> #endif
> >> #ifndef __NR_syz_fuseblk_mount
> >> #define __NR_syz_fuseblk_mount 1000005
> >> #endif
> >> #ifndef __NR_syz_open_dev
> >> #define __NR_syz_open_dev 1000002
> >> #endif
> >> #ifndef __NR_syz_open_pts
> >> #define __NR_syz_open_pts 1000003
> >> #endif
> >> #ifndef __NR_syz_test
> >> #define __NR_syz_test 1000001
> >> #endif
> >>
> >> #define SYZ_SANDBOX_NONE 1
> >> #define SYZ_REPEAT 1
> >>
> >> #define _GNU_SOURCE
> >>
> >> #include <sys/ioctl.h>
> >> #include <sys/mount.h>
> >> #include <sys/prctl.h>
> >> #include <sys/resource.h>
> >> #include <sys/socket.h>
> >> #include <sys/stat.h>
> >> #include <sys/syscall.h>
> >> #include <sys/time.h>
> >> #include <sys/types.h>
> >> #include <sys/wait.h>
> >>
> >> #include <linux/capability.h>
> >> #include <linux/if.h>
> >> #include <linux/if_tun.h>
> >> #include <linux/sched.h>
> >> #include <net/if_arp.h>
> >>
> >> #include <assert.h>
> >> #include <dirent.h>
> >> #include <errno.h>
> >> #include <fcntl.h>
> >> #include <grp.h>
> >> #include <pthread.h>
> >> #include <setjmp.h>
> >> #include <signal.h>
> >> #include <stdarg.h>
> >> #include <stddef.h>
> >> #include <stdint.h>
> >> #include <stdio.h>
> >> #include <stdlib.h>
> >> #include <string.h>
> >> #include <unistd.h>
> >>
> >> const int kFailStatus = 67;
> >> const int kErrorStatus = 68;
> >> const int kRetryStatus = 69;
> >>
> >> __attribute__((noreturn)) void fail(const char* msg, ...)
> >> {
> >> int e = errno;
> >> fflush(stdout);
> >> va_list args;
> >> va_start(args, msg);
> >> vfprintf(stderr, msg, args);
> >> va_end(args);
> >> fprintf(stderr, " (errno %d)\n", e);
> >> exit(kFailStatus);
> >> }
> >>
> >> __attribute__((noreturn)) void exitf(const char* msg, ...)
> >> {
> >> int e = errno;
> >> fflush(stdout);
> >> va_list args;
> >> va_start(args, msg);
> >> vfprintf(stderr, msg, args);
> >> va_end(args);
> >> fprintf(stderr, " (errno %d)\n", e);
> >> exit(kRetryStatus);
> >> }
> >>
> >> static int flag_debug;
> >>
> >> void debug(const char* msg, ...)
> >> {
> >> if (!flag_debug)
> >> return;
> >> va_list args;
> >> va_start(args, msg);
> >> vfprintf(stdout, msg, args);
> >> va_end(args);
> >> fflush(stdout);
> >> }
> >>
> >> __thread int skip_segv;
> >> __thread jmp_buf segv_env;
> >>
> >> static void segv_handler(int sig, siginfo_t* info, void* uctx)
> >> {
> >> if (__atomic_load_n(&skip_segv, __ATOMIC_RELAXED))
> >> _longjmp(segv_env, 1);
> >> exit(sig);
> >> }
> >>
> >> static void install_segv_handler()
> >> {
> >> struct sigaction sa;
> >> memset(&sa, 0, sizeof(sa));
> >> sa.sa_sigaction = segv_handler;
> >> sa.sa_flags = SA_NODEFER | SA_SIGINFO;
> >> sigaction(SIGSEGV, &sa, NULL);
> >> sigaction(SIGBUS, &sa, NULL);
> >> }
> >>
> >> #define NONFAILING(...) \
> >> { \
> >> __atomic_fetch_add(&skip_segv, 1, __ATOMIC_SEQ_CST); \
> >> if (_setjmp(segv_env) == 0) { \
> >> __VA_ARGS__; \
> >> } \
> >> __atomic_fetch_sub(&skip_segv, 1, __ATOMIC_SEQ_CST); \
> >> }
> >>
> >> static uintptr_t syz_open_dev(uintptr_t a0, uintptr_t a1, uintptr_t a2)
> >> {
> >> if (a0 == 0xc || a0 == 0xb) {
> >> char buf[128];
> >> sprintf(buf, "/dev/%s/%d:%d", a0 == 0xc ? "char" : "block",
> >> (uint8_t)a1, (uint8_t)a2);
> >> return open(buf, O_RDWR, 0);
> >> } else {
> >> char buf[1024];
> >> char* hash;
> >> strncpy(buf, (char*)a0, sizeof(buf));
> >> buf[sizeof(buf) - 1] = 0;
> >> while ((hash = strchr(buf, '#'))) {
> >> *hash = '0' + (char)(a1 % 10);
> >> a1 /= 10;
> >> }
> >> return open(buf, a2, 0);
> >> }
> >> }
> >>
> >> static uintptr_t syz_open_pts(uintptr_t a0, uintptr_t a1)
> >> {
> >> int ptyno = 0;
> >> if (ioctl(a0, TIOCGPTN, &ptyno))
> >> return -1;
> >> char buf[128];
> >> sprintf(buf, "/dev/pts/%d", ptyno);
> >> return open(buf, a1, 0);
> >> }
> >>
> >> static uintptr_t syz_fuse_mount(uintptr_t a0, uintptr_t a1,
> >> uintptr_t a2, uintptr_t a3,
> >> uintptr_t a4, uintptr_t a5)
> >> {
> >> uint64_t target = a0;
> >> uint64_t mode = a1;
> >> uint64_t uid = a2;
> >> uint64_t gid = a3;
> >> uint64_t maxread = a4;
> >> uint64_t flags = a5;
> >>
> >> int fd = open("/dev/fuse", O_RDWR);
> >> if (fd == -1)
> >> return fd;
> >> char buf[1024];
> >> sprintf(buf, "fd=%d,user_id=%ld,group_id=%ld,rootmode=0%o", fd,
> >> (long)uid, (long)gid, (unsigned)mode & ~3u);
> >> if (maxread != 0)
> >> sprintf(buf + strlen(buf), ",max_read=%ld", (long)maxread);
> >> if (mode & 1)
> >> strcat(buf, ",default_permissions");
> >> if (mode & 2)
> >> strcat(buf, ",allow_other");
> >> syscall(SYS_mount, "", target, "fuse", flags, buf);
> >> return fd;
> >> }
> >>
> >> static uintptr_t syz_fuseblk_mount(uintptr_t a0, uintptr_t a1,
> >> uintptr_t a2, uintptr_t a3,
> >> uintptr_t a4, uintptr_t a5,
> >> uintptr_t a6, uintptr_t a7)
> >> {
> >> uint64_t target = a0;
> >> uint64_t blkdev = a1;
> >> uint64_t mode = a2;
> >> uint64_t uid = a3;
> >> uint64_t gid = a4;
> >> uint64_t maxread = a5;
> >> uint64_t blksize = a6;
> >> uint64_t flags = a7;
> >>
> >> int fd = open("/dev/fuse", O_RDWR);
> >> if (fd == -1)
> >> return fd;
> >> if (syscall(SYS_mknodat, AT_FDCWD, blkdev, S_IFBLK, makedev(7, 199)))
> >> return fd;
> >> char buf[256];
> >> sprintf(buf, "fd=%d,user_id=%ld,group_id=%ld,rootmode=0%o", fd,
> >> (long)uid, (long)gid, (unsigned)mode & ~3u);
> >> if (maxread != 0)
> >> sprintf(buf + strlen(buf), ",max_read=%ld", (long)maxread);
> >> if (blksize != 0)
> >> sprintf(buf + strlen(buf), ",blksize=%ld", (long)blksize);
> >> if (mode & 1)
> >> strcat(buf, ",default_permissions");
> >> if (mode & 2)
> >> strcat(buf, ",allow_other");
> >> syscall(SYS_mount, blkdev, target, "fuseblk", flags, buf);
> >> return fd;
> >> }
> >>
> >> static uintptr_t execute_syscall(int nr, uintptr_t a0, uintptr_t a1,
> >> uintptr_t a2, uintptr_t a3,
> >> uintptr_t a4, uintptr_t a5,
> >> uintptr_t a6, uintptr_t a7,
> >> uintptr_t a8)
> >> {
> >> switch (nr) {
> >> default:
> >> return syscall(nr, a0, a1, a2, a3, a4, a5);
> >> case __NR_syz_test:
> >> return 0;
> >> case __NR_syz_open_dev:
> >> return syz_open_dev(a0, a1, a2);
> >> case __NR_syz_open_pts:
> >> return syz_open_pts(a0, a1);
> >> case __NR_syz_fuse_mount:
> >> return syz_fuse_mount(a0, a1, a2, a3, a4, a5);
> >> case __NR_syz_fuseblk_mount:
> >> return syz_fuseblk_mount(a0, a1, a2, a3, a4, a5, a6, a7);
> >> }
> >> }
> >>
> >> static void setup_main_process()
> >> {
> >> struct sigaction sa;
> >> memset(&sa, 0, sizeof(sa));
> >> sa.sa_handler = SIG_IGN;
> >> syscall(SYS_rt_sigaction, 0x20, &sa, NULL, 8);
> >> syscall(SYS_rt_sigaction, 0x21, &sa, NULL, 8);
> >> install_segv_handler();
> >>
> >> char tmpdir_template[] = "./syzkaller.XXXXXX";
> >> char* tmpdir = mkdtemp(tmpdir_template);
> >> if (!tmpdir)
> >> fail("failed to mkdtemp");
> >> if (chmod(tmpdir, 0777))
> >> fail("failed to chmod");
> >> if (chdir(tmpdir))
> >> fail("failed to chdir");
> >> }
> >>
> >> static void loop();
> >>
> >> static void sandbox_common()
> >> {
> >> prctl(PR_SET_PDEATHSIG, SIGKILL, 0, 0, 0);
> >> setpgrp();
> >> setsid();
> >>
> >> struct rlimit rlim;
> >> rlim.rlim_cur = rlim.rlim_max = 128 << 20;
> >> setrlimit(RLIMIT_AS, &rlim);
> >> rlim.rlim_cur = rlim.rlim_max = 1 << 20;
> >> setrlimit(RLIMIT_FSIZE, &rlim);
> >> rlim.rlim_cur = rlim.rlim_max = 1 << 20;
> >> setrlimit(RLIMIT_STACK, &rlim);
> >> rlim.rlim_cur = rlim.rlim_max = 0;
> >> setrlimit(RLIMIT_CORE, &rlim);
> >>
> >> unshare(CLONE_NEWNS);
> >> unshare(CLONE_NEWIPC);
> >> unshare(CLONE_IO);
> >> }
> >>
> >> static int do_sandbox_none()
> >> {
> >> int pid = fork();
> >> if (pid)
> >> return pid;
> >> sandbox_common();
> >> loop();
> >> exit(1);
> >> }
> >>
> >> static void remove_dir(const char* dir)
> >> {
> >> DIR* dp;
> >> struct dirent* ep;
> >> int iter = 0;
> >> int i;
> >> retry:
> >> dp = opendir(dir);
> >> if (dp == NULL) {
> >> if (errno == EMFILE) {
> >> exitf("opendir(%s) failed due to NOFILE, exiting");
> >> }
> >> exitf("opendir(%s) failed", dir);
> >> }
> >> while ((ep = readdir(dp))) {
> >> if (strcmp(ep->d_name, ".") == 0 || strcmp(ep->d_name, "..") == 0)
> >> continue;
> >> char filename[FILENAME_MAX];
> >> snprintf(filename, sizeof(filename), "%s/%s", dir, ep->d_name);
> >> struct stat st;
> >> if (lstat(filename, &st))
> >> exitf("lstat(%s) failed", filename);
> >> if (S_ISDIR(st.st_mode)) {
> >> remove_dir(filename);
> >> continue;
> >> }
> >> for (i = 0;; i++) {
> >> debug("unlink(%s)\n", filename);
> >> if (unlink(filename) == 0)
> >> break;
> >> if (errno == EROFS) {
> >> debug("ignoring EROFS\n");
> >> break;
> >> }
> >> if (errno != EBUSY || i > 100)
> >> exitf("unlink(%s) failed", filename);
> >> debug("umount(%s)\n", filename);
> >> if (umount2(filename, MNT_DETACH))
> >> exitf("umount(%s) failed", filename);
> >> }
> >> }
> >> closedir(dp);
> >> for (i = 0;; i++) {
> >> debug("rmdir(%s)\n", dir);
> >> if (rmdir(dir) == 0)
> >> break;
> >> if (i < 100) {
> >> if (errno == EROFS) {
> >> debug("ignoring EROFS\n");
> >> break;
> >> }
> >> if (errno == EBUSY) {
> >> debug("umount(%s)\n", dir);
> >> if (umount2(dir, MNT_DETACH))
> >> exitf("umount(%s) failed", dir);
> >> continue;
> >> }
> >> if (errno == ENOTEMPTY) {
> >> if (iter < 100) {
> >> iter++;
> >> goto retry;
> >> }
> >> }
> >> }
> >> exitf("rmdir(%s) failed", dir);
> >> }
> >> }
> >>
> >> static uint64_t current_time_ms()
> >> {
> >> struct timespec ts;
> >>
> >> if (clock_gettime(CLOCK_MONOTONIC, &ts))
> >> fail("clock_gettime failed");
> >> return (uint64_t)ts.tv_sec * 1000 + (uint64_t)ts.tv_nsec / 1000000;
> >> }
> >>
> >> static void test();
> >>
> >> void loop()
> >> {
> >> int iter;
> >> for (iter = 0;; iter++) {
> >> char cwdbuf[256];
> >> sprintf(cwdbuf, "./%d", iter);
> >> if (mkdir(cwdbuf, 0777))
> >> fail("failed to mkdir");
> >> int pid = fork();
> >> if (pid < 0)
> >> fail("clone failed");
> >> if (pid == 0) {
> >> prctl(PR_SET_PDEATHSIG, SIGKILL, 0, 0, 0);
> >> setpgrp();
> >> if (chdir(cwdbuf))
> >> fail("failed to chdir");
> >> test();
> >> exit(0);
> >> }
> >> int status = 0;
> >> uint64_t start = current_time_ms();
> >> for (;;) {
> >> int res = waitpid(pid, &status, __WALL | WNOHANG);
> >> int errno0 = errno;
> >> if (res == pid)
> >> break;
> >> usleep(1000);
> >> if (current_time_ms() - start > 5 * 1000) {
> >> kill(-pid, SIGKILL);
> >> kill(pid, SIGKILL);
> >> waitpid(pid, &status, __WALL);
> >> break;
> >> }
> >> }
> >> remove_dir(cwdbuf);
> >> }
> >> }
> >>
> >> long r[5];
> >> void* thr(void* arg)
> >> {
> >> switch ((long)arg) {
> >> case 0:
> >> r[0] =
> >> execute_syscall(__NR_mmap, 0x20000000ul, 0xa000ul, 0x3ul,
> >> 0x32ul, 0xfffffffffffffffful, 0x0ul, 0, 0, 0);
> >> break;
> >> case 1:
> >> r[1] = execute_syscall(__NR_socket, 0xaul, 0x5ul, 0x84ul, 0, 0, 0,
> >> 0, 0, 0);
> >> break;
> >> case 2:
> >> r[2] = execute_syscall(__NR_socket, 0x1ful, 0x3ul, 0x6ul, 0, 0, 0,
> >> 0, 0, 0);
> >> break;
> >> case 3:
> >> NONFAILING(memcpy(
> >> (void*)0x20009000,
> >> "\x83\x15\xf6\xdb\x47\x14\xae\xe2\x8d\xb8\x4d\xb9\x0f\x32\xe7"
> >> "\xf5\xbc\xa6\xae\x9a\x2f\x19\xed\xf0\x75\x6a\x0b\xf0\x00\xe9"
> >> "\xe1\x0e\xb4\xa5\x19\x08\x88\xfc\x8b\x2d\xe2\x9a\x0f\x55\x00"
> >> "\x00\x00\x00\x00\x08\x27\xab\x8e\x7d\xcb\xcc\x15\x4e\x79\xe2"
> >> "\xd9\xca\x15\xc3\x66\xbd\x44\xa8\x53\x1f\xda\xab\xce\x98\x39"
> >> "\x40\x4e\x75\x57\xfd\x57\xc0\x01\x0b\xb0",
> >> 85));
> >> r[4] = execute_syscall(__NR_setsockopt, r[1], 0x0ul, 0x40ul,
> >> 0x20009000ul, 0x55ul, 0, 0, 0, 0);
> >> break;
> >> }
> >> return 0;
> >> }
> >>
> >> void test()
> >> {
> >> long i;
> >> pthread_t th[8];
> >>
> >> memset(r, -1, sizeof(r));
> >> srand(getpid());
> >> for (i = 0; i < 4; i++) {
> >> pthread_create(&th[i], 0, thr, (void*)i);
> >> usleep(10000);
> >> }
> >> for (i = 0; i < 4; i++) {
> >> pthread_create(&th[4 + i], 0, thr, (void*)i);
> >> if (rand() % 2)
> >> usleep(rand() % 10000);
> >> }
> >> usleep(100000);
> >> }
> >>
> >> int main()
> >> {
> >> setup_main_process();
> >> int pid = do_sandbox_none();
> >> int status = 0;
> >> while (waitpid(pid, &status, __WALL) != pid) {
> >> }
> >> return 0;
> >> }
> >
>
^ permalink raw reply
* Re: [PATCH] stmmac ethernet: remove cut & paste code
From: Pavel Machek @ 2016-11-28 14:35 UTC (permalink / raw)
To: Joe Perches
Cc: peppe.cavallaro, netdev, kernel list, ezequiel, sonic.zhang,
fabrice.gasnier
In-Reply-To: <1480343068.14294.5.camel@perches.com>
[-- Attachment #1: Type: text/plain, Size: 2695 bytes --]
On Mon 2016-11-28 06:24:28, Joe Perches wrote:
> On Mon, 2016-11-28 at 12:50 +0100, Pavel Machek wrote:
> > On Thu 2016-11-24 14:27:13, Joe Perches wrote:
> > > On Thu, 2016-11-24 at 22:44 +0100, Pavel Machek wrote:
> > > > On Thu 2016-11-24 12:05:25, Joe Perches wrote:
> > > > > On Thu, 2016-11-24 at 12:05 +0100, Pavel Machek wrote:
> > > > > > Remove duplicate code from _tx routines.
> > > > >
> > > > > trivia:
> > > > >
> > > > > > diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
> > > > >
> > > > > []
> > > > > > @@ -1960,6 +1960,38 @@ static void stmmac_tso_allocator(struct stmmac_priv *priv, unsigned int des,
> > > > > > }
> > > > > > }
> > > > > >
> > > > > > +static void stmmac_xmit_common(struct sk_buff *skb, struct net_device *dev, int nfrags, struct dma_desc *desc)
> > > > > > +{
> > > > > > + struct stmmac_priv *priv = netdev_priv(dev);
> > > > > > +
> > > > > > + if (unlikely(stmmac_tx_avail(priv) <= (MAX_SKB_FRAGS + 1))) {
> > > > > > + if (netif_msg_hw(priv))
> > > > > > + pr_debug("%s: stop transmitted packets\n", __func__);
> > > > >
> > > > > netif_dbg(priv, hw, dev, "%s: stop transmitted packets\n",
> > > > > __func__);
> > > >
> > > > Not now. Modifying the code while de-duplicating would be bad idea.
> > >
> > > Too many people think overly granular patches are the
> > > best and only way to make changes.
> > > Deduplication and consolidation can happen simultaneously.
> >
> > Can, but should not at this point. Please take a look at the driver in
> > question before commenting on trivial printk style.
>
> I had.
>
> It's perfectly acceptable and already uses netif_<level> properly.
>
> This consolidation now introduces the _only_ instance where it is
> now improperly using a netif_msg_<type> then single pr_<level>
> function sequence that should be consolidated into netif_dbg.
> Every other use of netif_msg_<level> then either emits multiple
> lines or is used in an if/else.
Are you looking at right driver? I don't see single use of
netif_msg_<level>, but see this at stmmac_main.c:756. Code is actually
pretty consistent using pr_*.
if (netif_msg_link(priv))
pr_warn("%s: Speed (%d) not 10/100\n",
dev->name, phydev->speed);
Anyway, I'm moving code around, if you want to do trivial cleanups, do
them yourself.
Pavel
--
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html
[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 181 bytes --]
^ permalink raw reply
* Re: net/sctp: vmalloc allocation failure in sctp_setsockopt/xt_alloc_table_info
From: Andrey Konovalov @ 2016-11-28 14:33 UTC (permalink / raw)
To: Neil Horman
Cc: Vlad Yasevich, linux-sctp, netdev, LKML, Pablo Neira Ayuso,
Patrick McHardy, Jozsef Kadlecsik, David S. Miller,
netfilter-devel, coreteam, Dmitry Vyukov, Kostya Serebryany,
Eric Dumazet, syzkaller
In-Reply-To: <20161128141340.GA29839@hmsreliant.think-freely.org>
On Mon, Nov 28, 2016 at 3:13 PM, Neil Horman <nhorman@tuxdriver.com> wrote:
> On Mon, Nov 28, 2016 at 02:00:19PM +0100, Andrey Konovalov wrote:
>> Hi!
>>
>> I've got the following error report while running the syzkaller fuzzer.
>>
>> On commit d8e435f3ab6fea2ea324dce72b51dd7761747523 (Nov 26).
>>
>> A reproducer is attached.
>>
>> a.out: vmalloc: allocation failure, allocated 823562240 of 1427091456
>> bytes, mode:0x24000c2(GFP_KERNEL|__GFP_HIGHMEM)
>>
> How much total ram do you have in this system? The call appears to be
> attempting to allocate 1.3 Gb of data. Even using vmalloc to allow
> discontiguous allocation, thats alot of memory, and if enough is in use already,
> I could make the argument that this might be expected behavior.
Hi Neail,
I have 2 Gb.
Just tested with 4 Gb, everything seems to be working fine.
So I guess this is not actually a bug and allocating 1.3 Gb is OK.
Thanks!
>
> Neil
>
>> oom_reaper: reaped process 3810 (a.out), now anon-rss:0kB,
>> file-rss:0kB, shmem-rss:0kB
>> a.out invoked oom-killer:
>> gfp_mask=0x24002c2(GFP_KERNEL|__GFP_HIGHMEM|__GFP_NOWARN), nodemask=0,
>> order=0, oom_score_adj=0
>> a.out cpuset=/ mems_allowed=0
>> CPU: 0 PID: 3814 Comm: a.out Not tainted 4.9.0-rc6+ #457
>> Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Bochs 01/01/2011
>> ffff880068667380 ffffffff81c73b14 ffff880068667710 ffff88006b469018
>> ffff880068667718 0000000000000000 ffff880068667400 ffffffff81641a87
>> 0000000000000000 0000000000000000 0000000000000297 ffffffff84d37280
>> Call Trace:
>> [< inline >] __dump_stack lib/dump_stack.c:15
>> [<ffffffff81c73b14>] dump_stack+0xb3/0x10f lib/dump_stack.c:51
>> [<ffffffff81641a87>] dump_header.isra.21+0x16f/0x5f5 mm/oom_kill.c:416
>> [<ffffffff8154bad8>] oom_kill_process+0x4d8/0xab0 mm/oom_kill.c:835
>> [<ffffffff8154c77c>] out_of_memory+0x2dc/0x1790 mm/oom_kill.c:1044
>> [< inline >] __alloc_pages_may_oom mm/page_alloc.c:3086
>> [<ffffffff8155afb6>] __alloc_pages_slowpath+0x1886/0x1bf0 mm/page_alloc.c:3683
>> [<ffffffff8155b8e2>] __alloc_pages_nodemask+0x5c2/0x710 mm/page_alloc.c:3781
>> [<ffffffff816236a4>] alloc_pages_current+0xf4/0x400 mm/mempolicy.c:2072
>> [< inline >] alloc_pages ./include/linux/gfp.h:469
>> [< inline >] __vmalloc_area_node mm/vmalloc.c:1631
>> [<ffffffff815f8eab>] __vmalloc_node_range+0x33b/0x690 mm/vmalloc.c:1691
>> [< inline >] __vmalloc_node mm/vmalloc.c:1734
>> [< inline >] __vmalloc_node_flags mm/vmalloc.c:1748
>> [<ffffffff815f92cb>] vmalloc+0x5b/0x70 mm/vmalloc.c:1763
>> [<ffffffff82fd0893>] xt_alloc_table_info+0x83/0x120
>> net/netfilter/x_tables.c:961
>> [< inline >] do_replace net/ipv4/netfilter/ip_tables.c:1140
>> [<ffffffff8335b420>] do_ipt_set_ctl+0x210/0x420
>> net/ipv4/netfilter/ip_tables.c:1687
>> [< inline >] nf_sockopt net/netfilter/nf_sockopt.c:105
>> [<ffffffff82efdab7>] nf_setsockopt+0x67/0xc0 net/netfilter/nf_sockopt.c:114
>> [<ffffffff831be741>] ip_setsockopt+0xa1/0xb0 net/ipv4/ip_sockglue.c:1231
>> [<ffffffff832700d5>] udp_setsockopt+0x45/0x80 net/ipv4/udp.c:2085
>> [<ffffffff8346b31f>] ipv6_setsockopt+0x11f/0x140 net/ipv6/ipv6_sockglue.c:892
>> [<ffffffff83a6cd5d>] sctp_setsockopt+0x15d/0x3d70 net/sctp/socket.c:3788
>> [<ffffffff82ca40e6>] sock_common_setsockopt+0x96/0xd0 net/core/sock.c:2690
>> [< inline >] SYSC_setsockopt net/socket.c:1757
>> [<ffffffff82ca10c4>] SyS_setsockopt+0x154/0x240 net/socket.c:1736
>> [<ffffffff840f2c41>] entry_SYSCALL_64_fastpath+0x1f/0xc2
>> arch/x86/entry/entry_64.S:209
>> CPU: 1 PID: 3810 Comm: a.out Not tainted 4.9.0-rc6+ #457
>> Mem-Info:
>> active_anon:1938 inactive_anon:75 isolated_anon:0
>> active_file:14 inactive_file:30 isolated_file:4
>> unevictable:0 dirty:0 writeback:0 unstable:0
>> slab_reclaimable:3316 slab_unreclaimable:9767
>> mapped:21 shmem:81 pagetables:309 bounce:0
>> free:1 free_pcp:75 free_cma:0
>> Node 0 active_anon:7752kB inactive_anon:300kB active_file:56kB
>> inactive_file:120kB unevictable:0kB isolated(anon):0kB
>> isolated(file):16kB mapped:84kB dirty:0kB writeback:0kB shmem:324kB
>> writeback_tmp:0kB unstable:0kB pages_scanned:134 all_unreclaimable? no
>> Node 0 DMA free:4kB min:48kB low:60kB high:72kB active_anon:0kB
>> inactive_anon:0kB active_file:0kB inactive_file:0kB unevictable:0kB
>> writepending:0kB present:15992kB managed:15908kB mlocked:0kB
>> slab_reclaimable:0kB slab_unreclaimable:8kB kernel_stack:0kB
>> pagetables:0kB bounce:0kB free_pcp:0kB local_pcp:0kB free_cma:0kB
>> lowmem_reserve[]: 0 1641 1641 1641
>> Node 0 DMA32 free:0kB min:5156kB low:6836kB high:8516kB
>> active_anon:7752kB inactive_anon:300kB active_file:56kB
>> inactive_file:120kB unevictable:0kB writepending:0kB present:2080760kB
>> managed:1684640kB mlocked:0kB slab_reclaimable:13264kB
>> slab_unreclaimable:39060kB kernel_stack:2944kB pagetables:1236kB
>> bounce:0kB free_pcp:300kB local_pcp:120kB free_cma:0kB
>> lowmem_reserve[]: 0 0 0 0
>> Node 0 DMA: 0*4kB 0*8kB 0*16kB 0*32kB 0*64kB 0*128kB 0*256kB 0*512kB
>> 0*1024kB 0*2048kB 0*4096kB = 0kB
>> Node 0 DMA32: 0*4kB 0*8kB 0*16kB 0*32kB 0*64kB 0*128kB 0*256kB 0*512kB
>> 0*1024kB 0*2048kB 0*4096kB = 0kB
>> Node 0 hugepages_total=0 hugepages_free=0 hugepages_surp=0 hugepages_size=2048kB
>> 148 total pagecache pages
>> 0 pages in swap cache
>> Swap cache stats: add 0, delete 0, find 0/0
>> Free swap = 0kB
>> Total swap = 0kB
>> 524188 pages RAM
>> 0 pages HighMem/MovableOnly
>> 99051 pages reserved
>> [ pid ] uid tgid total_vm rss nr_ptes nr_pmds swapents
>> oom_score_adj name
>> 0 1767 5346 133 16 3 0 -1000 udevd
>> 0 1876 5315 122 15 3 0 -1000 udevd
>> 0 1877 5315 122 15 3 0 -1000 udevd
>> 0 3541 2493 573 8 3 0 0 dhclient
>> 0 3676 13231 171 22 3 0 0 rsyslogd
>> 0 3725 4725 52 15 3 0 0 cron
>> 0 3751 12490 155 28 3 0 -1000 sshd
>> 0 3775 3694 43 13 3 0 0 getty
>> 0 3776 3694 43 13 3 0 0 getty
>> 0 3777 3694 42 13 3 0 0 getty
>> 0 3778 3694 41 13 3 0 0 getty
>> 0 3779 3694 44 13 3 0 0 getty
>> 0 3780 3694 43 13 3 0 0 getty
>> 0 3785 3649 44 12 3 0 0 getty
>> 0 3797 17818 205 39 3 0 0 sshd
>> 0 3800 4474 126 15 3 0 0 bash
>> 0 3804 2053 22 9 3 0 0 a.out
>> 0 3805 2053 26 9 3 0 0 a.out
>> 0 3806 18488 0 18 3 0 0 a.out
>
>> // autogenerated by syzkaller (http://github.com/google/syzkaller)
>>
>> #ifndef __NR_mmap
>> #define __NR_mmap 9
>> #endif
>> #ifndef __NR_setsockopt
>> #define __NR_setsockopt 54
>> #endif
>> #ifndef __NR_syz_fuse_mount
>> #define __NR_syz_fuse_mount 1000004
>> #endif
>> #ifndef __NR_socket
>> #define __NR_socket 41
>> #endif
>> #ifndef __NR_syz_emit_ethernet
>> #define __NR_syz_emit_ethernet 1000006
>> #endif
>> #ifndef __NR_syz_fuseblk_mount
>> #define __NR_syz_fuseblk_mount 1000005
>> #endif
>> #ifndef __NR_syz_open_dev
>> #define __NR_syz_open_dev 1000002
>> #endif
>> #ifndef __NR_syz_open_pts
>> #define __NR_syz_open_pts 1000003
>> #endif
>> #ifndef __NR_syz_test
>> #define __NR_syz_test 1000001
>> #endif
>>
>> #define SYZ_SANDBOX_NONE 1
>> #define SYZ_REPEAT 1
>>
>> #define _GNU_SOURCE
>>
>> #include <sys/ioctl.h>
>> #include <sys/mount.h>
>> #include <sys/prctl.h>
>> #include <sys/resource.h>
>> #include <sys/socket.h>
>> #include <sys/stat.h>
>> #include <sys/syscall.h>
>> #include <sys/time.h>
>> #include <sys/types.h>
>> #include <sys/wait.h>
>>
>> #include <linux/capability.h>
>> #include <linux/if.h>
>> #include <linux/if_tun.h>
>> #include <linux/sched.h>
>> #include <net/if_arp.h>
>>
>> #include <assert.h>
>> #include <dirent.h>
>> #include <errno.h>
>> #include <fcntl.h>
>> #include <grp.h>
>> #include <pthread.h>
>> #include <setjmp.h>
>> #include <signal.h>
>> #include <stdarg.h>
>> #include <stddef.h>
>> #include <stdint.h>
>> #include <stdio.h>
>> #include <stdlib.h>
>> #include <string.h>
>> #include <unistd.h>
>>
>> const int kFailStatus = 67;
>> const int kErrorStatus = 68;
>> const int kRetryStatus = 69;
>>
>> __attribute__((noreturn)) void fail(const char* msg, ...)
>> {
>> int e = errno;
>> fflush(stdout);
>> va_list args;
>> va_start(args, msg);
>> vfprintf(stderr, msg, args);
>> va_end(args);
>> fprintf(stderr, " (errno %d)\n", e);
>> exit(kFailStatus);
>> }
>>
>> __attribute__((noreturn)) void exitf(const char* msg, ...)
>> {
>> int e = errno;
>> fflush(stdout);
>> va_list args;
>> va_start(args, msg);
>> vfprintf(stderr, msg, args);
>> va_end(args);
>> fprintf(stderr, " (errno %d)\n", e);
>> exit(kRetryStatus);
>> }
>>
>> static int flag_debug;
>>
>> void debug(const char* msg, ...)
>> {
>> if (!flag_debug)
>> return;
>> va_list args;
>> va_start(args, msg);
>> vfprintf(stdout, msg, args);
>> va_end(args);
>> fflush(stdout);
>> }
>>
>> __thread int skip_segv;
>> __thread jmp_buf segv_env;
>>
>> static void segv_handler(int sig, siginfo_t* info, void* uctx)
>> {
>> if (__atomic_load_n(&skip_segv, __ATOMIC_RELAXED))
>> _longjmp(segv_env, 1);
>> exit(sig);
>> }
>>
>> static void install_segv_handler()
>> {
>> struct sigaction sa;
>> memset(&sa, 0, sizeof(sa));
>> sa.sa_sigaction = segv_handler;
>> sa.sa_flags = SA_NODEFER | SA_SIGINFO;
>> sigaction(SIGSEGV, &sa, NULL);
>> sigaction(SIGBUS, &sa, NULL);
>> }
>>
>> #define NONFAILING(...) \
>> { \
>> __atomic_fetch_add(&skip_segv, 1, __ATOMIC_SEQ_CST); \
>> if (_setjmp(segv_env) == 0) { \
>> __VA_ARGS__; \
>> } \
>> __atomic_fetch_sub(&skip_segv, 1, __ATOMIC_SEQ_CST); \
>> }
>>
>> static uintptr_t syz_open_dev(uintptr_t a0, uintptr_t a1, uintptr_t a2)
>> {
>> if (a0 == 0xc || a0 == 0xb) {
>> char buf[128];
>> sprintf(buf, "/dev/%s/%d:%d", a0 == 0xc ? "char" : "block",
>> (uint8_t)a1, (uint8_t)a2);
>> return open(buf, O_RDWR, 0);
>> } else {
>> char buf[1024];
>> char* hash;
>> strncpy(buf, (char*)a0, sizeof(buf));
>> buf[sizeof(buf) - 1] = 0;
>> while ((hash = strchr(buf, '#'))) {
>> *hash = '0' + (char)(a1 % 10);
>> a1 /= 10;
>> }
>> return open(buf, a2, 0);
>> }
>> }
>>
>> static uintptr_t syz_open_pts(uintptr_t a0, uintptr_t a1)
>> {
>> int ptyno = 0;
>> if (ioctl(a0, TIOCGPTN, &ptyno))
>> return -1;
>> char buf[128];
>> sprintf(buf, "/dev/pts/%d", ptyno);
>> return open(buf, a1, 0);
>> }
>>
>> static uintptr_t syz_fuse_mount(uintptr_t a0, uintptr_t a1,
>> uintptr_t a2, uintptr_t a3,
>> uintptr_t a4, uintptr_t a5)
>> {
>> uint64_t target = a0;
>> uint64_t mode = a1;
>> uint64_t uid = a2;
>> uint64_t gid = a3;
>> uint64_t maxread = a4;
>> uint64_t flags = a5;
>>
>> int fd = open("/dev/fuse", O_RDWR);
>> if (fd == -1)
>> return fd;
>> char buf[1024];
>> sprintf(buf, "fd=%d,user_id=%ld,group_id=%ld,rootmode=0%o", fd,
>> (long)uid, (long)gid, (unsigned)mode & ~3u);
>> if (maxread != 0)
>> sprintf(buf + strlen(buf), ",max_read=%ld", (long)maxread);
>> if (mode & 1)
>> strcat(buf, ",default_permissions");
>> if (mode & 2)
>> strcat(buf, ",allow_other");
>> syscall(SYS_mount, "", target, "fuse", flags, buf);
>> return fd;
>> }
>>
>> static uintptr_t syz_fuseblk_mount(uintptr_t a0, uintptr_t a1,
>> uintptr_t a2, uintptr_t a3,
>> uintptr_t a4, uintptr_t a5,
>> uintptr_t a6, uintptr_t a7)
>> {
>> uint64_t target = a0;
>> uint64_t blkdev = a1;
>> uint64_t mode = a2;
>> uint64_t uid = a3;
>> uint64_t gid = a4;
>> uint64_t maxread = a5;
>> uint64_t blksize = a6;
>> uint64_t flags = a7;
>>
>> int fd = open("/dev/fuse", O_RDWR);
>> if (fd == -1)
>> return fd;
>> if (syscall(SYS_mknodat, AT_FDCWD, blkdev, S_IFBLK, makedev(7, 199)))
>> return fd;
>> char buf[256];
>> sprintf(buf, "fd=%d,user_id=%ld,group_id=%ld,rootmode=0%o", fd,
>> (long)uid, (long)gid, (unsigned)mode & ~3u);
>> if (maxread != 0)
>> sprintf(buf + strlen(buf), ",max_read=%ld", (long)maxread);
>> if (blksize != 0)
>> sprintf(buf + strlen(buf), ",blksize=%ld", (long)blksize);
>> if (mode & 1)
>> strcat(buf, ",default_permissions");
>> if (mode & 2)
>> strcat(buf, ",allow_other");
>> syscall(SYS_mount, blkdev, target, "fuseblk", flags, buf);
>> return fd;
>> }
>>
>> static uintptr_t execute_syscall(int nr, uintptr_t a0, uintptr_t a1,
>> uintptr_t a2, uintptr_t a3,
>> uintptr_t a4, uintptr_t a5,
>> uintptr_t a6, uintptr_t a7,
>> uintptr_t a8)
>> {
>> switch (nr) {
>> default:
>> return syscall(nr, a0, a1, a2, a3, a4, a5);
>> case __NR_syz_test:
>> return 0;
>> case __NR_syz_open_dev:
>> return syz_open_dev(a0, a1, a2);
>> case __NR_syz_open_pts:
>> return syz_open_pts(a0, a1);
>> case __NR_syz_fuse_mount:
>> return syz_fuse_mount(a0, a1, a2, a3, a4, a5);
>> case __NR_syz_fuseblk_mount:
>> return syz_fuseblk_mount(a0, a1, a2, a3, a4, a5, a6, a7);
>> }
>> }
>>
>> static void setup_main_process()
>> {
>> struct sigaction sa;
>> memset(&sa, 0, sizeof(sa));
>> sa.sa_handler = SIG_IGN;
>> syscall(SYS_rt_sigaction, 0x20, &sa, NULL, 8);
>> syscall(SYS_rt_sigaction, 0x21, &sa, NULL, 8);
>> install_segv_handler();
>>
>> char tmpdir_template[] = "./syzkaller.XXXXXX";
>> char* tmpdir = mkdtemp(tmpdir_template);
>> if (!tmpdir)
>> fail("failed to mkdtemp");
>> if (chmod(tmpdir, 0777))
>> fail("failed to chmod");
>> if (chdir(tmpdir))
>> fail("failed to chdir");
>> }
>>
>> static void loop();
>>
>> static void sandbox_common()
>> {
>> prctl(PR_SET_PDEATHSIG, SIGKILL, 0, 0, 0);
>> setpgrp();
>> setsid();
>>
>> struct rlimit rlim;
>> rlim.rlim_cur = rlim.rlim_max = 128 << 20;
>> setrlimit(RLIMIT_AS, &rlim);
>> rlim.rlim_cur = rlim.rlim_max = 1 << 20;
>> setrlimit(RLIMIT_FSIZE, &rlim);
>> rlim.rlim_cur = rlim.rlim_max = 1 << 20;
>> setrlimit(RLIMIT_STACK, &rlim);
>> rlim.rlim_cur = rlim.rlim_max = 0;
>> setrlimit(RLIMIT_CORE, &rlim);
>>
>> unshare(CLONE_NEWNS);
>> unshare(CLONE_NEWIPC);
>> unshare(CLONE_IO);
>> }
>>
>> static int do_sandbox_none()
>> {
>> int pid = fork();
>> if (pid)
>> return pid;
>> sandbox_common();
>> loop();
>> exit(1);
>> }
>>
>> static void remove_dir(const char* dir)
>> {
>> DIR* dp;
>> struct dirent* ep;
>> int iter = 0;
>> int i;
>> retry:
>> dp = opendir(dir);
>> if (dp == NULL) {
>> if (errno == EMFILE) {
>> exitf("opendir(%s) failed due to NOFILE, exiting");
>> }
>> exitf("opendir(%s) failed", dir);
>> }
>> while ((ep = readdir(dp))) {
>> if (strcmp(ep->d_name, ".") == 0 || strcmp(ep->d_name, "..") == 0)
>> continue;
>> char filename[FILENAME_MAX];
>> snprintf(filename, sizeof(filename), "%s/%s", dir, ep->d_name);
>> struct stat st;
>> if (lstat(filename, &st))
>> exitf("lstat(%s) failed", filename);
>> if (S_ISDIR(st.st_mode)) {
>> remove_dir(filename);
>> continue;
>> }
>> for (i = 0;; i++) {
>> debug("unlink(%s)\n", filename);
>> if (unlink(filename) == 0)
>> break;
>> if (errno == EROFS) {
>> debug("ignoring EROFS\n");
>> break;
>> }
>> if (errno != EBUSY || i > 100)
>> exitf("unlink(%s) failed", filename);
>> debug("umount(%s)\n", filename);
>> if (umount2(filename, MNT_DETACH))
>> exitf("umount(%s) failed", filename);
>> }
>> }
>> closedir(dp);
>> for (i = 0;; i++) {
>> debug("rmdir(%s)\n", dir);
>> if (rmdir(dir) == 0)
>> break;
>> if (i < 100) {
>> if (errno == EROFS) {
>> debug("ignoring EROFS\n");
>> break;
>> }
>> if (errno == EBUSY) {
>> debug("umount(%s)\n", dir);
>> if (umount2(dir, MNT_DETACH))
>> exitf("umount(%s) failed", dir);
>> continue;
>> }
>> if (errno == ENOTEMPTY) {
>> if (iter < 100) {
>> iter++;
>> goto retry;
>> }
>> }
>> }
>> exitf("rmdir(%s) failed", dir);
>> }
>> }
>>
>> static uint64_t current_time_ms()
>> {
>> struct timespec ts;
>>
>> if (clock_gettime(CLOCK_MONOTONIC, &ts))
>> fail("clock_gettime failed");
>> return (uint64_t)ts.tv_sec * 1000 + (uint64_t)ts.tv_nsec / 1000000;
>> }
>>
>> static void test();
>>
>> void loop()
>> {
>> int iter;
>> for (iter = 0;; iter++) {
>> char cwdbuf[256];
>> sprintf(cwdbuf, "./%d", iter);
>> if (mkdir(cwdbuf, 0777))
>> fail("failed to mkdir");
>> int pid = fork();
>> if (pid < 0)
>> fail("clone failed");
>> if (pid == 0) {
>> prctl(PR_SET_PDEATHSIG, SIGKILL, 0, 0, 0);
>> setpgrp();
>> if (chdir(cwdbuf))
>> fail("failed to chdir");
>> test();
>> exit(0);
>> }
>> int status = 0;
>> uint64_t start = current_time_ms();
>> for (;;) {
>> int res = waitpid(pid, &status, __WALL | WNOHANG);
>> int errno0 = errno;
>> if (res == pid)
>> break;
>> usleep(1000);
>> if (current_time_ms() - start > 5 * 1000) {
>> kill(-pid, SIGKILL);
>> kill(pid, SIGKILL);
>> waitpid(pid, &status, __WALL);
>> break;
>> }
>> }
>> remove_dir(cwdbuf);
>> }
>> }
>>
>> long r[5];
>> void* thr(void* arg)
>> {
>> switch ((long)arg) {
>> case 0:
>> r[0] =
>> execute_syscall(__NR_mmap, 0x20000000ul, 0xa000ul, 0x3ul,
>> 0x32ul, 0xfffffffffffffffful, 0x0ul, 0, 0, 0);
>> break;
>> case 1:
>> r[1] = execute_syscall(__NR_socket, 0xaul, 0x5ul, 0x84ul, 0, 0, 0,
>> 0, 0, 0);
>> break;
>> case 2:
>> r[2] = execute_syscall(__NR_socket, 0x1ful, 0x3ul, 0x6ul, 0, 0, 0,
>> 0, 0, 0);
>> break;
>> case 3:
>> NONFAILING(memcpy(
>> (void*)0x20009000,
>> "\x83\x15\xf6\xdb\x47\x14\xae\xe2\x8d\xb8\x4d\xb9\x0f\x32\xe7"
>> "\xf5\xbc\xa6\xae\x9a\x2f\x19\xed\xf0\x75\x6a\x0b\xf0\x00\xe9"
>> "\xe1\x0e\xb4\xa5\x19\x08\x88\xfc\x8b\x2d\xe2\x9a\x0f\x55\x00"
>> "\x00\x00\x00\x00\x08\x27\xab\x8e\x7d\xcb\xcc\x15\x4e\x79\xe2"
>> "\xd9\xca\x15\xc3\x66\xbd\x44\xa8\x53\x1f\xda\xab\xce\x98\x39"
>> "\x40\x4e\x75\x57\xfd\x57\xc0\x01\x0b\xb0",
>> 85));
>> r[4] = execute_syscall(__NR_setsockopt, r[1], 0x0ul, 0x40ul,
>> 0x20009000ul, 0x55ul, 0, 0, 0, 0);
>> break;
>> }
>> return 0;
>> }
>>
>> void test()
>> {
>> long i;
>> pthread_t th[8];
>>
>> memset(r, -1, sizeof(r));
>> srand(getpid());
>> for (i = 0; i < 4; i++) {
>> pthread_create(&th[i], 0, thr, (void*)i);
>> usleep(10000);
>> }
>> for (i = 0; i < 4; i++) {
>> pthread_create(&th[4 + i], 0, thr, (void*)i);
>> if (rand() % 2)
>> usleep(rand() % 10000);
>> }
>> usleep(100000);
>> }
>>
>> int main()
>> {
>> setup_main_process();
>> int pid = do_sandbox_none();
>> int status = 0;
>> while (waitpid(pid, &status, __WALL) != pid) {
>> }
>> return 0;
>> }
>
^ permalink raw reply
* [patch net] net: fec: cache statistics while device is down
From: Nikita Yushchenko @ 2016-11-28 14:27 UTC (permalink / raw)
To: David S. Miller, Fugang Duan, Troy Kisky, Andrew Lunn,
Eric Nelson, Philippe Reynes, Johannes Berg, netdev
Cc: Chris Healy, Fabio Estevam, linux-kernel, Nikita Yushchenko
Execution 'ethtool -S' on fec device that is down causes OOPS on Vybrid
board:
Unhandled fault: external abort on non-linefetch (0x1008) at 0xe0898200
pgd = ddecc000
[e0898200] *pgd=9e406811, *pte=400d1653, *ppte=400d1453
Internal error: : 1008 [#1] SMP ARM
...
Reason of OOPS is that fec_enet_get_ethtool_stats() accesses fec
registers while IPG clock is stopped by PM.
Fix that by caching statistics in fec_enet_private. Cache is updated
just before statistics request if device is up, and also just before
turning device off on down path.
Additional locking is not needed, since cached statistics is always
updated under rtnl_lock().
Signed-off-by: Nikita Yushchenko <nikita.yoush@cogentembedded.com>
---
drivers/net/ethernet/freescale/fec.h | 2 ++
drivers/net/ethernet/freescale/fec_main.c | 21 +++++++++++++++++----
2 files changed, 19 insertions(+), 4 deletions(-)
diff --git a/drivers/net/ethernet/freescale/fec.h b/drivers/net/ethernet/freescale/fec.h
index c865135f3cb9..5ea740b4cf14 100644
--- a/drivers/net/ethernet/freescale/fec.h
+++ b/drivers/net/ethernet/freescale/fec.h
@@ -574,6 +574,8 @@ struct fec_enet_private {
unsigned int reload_period;
int pps_enable;
unsigned int next_counter;
+
+ u64 ethtool_stats[0];
};
void fec_ptp_init(struct platform_device *pdev);
diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c
index 5aa9d4ded214..7da2d94ec8e5 100644
--- a/drivers/net/ethernet/freescale/fec_main.c
+++ b/drivers/net/ethernet/freescale/fec_main.c
@@ -2313,14 +2313,24 @@ static const struct fec_stat {
{ "IEEE_rx_octets_ok", IEEE_R_OCTETS_OK },
};
-static void fec_enet_get_ethtool_stats(struct net_device *dev,
- struct ethtool_stats *stats, u64 *data)
+static void fec_enet_update_ethtool_stats(struct net_device *dev)
{
struct fec_enet_private *fep = netdev_priv(dev);
int i;
for (i = 0; i < ARRAY_SIZE(fec_stats); i++)
- data[i] = readl(fep->hwp + fec_stats[i].offset);
+ fep->ethtool_stats[i] = readl(fep->hwp + fec_stats[i].offset);
+}
+
+static void fec_enet_get_ethtool_stats(struct net_device *dev,
+ struct ethtool_stats *stats, u64 *data)
+{
+ struct fec_enet_private *fep = netdev_priv(dev);
+
+ if (netif_running(dev))
+ fec_enet_update_ethtool_stats(dev);
+
+ memcpy(data, fep->ethtool_stats, ARRAY_SIZE(fec_stats) * sizeof(u64));
}
static void fec_enet_get_strings(struct net_device *netdev,
@@ -2874,6 +2884,8 @@ fec_enet_close(struct net_device *ndev)
if (fep->quirks & FEC_QUIRK_ERR006687)
imx6q_cpuidle_fec_irqs_unused();
+ fec_enet_update_ethtool_stats(ndev);
+
fec_enet_clk_enable(ndev, false);
pinctrl_pm_select_sleep_state(&fep->pdev->dev);
pm_runtime_mark_last_busy(&fep->pdev->dev);
@@ -3278,7 +3290,8 @@ fec_probe(struct platform_device *pdev)
fec_enet_get_queue_num(pdev, &num_tx_qs, &num_rx_qs);
/* Init network device */
- ndev = alloc_etherdev_mqs(sizeof(struct fec_enet_private),
+ ndev = alloc_etherdev_mqs(sizeof(struct fec_enet_private) +
+ ARRAY_SIZE(fec_stats) * sizeof(u64),
num_tx_qs, num_rx_qs);
if (!ndev)
return -ENOMEM;
--
2.1.4
^ permalink raw reply related
* [PATCH net] net/dccp: fix use-after-free in dccp_invalid_packet
From: Eric Dumazet @ 2016-11-28 14:26 UTC (permalink / raw)
To: Andrey Konovalov
Cc: Gerrit Renker, David S. Miller, dccp, netdev, LKML, Dmitry Vyukov,
Kostya Serebryany, Eric Dumazet, syzkaller
In-Reply-To: <CAAeHK+zYNyuFUU+w0rLWvvZqivSedrqMpS5UYt=c4uqajS_Stw@mail.gmail.com>
From: Eric Dumazet <edumazet@google.com>
pskb_may_pull() can reallocate skb->head, we need to reload dh pointer
in dccp_invalid_packet() or risk use after free.
Bug found by Andrey Konovalov using syzkaller.
Signed-off-by: Eric Dumazet <edumazet@google.com>
Reported-by: Andrey Konovalov <andreyknvl@google.com>
---
net/dccp/ipv4.c | 12 +++++++-----
1 file changed, 7 insertions(+), 5 deletions(-)
diff --git a/net/dccp/ipv4.c b/net/dccp/ipv4.c
index b567c8725aea..edbe59d203ef 100644
--- a/net/dccp/ipv4.c
+++ b/net/dccp/ipv4.c
@@ -700,6 +700,7 @@ int dccp_invalid_packet(struct sk_buff *skb)
{
const struct dccp_hdr *dh;
unsigned int cscov;
+ u8 dccph_doff;
if (skb->pkt_type != PACKET_HOST)
return 1;
@@ -721,18 +722,19 @@ int dccp_invalid_packet(struct sk_buff *skb)
/*
* If P.Data Offset is too small for packet type, drop packet and return
*/
- if (dh->dccph_doff < dccp_hdr_len(skb) / sizeof(u32)) {
- DCCP_WARN("P.Data Offset(%u) too small\n", dh->dccph_doff);
+ dccph_doff = dh->dccph_doff;
+ if (dccph_doff < dccp_hdr_len(skb) / sizeof(u32)) {
+ DCCP_WARN("P.Data Offset(%u) too small\n", dccph_doff);
return 1;
}
/*
* If P.Data Offset is too too large for packet, drop packet and return
*/
- if (!pskb_may_pull(skb, dh->dccph_doff * sizeof(u32))) {
- DCCP_WARN("P.Data Offset(%u) too large\n", dh->dccph_doff);
+ if (!pskb_may_pull(skb, dccph_doff * sizeof(u32))) {
+ DCCP_WARN("P.Data Offset(%u) too large\n", dccph_doff);
return 1;
}
-
+ dh = dccp_hdr(skb);
/*
* If P.type is not Data, Ack, or DataAck and P.X == 0 (the packet
* has short sequence numbers), drop packet and return
^ permalink raw reply related
* [PATCH net-next v2] mlxsw: switchib: add MLXSW_PCI dependency
From: Arnd Bergmann @ 2016-11-28 14:26 UTC (permalink / raw)
To: David Miller
Cc: Arnd Bergmann, Jiri Pirko, Ido Schimmel, Vadim Pasternak,
Ivan Vecera, Elad Raz, netdev, linux-kernel
The newly added switchib driver fails to link if MLXSW_PCI=m:
drivers/net/ethernet/mellanox/mlxsw/mlxsw_switchib.o: In function^Cmlxsw_sib_module_exit':
switchib.c:(.exit.text+0x8): undefined reference to `mlxsw_pci_driver_unregister'
switchib.c:(.exit.text+0x10): undefined reference to `mlxsw_pci_driver_unregister'
drivers/net/ethernet/mellanox/mlxsw/mlxsw_switchib.o: In function `mlxsw_sib_module_init':
switchib.c:(.init.text+0x28): undefined reference to `mlxsw_pci_driver_register'
switchib.c:(.init.text+0x38): undefined reference to `mlxsw_pci_driver_register'
switchib.c:(.init.text+0x48): undefined reference to `mlxsw_pci_driver_unregister'
The other two such sub-drivers have a dependency, so add the same one
here. In theory we could allow this driver if MLXSW_PCI is disabled,
but it's probably not worth it.
Fixes: d1ba52638456 ("mlxsw: switchib: Introduce SwitchIB and SwitchIB silicon driver")
Reviewed-by: Jiri Pirko <jiri@mellanox.com>
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
---
v2: add Fixes tag
drivers/net/ethernet/mellanox/mlxsw/Kconfig | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/mellanox/mlxsw/Kconfig b/drivers/net/ethernet/mellanox/mlxsw/Kconfig
index 95ae4c0d3a18..16f44b9aa076 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/Kconfig
+++ b/drivers/net/ethernet/mellanox/mlxsw/Kconfig
@@ -50,7 +50,7 @@ config MLXSW_I2C
config MLXSW_SWITCHIB
tristate "Mellanox Technologies SwitchIB and SwitchIB-2 support"
- depends on MLXSW_CORE && NET_SWITCHDEV
+ depends on MLXSW_CORE && MLXSW_PCI && NET_SWITCHDEV
default m
---help---
This driver supports Mellanox Technologies SwitchIB and SwitchIB-2
--
2.9.0
^ permalink raw reply related
* Re: [PATCH] stmmac ethernet: remove cut & paste code
From: Joe Perches @ 2016-11-28 14:24 UTC (permalink / raw)
To: Pavel Machek
Cc: peppe.cavallaro, netdev, kernel list, ezequiel, sonic.zhang,
fabrice.gasnier
In-Reply-To: <20161128115023.GA15034@amd>
On Mon, 2016-11-28 at 12:50 +0100, Pavel Machek wrote:
> On Thu 2016-11-24 14:27:13, Joe Perches wrote:
> > On Thu, 2016-11-24 at 22:44 +0100, Pavel Machek wrote:
> > > On Thu 2016-11-24 12:05:25, Joe Perches wrote:
> > > > On Thu, 2016-11-24 at 12:05 +0100, Pavel Machek wrote:
> > > > > Remove duplicate code from _tx routines.
> > > >
> > > > trivia:
> > > >
> > > > > diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
> > > >
> > > > []
> > > > > @@ -1960,6 +1960,38 @@ static void stmmac_tso_allocator(struct stmmac_priv *priv, unsigned int des,
> > > > > }
> > > > > }
> > > > >
> > > > > +static void stmmac_xmit_common(struct sk_buff *skb, struct net_device *dev, int nfrags, struct dma_desc *desc)
> > > > > +{
> > > > > + struct stmmac_priv *priv = netdev_priv(dev);
> > > > > +
> > > > > + if (unlikely(stmmac_tx_avail(priv) <= (MAX_SKB_FRAGS + 1))) {
> > > > > + if (netif_msg_hw(priv))
> > > > > + pr_debug("%s: stop transmitted packets\n", __func__);
> > > >
> > > > netif_dbg(priv, hw, dev, "%s: stop transmitted packets\n",
> > > > __func__);
> > >
> > > Not now. Modifying the code while de-duplicating would be bad idea.
> >
> > Too many people think overly granular patches are the
> > best and only way to make changes.
> > Deduplication and consolidation can happen simultaneously.
>
> Can, but should not at this point. Please take a look at the driver in
> question before commenting on trivial printk style.
I had.
It's perfectly acceptable and already uses netif_<level> properly.
This consolidation now introduces the _only_ instance where it is
now improperly using a netif_msg_<type> then single pr_<level>
function sequence that should be consolidated into netif_dbg.
Every other use of netif_msg_<level> then either emits multiple
lines or is used in an if/else.
cheers, Joe
^ permalink raw reply
* [PATCH] irda: w83977af_ir: fix damaged whitespace
From: Arnd Bergmann @ 2016-11-28 14:19 UTC (permalink / raw)
To: David Miller; +Cc: Arnd Bergmann, Samuel Ortiz, netdev, linux-kernel
As David Miller pointed out for for the previous patch, the whitespace
in some functions looks rather odd. This was caused by commit 6329da5f258a
("obsolete config in kernel source: USE_INTERNAL_TIMER"), which removed
some conditions but did not reindent the code.
This fixes the indentation in the file and removes extraneous whitespace
at the end of the lines and before tabs.
There are many other minor coding style problems in the driver, but I'm
not touching those here.
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
---
drivers/net/irda/w83977af_ir.c | 404 ++++++++++++++++++++---------------------
1 file changed, 202 insertions(+), 202 deletions(-)
diff --git a/drivers/net/irda/w83977af_ir.c b/drivers/net/irda/w83977af_ir.c
index e8c3a8c32534..96745888a4fc 100644
--- a/drivers/net/irda/w83977af_ir.c
+++ b/drivers/net/irda/w83977af_ir.c
@@ -1,5 +1,5 @@
/*********************************************************************
- *
+ *
* Filename: w83977af_ir.c
* Version: 1.0
* Description: FIR driver for the Winbond W83977AF Super I/O chip
@@ -8,31 +8,31 @@
* Created at: Wed Nov 4 11:46:16 1998
* Modified at: Fri Jan 28 12:10:59 2000
* Modified by: Dag Brattli <dagb@cs.uit.no>
- *
+ *
* Copyright (c) 1998-2000 Dag Brattli <dagb@cs.uit.no>
* Copyright (c) 1998-1999 Rebel.com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
- *
+ *
* Neither Paul VanderSpek nor Rebel.com admit liability nor provide
* warranty for any of this software. This material is provided "AS-IS"
* and at no charge.
- *
+ *
* If you find bugs in this file, its very likely that the same bug
* will also be in pc87108.c since the implementations are quite
* similar.
*
* Notice that all functions that needs to access the chip in _any_
- * way, must save BSR register on entry, and restore it on exit.
+ * way, must save BSR register on entry, and restore it on exit.
* It is _very_ important to follow this policy!
*
* __u8 bank;
- *
+ *
* bank = inb( iobase+BSR);
- *
+ *
* do_your_stuff_here();
*
* outb( bank, iobase+BSR);
@@ -63,7 +63,7 @@
#include "w83977af_ir.h"
#define CONFIG_USE_W977_PNP /* Currently needed */
-#define PIO_MAX_SPEED 115200
+#define PIO_MAX_SPEED 115200
static char *driver_name = "w83977af_ir";
static int qos_mtt_bits = 0x07; /* 1 ms or more */
@@ -83,11 +83,11 @@ static unsigned int efio = W977_EFIO_BASE;
static struct w83977af_ir *dev_self[] = { NULL, NULL, NULL, NULL};
/* Some prototypes */
-static int w83977af_open(int i, unsigned int iobase, unsigned int irq,
+static int w83977af_open(int i, unsigned int iobase, unsigned int irq,
unsigned int dma);
static int w83977af_close(struct w83977af_ir *self);
static int w83977af_probe(int iobase, int irq, int dma);
-static int w83977af_dma_receive(struct w83977af_ir *self);
+static int w83977af_dma_receive(struct w83977af_ir *self);
static int w83977af_dma_receive_complete(struct w83977af_ir *self);
static netdev_tx_t w83977af_hard_xmit(struct sk_buff *skb,
struct net_device *dev);
@@ -108,7 +108,7 @@ static int w83977af_net_ioctl(struct net_device *dev, struct ifreq *rq, int cmd
*/
static int __init w83977af_init(void)
{
- int i;
+ int i;
for (i=0; i < ARRAY_SIZE(dev_self) && io[i] < 2000; i++) {
if (w83977af_open(i, io[i], irq[i], dma[i]) == 0)
@@ -150,7 +150,7 @@ static int w83977af_open(int i, unsigned int iobase, unsigned int irq,
unsigned int dma)
{
struct net_device *dev;
- struct w83977af_ir *self;
+ struct w83977af_ir *self;
int err;
/* Lock the port that we need */
@@ -177,18 +177,18 @@ static int w83977af_open(int i, unsigned int iobase, unsigned int irq,
self = netdev_priv(dev);
spin_lock_init(&self->lock);
-
+
/* Initialize IO */
- self->io.fir_base = iobase;
- self->io.irq = irq;
- self->io.fir_ext = CHIP_IO_EXTENT;
- self->io.dma = dma;
- self->io.fifo_size = 32;
+ self->io.fir_base = iobase;
+ self->io.irq = irq;
+ self->io.fir_ext = CHIP_IO_EXTENT;
+ self->io.dma = dma;
+ self->io.fifo_size = 32;
/* Initialize QoS for this device */
irda_init_max_qos_capabilies(&self->qos);
-
+
/* The only value we must override it the baudrate */
/* FIXME: The HP HDLS-1100 does not support 1152000! */
@@ -198,11 +198,11 @@ static int w83977af_open(int i, unsigned int iobase, unsigned int irq,
/* The HP HDLS-1100 needs 1 ms according to the specs */
self->qos.min_turn_time.bits = qos_mtt_bits;
irda_qos_bits_to_value(&self->qos);
-
+
/* Max DMA buffer size needed = (data_size + 6) * (window_size) + 6; */
- self->rx_buff.truesize = 14384;
+ self->rx_buff.truesize = 14384;
self->tx_buff.truesize = 4000;
-
+
/* Allocate memory if needed */
self->rx_buff.head =
dma_zalloc_coherent(NULL, self->rx_buff.truesize,
@@ -238,12 +238,12 @@ static int w83977af_open(int i, unsigned int iobase, unsigned int irq,
/* Need to store self somewhere */
dev_self[i] = self;
-
+
return 0;
err_out3:
dma_free_coherent(NULL, self->tx_buff.truesize,
self->tx_buff.head, self->tx_buff_dma);
-err_out2:
+err_out2:
dma_free_coherent(NULL, self->rx_buff.truesize,
self->rx_buff.head, self->rx_buff_dma);
err_out1:
@@ -288,7 +288,7 @@ static int w83977af_close(struct w83977af_ir *self)
if (self->tx_buff.head)
dma_free_coherent(NULL, self->tx_buff.truesize,
self->tx_buff.head, self->tx_buff_dma);
-
+
if (self->rx_buff.head)
dma_free_coherent(NULL, self->rx_buff.truesize,
self->rx_buff.head, self->rx_buff_dma);
@@ -300,106 +300,106 @@ static int w83977af_close(struct w83977af_ir *self)
static int w83977af_probe(int iobase, int irq, int dma)
{
- int version;
+ int version;
int i;
-
- for (i=0; i < 2; i++) {
+
+ for (i=0; i < 2; i++) {
#ifdef CONFIG_USE_W977_PNP
- /* Enter PnP configuration mode */
+ /* Enter PnP configuration mode */
w977_efm_enter(efbase[i]);
-
- w977_select_device(W977_DEVICE_IR, efbase[i]);
-
- /* Configure PnP port, IRQ, and DMA channel */
- w977_write_reg(0x60, (iobase >> 8) & 0xff, efbase[i]);
- w977_write_reg(0x61, (iobase) & 0xff, efbase[i]);
-
- w977_write_reg(0x70, irq, efbase[i]);
+
+ w977_select_device(W977_DEVICE_IR, efbase[i]);
+
+ /* Configure PnP port, IRQ, and DMA channel */
+ w977_write_reg(0x60, (iobase >> 8) & 0xff, efbase[i]);
+ w977_write_reg(0x61, (iobase) & 0xff, efbase[i]);
+
+ w977_write_reg(0x70, irq, efbase[i]);
#ifdef CONFIG_ARCH_NETWINDER
/* Netwinder uses 1 higher than Linux */
- w977_write_reg(0x74, dma+1, efbase[i]);
+ w977_write_reg(0x74, dma+1, efbase[i]);
#else
- w977_write_reg(0x74, dma, efbase[i]);
+ w977_write_reg(0x74, dma, efbase[i]);
#endif /* CONFIG_ARCH_NETWINDER */
- w977_write_reg(0x75, 0x04, efbase[i]); /* Disable Tx DMA */
-
- /* Set append hardware CRC, enable IR bank selection */
- w977_write_reg(0xf0, APEDCRC|ENBNKSEL, efbase[i]);
-
- /* Activate device */
- w977_write_reg(0x30, 0x01, efbase[i]);
-
- w977_efm_exit(efbase[i]);
+ w977_write_reg(0x75, 0x04, efbase[i]);/* Disable Tx DMA */
+
+ /* Set append hardware CRC, enable IR bank selection */
+ w977_write_reg(0xf0, APEDCRC | ENBNKSEL, efbase[i]);
+
+ /* Activate device */
+ w977_write_reg(0x30, 0x01, efbase[i]);
+
+ w977_efm_exit(efbase[i]);
#endif /* CONFIG_USE_W977_PNP */
- /* Disable Advanced mode */
- switch_bank(iobase, SET2);
- outb(iobase+2, 0x00);
-
- /* Turn on UART (global) interrupts */
- switch_bank(iobase, SET0);
- outb(HCR_EN_IRQ, iobase+HCR);
-
- /* Switch to advanced mode */
- switch_bank(iobase, SET2);
- outb(inb(iobase+ADCR1) | ADCR1_ADV_SL, iobase+ADCR1);
-
- /* Set default IR-mode */
- switch_bank(iobase, SET0);
- outb(HCR_SIR, iobase+HCR);
-
- /* Read the Advanced IR ID */
- switch_bank(iobase, SET3);
- version = inb(iobase+AUID);
-
- /* Should be 0x1? */
- if (0x10 == (version & 0xf0)) {
- efio = efbase[i];
-
- /* Set FIFO size to 32 */
- switch_bank(iobase, SET2);
- outb(ADCR2_RXFS32|ADCR2_TXFS32, iobase+ADCR2);
-
- /* Set FIFO threshold to TX17, RX16 */
- switch_bank(iobase, SET0);
- outb(UFR_RXTL|UFR_TXTL|UFR_TXF_RST|UFR_RXF_RST|
+ /* Disable Advanced mode */
+ switch_bank(iobase, SET2);
+ outb(iobase+2, 0x00);
+
+ /* Turn on UART (global) interrupts */
+ switch_bank(iobase, SET0);
+ outb(HCR_EN_IRQ, iobase+HCR);
+
+ /* Switch to advanced mode */
+ switch_bank(iobase, SET2);
+ outb(inb(iobase+ADCR1) | ADCR1_ADV_SL, iobase+ADCR1);
+
+ /* Set default IR-mode */
+ switch_bank(iobase, SET0);
+ outb(HCR_SIR, iobase+HCR);
+
+ /* Read the Advanced IR ID */
+ switch_bank(iobase, SET3);
+ version = inb(iobase+AUID);
+
+ /* Should be 0x1? */
+ if (0x10 == (version & 0xf0)) {
+ efio = efbase[i];
+
+ /* Set FIFO size to 32 */
+ switch_bank(iobase, SET2);
+ outb(ADCR2_RXFS32|ADCR2_TXFS32, iobase+ADCR2);
+
+ /* Set FIFO threshold to TX17, RX16 */
+ switch_bank(iobase, SET0);
+ outb(UFR_RXTL|UFR_TXTL|UFR_TXF_RST|UFR_RXF_RST|
UFR_EN_FIFO,iobase+UFR);
-
- /* Receiver frame length */
- switch_bank(iobase, SET4);
+
+ /* Receiver frame length */
+ switch_bank(iobase, SET4);
outb(2048 & 0xff, iobase+6);
outb((2048 >> 8) & 0x1f, iobase+7);
- /*
- * Init HP HSDL-1100 transceiver.
- *
- * Set IRX_MSL since we have 2 * receive paths IRRX,
- * and IRRXH. Clear IRSL0D since we want IRSL0 * to
- * be a input pin used for IRRXH
+ /*
+ * Init HP HSDL-1100 transceiver.
*
- * IRRX pin 37 connected to receiver
+ * Set IRX_MSL since we have 2 * receive paths IRRX,
+ * and IRRXH. Clear IRSL0D since we want IRSL0 * to
+ * be a input pin used for IRRXH
+ *
+ * IRRX pin 37 connected to receiver
* IRTX pin 38 connected to transmitter
- * FIRRX pin 39 connected to receiver (IRSL0)
+ * FIRRX pin 39 connected to receiver (IRSL0)
* CIRRX pin 40 connected to pin 37
*/
switch_bank(iobase, SET7);
outb(0x40, iobase+7);
-
+
net_info_ratelimited("W83977AF (IR) driver loaded. Version: 0x%02x\n",
version);
-
+
return 0;
} else {
/* Try next extented function register address */
pr_debug("%s(), Wrong chip version", __func__);
}
- }
+ }
return -1;
}
static void w83977af_change_speed(struct w83977af_ir *self, __u32 speed)
{
int ir_mode = HCR_SIR;
- int iobase;
+ int iobase;
__u8 set;
iobase = self->io.fir_base;
@@ -448,8 +448,8 @@ static void w83977af_change_speed(struct w83977af_ir *self, __u32 speed)
/* set FIFO size to 32 */
switch_bank(iobase, SET2);
- outb(ADCR2_RXFS32|ADCR2_TXFS32, iobase+ADCR2);
-
+ outb(ADCR2_RXFS32|ADCR2_TXFS32, iobase+ADCR2);
+
/* set FIFO threshold to TX17, RX16 */
switch_bank(iobase, SET0);
outb(0x00, iobase+UFR); /* Reset */
@@ -457,7 +457,7 @@ static void w83977af_change_speed(struct w83977af_ir *self, __u32 speed)
outb(0xa7, iobase+UFR);
netif_wake_queue(self->netdev);
-
+
/* Enable some interrupts so we can receive frames */
switch_bank(iobase, SET0);
if (speed > PIO_MAX_SPEED) {
@@ -465,7 +465,7 @@ static void w83977af_change_speed(struct w83977af_ir *self, __u32 speed)
w83977af_dma_receive(self);
} else
outb(ICR_ERBRI, iobase+ICR);
-
+
/* Restore SSR */
outb(set, iobase+SSR);
}
@@ -484,23 +484,23 @@ static netdev_tx_t w83977af_hard_xmit(struct sk_buff *skb,
int iobase;
__u8 set;
int mtt;
-
+
self = netdev_priv(dev);
iobase = self->io.fir_base;
pr_debug("%s(%ld), skb->len=%d\n", __func__ , jiffies,
(int)skb->len);
-
+
/* Lock transmit buffer */
netif_stop_queue(dev);
-
+
/* Check if we need to change the speed */
speed = irda_get_next_speed(skb);
if ((speed != self->io.speed) && (speed != -1)) {
/* Check for empty frame */
if (!skb->len) {
- w83977af_change_speed(self, speed);
+ w83977af_change_speed(self, speed);
dev_kfree_skb(skb);
return NETDEV_TX_OK;
} else
@@ -509,29 +509,29 @@ static netdev_tx_t w83977af_hard_xmit(struct sk_buff *skb,
/* Save current set */
set = inb(iobase+SSR);
-
+
/* Decide if we should use PIO or DMA transfer */
if (self->io.speed > PIO_MAX_SPEED) {
self->tx_buff.data = self->tx_buff.head;
skb_copy_from_linear_data(skb, self->tx_buff.data, skb->len);
self->tx_buff.len = skb->len;
-
+
mtt = irda_get_mtt(skb);
pr_debug("%s(%ld), mtt=%d\n", __func__ , jiffies, mtt);
- if (mtt > 1000)
- mdelay(mtt/1000);
- else if (mtt)
- udelay(mtt);
+ if (mtt > 1000)
+ mdelay(mtt/1000);
+ else if (mtt)
+ udelay(mtt);
- /* Enable DMA interrupt */
- switch_bank(iobase, SET0);
- outb(ICR_EDMAI, iobase+ICR);
- w83977af_dma_write(self, iobase);
+ /* Enable DMA interrupt */
+ switch_bank(iobase, SET0);
+ outb(ICR_EDMAI, iobase+ICR);
+ w83977af_dma_write(self, iobase);
} else {
self->tx_buff.data = self->tx_buff.head;
- self->tx_buff.len = async_wrap_skb(skb, self->tx_buff.data,
+ self->tx_buff.len = async_wrap_skb(skb, self->tx_buff.data,
self->tx_buff.truesize);
-
+
/* Add interrupt on tx low level (will fire immediately) */
switch_bank(iobase, SET0);
outb(ICR_ETXTHI, iobase+ICR);
@@ -562,15 +562,15 @@ static void w83977af_dma_write(struct w83977af_ir *self, int iobase)
switch_bank(iobase, SET0);
outb(inb(iobase+HCR) & ~HCR_EN_DMA, iobase+HCR);
- /* Choose transmit DMA channel */
+ /* Choose transmit DMA channel */
switch_bank(iobase, SET2);
outb(ADCR1_D_CHSW|/*ADCR1_DMA_F|*/ADCR1_ADV_SL, iobase+ADCR1);
irda_setup_dma(self->io.dma, self->tx_buff_dma, self->tx_buff.len,
- DMA_MODE_WRITE);
+ DMA_MODE_WRITE);
self->io.direction = IO_XMIT;
-
+
/* Enable DMA */
- switch_bank(iobase, SET0);
+ switch_bank(iobase, SET0);
outb(inb(iobase+HCR) | HCR_EN_DMA | HCR_TX_WT, iobase+HCR);
/* Restore set register */
@@ -580,14 +580,14 @@ static void w83977af_dma_write(struct w83977af_ir *self, int iobase)
/*
* Function w83977af_pio_write (iobase, buf, len, fifo_size)
*
- *
+ *
*
*/
static int w83977af_pio_write(int iobase, __u8 *buf, int len, int fifo_size)
{
int actual = 0;
__u8 set;
-
+
/* Save current bank */
set = inb(iobase+SSR);
@@ -605,7 +605,7 @@ static int w83977af_pio_write(int iobase, __u8 *buf, int len, int fifo_size)
/* Transmit next byte */
outb(buf[actual++], iobase+TBR);
}
-
+
pr_debug("%s(), fifo_size %d ; %d sent of %d\n",
__func__ , fifo_size, actual, len);
@@ -620,7 +620,7 @@ static int w83977af_pio_write(int iobase, __u8 *buf, int len, int fifo_size)
*
* The transfer of a frame in finished. So do the necessary things
*
- *
+ *
*/
static void w83977af_dma_xmit_complete(struct w83977af_ir *self)
{
@@ -639,11 +639,11 @@ static void w83977af_dma_xmit_complete(struct w83977af_ir *self)
/* Disable DMA */
switch_bank(iobase, SET0);
outb(inb(iobase+HCR) & ~HCR_EN_DMA, iobase+HCR);
-
+
/* Check for underrun! */
if (inb(iobase+AUDR) & AUDR_UNDR) {
pr_debug("%s(), Transmit underrun!\n", __func__);
-
+
self->netdev->stats.tx_errors++;
self->netdev->stats.tx_fifo_errors++;
@@ -652,7 +652,7 @@ static void w83977af_dma_xmit_complete(struct w83977af_ir *self)
} else
self->netdev->stats.tx_packets++;
-
+
if (self->new_speed) {
w83977af_change_speed(self, self->new_speed);
self->new_speed = 0;
@@ -661,7 +661,7 @@ static void w83977af_dma_xmit_complete(struct w83977af_ir *self)
/* Unlock tx_buff and request another frame */
/* Tell the network layer, that we want more frames */
netif_wake_queue(self->netdev);
-
+
/* Restore set */
outb(set, iobase+SSR);
}
@@ -714,15 +714,15 @@ static int w83977af_dma_receive(struct w83977af_ir *self)
irda_setup_dma(self->io.dma, self->rx_buff_dma, self->rx_buff.truesize,
DMA_MODE_READ);
#endif
- /*
- * Reset Rx FIFO. This will also flush the ST_FIFO, it's very
+ /*
+ * Reset Rx FIFO. This will also flush the ST_FIFO, it's very
* important that we don't reset the Tx FIFO since it might not
* be finished transmitting yet
*/
switch_bank(iobase, SET0);
outb(UFR_RXTL|UFR_TXTL|UFR_RXF_RST|UFR_EN_FIFO, iobase+UFR);
self->st_fifo.len = self->st_fifo.tail = self->st_fifo.head = 0;
-
+
/* Enable DMA */
switch_bank(iobase, SET0);
#ifdef CONFIG_ARCH_NETWINDER
@@ -730,7 +730,7 @@ static int w83977af_dma_receive(struct w83977af_ir *self)
outb(hcr | HCR_EN_DMA, iobase+HCR);
enable_dma(self->io.dma);
spin_unlock_irqrestore(&self->lock, flags);
-#else
+#else
outb(inb(iobase+HCR) | HCR_EN_DMA, iobase+HCR);
#endif
/* Restore set */
@@ -762,21 +762,21 @@ static int w83977af_dma_receive_complete(struct w83977af_ir *self)
/* Save current set */
set = inb(iobase+SSR);
-
+
iobase = self->io.fir_base;
/* Read status FIFO */
switch_bank(iobase, SET5);
while ((status = inb(iobase+FS_FO)) & FS_FO_FSFDR) {
st_fifo->entries[st_fifo->tail].status = status;
-
+
st_fifo->entries[st_fifo->tail].len = inb(iobase+RFLFL);
st_fifo->entries[st_fifo->tail].len |= inb(iobase+RFLFH) << 8;
-
+
st_fifo->tail++;
st_fifo->len++;
}
-
+
while (st_fifo->len) {
/* Get first entry */
status = st_fifo->entries[st_fifo->head].status;
@@ -792,32 +792,32 @@ static int w83977af_dma_receive_complete(struct w83977af_ir *self)
} else {
/* Skip frame */
self->netdev->stats.rx_errors++;
-
+
self->rx_buff.data += len;
-
+
if (status & FS_FO_MX_LEX)
self->netdev->stats.rx_length_errors++;
-
- if (status & FS_FO_PHY_ERR)
+
+ if (status & FS_FO_PHY_ERR)
self->netdev->stats.rx_frame_errors++;
-
- if (status & FS_FO_CRC_ERR)
+
+ if (status & FS_FO_CRC_ERR)
self->netdev->stats.rx_crc_errors++;
}
/* The errors below can be reported in both cases */
if (status & FS_FO_RX_OV)
self->netdev->stats.rx_fifo_errors++;
-
+
if (status & FS_FO_FSF_OV)
self->netdev->stats.rx_fifo_errors++;
-
+
} else {
/* Check if we have transferred all data to memory */
switch_bank(iobase, SET0);
if (inb(iobase+USR) & USR_RDR) {
udelay(80); /* Should be enough!? */
}
-
+
skb = dev_alloc_skb(len+1);
if (skb == NULL) {
printk(KERN_INFO
@@ -827,10 +827,10 @@ static int w83977af_dma_receive_complete(struct w83977af_ir *self)
return FALSE;
}
-
+
/* Align to 20 bytes */
- skb_reserve(skb, 1);
-
+ skb_reserve(skb, 1);
+
/* Copy frame without CRC */
if (self->io.speed < 4000000) {
skb_put(skb, len-2);
@@ -847,7 +847,7 @@ static int w83977af_dma_receive_complete(struct w83977af_ir *self)
/* Move to next frame */
self->rx_buff.data += len;
self->netdev->stats.rx_packets++;
-
+
skb->dev = self->netdev;
skb_reset_mac_header(skb);
skb->protocol = htons(ETH_P_IRDA);
@@ -866,21 +866,21 @@ static int w83977af_dma_receive_complete(struct w83977af_ir *self)
* Receive all data in receiver FIFO
*
*/
-static void w83977af_pio_receive(struct w83977af_ir *self)
+static void w83977af_pio_receive(struct w83977af_ir *self)
{
__u8 byte = 0x00;
int iobase;
IRDA_ASSERT(self != NULL, return;);
-
+
iobase = self->io.fir_base;
-
+
/* Receive all characters in Rx FIFO */
do {
byte = inb(iobase+RBR);
async_unwrap_char(self->netdev, &self->netdev->stats, &self->rx_buff,
byte);
- } while (inb(iobase+USR) & USR_RDR); /* Data available */
+ } while (inb(iobase+USR) & USR_RDR); /* Data available */
}
/*
@@ -897,19 +897,19 @@ static __u8 w83977af_sir_interrupt(struct w83977af_ir *self, int isr)
int iobase;
pr_debug("%s(), isr=%#x\n", __func__ , isr);
-
+
iobase = self->io.fir_base;
/* Transmit FIFO low on data */
if (isr & ISR_TXTH_I) {
/* Write data left in transmit buffer */
- actual = w83977af_pio_write(self->io.fir_base,
- self->tx_buff.data,
- self->tx_buff.len,
+ actual = w83977af_pio_write(self->io.fir_base,
+ self->tx_buff.data,
+ self->tx_buff.len,
self->io.fifo_size);
self->tx_buff.data += actual;
self->tx_buff.len -= actual;
-
+
self->io.direction = IO_XMIT;
/* Check if finished */
@@ -919,7 +919,7 @@ static __u8 w83977af_sir_interrupt(struct w83977af_ir *self, int isr)
set = inb(iobase+SSR);
switch_bank(iobase, SET0);
outb(AUDR_SFEND, iobase+AUDR);
- outb(set, iobase+SSR);
+ outb(set, iobase+SSR);
self->netdev->stats.tx_packets++;
@@ -929,7 +929,7 @@ static __u8 w83977af_sir_interrupt(struct w83977af_ir *self, int isr)
}
}
/* Check if transmission has completed */
- if (isr & ISR_TXEMP_I) {
+ if (isr & ISR_TXEMP_I) {
/* Check if we need to change the speed? */
if (self->new_speed) {
pr_debug("%s(), Changing speed!\n", __func__);
@@ -966,11 +966,11 @@ static __u8 w83977af_fir_interrupt(struct w83977af_ir *self, int isr)
iobase = self->io.fir_base;
set = inb(iobase+SSR);
-
+
/* End of frame detected in FIFO */
if (isr & (ISR_FEND_I|ISR_FSF_I)) {
if (w83977af_dma_receive_complete(self)) {
-
+
/* Wait for next status FIFO interrupt */
new_icr |= ICR_EFSFI;
} else {
@@ -995,7 +995,7 @@ static __u8 w83977af_fir_interrupt(struct w83977af_ir *self, int isr)
/* Clear timer event */
/* switch_bank(iobase, SET0); */
-/* outb(ASCR_CTE, iobase+ASCR); */
+/* outb(ASCR_CTE, iobase+ASCR); */
/* Check if this is a TX timer interrupt */
if (self->io.direction == IO_XMIT) {
@@ -1008,23 +1008,23 @@ static __u8 w83977af_fir_interrupt(struct w83977af_ir *self, int isr)
new_icr |= ICR_EFSFI;
}
- }
+ }
/* Finished with DMA */
if (isr & ISR_DMA_I) {
w83977af_dma_xmit_complete(self);
/* Check if there are more frames to be transmitted */
/* if (irda_device_txqueue_empty(self)) { */
-
- /* Prepare for receive
- *
+
+ /* Prepare for receive
+ *
* ** Netwinder Tx DMA likes that we do this anyway **
*/
w83977af_dma_receive(self);
new_icr = ICR_EFSFI;
- /* } */
+ /* } */
}
-
+
/* Restore set */
outb(set, iobase+SSR);
@@ -1051,12 +1051,12 @@ static irqreturn_t w83977af_interrupt(int irq, void *dev_id)
/* Save current bank */
set = inb(iobase+SSR);
switch_bank(iobase, SET0);
-
- icr = inb(iobase+ICR);
- isr = inb(iobase+ISR) & icr; /* Mask out the interesting ones */
+
+ icr = inb(iobase+ICR);
+ isr = inb(iobase+ISR) & icr; /* Mask out the interesting ones */
outb(0, iobase+ICR); /* Disable interrupts */
-
+
if (isr) {
/* Dispatch interrupt handler for the current speed */
if (self->io.speed > PIO_MAX_SPEED )
@@ -1095,9 +1095,9 @@ static int w83977af_is_receiving(struct w83977af_ir *self)
status = TRUE;
}
outb(set, iobase+SSR);
- } else
+ } else
status = (self->rx_buff.state != OUTSIDE_FRAME);
-
+
return status;
}
@@ -1113,16 +1113,16 @@ static int w83977af_net_open(struct net_device *dev)
int iobase;
char hwname[32];
__u8 set;
-
-
+
+
IRDA_ASSERT(dev != NULL, return -1;);
self = netdev_priv(dev);
-
+
IRDA_ASSERT(self != NULL, return 0;);
-
+
iobase = self->io.fir_base;
- if (request_irq(self->io.irq, w83977af_interrupt, 0, dev->name,
+ if (request_irq(self->io.irq, w83977af_interrupt, 0, dev->name,
(void *) dev)) {
return -EAGAIN;
}
@@ -1134,30 +1134,30 @@ static int w83977af_net_open(struct net_device *dev)
free_irq(self->io.irq, dev);
return -EAGAIN;
}
-
+
/* Save current set */
set = inb(iobase+SSR);
- /* Enable some interrupts so we can receive frames again */
- switch_bank(iobase, SET0);
- if (self->io.speed > 115200) {
- outb(ICR_EFSFI, iobase+ICR);
- w83977af_dma_receive(self);
- } else
- outb(ICR_ERBRI, iobase+ICR);
+ /* Enable some interrupts so we can receive frames again */
+ switch_bank(iobase, SET0);
+ if (self->io.speed > 115200) {
+ outb(ICR_EFSFI, iobase+ICR);
+ w83977af_dma_receive(self);
+ } else
+ outb(ICR_ERBRI, iobase+ICR);
/* Restore bank register */
outb(set, iobase+SSR);
/* Ready to play! */
netif_start_queue(dev);
-
+
/* Give self a hardware name */
sprintf(hwname, "w83977af @ 0x%03x", self->io.fir_base);
- /*
+ /*
* Open new IrLAP layer instance, now that everything should be
- * initialized properly
+ * initialized properly
*/
self->irlap = irlap_open(dev, &self->qos, hwname);
@@ -1177,16 +1177,16 @@ static int w83977af_net_close(struct net_device *dev)
__u8 set;
IRDA_ASSERT(dev != NULL, return -1;);
-
+
self = netdev_priv(dev);
-
+
IRDA_ASSERT(self != NULL, return 0;);
-
+
iobase = self->io.fir_base;
/* Stop device */
netif_stop_queue(dev);
-
+
/* Stop and remove instance of IrLAP */
if (self->irlap)
irlap_close(self->irlap);
@@ -1196,10 +1196,10 @@ static int w83977af_net_close(struct net_device *dev)
/* Save current set */
set = inb(iobase+SSR);
-
+
/* Disable interrupts */
switch_bank(iobase, SET0);
- outb(0, iobase+ICR);
+ outb(0, iobase+ICR);
free_irq(self->io.irq, dev);
free_dma(self->io.dma);
@@ -1230,7 +1230,7 @@ static int w83977af_net_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
IRDA_ASSERT(self != NULL, return -1;);
pr_debug("%s(), %s, (cmd=0x%X)\n", __func__ , dev->name, cmd);
-
+
spin_lock_irqsave(&self->lock, flags);
switch (cmd) {
@@ -1274,7 +1274,7 @@ MODULE_PARM_DESC(irq, "IRQ lines");
/*
* Function init_module (void)
*
- *
+ *
*
*/
module_init(w83977af_init);
@@ -1282,7 +1282,7 @@ module_init(w83977af_init);
/*
* Function cleanup_module (void)
*
- *
+ *
*
*/
module_exit(w83977af_cleanup);
--
2.9.0
^ permalink raw reply related
* [PATCH v2] net: phy: Fix use after free in phy_detach()
From: Geert Uytterhoeven @ 2016-11-28 14:18 UTC (permalink / raw)
To: Florian Fainelli, David S. Miller, Josh Cartwright,
Nathan Sullivan, Zach Brown
Cc: Woojung Huh, netdev, linux-renesas-soc, linux-kernel,
Geert Uytterhoeven
If device_release_driver(&phydev->mdio.dev) is called, it releases all
resources belonging to the PHY device. Hence the subsequent call to
phy_led_triggers_unregister() will access already freed memory when
unregistering the LEDs.
Move the call to phy_led_triggers_unregister() before the possible call
to device_release_driver() to fix this.
Fixes: 2e0bc452f4721520 ("net: phy: leds: add support for led triggers on phy link state change")
Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
---
This is v2 of "[RFC] net: phy: Fix double free in phy_detach()".
v2:
- Dropped RFC,
- Reworded, as commit a7dac9f9c1695d74 ("phy: fix error case of
phy_led_triggers_(un)register") fixed the double free, and thus the
warning I was seeing during "poweroff" on sh73a0/kzm9g,
- Verified use after free using CONFIG_DEBUG_DEVRES, log_devres = 1,
and additional debug code printing the address of
phy->phy_led_triggers. Adding poisoning of freed memory to
devres_log() will cause a crash.
---
drivers/net/phy/phy_device.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c
index ba86c191a13ea81c..a1d6e13b1b4113a4 100644
--- a/drivers/net/phy/phy_device.c
+++ b/drivers/net/phy/phy_device.c
@@ -981,6 +981,8 @@ void phy_detach(struct phy_device *phydev)
phydev->attached_dev = NULL;
phy_suspend(phydev);
+ phy_led_triggers_unregister(phydev);
+
/* If the device had no specific driver before (i.e. - it
* was using the generic driver), we unbind the device
* from the generic driver so that there's a chance a
@@ -994,8 +996,6 @@ void phy_detach(struct phy_device *phydev)
}
}
- phy_led_triggers_unregister(phydev);
-
/*
* The phydev might go away on the put_device() below, so avoid
* a use-after-free bug by reading the underlying bus first.
--
1.9.1
^ permalink raw reply related
* Re: [PATCH net-next 1/3] ethtool: (uapi) Add ETHTOOL_PHY_LOOPBACK to PHY tunables
From: Andrew Lunn @ 2016-11-28 14:14 UTC (permalink / raw)
To: Allan W. Nielsen; +Cc: netdev, f.fainelli, raju.lakkaraju
In-Reply-To: <1480339472-5823-2-git-send-email-allan.nielsen@microsemi.com>
On Mon, Nov 28, 2016 at 02:24:30PM +0100, Allan W. Nielsen wrote:
> From: Raju Lakkaraju <Raju.Lakkaraju@microsemi.com>
>
> 3 types of PHY loopback are supported.
> i.e. Near-End Loopback, Far-End Loopback and External Loopback.
Hi Allan
Is this integrated with ethtool --test? You only want the PHY to go
into loopback mode when running ethtool --test external_lb or maybe
ethtool --test offline.
What i think should happen is that this tunable sets the mode the PHY
will go into when loopback is enabled. It does not however enable
loopback. It is running ethtool --test which actually enables the
loopback, probably by setting BMCR_LOOPBACK. Once the test is
finished, the bit is cleared and the PHY goes back into normal
operation.
Andrew
^ permalink raw reply
* Re: net/sctp: vmalloc allocation failure in sctp_setsockopt/xt_alloc_table_info
From: Neil Horman @ 2016-11-28 14:13 UTC (permalink / raw)
To: Andrey Konovalov
Cc: Vlad Yasevich, linux-sctp, netdev, LKML, Pablo Neira Ayuso,
Patrick McHardy, Jozsef Kadlecsik, David S. Miller,
netfilter-devel, coreteam, Dmitry Vyukov, Kostya Serebryany,
Eric Dumazet, syzkaller
In-Reply-To: <CAAeHK+wecw6ST_DWJQBLFNwVsOVgderGE-EEJiN0-kf796XHtw@mail.gmail.com>
On Mon, Nov 28, 2016 at 02:00:19PM +0100, Andrey Konovalov wrote:
> Hi!
>
> I've got the following error report while running the syzkaller fuzzer.
>
> On commit d8e435f3ab6fea2ea324dce72b51dd7761747523 (Nov 26).
>
> A reproducer is attached.
>
> a.out: vmalloc: allocation failure, allocated 823562240 of 1427091456
> bytes, mode:0x24000c2(GFP_KERNEL|__GFP_HIGHMEM)
>
How much total ram do you have in this system? The call appears to be
attempting to allocate 1.3 Gb of data. Even using vmalloc to allow
discontiguous allocation, thats alot of memory, and if enough is in use already,
I could make the argument that this might be expected behavior.
Neil
> oom_reaper: reaped process 3810 (a.out), now anon-rss:0kB,
> file-rss:0kB, shmem-rss:0kB
> a.out invoked oom-killer:
> gfp_mask=0x24002c2(GFP_KERNEL|__GFP_HIGHMEM|__GFP_NOWARN), nodemask=0,
> order=0, oom_score_adj=0
> a.out cpuset=/ mems_allowed=0
> CPU: 0 PID: 3814 Comm: a.out Not tainted 4.9.0-rc6+ #457
> Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Bochs 01/01/2011
> ffff880068667380 ffffffff81c73b14 ffff880068667710 ffff88006b469018
> ffff880068667718 0000000000000000 ffff880068667400 ffffffff81641a87
> 0000000000000000 0000000000000000 0000000000000297 ffffffff84d37280
> Call Trace:
> [< inline >] __dump_stack lib/dump_stack.c:15
> [<ffffffff81c73b14>] dump_stack+0xb3/0x10f lib/dump_stack.c:51
> [<ffffffff81641a87>] dump_header.isra.21+0x16f/0x5f5 mm/oom_kill.c:416
> [<ffffffff8154bad8>] oom_kill_process+0x4d8/0xab0 mm/oom_kill.c:835
> [<ffffffff8154c77c>] out_of_memory+0x2dc/0x1790 mm/oom_kill.c:1044
> [< inline >] __alloc_pages_may_oom mm/page_alloc.c:3086
> [<ffffffff8155afb6>] __alloc_pages_slowpath+0x1886/0x1bf0 mm/page_alloc.c:3683
> [<ffffffff8155b8e2>] __alloc_pages_nodemask+0x5c2/0x710 mm/page_alloc.c:3781
> [<ffffffff816236a4>] alloc_pages_current+0xf4/0x400 mm/mempolicy.c:2072
> [< inline >] alloc_pages ./include/linux/gfp.h:469
> [< inline >] __vmalloc_area_node mm/vmalloc.c:1631
> [<ffffffff815f8eab>] __vmalloc_node_range+0x33b/0x690 mm/vmalloc.c:1691
> [< inline >] __vmalloc_node mm/vmalloc.c:1734
> [< inline >] __vmalloc_node_flags mm/vmalloc.c:1748
> [<ffffffff815f92cb>] vmalloc+0x5b/0x70 mm/vmalloc.c:1763
> [<ffffffff82fd0893>] xt_alloc_table_info+0x83/0x120
> net/netfilter/x_tables.c:961
> [< inline >] do_replace net/ipv4/netfilter/ip_tables.c:1140
> [<ffffffff8335b420>] do_ipt_set_ctl+0x210/0x420
> net/ipv4/netfilter/ip_tables.c:1687
> [< inline >] nf_sockopt net/netfilter/nf_sockopt.c:105
> [<ffffffff82efdab7>] nf_setsockopt+0x67/0xc0 net/netfilter/nf_sockopt.c:114
> [<ffffffff831be741>] ip_setsockopt+0xa1/0xb0 net/ipv4/ip_sockglue.c:1231
> [<ffffffff832700d5>] udp_setsockopt+0x45/0x80 net/ipv4/udp.c:2085
> [<ffffffff8346b31f>] ipv6_setsockopt+0x11f/0x140 net/ipv6/ipv6_sockglue.c:892
> [<ffffffff83a6cd5d>] sctp_setsockopt+0x15d/0x3d70 net/sctp/socket.c:3788
> [<ffffffff82ca40e6>] sock_common_setsockopt+0x96/0xd0 net/core/sock.c:2690
> [< inline >] SYSC_setsockopt net/socket.c:1757
> [<ffffffff82ca10c4>] SyS_setsockopt+0x154/0x240 net/socket.c:1736
> [<ffffffff840f2c41>] entry_SYSCALL_64_fastpath+0x1f/0xc2
> arch/x86/entry/entry_64.S:209
> CPU: 1 PID: 3810 Comm: a.out Not tainted 4.9.0-rc6+ #457
> Mem-Info:
> active_anon:1938 inactive_anon:75 isolated_anon:0
> active_file:14 inactive_file:30 isolated_file:4
> unevictable:0 dirty:0 writeback:0 unstable:0
> slab_reclaimable:3316 slab_unreclaimable:9767
> mapped:21 shmem:81 pagetables:309 bounce:0
> free:1 free_pcp:75 free_cma:0
> Node 0 active_anon:7752kB inactive_anon:300kB active_file:56kB
> inactive_file:120kB unevictable:0kB isolated(anon):0kB
> isolated(file):16kB mapped:84kB dirty:0kB writeback:0kB shmem:324kB
> writeback_tmp:0kB unstable:0kB pages_scanned:134 all_unreclaimable? no
> Node 0 DMA free:4kB min:48kB low:60kB high:72kB active_anon:0kB
> inactive_anon:0kB active_file:0kB inactive_file:0kB unevictable:0kB
> writepending:0kB present:15992kB managed:15908kB mlocked:0kB
> slab_reclaimable:0kB slab_unreclaimable:8kB kernel_stack:0kB
> pagetables:0kB bounce:0kB free_pcp:0kB local_pcp:0kB free_cma:0kB
> lowmem_reserve[]: 0 1641 1641 1641
> Node 0 DMA32 free:0kB min:5156kB low:6836kB high:8516kB
> active_anon:7752kB inactive_anon:300kB active_file:56kB
> inactive_file:120kB unevictable:0kB writepending:0kB present:2080760kB
> managed:1684640kB mlocked:0kB slab_reclaimable:13264kB
> slab_unreclaimable:39060kB kernel_stack:2944kB pagetables:1236kB
> bounce:0kB free_pcp:300kB local_pcp:120kB free_cma:0kB
> lowmem_reserve[]: 0 0 0 0
> Node 0 DMA: 0*4kB 0*8kB 0*16kB 0*32kB 0*64kB 0*128kB 0*256kB 0*512kB
> 0*1024kB 0*2048kB 0*4096kB = 0kB
> Node 0 DMA32: 0*4kB 0*8kB 0*16kB 0*32kB 0*64kB 0*128kB 0*256kB 0*512kB
> 0*1024kB 0*2048kB 0*4096kB = 0kB
> Node 0 hugepages_total=0 hugepages_free=0 hugepages_surp=0 hugepages_size=2048kB
> 148 total pagecache pages
> 0 pages in swap cache
> Swap cache stats: add 0, delete 0, find 0/0
> Free swap = 0kB
> Total swap = 0kB
> 524188 pages RAM
> 0 pages HighMem/MovableOnly
> 99051 pages reserved
> [ pid ] uid tgid total_vm rss nr_ptes nr_pmds swapents
> oom_score_adj name
> 0 1767 5346 133 16 3 0 -1000 udevd
> 0 1876 5315 122 15 3 0 -1000 udevd
> 0 1877 5315 122 15 3 0 -1000 udevd
> 0 3541 2493 573 8 3 0 0 dhclient
> 0 3676 13231 171 22 3 0 0 rsyslogd
> 0 3725 4725 52 15 3 0 0 cron
> 0 3751 12490 155 28 3 0 -1000 sshd
> 0 3775 3694 43 13 3 0 0 getty
> 0 3776 3694 43 13 3 0 0 getty
> 0 3777 3694 42 13 3 0 0 getty
> 0 3778 3694 41 13 3 0 0 getty
> 0 3779 3694 44 13 3 0 0 getty
> 0 3780 3694 43 13 3 0 0 getty
> 0 3785 3649 44 12 3 0 0 getty
> 0 3797 17818 205 39 3 0 0 sshd
> 0 3800 4474 126 15 3 0 0 bash
> 0 3804 2053 22 9 3 0 0 a.out
> 0 3805 2053 26 9 3 0 0 a.out
> 0 3806 18488 0 18 3 0 0 a.out
> // autogenerated by syzkaller (http://github.com/google/syzkaller)
>
> #ifndef __NR_mmap
> #define __NR_mmap 9
> #endif
> #ifndef __NR_setsockopt
> #define __NR_setsockopt 54
> #endif
> #ifndef __NR_syz_fuse_mount
> #define __NR_syz_fuse_mount 1000004
> #endif
> #ifndef __NR_socket
> #define __NR_socket 41
> #endif
> #ifndef __NR_syz_emit_ethernet
> #define __NR_syz_emit_ethernet 1000006
> #endif
> #ifndef __NR_syz_fuseblk_mount
> #define __NR_syz_fuseblk_mount 1000005
> #endif
> #ifndef __NR_syz_open_dev
> #define __NR_syz_open_dev 1000002
> #endif
> #ifndef __NR_syz_open_pts
> #define __NR_syz_open_pts 1000003
> #endif
> #ifndef __NR_syz_test
> #define __NR_syz_test 1000001
> #endif
>
> #define SYZ_SANDBOX_NONE 1
> #define SYZ_REPEAT 1
>
> #define _GNU_SOURCE
>
> #include <sys/ioctl.h>
> #include <sys/mount.h>
> #include <sys/prctl.h>
> #include <sys/resource.h>
> #include <sys/socket.h>
> #include <sys/stat.h>
> #include <sys/syscall.h>
> #include <sys/time.h>
> #include <sys/types.h>
> #include <sys/wait.h>
>
> #include <linux/capability.h>
> #include <linux/if.h>
> #include <linux/if_tun.h>
> #include <linux/sched.h>
> #include <net/if_arp.h>
>
> #include <assert.h>
> #include <dirent.h>
> #include <errno.h>
> #include <fcntl.h>
> #include <grp.h>
> #include <pthread.h>
> #include <setjmp.h>
> #include <signal.h>
> #include <stdarg.h>
> #include <stddef.h>
> #include <stdint.h>
> #include <stdio.h>
> #include <stdlib.h>
> #include <string.h>
> #include <unistd.h>
>
> const int kFailStatus = 67;
> const int kErrorStatus = 68;
> const int kRetryStatus = 69;
>
> __attribute__((noreturn)) void fail(const char* msg, ...)
> {
> int e = errno;
> fflush(stdout);
> va_list args;
> va_start(args, msg);
> vfprintf(stderr, msg, args);
> va_end(args);
> fprintf(stderr, " (errno %d)\n", e);
> exit(kFailStatus);
> }
>
> __attribute__((noreturn)) void exitf(const char* msg, ...)
> {
> int e = errno;
> fflush(stdout);
> va_list args;
> va_start(args, msg);
> vfprintf(stderr, msg, args);
> va_end(args);
> fprintf(stderr, " (errno %d)\n", e);
> exit(kRetryStatus);
> }
>
> static int flag_debug;
>
> void debug(const char* msg, ...)
> {
> if (!flag_debug)
> return;
> va_list args;
> va_start(args, msg);
> vfprintf(stdout, msg, args);
> va_end(args);
> fflush(stdout);
> }
>
> __thread int skip_segv;
> __thread jmp_buf segv_env;
>
> static void segv_handler(int sig, siginfo_t* info, void* uctx)
> {
> if (__atomic_load_n(&skip_segv, __ATOMIC_RELAXED))
> _longjmp(segv_env, 1);
> exit(sig);
> }
>
> static void install_segv_handler()
> {
> struct sigaction sa;
> memset(&sa, 0, sizeof(sa));
> sa.sa_sigaction = segv_handler;
> sa.sa_flags = SA_NODEFER | SA_SIGINFO;
> sigaction(SIGSEGV, &sa, NULL);
> sigaction(SIGBUS, &sa, NULL);
> }
>
> #define NONFAILING(...) \
> { \
> __atomic_fetch_add(&skip_segv, 1, __ATOMIC_SEQ_CST); \
> if (_setjmp(segv_env) == 0) { \
> __VA_ARGS__; \
> } \
> __atomic_fetch_sub(&skip_segv, 1, __ATOMIC_SEQ_CST); \
> }
>
> static uintptr_t syz_open_dev(uintptr_t a0, uintptr_t a1, uintptr_t a2)
> {
> if (a0 == 0xc || a0 == 0xb) {
> char buf[128];
> sprintf(buf, "/dev/%s/%d:%d", a0 == 0xc ? "char" : "block",
> (uint8_t)a1, (uint8_t)a2);
> return open(buf, O_RDWR, 0);
> } else {
> char buf[1024];
> char* hash;
> strncpy(buf, (char*)a0, sizeof(buf));
> buf[sizeof(buf) - 1] = 0;
> while ((hash = strchr(buf, '#'))) {
> *hash = '0' + (char)(a1 % 10);
> a1 /= 10;
> }
> return open(buf, a2, 0);
> }
> }
>
> static uintptr_t syz_open_pts(uintptr_t a0, uintptr_t a1)
> {
> int ptyno = 0;
> if (ioctl(a0, TIOCGPTN, &ptyno))
> return -1;
> char buf[128];
> sprintf(buf, "/dev/pts/%d", ptyno);
> return open(buf, a1, 0);
> }
>
> static uintptr_t syz_fuse_mount(uintptr_t a0, uintptr_t a1,
> uintptr_t a2, uintptr_t a3,
> uintptr_t a4, uintptr_t a5)
> {
> uint64_t target = a0;
> uint64_t mode = a1;
> uint64_t uid = a2;
> uint64_t gid = a3;
> uint64_t maxread = a4;
> uint64_t flags = a5;
>
> int fd = open("/dev/fuse", O_RDWR);
> if (fd == -1)
> return fd;
> char buf[1024];
> sprintf(buf, "fd=%d,user_id=%ld,group_id=%ld,rootmode=0%o", fd,
> (long)uid, (long)gid, (unsigned)mode & ~3u);
> if (maxread != 0)
> sprintf(buf + strlen(buf), ",max_read=%ld", (long)maxread);
> if (mode & 1)
> strcat(buf, ",default_permissions");
> if (mode & 2)
> strcat(buf, ",allow_other");
> syscall(SYS_mount, "", target, "fuse", flags, buf);
> return fd;
> }
>
> static uintptr_t syz_fuseblk_mount(uintptr_t a0, uintptr_t a1,
> uintptr_t a2, uintptr_t a3,
> uintptr_t a4, uintptr_t a5,
> uintptr_t a6, uintptr_t a7)
> {
> uint64_t target = a0;
> uint64_t blkdev = a1;
> uint64_t mode = a2;
> uint64_t uid = a3;
> uint64_t gid = a4;
> uint64_t maxread = a5;
> uint64_t blksize = a6;
> uint64_t flags = a7;
>
> int fd = open("/dev/fuse", O_RDWR);
> if (fd == -1)
> return fd;
> if (syscall(SYS_mknodat, AT_FDCWD, blkdev, S_IFBLK, makedev(7, 199)))
> return fd;
> char buf[256];
> sprintf(buf, "fd=%d,user_id=%ld,group_id=%ld,rootmode=0%o", fd,
> (long)uid, (long)gid, (unsigned)mode & ~3u);
> if (maxread != 0)
> sprintf(buf + strlen(buf), ",max_read=%ld", (long)maxread);
> if (blksize != 0)
> sprintf(buf + strlen(buf), ",blksize=%ld", (long)blksize);
> if (mode & 1)
> strcat(buf, ",default_permissions");
> if (mode & 2)
> strcat(buf, ",allow_other");
> syscall(SYS_mount, blkdev, target, "fuseblk", flags, buf);
> return fd;
> }
>
> static uintptr_t execute_syscall(int nr, uintptr_t a0, uintptr_t a1,
> uintptr_t a2, uintptr_t a3,
> uintptr_t a4, uintptr_t a5,
> uintptr_t a6, uintptr_t a7,
> uintptr_t a8)
> {
> switch (nr) {
> default:
> return syscall(nr, a0, a1, a2, a3, a4, a5);
> case __NR_syz_test:
> return 0;
> case __NR_syz_open_dev:
> return syz_open_dev(a0, a1, a2);
> case __NR_syz_open_pts:
> return syz_open_pts(a0, a1);
> case __NR_syz_fuse_mount:
> return syz_fuse_mount(a0, a1, a2, a3, a4, a5);
> case __NR_syz_fuseblk_mount:
> return syz_fuseblk_mount(a0, a1, a2, a3, a4, a5, a6, a7);
> }
> }
>
> static void setup_main_process()
> {
> struct sigaction sa;
> memset(&sa, 0, sizeof(sa));
> sa.sa_handler = SIG_IGN;
> syscall(SYS_rt_sigaction, 0x20, &sa, NULL, 8);
> syscall(SYS_rt_sigaction, 0x21, &sa, NULL, 8);
> install_segv_handler();
>
> char tmpdir_template[] = "./syzkaller.XXXXXX";
> char* tmpdir = mkdtemp(tmpdir_template);
> if (!tmpdir)
> fail("failed to mkdtemp");
> if (chmod(tmpdir, 0777))
> fail("failed to chmod");
> if (chdir(tmpdir))
> fail("failed to chdir");
> }
>
> static void loop();
>
> static void sandbox_common()
> {
> prctl(PR_SET_PDEATHSIG, SIGKILL, 0, 0, 0);
> setpgrp();
> setsid();
>
> struct rlimit rlim;
> rlim.rlim_cur = rlim.rlim_max = 128 << 20;
> setrlimit(RLIMIT_AS, &rlim);
> rlim.rlim_cur = rlim.rlim_max = 1 << 20;
> setrlimit(RLIMIT_FSIZE, &rlim);
> rlim.rlim_cur = rlim.rlim_max = 1 << 20;
> setrlimit(RLIMIT_STACK, &rlim);
> rlim.rlim_cur = rlim.rlim_max = 0;
> setrlimit(RLIMIT_CORE, &rlim);
>
> unshare(CLONE_NEWNS);
> unshare(CLONE_NEWIPC);
> unshare(CLONE_IO);
> }
>
> static int do_sandbox_none()
> {
> int pid = fork();
> if (pid)
> return pid;
> sandbox_common();
> loop();
> exit(1);
> }
>
> static void remove_dir(const char* dir)
> {
> DIR* dp;
> struct dirent* ep;
> int iter = 0;
> int i;
> retry:
> dp = opendir(dir);
> if (dp == NULL) {
> if (errno == EMFILE) {
> exitf("opendir(%s) failed due to NOFILE, exiting");
> }
> exitf("opendir(%s) failed", dir);
> }
> while ((ep = readdir(dp))) {
> if (strcmp(ep->d_name, ".") == 0 || strcmp(ep->d_name, "..") == 0)
> continue;
> char filename[FILENAME_MAX];
> snprintf(filename, sizeof(filename), "%s/%s", dir, ep->d_name);
> struct stat st;
> if (lstat(filename, &st))
> exitf("lstat(%s) failed", filename);
> if (S_ISDIR(st.st_mode)) {
> remove_dir(filename);
> continue;
> }
> for (i = 0;; i++) {
> debug("unlink(%s)\n", filename);
> if (unlink(filename) == 0)
> break;
> if (errno == EROFS) {
> debug("ignoring EROFS\n");
> break;
> }
> if (errno != EBUSY || i > 100)
> exitf("unlink(%s) failed", filename);
> debug("umount(%s)\n", filename);
> if (umount2(filename, MNT_DETACH))
> exitf("umount(%s) failed", filename);
> }
> }
> closedir(dp);
> for (i = 0;; i++) {
> debug("rmdir(%s)\n", dir);
> if (rmdir(dir) == 0)
> break;
> if (i < 100) {
> if (errno == EROFS) {
> debug("ignoring EROFS\n");
> break;
> }
> if (errno == EBUSY) {
> debug("umount(%s)\n", dir);
> if (umount2(dir, MNT_DETACH))
> exitf("umount(%s) failed", dir);
> continue;
> }
> if (errno == ENOTEMPTY) {
> if (iter < 100) {
> iter++;
> goto retry;
> }
> }
> }
> exitf("rmdir(%s) failed", dir);
> }
> }
>
> static uint64_t current_time_ms()
> {
> struct timespec ts;
>
> if (clock_gettime(CLOCK_MONOTONIC, &ts))
> fail("clock_gettime failed");
> return (uint64_t)ts.tv_sec * 1000 + (uint64_t)ts.tv_nsec / 1000000;
> }
>
> static void test();
>
> void loop()
> {
> int iter;
> for (iter = 0;; iter++) {
> char cwdbuf[256];
> sprintf(cwdbuf, "./%d", iter);
> if (mkdir(cwdbuf, 0777))
> fail("failed to mkdir");
> int pid = fork();
> if (pid < 0)
> fail("clone failed");
> if (pid == 0) {
> prctl(PR_SET_PDEATHSIG, SIGKILL, 0, 0, 0);
> setpgrp();
> if (chdir(cwdbuf))
> fail("failed to chdir");
> test();
> exit(0);
> }
> int status = 0;
> uint64_t start = current_time_ms();
> for (;;) {
> int res = waitpid(pid, &status, __WALL | WNOHANG);
> int errno0 = errno;
> if (res == pid)
> break;
> usleep(1000);
> if (current_time_ms() - start > 5 * 1000) {
> kill(-pid, SIGKILL);
> kill(pid, SIGKILL);
> waitpid(pid, &status, __WALL);
> break;
> }
> }
> remove_dir(cwdbuf);
> }
> }
>
> long r[5];
> void* thr(void* arg)
> {
> switch ((long)arg) {
> case 0:
> r[0] =
> execute_syscall(__NR_mmap, 0x20000000ul, 0xa000ul, 0x3ul,
> 0x32ul, 0xfffffffffffffffful, 0x0ul, 0, 0, 0);
> break;
> case 1:
> r[1] = execute_syscall(__NR_socket, 0xaul, 0x5ul, 0x84ul, 0, 0, 0,
> 0, 0, 0);
> break;
> case 2:
> r[2] = execute_syscall(__NR_socket, 0x1ful, 0x3ul, 0x6ul, 0, 0, 0,
> 0, 0, 0);
> break;
> case 3:
> NONFAILING(memcpy(
> (void*)0x20009000,
> "\x83\x15\xf6\xdb\x47\x14\xae\xe2\x8d\xb8\x4d\xb9\x0f\x32\xe7"
> "\xf5\xbc\xa6\xae\x9a\x2f\x19\xed\xf0\x75\x6a\x0b\xf0\x00\xe9"
> "\xe1\x0e\xb4\xa5\x19\x08\x88\xfc\x8b\x2d\xe2\x9a\x0f\x55\x00"
> "\x00\x00\x00\x00\x08\x27\xab\x8e\x7d\xcb\xcc\x15\x4e\x79\xe2"
> "\xd9\xca\x15\xc3\x66\xbd\x44\xa8\x53\x1f\xda\xab\xce\x98\x39"
> "\x40\x4e\x75\x57\xfd\x57\xc0\x01\x0b\xb0",
> 85));
> r[4] = execute_syscall(__NR_setsockopt, r[1], 0x0ul, 0x40ul,
> 0x20009000ul, 0x55ul, 0, 0, 0, 0);
> break;
> }
> return 0;
> }
>
> void test()
> {
> long i;
> pthread_t th[8];
>
> memset(r, -1, sizeof(r));
> srand(getpid());
> for (i = 0; i < 4; i++) {
> pthread_create(&th[i], 0, thr, (void*)i);
> usleep(10000);
> }
> for (i = 0; i < 4; i++) {
> pthread_create(&th[4 + i], 0, thr, (void*)i);
> if (rand() % 2)
> usleep(rand() % 10000);
> }
> usleep(100000);
> }
>
> int main()
> {
> setup_main_process();
> int pid = do_sandbox_none();
> int status = 0;
> while (waitpid(pid, &status, __WALL) != pid) {
> }
> return 0;
> }
^ permalink raw reply
* Re: [PATCH] net: fec: turn on device when extracting statistics
From: David Miller @ 2016-11-28 14:11 UTC (permalink / raw)
To: nikita.yoush
Cc: fugang.duan, troy.kisky, andrew, eric, tremyfr, johannes, netdev,
linux-kernel, cphealy, fabio.estevam
In-Reply-To: <4ddb5842-0ece-2950-214f-f56db808ffbd@cogentembedded.com>
From: Nikita Yushchenko <nikita.yoush@cogentembedded.com>
Date: Mon, 28 Nov 2016 10:06:31 +0300
>
>
> 28.11.2016 04:29, David Miller пишет:
>> From: Nikita Yushchenko <nikita.yoush@cogentembedded.com>
>> Date: Fri, 25 Nov 2016 13:02:00 +0300
>>
>>> + int i, ret;
>>> +
>>> + ret = pm_runtime_get_sync(&fep->pdev->dev);
>>> + if (IS_ERR_VALUE(ret)) {
>>> + memset(data, 0, sizeof(*data) * ARRAY_SIZE(fec_stats));
>>> + return;
>>> + }
>>
>> This really isn't the way to do this.
>>
>> When the device is suspended and the clocks are going to be stopped,
>> you must fetch the statistic values into a software copy and provide
>> those if the device is suspended when statistics are requested.
>
> Ok, can do that, although can't see what's wrong with waking device
> here. The situation of requesting stats on down device isn't something
> widely used, thus keeping handling of that as local as possible looks
> better for me.
The issue is the fact that you need error handling at all and might
therefore provide a set of zero stats to the user when that entire
possibility could have been avoided in the first place by recording
the stats at suspend time.
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox