Commit a4282717c102aef2bfab1d947c392de4d8abc0ec
Committed by
David S. Miller
1 parent
58bc574715
Exists in
master
and in
4 other branches
[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>
Showing 4 changed files with 29 additions and 52 deletions Side-by-side Diff
include/net/ax25.h
... | ... | @@ -342,8 +342,14 @@ |
342 | 342 | |
343 | 343 | extern void ax25_register_pid(struct ax25_protocol *ap); |
344 | 344 | extern void ax25_protocol_release(unsigned int); |
345 | -extern int __must_check ax25_linkfail_register(void (*)(ax25_cb *, int)); | |
346 | -extern void ax25_linkfail_release(void (*)(ax25_cb *, int)); | |
345 | + | |
346 | +struct ax25_linkfail { | |
347 | + struct hlist_node lf_node; | |
348 | + void (*func)(ax25_cb *, int); | |
349 | +}; | |
350 | + | |
351 | +extern void ax25_linkfail_register(struct ax25_linkfail *lf); | |
352 | +extern void ax25_linkfail_release(struct ax25_linkfail *lf); | |
347 | 353 | extern int __must_check ax25_listen_register(ax25_address *, |
348 | 354 | struct net_device *); |
349 | 355 | extern void ax25_listen_release(ax25_address *, struct net_device *); |
net/ax25/ax25_iface.c
... | ... | @@ -32,10 +32,7 @@ |
32 | 32 | static struct ax25_protocol *protocol_list; |
33 | 33 | static DEFINE_RWLOCK(protocol_list_lock); |
34 | 34 | |
35 | -static struct linkfail_struct { | |
36 | - struct linkfail_struct *next; | |
37 | - void (*func)(ax25_cb *, int); | |
38 | -} *linkfail_list = NULL; | |
35 | +static HLIST_HEAD(ax25_linkfail_list); | |
39 | 36 | static DEFINE_SPINLOCK(linkfail_lock); |
40 | 37 | |
41 | 38 | static struct listen_struct { |
42 | 39 | |
43 | 40 | |
44 | 41 | |
45 | 42 | |
46 | 43 | |
47 | 44 | |
... | ... | @@ -93,54 +90,19 @@ |
93 | 90 | |
94 | 91 | EXPORT_SYMBOL(ax25_protocol_release); |
95 | 92 | |
96 | -int ax25_linkfail_register(void (*func)(ax25_cb *, int)) | |
93 | +void 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 | 95 | spin_lock_bh(&linkfail_lock); |
106 | - linkfail->next = linkfail_list; | |
107 | - linkfail_list = linkfail; | |
96 | + hlist_add_head(&lf->lf_node, &ax25_linkfail_list); | |
108 | 97 | spin_unlock_bh(&linkfail_lock); |
109 | - | |
110 | - return 1; | |
111 | 98 | } |
112 | 99 | |
113 | 100 | EXPORT_SYMBOL(ax25_linkfail_register); |
114 | 101 | |
115 | -void ax25_linkfail_release(void (*func)(ax25_cb *, int)) | |
102 | +void ax25_linkfail_release(struct ax25_linkfail *lf) | |
116 | 103 | { |
117 | - struct linkfail_struct *s, *linkfail; | |
118 | - | |
119 | 104 | spin_lock_bh(&linkfail_lock); |
120 | - linkfail = linkfail_list; | |
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 | - } | |
105 | + hlist_del_init(&lf->lf_node); | |
144 | 106 | spin_unlock_bh(&linkfail_lock); |
145 | 107 | } |
146 | 108 | |
147 | 109 | |
... | ... | @@ -237,11 +199,12 @@ |
237 | 199 | |
238 | 200 | void 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 | 205 | spin_lock_bh(&linkfail_lock); |
243 | - for (linkfail = linkfail_list; linkfail != NULL; linkfail = linkfail->next) | |
244 | - (linkfail->func)(ax25, reason); | |
206 | + hlist_for_each_entry(lf, node, &ax25_linkfail_list, lf_node) | |
207 | + lf->func(ax25, reason); | |
245 | 208 | spin_unlock_bh(&linkfail_lock); |
246 | 209 | } |
247 | 210 |
net/netrom/af_netrom.c
... | ... | @@ -1382,6 +1382,10 @@ |
1382 | 1382 | .func = nr_route_frame |
1383 | 1383 | }; |
1384 | 1384 | |
1385 | +static struct ax25_linkfail nr_linkfail_notifier = { | |
1386 | + .func = nr_link_failed, | |
1387 | +}; | |
1388 | + | |
1385 | 1389 | static int __init nr_proto_init(void) |
1386 | 1390 | { |
1387 | 1391 | int i; |
... | ... | @@ -1430,7 +1434,7 @@ |
1430 | 1434 | register_netdevice_notifier(&nr_dev_notifier); |
1431 | 1435 | |
1432 | 1436 | ax25_register_pid(&nr_pid); |
1433 | - ax25_linkfail_register(nr_link_failed); | |
1437 | + ax25_linkfail_register(&nr_linkfail_notifier); | |
1434 | 1438 | |
1435 | 1439 | #ifdef CONFIG_SYSCTL |
1436 | 1440 | nr_register_sysctl(); |
... | ... | @@ -1479,7 +1483,7 @@ |
1479 | 1483 | nr_unregister_sysctl(); |
1480 | 1484 | #endif |
1481 | 1485 | |
1482 | - ax25_linkfail_release(nr_link_failed); | |
1486 | + ax25_linkfail_release(&nr_linkfail_notifier); | |
1483 | 1487 | ax25_protocol_release(AX25_P_NETROM); |
1484 | 1488 | |
1485 | 1489 | unregister_netdevice_notifier(&nr_dev_notifier); |
net/rose/af_rose.c
... | ... | @@ -1487,6 +1487,10 @@ |
1487 | 1487 | .func = rose_route_frame |
1488 | 1488 | }; |
1489 | 1489 | |
1490 | +static struct ax25_linkfail rose_linkfail_notifier = { | |
1491 | + .func = rose_link_failed | |
1492 | +}; | |
1493 | + | |
1490 | 1494 | static int __init rose_proto_init(void) |
1491 | 1495 | { |
1492 | 1496 | int i; |
... | ... | @@ -1537,7 +1541,7 @@ |
1537 | 1541 | register_netdevice_notifier(&rose_dev_notifier); |
1538 | 1542 | |
1539 | 1543 | ax25_register_pid(&rose_pid); |
1540 | - ax25_linkfail_register(rose_link_failed); | |
1544 | + ax25_linkfail_register(&rose_linkfail_notifier); | |
1541 | 1545 | |
1542 | 1546 | #ifdef CONFIG_SYSCTL |
1543 | 1547 | rose_register_sysctl(); |
... | ... | @@ -1585,7 +1589,7 @@ |
1585 | 1589 | rose_rt_free(); |
1586 | 1590 | |
1587 | 1591 | ax25_protocol_release(AX25_P_ROSE); |
1588 | - ax25_linkfail_release(rose_link_failed); | |
1592 | + ax25_linkfail_release(&rose_linkfail_notifier); | |
1589 | 1593 | |
1590 | 1594 | if (ax25cmp(&rose_callsign, &null_ax25_address) != 0) |
1591 | 1595 | ax25_listen_release(&rose_callsign, NULL); |