* [PATCH v2 net-next 27/27] net: create sysfs symlinks for neighbour devices
From: Veaceslav Falico @ 2013-09-10 20:58 UTC (permalink / raw)
To: netdev
Cc: jiri, Veaceslav Falico, Jay Vosburgh, Andy Gospodarek,
David S. Miller, Eric Dumazet, Alexander Duyck
In-Reply-To: <1378846691-9717-1-git-send-email-vfalico@redhat.com>
Also, remove the same functionality from bonding - it will be already done
for any device that links to its lower/upper neighbour.
The links will be created for dev's kobject, and will look like
lower_eth0 for lower device eth0 and upper_bridge0 for upper device
bridge0.
CC: Jay Vosburgh <fubar@us.ibm.com>
CC: Andy Gospodarek <andy@greyhouse.net>
CC: "David S. Miller" <davem@davemloft.net>
CC: Eric Dumazet <edumazet@google.com>
CC: Jiri Pirko <jiri@resnulli.us>
CC: Alexander Duyck <alexander.h.duyck@intel.com>
Signed-off-by: Veaceslav Falico <vfalico@redhat.com>
---
Notes:
v1 -> v2:
No changes.
RFC -> v1:
Rename lower devices from slave_eth0 to lower_eth0, so that it meets
the lower/upper naming. I've searched for any active users of bonding's
slave_eth0, and seems that nobody's actively using it or relying on it.
drivers/net/bonding/bond_main.c | 11 +----------
drivers/net/bonding/bond_sysfs.c | 25 -------------------------
drivers/net/bonding/bonding.h | 2 --
net/core/dev.c | 29 +++++++++++++++++++++++++++++
4 files changed, 30 insertions(+), 37 deletions(-)
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index 707b0bc..2c0e4a5 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -1612,15 +1612,11 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
read_unlock(&bond->lock);
- res = bond_create_slave_symlinks(bond_dev, slave_dev);
- if (res)
- goto err_detach;
-
res = netdev_rx_handler_register(slave_dev, bond_handle_frame,
new_slave);
if (res) {
pr_debug("Error %d calling netdev_rx_handler_register\n", res);
- goto err_dest_symlinks;
+ goto err_detach;
}
res = bond_master_upper_dev_link(bond_dev, slave_dev, new_slave);
@@ -1642,9 +1638,6 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
err_unregister:
netdev_rx_handler_unregister(slave_dev);
-err_dest_symlinks:
- bond_destroy_slave_symlinks(bond_dev, slave_dev);
-
err_detach:
if (!USES_PRIMARY(bond->params.mode))
bond_hw_addr_flush(bond_dev, slave_dev);
@@ -1842,8 +1835,6 @@ static int __bond_release_one(struct net_device *bond_dev,
bond_dev->name, slave_dev->name, bond_dev->name);
/* must do this from outside any spinlocks */
- bond_destroy_slave_symlinks(bond_dev, slave_dev);
-
vlan_vids_del_by_dev(slave_dev, bond_dev);
/* If the mode USES_PRIMARY, then this cases was handled above by
diff --git a/drivers/net/bonding/bond_sysfs.c b/drivers/net/bonding/bond_sysfs.c
index fd178a4..ef75471 100644
--- a/drivers/net/bonding/bond_sysfs.c
+++ b/drivers/net/bonding/bond_sysfs.c
@@ -168,31 +168,6 @@ static const struct class_attribute class_attr_bonding_masters = {
.namespace = bonding_namespace,
};
-int bond_create_slave_symlinks(struct net_device *master,
- struct net_device *slave)
-{
- char linkname[IFNAMSIZ+7];
- int ret = 0;
-
- /* create a link from the master to the slave */
- sprintf(linkname, "slave_%s", slave->name);
- ret = sysfs_create_link(&(master->dev.kobj), &(slave->dev.kobj),
- linkname);
-
- return ret;
-
-}
-
-void bond_destroy_slave_symlinks(struct net_device *master,
- struct net_device *slave)
-{
- char linkname[IFNAMSIZ+7];
-
- sprintf(linkname, "slave_%s", slave->name);
- sysfs_remove_link(&(master->dev.kobj), linkname);
-}
-
-
/*
* Show the slaves in the current bond.
*/
diff --git a/drivers/net/bonding/bonding.h b/drivers/net/bonding/bonding.h
index 0e8e00e..74efa45 100644
--- a/drivers/net/bonding/bonding.h
+++ b/drivers/net/bonding/bonding.h
@@ -410,8 +410,6 @@ int bond_create(struct net *net, const char *name);
int bond_create_sysfs(struct bond_net *net);
void bond_destroy_sysfs(struct bond_net *net);
void bond_prepare_sysfs_group(struct bonding *bond);
-int bond_create_slave_symlinks(struct net_device *master, struct net_device *slave);
-void bond_destroy_slave_symlinks(struct net_device *master, struct net_device *slave);
int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev);
int bond_release(struct net_device *bond_dev, struct net_device *slave_dev);
void bond_mii_monitor(struct work_struct *);
diff --git a/net/core/dev.c b/net/core/dev.c
index 27ca03f..5fe2dd0 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -4638,6 +4638,7 @@ static int __netdev_adjacent_dev_insert(struct net_device *dev,
bool upper, void *private)
{
struct netdev_adjacent *adj, *neigh = NULL;
+ char linkname[IFNAMSIZ+7];
int ret;
adj = __netdev_find_adj(dev, adj_dev, upper, false);
@@ -4685,6 +4686,16 @@ static int __netdev_adjacent_dev_insert(struct net_device *dev,
*/
if (master)
neigh->private = private;
+
+ sprintf(linkname, "lower_%s", adj_dev->name);
+ ret = sysfs_create_link(&(dev->dev.kobj),
+ &(adj_dev->dev.kobj),
+ linkname);
+ if (ret) {
+ kfree(neigh);
+ kfree(adj);
+ return ret;
+ }
list_add_tail_rcu(&neigh->list,
&dev->adj_list.lower);
}
@@ -4692,10 +4703,24 @@ static int __netdev_adjacent_dev_insert(struct net_device *dev,
return 0;
}
+ /* it's upper neighbour, we don't care if it's master or not */
+ if (neigh) {
+ sprintf(linkname, "upper_%s", adj_dev->name);
+ ret = sysfs_create_link(&(dev->dev.kobj), &(adj_dev->dev.kobj),
+ linkname);
+ if (ret) {
+ kfree(neigh);
+ kfree(adj);
+ return ret;
+ }
+ }
+
/* Ensure that master upper link is always the first item in list. */
if (master) {
ret = sysfs_create_link(&(dev->dev.kobj), &(adj_dev->dev.kobj), "master");
if (ret) {
+ if (neigh)
+ sysfs_remove_link(&(dev->dev.kobj), linkname);
kfree(neigh);
kfree(adj);
return ret;
@@ -4736,6 +4761,7 @@ void __netdev_adjacent_dev_remove(struct net_device *dev,
bool is_neigh)
{
struct netdev_adjacent *adj, *neighbour;
+ char linkname[IFNAMSIZ+7];
if (upper) {
adj = __netdev_all_upper_find(dev, adj_dev);
@@ -4758,6 +4784,9 @@ void __netdev_adjacent_dev_remove(struct net_device *dev,
adj_dev->name);
if (neighbour->master && upper)
sysfs_remove_link(&(dev->dev.kobj), "master");
+ sprintf(linkname, "%s_%s", upper ? "upper" : "lower",
+ adj_dev->name);
+ sysfs_remove_link(&(dev->dev.kobj), linkname);
list_del_rcu(&neighbour->list);
dev_put(adj_dev);
kfree_rcu(neighbour, rcu);
--
1.8.4
^ permalink raw reply related
* [PATCH v2 net-next 14/27] bonding: rework bond_ab_arp_probe() to use bond_for_each_slave()
From: Veaceslav Falico @ 2013-09-10 20:57 UTC (permalink / raw)
To: netdev; +Cc: jiri, Veaceslav Falico, Jay Vosburgh, Andy Gospodarek
In-Reply-To: <1378846691-9717-1-git-send-email-vfalico@redhat.com>
Currently it uses the hard-to-rcuify bond_for_each_slave_from(), and also
it doesn't check every slave for disrepencies between the actual
IS_UP(slave) and the slave->link == BOND_LINK_UP, but only till we find the
next suitable slave.
Fix this by using bond_for_each_slave() and storing the first good slave in
*before till we find the current_arp_slave, after that we store the first good
slave in new_slave. If new_slave is empty - use the slave stored in before,
and if it's also empty - then we didn't find any suitable slave.
Also, in the meanwhile, check for each slave status.
CC: Jay Vosburgh <fubar@us.ibm.com>
CC: Andy Gospodarek <andy@greyhouse.net>
Signed-off-by: Veaceslav Falico <vfalico@redhat.com>
---
Notes:
v1 -> v2:
No changes.
RFC -> v1:
New patch.
drivers/net/bonding/bond_main.c | 38 ++++++++++++++++++++++++--------------
1 file changed, 24 insertions(+), 14 deletions(-)
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index b5497e7..eedfa8f 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -2761,8 +2761,9 @@ do_failover:
*/
static void bond_ab_arp_probe(struct bonding *bond)
{
- struct slave *slave, *next_slave;
- int i;
+ struct slave *slave, *before = NULL, *new_slave = NULL;
+ struct list_head *iter;
+ bool found = false;
read_lock(&bond->curr_slave_lock);
@@ -2792,18 +2793,12 @@ static void bond_ab_arp_probe(struct bonding *bond)
bond_set_slave_inactive_flags(bond->current_arp_slave);
- /* search for next candidate */
- next_slave = bond_next_slave(bond, bond->current_arp_slave);
- bond_for_each_slave_from(bond, slave, i, next_slave) {
- if (IS_UP(slave->dev)) {
- slave->link = BOND_LINK_BACK;
- bond_set_slave_active_flags(slave);
- bond_arp_send_all(bond, slave);
- slave->jiffies = jiffies;
- bond->current_arp_slave = slave;
- break;
- }
+ bond_for_each_slave(bond, slave, iter) {
+ if (!found && !before && IS_UP(slave->dev))
+ before = slave;
+ if (found && !new_slave && IS_UP(slave->dev))
+ new_slave = slave;
/* if the link state is up at this point, we
* mark it down - this can happen if we have
* simultaneous link failures and
@@ -2811,7 +2806,7 @@ static void bond_ab_arp_probe(struct bonding *bond)
* one the current slave so it is still marked
* up when it is actually down
*/
- if (slave->link == BOND_LINK_UP) {
+ if (!IS_UP(slave->dev) && slave->link == BOND_LINK_UP) {
slave->link = BOND_LINK_DOWN;
if (slave->link_failure_count < UINT_MAX)
slave->link_failure_count++;
@@ -2821,7 +2816,22 @@ static void bond_ab_arp_probe(struct bonding *bond)
pr_info("%s: backup interface %s is now down.\n",
bond->dev->name, slave->dev->name);
}
+ if (slave == bond->current_arp_slave)
+ found = true;
}
+
+ if (!new_slave && before)
+ new_slave = before;
+
+ if (!new_slave)
+ return;
+
+ new_slave->link = BOND_LINK_BACK;
+ bond_set_slave_active_flags(new_slave);
+ bond_arp_send_all(bond, new_slave);
+ new_slave->jiffies = jiffies;
+ bond->current_arp_slave = new_slave;
+
}
void bond_activebackup_arp_mon(struct work_struct *work)
--
1.8.4
^ permalink raw reply related
* Hello
From: T. Stratford @ 2013-09-10 5:59 UTC (permalink / raw)
To: Recipients
Hello,
You have won 1,000.000 great british pounds in the ongoing promo draw.
For claims, contact Mr Jeremy via email on: jeremy-office@qq.com
Thanks,
T. Stratford.
^ permalink raw reply
* Namaste
From: r.diterlizzi @ 2013-09-10 21:11 UTC (permalink / raw)
To: Recipients
Hello ,
Namaste to you and your loved ones.
Kindly forgive my intrusion ,my email must have come as a surprise to you seeing that we hardly know eachother ,I am a native of India ,female and 26yrs of old , I presently live in the England.
I have mailed you to seek for your help in a matter of great importance to my family ,I would be able to tell you more when I get a response from you.
Thank you for taking time out to read my mail.
Wishing you and your loved ones a Happy New Year
Sonali Sachdeva
^ permalink raw reply
* Re: [PATCH] ipv6: Do route updating for redirect in ndisc layer
From: Hannes Frederic Sowa @ 2013-09-10 22:50 UTC (permalink / raw)
To: Duan Jiong; +Cc: davem, netdev
In-Reply-To: <522D7444.20505@cn.fujitsu.com>
On Mon, Sep 09, 2013 at 03:09:56PM +0800, Duan Jiong wrote:
> diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
> index 5c71501..61fe8e5 100644
> --- a/net/ipv6/tcp_ipv6.c
> +++ b/net/ipv6/tcp_ipv6.c
> @@ -382,14 +382,6 @@ static void tcp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
>
> np = inet6_sk(sk);
>
> - if (type == NDISC_REDIRECT) {
> - struct dst_entry *dst = __sk_dst_check(sk, np->dst_cookie);
> -
> - if (dst)
> - dst->ops->redirect(dst, sk, skb);
> - goto out;
> - }
> -
You dropped the "goto out" here in case of an NDISC_REDIRECT, so this sends an
EPROTO further up the socket layer. Was this intended?
Also:
In some _err() functions there is this check, e.g. ah6.c:
621 if (type != ICMPV6_DEST_UNREACH &&
622 type != ICMPV6_PKT_TOOBIG &&
623 type != NDISC_REDIRECT)
624 return;
It could actually be adjusted now as we don't handle NDISC_REDIRECTs here any
more. I don't see any side-effects down the code in these functions. We could
also only just match on ICMPV6_PKT_TOOBIG. Can you confirm?
Greetings,
Hannes
^ permalink raw reply
* Cross-compile iproute2 for android?
From: Ben Greear @ 2013-09-10 23:01 UTC (permalink / raw)
To: netdev
Has anyone managed to cross-compile iproute2 for android using the android NDK?
I managed to compile it, with some fairly ugly hacks related to include
files, but then when I try to run it, I get a core dump that doesn't
do much for me:
$ ~/android-ndk-r9/toolchains/arm-linux-androideabi-4.8/prebuilt/linux-x86_64/bin/arm-linux-androideabi-gdb ~/btbits/btbits-arm/server/local/sbin/ip core
GNU gdb (GDB) 7.3.1-gg2
Copyright (C) 2011 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "--host=x86_64-linux-gnu --target=arm-linux-android".
For bug reporting instructions, please see:
<http://source.android.com/source/report-bugs.html>...
Reading symbols from /home/greearb/btbits/btbits-arm/server/local/sbin/ip...done.
[New LWP 3756]
Core was generated by `./ip list'.
Program terminated with signal 4, Illegal instruction.
#0 0xb6f4b000 in ?? ()
(gdb) bt
#0 0xb6f4b000 in ?? ()
#1 0x00000000 in ?? ()
(gdb) quit
$ file /home/greearb/btbits/btbits-arm/server/local/sbin/ip
/home/greearb/btbits/btbits-arm/server/local/sbin/ip: ELF 32-bit LSB shared object, ARM, version 1 (SYSV), dynamically linked, not stripped
If anyone has any suggestions, please let me know.
If anyone wants to take a look at my attempt to get it cross-compiling, my
repository is here:
https://github.com/greearb/iproute2-ct/commits/master
Thanks,
Ben
--
Ben Greear <greearb@candelatech.com>
Candela Technologies Inc http://www.candelatech.com
^ permalink raw reply
* Re: Question about reading the routing table with netlink
From: Hannes Frederic Sowa @ 2013-09-10 23:13 UTC (permalink / raw)
To: Fernando Gont; +Cc: netdev
In-Reply-To: <522F2AF8.9080106@gont.com.ar>
On Tue, Sep 10, 2013 at 11:21:44AM -0300, Fernando Gont wrote:
> Folks,
>
> Short version of the question:
> I'm trying to loop up a routing table entry with a
> socket(AF_NETLINK,SOCK_RAW,NETLINK_ROUTE).
>
> Everything seems fine, except that I do not quite understand what's the
> effect of setting the RTA_SRC attribute type when doing that.
It sets the source address for the routing table lookup. This is important if
e.g. rules are specified or if ipv6 subtrees are in use.
> Empirically, it seems that if the RTA_SRC attribute is set and it
> contains an address that is assigned to the interface involved in the
> route, then such address is later returned in the reply as an RTA_SRC
> attribute.
Hm, I thought that RTA_SRC only has a semantic in the request and is moslty
just copied over to the response.
Greetings,
Hannes
^ permalink raw reply
* Use-after-free in TUNSETIFF
From: Wannes Rombouts @ 2013-09-10 23:59 UTC (permalink / raw)
To: davem, jasowang, mst, edumazet, nhorman, netdev; +Cc: Kevin Soules
In-Reply-To: <522FACCB.1040707@epitech.eu>
(I sent this email to security@kernel.org but they told me I should send
it to you guys, so here you go.)
Hi,
I would like to report what I believe could be a potential CAP_NET_ADMIN
to ring0 privilege escalation.
The bug is in the way tuntap interfaces are initialized, when given an
invalid name they cause a use after free. Also software like vmware
allows for at least a freeze or kernel panic by a simple user but might
also allow privilege escalation.
Very simple to test, this causes a crash:
# ip tuntap add dev %% mode tap
If it doesn't crash immediately wait a few seconds and try again.
We haven't managed to exploit the use after free yet, but we are still
working on it. At least it crashes even with the latest kernel 3.11 and
on different distros. (tested on Debian, Ubuntu and Arch) Looking at the
source the bug seems quite old.
Here is our analysis:
A user with CAP_NET_ADMIN calls ioctl with TUNSETIFF and an invalid name
for example "%d%d".
tun_set_iff starts to initialize the tun_struct.
http://lxr.free-electrons.com/source/drivers/net/tun.c#L1589
It calls tun_flow_init which starts a timer with tun_flow_cleanup as
callback. http://lxr.free-electrons.com/source/drivers/net/tun.c#L852
After this tun_set_iff calls register_netdevice which returns an error
because of the invalid name.
This error causes the goto err_free_dev and the call to free_netdev.
This will free the tun_struct.
Later, once the callback gets called it uses bad memory. Sometimes it
doesn’t get called because the timer_list has been compromised and we
get a kernel panic at:
http://lxr.free-electrons.com/source/kernel/timer.c?v=2.6.33#L949
But it is possible to get some memory from userland that overlaps only
the beginning of the tun_struct without overwriting the timer_list
because there is a big array before it. Then it might be possible to
exploit tun_flow_cleanup when it is called, but we didn't succeed yet.
------------------------------------------------------------------------
This is the first time we try to exploit the kernel so we basically suck
at this. I don't know if someone more skilled could do this easily or
not, but we'll keep trying and I'll let you know if we manage it.
In the mean time please let us know what you think of this and of course
we are very interested in the way this is patched. Please keep us in the
loop.
Of course we will be happy to assist in any way we can, feel free to
ask! Also we would like to know when you think it would be reasonable to
disclose and talk about this bug.
Regards,
Wannes 'wapiflapi' Rombouts
Kevin 'eax64' Soules
^ permalink raw reply
* Re: [PATCH RFC 0/2] Multiple VLAN Registration Protocol (IEEE 802.1Q-2011)
From: Noel Burton-Krahn @ 2013-09-11 0:22 UTC (permalink / raw)
To: netdev
In-Reply-To: <1348520855-8810-1-git-send-email-david.ward@ll.mit.edu>
David Ward <david.ward <at> ll.mit.edu> writes:
> The following patches add support for MVRP to
> the Linux kernel and iproute2 utility. They are based largely off of
> the existing implementation of GVRP, but have been modified for the
> new PDU structure and state machine.
>
> Please let me know if you have any comments. This implementation was
> tested with two Juniper EX4200 switches and found to work as expected.
> If you have access to other switches that implement MVRP, I would of
> course welcome additional testing.
>
> Signed-off-by: David Ward <david.ward <at> ll.mit.edu>
>
David,
Thanks for your MVRP implementation. I ran into a problem with MVRP where
it would fail to register if MVRP started too soon after the network
interface came up. There's a few seconds from when an interface is up until
it can actually send packets, even after it reports it's up, so the first
few MVRP JoinIn packets would get lost. The Linux MRP implementation that
sends JoinIn packets was missing the periodic timer required by
[802.1Q-2011], so after the JoinIn's were lost, the MVRP registration would
never retry, and MVRP would fail to register:
10.7.4.4 periodictimer
The Periodic Transmission timer, periodictimer, controls the
frequency with which the PeriodicTransmission state machine
generates periodic! events. The timer is required on a per-Port
basis. The Periodic Transmission timer is set to one second when it
is started.
The weird thing about the periodictimer is that it fires every second
forever, and the MRP Applicant state machine bounces from QA to AA states
and back every second, sending a MRP request every time. There's no state
to be quiet after the applicant receives a rJoinIn acknowledgement. See
Section 10.7.7 (Applicant state machine) in [802.1Q-2011]. The result is
that the MRP application sends JoinIn every second, which seems a little
noisy. Am I missing something?
[802.1Q-2011]
http://standards.ieee.org/findstds/standard/802.1Q-2011.html
Here's a patch for net/mrp.c that adds the periodic timer. My working fork
is at https://github.com/noelbk/linux.
Cheers,
--
Noel
diff --git a/include/net/mrp.h b/include/net/mrp.h
index 4fbf02a..0f7558b 100644
--- a/include/net/mrp.h
+++ b/include/net/mrp.h
@@ -112,6 +112,7 @@ struct mrp_applicant {
struct mrp_application *app;
struct net_device *dev;
struct timer_list join_timer;
+ struct timer_list periodic_timer;
spinlock_t lock;
struct sk_buff_head queue;
diff --git a/net/802/mrp.c b/net/802/mrp.c
index 1eb05d8..8f1fa4f 100644
--- a/net/802/mrp.c
+++ b/net/802/mrp.c
@@ -1,3 +1,5 @@
+#define pr_fmt(fmt) KBUILD_MODNAME ": %s: " fmt, __func__
+
/*
* IEEE 802.1Q Multiple Registration Protocol (MRP)
*
@@ -24,6 +26,12 @@
static unsigned int mrp_join_time __read_mostly = 200;
module_param(mrp_join_time, uint, 0644);
MODULE_PARM_DESC(mrp_join_time, "Join time in ms (default 200ms)");
+
+static unsigned int mrp_periodic_time __read_mostly = 1000;
+module_param(mrp_periodic_time, uint, 0644);
+MODULE_PARM_DESC(mrp_periodic_time, "Periodic time in ms (default 1s)");
+
+
MODULE_LICENSE("GPL");
static const u8
@@ -210,6 +218,52 @@ mrp_tx_action_table[MRP_APPLICANT_MAX + 1] = {
[MRP_APPLICANT_QP] = MRP_TX_ACTION_S_IN_OPTIONAL,
};
+
+// debug
+static char *
+mrp_event_str(enum mrp_event event) {
+ char *s = "unknown";
+ switch(event) {
+ case MRP_EVENT_NEW: s = "NEW"; break;
+ case MRP_EVENT_JOIN: s = "JOIN"; break;
+ case MRP_EVENT_LV: s = "LV"; break;
+ case MRP_EVENT_TX: s = "TX"; break;
+ case MRP_EVENT_R_NEW: s = "R_NEW"; break;
+ case MRP_EVENT_R_JOIN_IN: s = "R_JOIN_IN"; break;
+ case MRP_EVENT_R_IN: s = "R_IN"; break;
+ case MRP_EVENT_R_JOIN_MT: s = "R_JOIN_MT"; break;
+ case MRP_EVENT_R_MT: s = "R_MT"; break;
+ case MRP_EVENT_R_LV: s = "R_LV"; break;
+ case MRP_EVENT_R_LA: s = "R_LA"; break;
+ case MRP_EVENT_REDECLARE: s = "REDECLARE"; break;
+ case MRP_EVENT_PERIODIC: s = "PERIODIC"; break;
+ case __MRP_EVENT_MAX: break;
+ }
+ return s;
+}
+
+// debug
+static char *
+mrp_applicant_state_str(enum mrp_applicant_state state) {
+ char *s = "unknown";
+ switch(state) {
+ case MRP_APPLICANT_INVALID: s = "INVALID"; break;
+ case MRP_APPLICANT_VO: s = "VO"; break;
+ case MRP_APPLICANT_VP: s = "VP"; break;
+ case MRP_APPLICANT_VN: s = "VN"; break;
+ case MRP_APPLICANT_AN: s = "AN"; break;
+ case MRP_APPLICANT_AA: s = "AA"; break;
+ case MRP_APPLICANT_QA: s = "QA"; break;
+ case MRP_APPLICANT_LA: s = "LA"; break;
+ case MRP_APPLICANT_AO: s = "AO"; break;
+ case MRP_APPLICANT_QO: s = "QO"; break;
+ case MRP_APPLICANT_AP: s = "AP"; break;
+ case MRP_APPLICANT_QP: s = "QP"; break;
+ case __MRP_APPLICANT_MAX: break;
+ }
+ return s;
+}
+
static void mrp_attrvalue_inc(void *value, u8 len)
{
u8 *v = (u8 *)value;
@@ -345,8 +399,15 @@ static void mrp_queue_xmit(struct mrp_applicant *app)
{
struct sk_buff *skb;
- while ((skb = skb_dequeue(&app->queue)))
- dev_queue_xmit(skb);
+ while ((skb = skb_dequeue(&app->queue))) {
+ int xmit_err = dev_queue_xmit(skb);
+ pr_debug("dev=%s len=%d dev_queue_xmit=%d carrier_ok=%d dormant=%d\n"
+ ,skb->dev->name, (int)skb->len
+ ,(int)xmit_err
+ ,(int)netif_carrier_ok(skb->dev)
+ ,(int)netif_dormant(skb->dev)
+ );
+ }
}
static int mrp_pdu_append_msg_hdr(struct mrp_applicant *app,
@@ -474,6 +535,13 @@ static void mrp_attr_event(struct mrp_applicant *app,
return;
}
+ pr_debug("attr_type=%d event=%s attr->state=%s new state=%s\n"
+ ,(int)attr->type
+ ,mrp_event_str(event)
+ ,mrp_applicant_state_str(attr->state)
+ ,mrp_applicant_state_str(state));
+
+
if (event == MRP_EVENT_TX) {
/* When appending the attribute fails, don't update its state
* in order to retry at the next TX event.
@@ -521,6 +589,8 @@ int mrp_request_join(const struct net_device *dev,
port->applicants[appl->type]);
struct mrp_attr *attr;
+ pr_debug("dev->name=%s attr_type=%d\n", dev->name, (int)type);
+
if (sizeof(struct mrp_skb_cb) + len >
FIELD_SIZEOF(struct sk_buff, cb))
return -ENOMEM;
@@ -546,6 +616,8 @@ void mrp_request_leave(const struct net_device *dev,
port->applicants[appl->type]);
struct mrp_attr *attr;
+ pr_debug("dev->name=%s attr_type=%d\n", dev->name, (int)type);
+
if (sizeof(struct mrp_skb_cb) + len >
FIELD_SIZEOF(struct sk_buff, cb))
return;
@@ -595,6 +667,52 @@ static void mrp_join_timer(unsigned long data)
mrp_join_timer_arm(app);
}
+static void mrp_periodic_timer_arm(struct mrp_applicant *app)
+{
+ unsigned long delay;
+
+ delay = (u64)msecs_to_jiffies(mrp_periodic_time);
+ mod_timer(&app->periodic_timer, jiffies + delay);
+}
+
+
+/*
+
+from [802.1Q-2011]
+http://standards.ieee.org/findstds/standard/802.1Q-2011.html
+
+
+10.7.4.4 periodictimer
+
+The Periodic Transmission timer, periodictimer, controls the frequency
+with which the PeriodicTransmission state machine generates periodic!
+events. The timer is required on a per-Port basis. The Periodic
+Transmission timer is set to one second when it is started.
+
+10.7.5.10 periodic!
+
+This event indicates to the Applicant state machine that the timer
+used to stimulate periodic transmission has expired.
+
+10.7.5.23 periodictimer!
+
+For an instance of the PeriodicTransmission state machine, the
+periodictimer! event is deemed to have occurred when the periodictimer
+associated with that state machine expires.
+
+*/
+static void mrp_periodic_timer(unsigned long data)
+{
+ struct mrp_applicant *app = (struct mrp_applicant *)data;
+
+ spin_lock(&app->lock);
+ mrp_mad_event(app, MRP_EVENT_PERIODIC);
+ mrp_pdu_queue(app);
+ spin_unlock(&app->lock);
+
+ mrp_periodic_timer_arm(app);
+}
+
static int mrp_pdu_parse_end_mark(struct sk_buff *skb, int *offset)
{
__be16 endmark;
@@ -791,10 +909,13 @@ out:
return 0;
}
+
static int mrp_init_port(struct net_device *dev)
{
struct mrp_port *port;
+ pr_debug("dev->name=%s\n", dev->name);
+
port = kzalloc(sizeof(*port), GFP_KERNEL);
if (!port)
return -ENOMEM;
@@ -807,6 +928,8 @@ static void mrp_release_port(struct net_device *dev)
struct mrp_port *port = rtnl_dereference(dev->mrp_port);
unsigned int i;
+ pr_debug("dev->name=%s\n", dev->name);
+
for (i = 0; i <= MRP_APPLICATION_MAX; i++) {
if (rtnl_dereference(port->applicants[i]))
return;
@@ -820,6 +943,8 @@ int mrp_init_applicant(struct net_device *dev, struct
mrp_application *appl)
struct mrp_applicant *app;
int err;
+ pr_debug("dev->name=%s\n", dev->name);
+
ASSERT_RTNL();
if (!rtnl_dereference(dev->mrp_port)) {
@@ -845,6 +970,8 @@ int mrp_init_applicant(struct net_device *dev, struct
mrp_application *appl)
rcu_assign_pointer(dev->mrp_port->applicants[appl->type], app);
setup_timer(&app->join_timer, mrp_join_timer, (unsigned long)app);
mrp_join_timer_arm(app);
+ setup_timer(&app->periodic_timer, mrp_periodic_timer, (unsigned long)app);
+ mrp_periodic_timer_arm(app);
return 0;
err3:
@@ -862,6 +989,8 @@ void mrp_uninit_applicant(struct net_device *dev, struct
mrp_application *appl)
struct mrp_applicant *app = rtnl_dereference(
port->applicants[appl->type]);
+ pr_debug("dev->name=%s\n", dev->name);
+
ASSERT_RTNL();
RCU_INIT_POINTER(port->applicants[appl->type], NULL);
@@ -870,6 +999,7 @@ void mrp_uninit_applicant(struct net_device *dev, struct
mrp_application *appl)
* all pending messages before the applicant is gone.
*/
del_timer_sync(&app->join_timer);
+ del_timer_sync(&app->periodic_timer);
spin_lock_bh(&app->lock);
mrp_mad_event(app, MRP_EVENT_TX);
@@ -897,3 +1027,4 @@ void mrp_unregister_application(struct mrp_application
*appl)
dev_remove_pack(&appl->pkttype);
}
EXPORT_SYMBOL_GPL(mrp_unregister_application);
+
^ permalink raw reply related
* Re: Use-after-free in TUNSETIFF
From: Stephen Hemminger @ 2013-09-11 0:32 UTC (permalink / raw)
To: Wannes Rombouts
Cc: davem, jasowang, mst, edumazet, nhorman, netdev, Kevin Soules
In-Reply-To: <522FB273.1030506@epitech.eu>
On Wed, 11 Sep 2013 01:59:47 +0200
Wannes Rombouts <wannes.rombouts@epitech.eu> wrote:
> (I sent this email to security@kernel.org but they told me I should send
> it to you guys, so here you go.)
>
> Hi,
>
> I would like to report what I believe could be a potential CAP_NET_ADMIN
> to ring0 privilege escalation.
>
> The bug is in the way tuntap interfaces are initialized, when given an
> invalid name they cause a use after free. Also software like vmware
> allows for at least a freeze or kernel panic by a simple user but might
> also allow privilege escalation.
>
> Very simple to test, this causes a crash:
> # ip tuntap add dev %% mode tap
> If it doesn't crash immediately wait a few seconds and try again.
>
>
> We haven't managed to exploit the use after free yet, but we are still
> working on it. At least it crashes even with the latest kernel 3.11 and
> on different distros. (tested on Debian, Ubuntu and Arch) Looking at the
> source the bug seems quite old.
>
>
> Here is our analysis:
>
> A user with CAP_NET_ADMIN calls ioctl with TUNSETIFF and an invalid name
> for example "%d%d".
>
> tun_set_iff starts to initialize the tun_struct.
> http://lxr.free-electrons.com/source/drivers/net/tun.c#L1589
>
> It calls tun_flow_init which starts a timer with tun_flow_cleanup as
> callback. http://lxr.free-electrons.com/source/drivers/net/tun.c#L852
>
> After this tun_set_iff calls register_netdevice which returns an error
> because of the invalid name.
>
> This error causes the goto err_free_dev and the call to free_netdev.
> This will free the tun_struct.
>
> Later, once the callback gets called it uses bad memory. Sometimes it
> doesn’t get called because the timer_list has been compromised and we
> get a kernel panic at:
> http://lxr.free-electrons.com/source/kernel/timer.c?v=2.6.33#L949
>
> But it is possible to get some memory from userland that overlaps only
> the beginning of the tun_struct without overwriting the timer_list
> because there is a big array before it. Then it might be possible to
> exploit tun_flow_cleanup when it is called, but we didn't succeed yet.
>
> ------------------------------------------------------------------------
>
>
> This is the first time we try to exploit the kernel so we basically suck
> at this. I don't know if someone more skilled could do this easily or
> not, but we'll keep trying and I'll let you know if we manage it.
>
> In the mean time please let us know what you think of this and of course
> we are very interested in the way this is patched. Please keep us in the
> loop.
>
> Of course we will be happy to assist in any way we can, feel free to
> ask! Also we would like to know when you think it would be reasonable to
> disclose and talk about this bug.
Thank you for the bug report.
I wouldn't go all security crazy, if you want to spend hours making an exploit
have fun, but it is a waste of time[1]. It is a simple bug introduced in 3.8
commit c8d68e6be1c3b242f1c598595830890b65cea64a
Author: Jason Wang <jasowang@redhat.com>
Date: Wed Oct 31 19:46:00 2012 +0000
tuntap: multiqueue support
The fix isn't that hard, why don't you make a patch.
[1] A user with CAP_NET_ADMIN can basically hose the system many other ways.
Capabilities are a failed security model.
Almost all distro's limit CAP_NET_ADMIN to root anyway.
^ permalink raw reply
* [PATCH] net_sched: htb: fix a typo in htb_change_class()
From: Eric Dumazet @ 2013-09-11 0:36 UTC (permalink / raw)
To: David Miller; +Cc: netdev, Jesper Dangaard Brouer, Vimalkumar, Jiri Pirko
From: Vimalkumar <j.vimal@gmail.com>
Fix a typo added in commit 56b765b79 ("htb: improved accuracy at high
rates")
cbuffer should not be a copy of buffer.
Signed-off-by: Vimalkumar <j.vimal@gmail.com>
Signed-off-by: Eric Dumazet <edumazet@google.com>
Cc: Jesper Dangaard Brouer <brouer@redhat.com>
Cc: Jiri Pirko <jpirko@redhat.com>
---
net/sched/sch_htb.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/net/sched/sch_htb.c b/net/sched/sch_htb.c
index c2178b1..863846c 100644
--- a/net/sched/sch_htb.c
+++ b/net/sched/sch_htb.c
@@ -1495,7 +1495,7 @@ static int htb_change_class(struct Qdisc *sch, u32 classid,
psched_ratecfg_precompute(&cl->ceil, &hopt->ceil);
cl->buffer = PSCHED_TICKS2NS(hopt->buffer);
- cl->cbuffer = PSCHED_TICKS2NS(hopt->buffer);
+ cl->cbuffer = PSCHED_TICKS2NS(hopt->cbuffer);
sch_tree_unlock(sch);
^ permalink raw reply related
* Re: [PATCH] net: korina: remove deprecated IRQF_DISABLED
From: Jingoo Han @ 2013-09-11 1:00 UTC (permalink / raw)
To: 'Michael Opdenacker'
Cc: davem, emilio, mugunthanvnm, hsweeten, netdev, linux-kernel
In-Reply-To: <1378531257-5446-1-git-send-email-michael.opdenacker@free-electrons.com>
On Saturday, September 07, 2013 2:21 PM, Michael Opdenacker wrote:
>
> This patch proposes to remove the IRQF_DISABLED flag from
> drivers/net/ethernet/korina.c
>
> It's a NOOP since 2.6.35 and it will be removed one day.
>
> Signed-off-by: Michael Opdenacker <michael.opdenacker@free-electrons.com>
Reviewed-by: Jingoo Han <jg1.han@samsung.com>
Best regards,
Jingoo Han
> ---
> drivers/net/ethernet/korina.c | 8 ++++----
> 1 file changed, 4 insertions(+), 4 deletions(-)
>
^ permalink raw reply
* Re: [PATCH] bcm63xx_enet: remove deprecated IRQF_DISABLED
From: Jingoo Han @ 2013-09-11 1:05 UTC (permalink / raw)
To: 'Michael Opdenacker'
Cc: davem, jogo, joe, mbizon, netdev, linux-kernel
In-Reply-To: <1378537010-7128-1-git-send-email-michael.opdenacker@free-electrons.com>
On Saturday, September 07, 2013 3:57 PM, Michael Opdenacker wrote:
>
> This patch proposes to remove the IRQF_DISABLED flag from
> drivers/net/ethernet/broadcom/bcm63xx_enet.c
>
> It's a NOOP since 2.6.35 and it will be removed one day.
>
> Signed-off-by: Michael Opdenacker <michael.opdenacker@free-electrons.com>
Reviewed-by: Jingoo Han <jg1.han@samsung.com>
Best regards,
Jingoo Han
> ---
> drivers/net/ethernet/broadcom/bcm63xx_enet.c | 8 ++++----
> 1 file changed, 4 insertions(+), 4 deletions(-)
^ permalink raw reply
* RE: [PATCH] net: fec: add the initial to set the physical mac address
From: Duan Fugang-B38611 @ 2013-09-11 1:15 UTC (permalink / raw)
To: Denis Kirjanov
Cc: Li Frank-B20596, Zhou Luwei-B45643, davem@davemloft.net,
netdev@vger.kernel.org, shawn.guo@linaro.org,
bhutchings@solarflare.com, Estevam Fabio-R49496,
stephen@networkplumber.org
In-Reply-To: <CAOJe8K2eH+6Eg0vOnOFwNsy9-TyxBJwYDCTDbLcbB3yu42OW1w@mail.gmail.com>
From: Denis Kirjanov [mailto:kda@linux-powerpc.org]
Data: Tuesday, September 10, 2013 10:19 PM
> To: Duan Fugang-B38611
> Cc: Li Frank-B20596; Zhou Luwei-B45643; davem@davemloft.net;
> netdev@vger.kernel.org; shawn.guo@linaro.org; bhutchings@solarflare.com;
> Estevam Fabio-R49496; stephen@networkplumber.org
> Subject: Re: [PATCH] net: fec: add the initial to set the physical mac
> address
>
> On 8/22/13, Fugang Duan <B38611@freescale.com> wrote:
> > For imx6slx evk platform, the fec driver cannot work since there have
> > no valid mac address set in physical mac registers.
> >
> > For imx serial platform, fec/enet IPs both need the physical MAC
> > address initial, otherwise it cannot work.
> >
> > After acquiring the valid MAC address from devices tree/pfuse/ kernel
> > command line/random mac address, and then set it to the physical MAC
> > address registers.
> >
> > Signed-off-by: Fugang Duan <B38611@freescale.com>
> > ---
> > drivers/net/ethernet/freescale/fec_main.c | 9 ++++++---
> > 1 files changed, 6 insertions(+), 3 deletions(-)
> >
> > diff --git a/drivers/net/ethernet/freescale/fec_main.c
> > b/drivers/net/ethernet/freescale/fec_main.c
> > index 4349a9e..9b5e08c 100644
> > --- a/drivers/net/ethernet/freescale/fec_main.c
> > +++ b/drivers/net/ethernet/freescale/fec_main.c
> > @@ -1867,10 +1867,12 @@ fec_set_mac_address(struct net_device *ndev,
> > void
> > *p)
> > struct fec_enet_private *fep = netdev_priv(ndev);
> > struct sockaddr *addr = p;
> >
> > - if (!is_valid_ether_addr(addr->sa_data))
> > - return -EADDRNOTAVAIL;
> > + if (p) {
>
> I don't see how the p pointer can be NULL...
As below, fec_enet_init() function calls fec_set_mac_address(ndev, NULL).
>
> > + if (!is_valid_ether_addr(addr->sa_data))
> > + return -EADDRNOTAVAIL;
> >
> > - memcpy(ndev->dev_addr, addr->sa_data, ndev->addr_len);
> > + memcpy(ndev->dev_addr, addr->sa_data, ndev->addr_len);
> > + }
> >
> > writel(ndev->dev_addr[3] | (ndev->dev_addr[2] << 8) |
> > (ndev->dev_addr[1] << 16) | (ndev->dev_addr[0] << 24), @@ -
> 1969,6
> > +1971,7 @@ static int fec_enet_init(struct net_device *ndev)
> >
> > /* Get the Ethernet address */
> > fec_get_mac(ndev);
> > + fec_set_mac_address(ndev, NULL);
> >
> > /* Set receive and transmit descriptor base. */
> > fep->rx_bd_base = cbd_base;
^ permalink raw reply
* RE: [PATCH] net: fec: fix phy reset operation to let imx6sl evk work
From: Duan Fugang-B38611 @ 2013-09-11 1:17 UTC (permalink / raw)
To: Sascha Hauer
Cc: shawn.guo@linaro.org, davem@davemloft.net, netdev@vger.kernel.org,
bhutchings@solarflare.com, stephen@networkplumber.org,
Li Frank-B20596
In-Reply-To: <20130910184856.GF30088@pengutronix.de>
From: Sascha Hauer [mailto:s.hauer@pengutronix.de]
Data: Wednesday, September 11, 2013 2:49 AM
> To: Duan Fugang-B38611
> Cc: shawn.guo@linaro.org; davem@davemloft.net; netdev@vger.kernel.org;
> bhutchings@solarflare.com; stephen@networkplumber.org; Li Frank-B20596
> Subject: Re: [PATCH] net: fec: fix phy reset operation to let imx6sl evk
> work
>
> On Tue, Sep 10, 2013 at 05:07:33PM +0800, Fugang Duan wrote:
> > diff --git a/drivers/net/ethernet/freescale/fec_main.c
> > b/drivers/net/ethernet/freescale/fec_main.c
> > index f9aacf5..0c17df2 100644
> > --- a/drivers/net/ethernet/freescale/fec_main.c
> > +++ b/drivers/net/ethernet/freescale/fec_main.c
> > @@ -61,6 +61,7 @@
> > #include "fec.h"
> >
> > static void set_multicast_list(struct net_device *ndev);
> > +static void fec_enet_reset_phy(struct platform_device *pdev);
>
> Please move the function up and remove the prototype.
Ok, i will do it. Thanks.
>
> > @@ -1780,6 +1781,10 @@ fec_enet_open(struct net_device *ndev)
> > phy_start(fep->phy_dev);
> > netif_start_queue(ndev);
> > fep->opened = 1;
> > +
> > + /* reset phy */
> > + fec_enet_reset_phy(fep->pdev);
>
> Drop this comment. It's very redundant to the function name.
Thanks, I will remove the comment.
>
> > +static void fec_enet_reset_phy(struct platform_device *pdev)
> > {
> > - /*
> > - * In case of platform probe, the reset has been done
> > - * by machine code.
> > - */
> > + struct net_device *ndev = platform_get_drvdata(pdev);
> > + struct fec_enet_private *fep = netdev_priv(ndev);
> > +
> > + /* check GPIO valid to avoid kernel print warning when no gpio reset
> */
> > + if (gpio_is_valid(fep->phy_reset_gpio)) {
> > + gpio_set_value(fep->phy_reset_gpio, 0);
> > + msleep(fep->reset_duration);
> > + gpio_set_value(fep->phy_reset_gpio, 1);
> > + }
>
> Drop the comment. It's obvious why it's a good idea to check for a valid
> gpio.
Thanks, I will remove the comments.
^ permalink raw reply
* Re: [PATCH v2 net-next 07/27] net: add for_each iterators through neighbour lower link's private
From: Cong Wang @ 2013-09-11 1:46 UTC (permalink / raw)
To: netdev
In-Reply-To: <1378846691-9717-8-git-send-email-vfalico@redhat.com>
On Tue, 10 Sep 2013 at 20:57 GMT, Veaceslav Falico <vfalico@redhat.com> wrote:
> +void *netdev_lower_get_next_private_rcu(struct net_device *dev,
> + struct list_head **iter)
> +{
> + struct netdev_adjacent *lower;
> +
> + WARN_ON_ONCE(!rcu_read_lock_held());
> +
Since this function has _rcu suffix, this warning is not useful at all.
^ permalink raw reply
* Re: [PATCH v2 net-next 08/27] bonding: remove bond_for_each_slave_reverse()
From: Cong Wang @ 2013-09-11 1:53 UTC (permalink / raw)
To: netdev
In-Reply-To: <1378846691-9717-9-git-send-email-vfalico@redhat.com>
On Tue, 10 Sep 2013 at 20:57 GMT, Veaceslav Falico <vfalico@redhat.com> wrote:
> We only use it in rollback scenarios and can easily use the standart
> bond_for_each_dev() instead.
>
What you remove actually is bond_for_each_slave_continue_reverse()...
$subject needs to be fixed.
> diff --git a/drivers/net/bonding/bond_alb.c b/drivers/net/bonding/bond_alb.c
> index c3dcc6b..46f6b40 100644
> --- a/drivers/net/bonding/bond_alb.c
> +++ b/drivers/net/bonding/bond_alb.c
> @@ -1246,9 +1246,9 @@ static int alb_handle_addr_collision_on_attach(struct bonding *bond, struct slav
> */
> static int alb_set_mac_address(struct bonding *bond, void *addr)
> {
> - char tmp_addr[ETH_ALEN];
> - struct slave *slave;
> + struct slave *slave, *rollback_slave;
> struct sockaddr sa;
> + char tmp_addr[ETH_ALEN];
Why are you moving tmp_addr[]?
^ permalink raw reply
* [PATCH] alx: remove redundant D0 power state set
From: Yijing Wang @ 2013-09-11 2:07 UTC (permalink / raw)
To: Jay Cliburn, Chris Snook, David S. Miller; +Cc: netdev, Yijing Wang, Hanjun Guo
Pci_enable_device_mem() will set device power state to D0,
so it's no need to do it again in alx_probe().
Also remove redundant PM Cap find code, because pci core
has been saved the pci device pm cap value.
Signed-off-by: Yijing Wang <wangyijing@huawei.com>
---
drivers/net/ethernet/atheros/alx/main.c | 9 ++-------
1 files changed, 2 insertions(+), 7 deletions(-)
diff --git a/drivers/net/ethernet/atheros/alx/main.c b/drivers/net/ethernet/atheros/alx/main.c
index 027398e..fc95b23 100644
--- a/drivers/net/ethernet/atheros/alx/main.c
+++ b/drivers/net/ethernet/atheros/alx/main.c
@@ -1188,7 +1188,7 @@ static int alx_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
struct alx_priv *alx;
struct alx_hw *hw;
bool phy_configured;
- int bars, pm_cap, err;
+ int bars, err;
err = pci_enable_device_mem(pdev);
if (err)
@@ -1225,18 +1225,13 @@ static int alx_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
pci_enable_pcie_error_reporting(pdev);
pci_set_master(pdev);
- pm_cap = pci_find_capability(pdev, PCI_CAP_ID_PM);
- if (pm_cap == 0) {
+ if (!pdev->pm_cap) {
dev_err(&pdev->dev,
"Can't find power management capability, aborting\n");
err = -EIO;
goto out_pci_release;
}
- err = pci_set_power_state(pdev, PCI_D0);
- if (err)
- goto out_pci_release;
-
netdev = alloc_etherdev(sizeof(*alx));
if (!netdev) {
err = -ENOMEM;
--
1.7.1
^ permalink raw reply related
* [PATCH v2 1/1] net: fec: fix phy reset operation to let imx6sl evk work
From: Fugang Duan @ 2013-09-11 2:18 UTC (permalink / raw)
To: shawn.guo, davem; +Cc: netdev, bhutchings, stephen, b20596, s.hauer, b38611
The patch do correct phy reset operation to let imx6sl evk
ethernet work.
Current driver only do phy reset in probe function, which is
not right. Since some phy clock is disabled after module probe,
the phy enter abnormal status, which needs do reset to recovery
the phy. And do ifconfig ethx up/down test, the phy also enter
abnormal status.
The log as:
libphy: 2188000.ethernet:04 - Link is Up - 10/Full
libphy: 2188000.ethernet:04 - Link is Up - 100/Full
libphy: 2188000.ethernet:04 - Link is Down
libphy: 2188000.ethernet:04 - Link is Up - 10/Half
libphy: 2188000.ethernet:04 - Link is Up - 10/Full
libphy: 2188000.ethernet:04 - Link is Up - 100/Full
...
So, do phy reset if ethx up/down or clock enable/disable.
Changes from V1:
- remove some unecessary comments.
- move the function "fec_enet_reset_phy()" up and remove
the prototype for the function.
Signed-off-by: Fugang Duan <B38611@freescale.com>
Reviewed-by: Shawn Guo <R65073@freescale.com>
CC: Shawn Guo <shawn.guo@linaro.org>
CC: Li Frank <B20596@freescale.com>
CC: "David S. Miller" <davem@davemloft.net>
CC: Sascha Hauer <s.hauer@pengutronix.de>
---
drivers/net/ethernet/freescale/fec.h | 3 +
drivers/net/ethernet/freescale/fec_main.c | 60 +++++++++++++++++------------
2 files changed, 38 insertions(+), 25 deletions(-)
diff --git a/drivers/net/ethernet/freescale/fec.h b/drivers/net/ethernet/freescale/fec.h
index 0120217..473d5fb 100644
--- a/drivers/net/ethernet/freescale/fec.h
+++ b/drivers/net/ethernet/freescale/fec.h
@@ -321,6 +321,9 @@ struct fec_enet_private {
struct napi_struct napi;
int csum_flags;
+ int phy_reset_gpio;
+ int reset_duration;
+
struct ptp_clock *ptp_clock;
struct ptp_clock_info ptp_caps;
unsigned long last_overflow_check;
diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c
index f9aacf5..153dcbf 100644
--- a/drivers/net/ethernet/freescale/fec_main.c
+++ b/drivers/net/ethernet/freescale/fec_main.c
@@ -238,6 +238,18 @@ MODULE_PARM_DESC(macaddr, "FEC Ethernet MAC address");
static int mii_cnt;
+static void fec_enet_reset_phy(struct platform_device *pdev)
+{
+ struct net_device *ndev = platform_get_drvdata(pdev);
+ struct fec_enet_private *fep = netdev_priv(ndev);
+
+ if (gpio_is_valid(fep->phy_reset_gpio)) {
+ gpio_set_value(fep->phy_reset_gpio, 0);
+ msleep(fep->reset_duration);
+ gpio_set_value(fep->phy_reset_gpio, 1);
+ }
+}
+
static inline
struct bufdesc *fec_enet_get_nextdesc(struct bufdesc *bdp, struct fec_enet_private *fep)
{
@@ -1780,6 +1792,9 @@ fec_enet_open(struct net_device *ndev)
phy_start(fep->phy_dev);
netif_start_queue(ndev);
fep->opened = 1;
+
+ fec_enet_reset_phy(fep->pdev);
+
return 0;
}
@@ -2029,43 +2044,39 @@ static int fec_enet_init(struct net_device *ndev)
return 0;
}
-#ifdef CONFIG_OF
-static void fec_reset_phy(struct platform_device *pdev)
+static void fec_enet_of_init(struct platform_device *pdev)
{
- int err, phy_reset;
- int msec = 1;
struct device_node *np = pdev->dev.of_node;
+ struct net_device *ndev = platform_get_drvdata(pdev);
+ struct fec_enet_private *fep = netdev_priv(ndev);
+ int err;
+
+ /*
+ * init phy-reset-gpio to one invalid GPIO for no phy
+ * gpio reset platform
+ */
+ fep->phy_reset_gpio = -1;
if (!np)
return;
- of_property_read_u32(np, "phy-reset-duration", &msec);
+ of_property_read_u32(np, "phy-reset-duration",
+ &fep->reset_duration);
/* A sane reset duration should not be longer than 1s */
- if (msec > 1000)
- msec = 1;
+ if ((fep->reset_duration > 1000) || (fep->reset_duration == 0))
+ fep->reset_duration = 1;
- phy_reset = of_get_named_gpio(np, "phy-reset-gpios", 0);
- if (!gpio_is_valid(phy_reset))
+ fep->phy_reset_gpio = of_get_named_gpio(np, "phy-reset-gpios", 0);
+ if (!gpio_is_valid(fep->phy_reset_gpio))
return;
- err = devm_gpio_request_one(&pdev->dev, phy_reset,
- GPIOF_OUT_INIT_LOW, "phy-reset");
+ err = devm_gpio_request_one(&pdev->dev, fep->phy_reset_gpio,
+ GPIOF_OUT_INIT_HIGH, "phy-reset");
if (err) {
dev_err(&pdev->dev, "failed to get phy-reset-gpios: %d\n", err);
- return;
+ fep->phy_reset_gpio = -1;
}
- msleep(msec);
- gpio_set_value(phy_reset, 1);
}
-#else /* CONFIG_OF */
-static void fec_reset_phy(struct platform_device *pdev)
-{
- /*
- * In case of platform probe, the reset has been done
- * by machine code.
- */
-}
-#endif /* CONFIG_OF */
static int
fec_probe(struct platform_device *pdev)
@@ -2113,6 +2124,7 @@ fec_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, ndev);
+ fec_enet_of_init(pdev);
ret = of_get_phy_mode(pdev->dev.of_node);
if (ret < 0) {
pdata = dev_get_platdata(&pdev->dev);
@@ -2181,8 +2193,6 @@ fec_probe(struct platform_device *pdev)
fep->reg_phy = NULL;
}
- fec_reset_phy(pdev);
-
if (fep->bufdesc_ex)
fec_ptp_init(pdev);
--
1.7.1
^ permalink raw reply related
* [PATCH] bug[#43]: kgdboe: netpoll: Should handle ETH_P_ARP other than ETH_P_IP in netpoll_neigh_reply
From: Sonic Zhang @ 2013-09-11 3:31 UTC (permalink / raw)
To: David S. Miller; +Cc: netdev, adi-buildroot-devel, Sonic Zhang
From: Sonic Zhang <sonic.zhang@analog.com>
The received ARP request type in the Ethernet packet head is ETH_P_ARP other than ETH_P_IP.
Signed-off-by: Sonic Zhang <sonic.zhang@analog.com>
---
net/core/netpoll.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/net/core/netpoll.c b/net/core/netpoll.c
index 2c637e9..c3c7b27 100644
--- a/net/core/netpoll.c
+++ b/net/core/netpoll.c
@@ -550,7 +550,7 @@ static void netpoll_neigh_reply(struct sk_buff *skb, struct netpoll_info *npinfo
return;
proto = ntohs(eth_hdr(skb)->h_proto);
- if (proto == ETH_P_IP) {
+ if (proto == ETH_P_ARP) {
struct arphdr *arp;
unsigned char *arp_ptr;
/* No arp on this interface */
--
1.8.2.3
^ permalink raw reply related
* [PATCH] xen-netback: fix possible format string flaw
From: Kees Cook @ 2013-09-11 4:39 UTC (permalink / raw)
To: linux-kernel; +Cc: Ian Campbell, xen-devel, netdev
This makes sure a format string cannot accidentally leak into the
kthread_run() call.
Signed-off-by: Kees Cook <keescook@chromium.org>
---
drivers/net/xen-netback/interface.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/xen-netback/interface.c b/drivers/net/xen-netback/interface.c
index 625c6f4..77fee1d 100644
--- a/drivers/net/xen-netback/interface.c
+++ b/drivers/net/xen-netback/interface.c
@@ -406,7 +406,7 @@ int xenvif_connect(struct xenvif *vif, unsigned long tx_ring_ref,
init_waitqueue_head(&vif->wq);
vif->task = kthread_create(xenvif_kthread,
- (void *)vif, vif->dev->name);
+ (void *)vif, "%s", vif->dev->name);
if (IS_ERR(vif->task)) {
pr_warn("Could not allocate kthread for %s\n", vif->dev->name);
err = PTR_ERR(vif->task);
--
1.7.9.5
--
Kees Cook
Chrome OS Security
^ permalink raw reply related
* Re: Use-after-free in TUNSETIFF
From: Michael S. Tsirkin @ 2013-09-11 4:43 UTC (permalink / raw)
To: Wannes Rombouts; +Cc: davem, jasowang, edumazet, nhorman, netdev, Kevin Soules
In-Reply-To: <522FB273.1030506@epitech.eu>
On Wed, Sep 11, 2013 at 01:59:47AM +0200, Wannes Rombouts wrote:
> (I sent this email to security@kernel.org but they told me I should send
> it to you guys, so here you go.)
>
> Hi,
>
> I would like to report what I believe could be a potential CAP_NET_ADMIN
> to ring0 privilege escalation.
>
> The bug is in the way tuntap interfaces are initialized, when given an
> invalid name they cause a use after free. Also software like vmware
> allows for at least a freeze or kernel panic by a simple user but might
> also allow privilege escalation.
>
> Very simple to test, this causes a crash:
> # ip tuntap add dev %% mode tap
> If it doesn't crash immediately wait a few seconds and try again.
>
>
> We haven't managed to exploit the use after free yet, but we are still
> working on it. At least it crashes even with the latest kernel 3.11 and
> on different distros. (tested on Debian, Ubuntu and Arch) Looking at the
> source the bug seems quite old.
>
>
> Here is our analysis:
>
> A user with CAP_NET_ADMIN calls ioctl with TUNSETIFF and an invalid name
> for example "%d%d".
>
> tun_set_iff starts to initialize the tun_struct.
> http://lxr.free-electrons.com/source/drivers/net/tun.c#L1589
>
> It calls tun_flow_init which starts a timer with tun_flow_cleanup as
> callback. http://lxr.free-electrons.com/source/drivers/net/tun.c#L852
>
> After this tun_set_iff calls register_netdevice which returns an error
> because of the invalid name.
>
> This error causes the goto err_free_dev and the call to free_netdev.
> This will free the tun_struct.
>
> Later, once the callback gets called it uses bad memory. Sometimes it
> doesn’t get called because the timer_list has been compromised and we
> get a kernel panic at:
> http://lxr.free-electrons.com/source/kernel/timer.c?v=2.6.33#L949
>
> But it is possible to get some memory from userland that overlaps only
> the beginning of the tun_struct without overwriting the timer_list
> because there is a big array before it. Then it might be possible to
> exploit tun_flow_cleanup when it is called, but we didn't succeed yet.
>
> ------------------------------------------------------------------------
>
>
> This is the first time we try to exploit the kernel so we basically suck
> at this. I don't know if someone more skilled could do this easily or
> not, but we'll keep trying and I'll let you know if we manage it.
>
> In the mean time please let us know what you think of this and of course
> we are very interested in the way this is patched. Please keep us in the
> loop.
>
> Of course we will be happy to assist in any way we can, feel free to
> ask! Also we would like to know when you think it would be reasonable to
> disclose and talk about this bug.
>
> Regards,
>
> Wannes 'wapiflapi' Rombouts
> Kevin 'eax64' Soules
>
>
>
Thanks a lot for the report. So this one is easy to fix I think.
Does the below patch help?
However, looking at the error handling in that function,
it looks like it could leak resources in many other ways.
We probably need more patches on top to fix it properly.
-->
tun: cleanup flow on set_iff error path
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
---
diff --git a/drivers/net/tun.c b/drivers/net/tun.c
index b7c457a..c0470c1 100644
--- a/drivers/net/tun.c
+++ b/drivers/net/tun.c
@@ -1660,11 +1660,11 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr)
INIT_LIST_HEAD(&tun->disabled);
err = tun_attach(tun, file);
if (err < 0)
- goto err_free_dev;
+ goto err_free_flow;
err = register_netdevice(tun->dev);
if (err < 0)
- goto err_free_dev;
+ goto err_free_flow;
if (device_create_file(&tun->dev->dev, &dev_attr_tun_flags) ||
device_create_file(&tun->dev->dev, &dev_attr_owner) ||
@@ -1708,7 +1708,9 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr)
strcpy(ifr->ifr_name, tun->dev->name);
return 0;
- err_free_dev:
+err_free_flow:
+ tun_flow_uninit(dev);
+err_free_dev:
free_netdev(dev);
return err;
}
^ permalink raw reply related
* Re: [PATCH 1/1] sfc: Staticize efx_ethtool_get_ts_info
From: Sachin Kamat @ 2013-09-11 4:43 UTC (permalink / raw)
To: Ben Hutchings; +Cc: netdev@vger.kernel.org, linux-net-drivers
In-Reply-To: <1378814891.32513.29.camel@deadeye.wl.decadent.org.uk>
On 10 September 2013 17:38, Ben Hutchings <bhutchings@solarflare.com> wrote:
> On Tue, 2013-09-10 at 15:13 +0530, Sachin Kamat wrote:
>> 'efx_ethtool_get_ts_info' is used only in this file.
>> Make it static.
>
> I already have this fix, but net-next is not open for changes.
I wasn't aware. Sorry for the noise.
--
With warm regards,
Sachin
^ permalink raw reply
* Re: Use-after-free in TUNSETIFF
From: Jason Wang @ 2013-09-11 4:45 UTC (permalink / raw)
To: Michael S. Tsirkin
Cc: Wannes Rombouts, davem, edumazet, nhorman, netdev, Kevin Soules
In-Reply-To: <20130911044355.GB13891@redhat.com>
----- Original Message -----
> On Wed, Sep 11, 2013 at 01:59:47AM +0200, Wannes Rombouts wrote:
> > (I sent this email to security@kernel.org but they told me I should send
> > it to you guys, so here you go.)
> >
> > Hi,
> >
> > I would like to report what I believe could be a potential CAP_NET_ADMIN
> > to ring0 privilege escalation.
> >
> > The bug is in the way tuntap interfaces are initialized, when given an
> > invalid name they cause a use after free. Also software like vmware
> > allows for at least a freeze or kernel panic by a simple user but might
> > also allow privilege escalation.
> >
> > Very simple to test, this causes a crash:
> > # ip tuntap add dev %% mode tap
> > If it doesn't crash immediately wait a few seconds and try again.
> >
> >
> > We haven't managed to exploit the use after free yet, but we are still
> > working on it. At least it crashes even with the latest kernel 3.11 and
> > on different distros. (tested on Debian, Ubuntu and Arch) Looking at the
> > source the bug seems quite old.
> >
> >
> > Here is our analysis:
> >
> > A user with CAP_NET_ADMIN calls ioctl with TUNSETIFF and an invalid name
> > for example "%d%d".
> >
> > tun_set_iff starts to initialize the tun_struct.
> > http://lxr.free-electrons.com/source/drivers/net/tun.c#L1589
> >
> > It calls tun_flow_init which starts a timer with tun_flow_cleanup as
> > callback. http://lxr.free-electrons.com/source/drivers/net/tun.c#L852
> >
> > After this tun_set_iff calls register_netdevice which returns an error
> > because of the invalid name.
> >
> > This error causes the goto err_free_dev and the call to free_netdev.
> > This will free the tun_struct.
> >
> > Later, once the callback gets called it uses bad memory. Sometimes it
> > doesn’t get called because the timer_list has been compromised and we
> > get a kernel panic at:
> > http://lxr.free-electrons.com/source/kernel/timer.c?v=2.6.33#L949
> >
> > But it is possible to get some memory from userland that overlaps only
> > the beginning of the tun_struct without overwriting the timer_list
> > because there is a big array before it. Then it might be possible to
> > exploit tun_flow_cleanup when it is called, but we didn't succeed yet.
> >
> > ------------------------------------------------------------------------
> >
> >
> > This is the first time we try to exploit the kernel so we basically suck
> > at this. I don't know if someone more skilled could do this easily or
> > not, but we'll keep trying and I'll let you know if we manage it.
> >
> > In the mean time please let us know what you think of this and of course
> > we are very interested in the way this is patched. Please keep us in the
> > loop.
> >
> > Of course we will be happy to assist in any way we can, feel free to
> > ask! Also we would like to know when you think it would be reasonable to
> > disclose and talk about this bug.
> >
> > Regards,
> >
> > Wannes 'wapiflapi' Rombouts
> > Kevin 'eax64' Soules
> >
> >
> >
>
> Thanks a lot for the report. So this one is easy to fix I think.
> Does the below patch help?
> However, looking at the error handling in that function,
> it looks like it could leak resources in many other ways.
> We probably need more patches on top to fix it properly.
>
True, I'm working on a patch to solve all of them. Will post soon
^ permalink raw reply
* Re: [PATCH v2 net-next 07/27] net: add for_each iterators through neighbour lower link's private
From: Veaceslav Falico @ 2013-09-11 5:37 UTC (permalink / raw)
To: Cong Wang; +Cc: netdev
In-Reply-To: <l0oi1g$jo6$1@ger.gmane.org>
On Wed, Sep 11, 2013 at 3:46 AM, Cong Wang <xiyou.wangcong@gmail.com> wrote:
> On Tue, 10 Sep 2013 at 20:57 GMT, Veaceslav Falico <vfalico@redhat.com> wrote:
>> +void *netdev_lower_get_next_private_rcu(struct net_device *dev,
>> + struct list_head **iter)
>> +{
>> + struct netdev_adjacent *lower;
>> +
>> + WARN_ON_ONCE(!rcu_read_lock_held());
>> +
>
> Since this function has _rcu suffix, this warning is not useful at all.
I've been using it to catch offenders, just in case, like BUG_ON.
I can easily remove it, if needed, there are *tons* of cleanups
that can be made for this patchset, tbh, I've just left it the way it
is to be able to catch bug/review easier :).
p.s. Please, use reply-all when replying...
--
Best regards,
Veaceslav Falico
^ 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