aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>2006-12-14 18:51:23 -0500
committerDavid S. Miller <davem@sunset.davemloft.net>2006-12-18 00:59:11 -0500
commita4282717c102aef2bfab1d947c392de4d8abc0ec (patch)
treeef178b6eea8cd9a8790ae58a6c19ff2aa877bcc1
parent58bc57471514be9206ebcda90b1076f6be41d1c7 (diff)
[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>
-rw-r--r--include/net/ax25.h10
-rw-r--r--net/ax25/ax25_iface.c55
-rw-r--r--net/netrom/af_netrom.c8
-rw-r--r--net/rose/af_rose.c8
4 files changed, 29 insertions, 52 deletions
diff --git a/include/net/ax25.h b/include/net/ax25.h
index 51060ef74590..5ae10dd2e32e 100644
--- a/include/net/ax25.h
+++ b/include/net/ax25.h
@@ -342,8 +342,14 @@ struct ax25_protocol {
342 342
343extern void ax25_register_pid(struct ax25_protocol *ap); 343extern void ax25_register_pid(struct ax25_protocol *ap);
344extern void ax25_protocol_release(unsigned int); 344extern void ax25_protocol_release(unsigned int);
345extern int __must_check ax25_linkfail_register(void (*)(ax25_cb *, int)); 345
346extern void ax25_linkfail_release(void (*)(ax25_cb *, int)); 346struct ax25_linkfail {
347 struct hlist_node lf_node;
348 void (*func)(ax25_cb *, int);
349};
350
351extern void ax25_linkfail_register(struct ax25_linkfail *lf);
352extern void ax25_linkfail_release(struct ax25_linkfail *lf);
347extern int __must_check ax25_listen_register(ax25_address *, 353extern int __must_check ax25_listen_register(ax25_address *,
348 struct net_device *); 354 struct net_device *);
349extern void ax25_listen_release(ax25_address *, struct net_device *); 355extern void ax25_listen_release(ax25_address *, struct net_device *);
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 @@
32static struct ax25_protocol *protocol_list; 32static struct ax25_protocol *protocol_list;
33static DEFINE_RWLOCK(protocol_list_lock); 33static DEFINE_RWLOCK(protocol_list_lock);
34 34
35static struct linkfail_struct { 35static HLIST_HEAD(ax25_linkfail_list);
36 struct linkfail_struct *next;
37 void (*func)(ax25_cb *, int);
38} *linkfail_list = NULL;
39static DEFINE_SPINLOCK(linkfail_lock); 36static DEFINE_SPINLOCK(linkfail_lock);
40 37
41static struct listen_struct { 38static struct listen_struct {
@@ -93,54 +90,19 @@ void ax25_protocol_release(unsigned int pid)
93 90
94EXPORT_SYMBOL(ax25_protocol_release); 91EXPORT_SYMBOL(ax25_protocol_release);
95 92
96int ax25_linkfail_register(void (*func)(ax25_cb *, int)) 93void ax25_linkfail_register(struct ax25_linkfail *lf)
97{ 94{
98 struct linkfail_struct *linkfail;
99
100 if ((linkfail = kmalloc(sizeof(*linkfail), GFP_ATOMIC)) == NULL)
101 return 0;
102
103 linkfail->func = func;
104
105 spin_lock_bh(&linkfail_lock); 95 spin_lock_bh(&linkfail_lock);
106 linkfail->next = linkfail_list; 96 hlist_add_head(&lf->lf_node, &ax25_linkfail_list);
107 linkfail_list = linkfail;
108 spin_unlock_bh(&linkfail_lock); 97 spin_unlock_bh(&linkfail_lock);
109
110 return 1;
111} 98}
112 99
113EXPORT_SYMBOL(ax25_linkfail_register); 100EXPORT_SYMBOL(ax25_linkfail_register);
114 101
115void ax25_linkfail_release(void (*func)(ax25_cb *, int)) 102void ax25_linkfail_release(struct ax25_linkfail *lf)
116{ 103{
117 struct linkfail_struct *s, *linkfail;
118
119 spin_lock_bh(&linkfail_lock); 104 spin_lock_bh(&linkfail_lock);
120 linkfail = linkfail_list; 105 hlist_del_init(&lf->lf_node);
121 if (linkfail == NULL) {
122 spin_unlock_bh(&linkfail_lock);
123 return;
124 }
125
126 if (linkfail->func == func) {
127 linkfail_list = linkfail->next;
128 spin_unlock_bh(&linkfail_lock);
129 kfree(linkfail);
130 return;
131 }
132
133 while (linkfail != NULL && linkfail->next != NULL) {
134 if (linkfail->next->func == func) {
135 s = linkfail->next;
136 linkfail->next = linkfail->next->next;
137 spin_unlock_bh(&linkfail_lock);
138 kfree(s);
139 return;
140 }
141
142 linkfail = linkfail->next;
143 }
144 spin_unlock_bh(&linkfail_lock); 106 spin_unlock_bh(&linkfail_lock);
145} 107}
146 108
@@ -237,11 +199,12 @@ int ax25_listen_mine(ax25_address *callsign, struct net_device *dev)
237 199
238void ax25_link_failed(ax25_cb *ax25, int reason) 200void ax25_link_failed(ax25_cb *ax25, int reason)
239{ 201{
240 struct linkfail_struct *linkfail; 202 struct ax25_linkfail *lf;
203 struct hlist_node *node;
241 204
242 spin_lock_bh(&linkfail_lock); 205 spin_lock_bh(&linkfail_lock);
243 for (linkfail = linkfail_list; linkfail != NULL; linkfail = linkfail->next) 206 hlist_for_each_entry(lf, node, &ax25_linkfail_list, lf_node)
244 (linkfail->func)(ax25, reason); 207 lf->func(ax25, reason);
245 spin_unlock_bh(&linkfail_lock); 208 spin_unlock_bh(&linkfail_lock);
246} 209}
247 210
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 = {
1382 .func = nr_route_frame 1382 .func = nr_route_frame
1383}; 1383};
1384 1384
1385static struct ax25_linkfail nr_linkfail_notifier = {
1386 .func = nr_link_failed,
1387};
1388
1385static int __init nr_proto_init(void) 1389static int __init nr_proto_init(void)
1386{ 1390{
1387 int i; 1391 int i;
@@ -1430,7 +1434,7 @@ static int __init nr_proto_init(void)
1430 register_netdevice_notifier(&nr_dev_notifier); 1434 register_netdevice_notifier(&nr_dev_notifier);
1431 1435
1432 ax25_register_pid(&nr_pid); 1436 ax25_register_pid(&nr_pid);
1433 ax25_linkfail_register(nr_link_failed); 1437 ax25_linkfail_register(&nr_linkfail_notifier);
1434 1438
1435#ifdef CONFIG_SYSCTL 1439#ifdef CONFIG_SYSCTL
1436 nr_register_sysctl(); 1440 nr_register_sysctl();
@@ -1479,7 +1483,7 @@ static void __exit nr_exit(void)
1479 nr_unregister_sysctl(); 1483 nr_unregister_sysctl();
1480#endif 1484#endif
1481 1485
1482 ax25_linkfail_release(nr_link_failed); 1486 ax25_linkfail_release(&nr_linkfail_notifier);
1483 ax25_protocol_release(AX25_P_NETROM); 1487 ax25_protocol_release(AX25_P_NETROM);
1484 1488
1485 unregister_netdevice_notifier(&nr_dev_notifier); 1489 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 = {
1487 .func = rose_route_frame 1487 .func = rose_route_frame
1488}; 1488};
1489 1489
1490static struct ax25_linkfail rose_linkfail_notifier = {
1491 .func = rose_link_failed
1492};
1493
1490static int __init rose_proto_init(void) 1494static int __init rose_proto_init(void)
1491{ 1495{
1492 int i; 1496 int i;
@@ -1537,7 +1541,7 @@ static int __init rose_proto_init(void)
1537 register_netdevice_notifier(&rose_dev_notifier); 1541 register_netdevice_notifier(&rose_dev_notifier);
1538 1542
1539 ax25_register_pid(&rose_pid); 1543 ax25_register_pid(&rose_pid);
1540 ax25_linkfail_register(rose_link_failed); 1544 ax25_linkfail_register(&rose_linkfail_notifier);
1541 1545
1542#ifdef CONFIG_SYSCTL 1546#ifdef CONFIG_SYSCTL
1543 rose_register_sysctl(); 1547 rose_register_sysctl();
@@ -1585,7 +1589,7 @@ static void __exit rose_exit(void)
1585 rose_rt_free(); 1589 rose_rt_free();
1586 1590
1587 ax25_protocol_release(AX25_P_ROSE); 1591 ax25_protocol_release(AX25_P_ROSE);
1588 ax25_linkfail_release(rose_link_failed); 1592 ax25_linkfail_release(&rose_linkfail_notifier);
1589 1593
1590 if (ax25cmp(&rose_callsign, &null_ax25_address) != 0) 1594 if (ax25cmp(&rose_callsign, &null_ax25_address) != 0)
1591 ax25_listen_release(&rose_callsign, NULL); 1595 ax25_listen_release(&rose_callsign, NULL);