Commit a4282717c102aef2bfab1d947c392de4d8abc0ec

Authored by Ralf Baechle
Committed by David S. Miller
1 parent 58bc574715

[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

... ... @@ -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);
... ... @@ -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);