summaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>2006-12-14 15:51:23 -0800
committerDavid S. Miller <davem@sunset.davemloft.net>2006-12-17 21:59:11 -0800
commita4282717c102aef2bfab1d947c392de4d8abc0ec (patch)
treeef178b6eea8cd9a8790ae58a6c19ff2aa877bcc1 /net
parent58bc57471514be9206ebcda90b1076f6be41d1c7 (diff)
downloadlinux-a4282717c102aef2bfab1d947c392de4d8abc0ec.tar.gz
linux-a4282717c102aef2bfab1d947c392de4d8abc0ec.tar.bz2
linux-a4282717c102aef2bfab1d947c392de4d8abc0ec.zip
[AX.25]: Fix unchecked ax25_linkfail_register uses
ax25_linkfail_register uses kmalloc and the callers were ignoring the error value. Rewrite to let the caller deal with the allocation. This allows the use of static allocation of kmalloc use entirely. Signed-off-by: Ralf Baechle <ralf@linux-mips.org> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net')
-rw-r--r--net/ax25/ax25_iface.c55
-rw-r--r--net/netrom/af_netrom.c8
-rw-r--r--net/rose/af_rose.c8
3 files changed, 21 insertions, 50 deletions
diff --git a/net/ax25/ax25_iface.c b/net/ax25/ax25_iface.c
index 51e293420b7f..aff3e652c2d1 100644
--- a/net/ax25/ax25_iface.c
+++ b/net/ax25/ax25_iface.c
@@ -32,10 +32,7 @@
static struct ax25_protocol *protocol_list;
static DEFINE_RWLOCK(protocol_list_lock);
-static struct linkfail_struct {
- struct linkfail_struct *next;
- void (*func)(ax25_cb *, int);
-} *linkfail_list = NULL;
+static HLIST_HEAD(ax25_linkfail_list);
static DEFINE_SPINLOCK(linkfail_lock);
static struct listen_struct {
@@ -93,54 +90,19 @@ void ax25_protocol_release(unsigned int pid)
EXPORT_SYMBOL(ax25_protocol_release);
-int ax25_linkfail_register(void (*func)(ax25_cb *, int))
+void ax25_linkfail_register(struct ax25_linkfail *lf)
{
- struct linkfail_struct *linkfail;
-
- if ((linkfail = kmalloc(sizeof(*linkfail), GFP_ATOMIC)) == NULL)
- return 0;
-
- linkfail->func = func;
-
spin_lock_bh(&linkfail_lock);
- linkfail->next = linkfail_list;
- linkfail_list = linkfail;
+ hlist_add_head(&lf->lf_node, &ax25_linkfail_list);
spin_unlock_bh(&linkfail_lock);
-
- return 1;
}
EXPORT_SYMBOL(ax25_linkfail_register);
-void ax25_linkfail_release(void (*func)(ax25_cb *, int))
+void ax25_linkfail_release(struct ax25_linkfail *lf)
{
- struct linkfail_struct *s, *linkfail;
-
spin_lock_bh(&linkfail_lock);
- linkfail = linkfail_list;
- if (linkfail == NULL) {
- spin_unlock_bh(&linkfail_lock);
- return;
- }
-
- if (linkfail->func == func) {
- linkfail_list = linkfail->next;
- spin_unlock_bh(&linkfail_lock);
- kfree(linkfail);
- return;
- }
-
- while (linkfail != NULL && linkfail->next != NULL) {
- if (linkfail->next->func == func) {
- s = linkfail->next;
- linkfail->next = linkfail->next->next;
- spin_unlock_bh(&linkfail_lock);
- kfree(s);
- return;
- }
-
- linkfail = linkfail->next;
- }
+ hlist_del_init(&lf->lf_node);
spin_unlock_bh(&linkfail_lock);
}
@@ -237,11 +199,12 @@ int ax25_listen_mine(ax25_address *callsign, struct net_device *dev)
void ax25_link_failed(ax25_cb *ax25, int reason)
{
- struct linkfail_struct *linkfail;
+ struct ax25_linkfail *lf;
+ struct hlist_node *node;
spin_lock_bh(&linkfail_lock);
- for (linkfail = linkfail_list; linkfail != NULL; linkfail = linkfail->next)
- (linkfail->func)(ax25, reason);
+ hlist_for_each_entry(lf, node, &ax25_linkfail_list, lf_node)
+ lf->func(ax25, reason);
spin_unlock_bh(&linkfail_lock);
}
diff --git a/net/netrom/af_netrom.c b/net/netrom/af_netrom.c
index f4675bf3976c..43bbe2c9e49a 100644
--- a/net/netrom/af_netrom.c
+++ b/net/netrom/af_netrom.c
@@ -1382,6 +1382,10 @@ static struct ax25_protocol nr_pid = {
.func = nr_route_frame
};
+static struct ax25_linkfail nr_linkfail_notifier = {
+ .func = nr_link_failed,
+};
+
static int __init nr_proto_init(void)
{
int i;
@@ -1430,7 +1434,7 @@ static int __init nr_proto_init(void)
register_netdevice_notifier(&nr_dev_notifier);
ax25_register_pid(&nr_pid);
- ax25_linkfail_register(nr_link_failed);
+ ax25_linkfail_register(&nr_linkfail_notifier);
#ifdef CONFIG_SYSCTL
nr_register_sysctl();
@@ -1479,7 +1483,7 @@ static void __exit nr_exit(void)
nr_unregister_sysctl();
#endif
- ax25_linkfail_release(nr_link_failed);
+ ax25_linkfail_release(&nr_linkfail_notifier);
ax25_protocol_release(AX25_P_NETROM);
unregister_netdevice_notifier(&nr_dev_notifier);
diff --git a/net/rose/af_rose.c b/net/rose/af_rose.c
index 09f8a06bf806..9e279464c9d1 100644
--- a/net/rose/af_rose.c
+++ b/net/rose/af_rose.c
@@ -1487,6 +1487,10 @@ static struct ax25_protocol rose_pid = {
.func = rose_route_frame
};
+static struct ax25_linkfail rose_linkfail_notifier = {
+ .func = rose_link_failed
+};
+
static int __init rose_proto_init(void)
{
int i;
@@ -1537,7 +1541,7 @@ static int __init rose_proto_init(void)
register_netdevice_notifier(&rose_dev_notifier);
ax25_register_pid(&rose_pid);
- ax25_linkfail_register(rose_link_failed);
+ ax25_linkfail_register(&rose_linkfail_notifier);
#ifdef CONFIG_SYSCTL
rose_register_sysctl();
@@ -1585,7 +1589,7 @@ static void __exit rose_exit(void)
rose_rt_free();
ax25_protocol_release(AX25_P_ROSE);
- ax25_linkfail_release(rose_link_failed);
+ ax25_linkfail_release(&rose_linkfail_notifier);
if (ax25cmp(&rose_callsign, &null_ax25_address) != 0)
ax25_listen_release(&rose_callsign, NULL);