hc
2024-02-20 102a0743326a03cd1a1202ceda21e175b7d3575c
kernel/net/ax25/ax25_dev.c
....@@ -1,8 +1,5 @@
1
+// SPDX-License-Identifier: GPL-2.0-or-later
12 /*
2
- * This program is free software; you can redistribute it and/or modify
3
- * it under the terms of the GNU General Public License as published by
4
- * the Free Software Foundation; either version 2 of the License, or
5
- * (at your option) any later version.
63 *
74 * Copyright (C) Jonathan Naylor G4KLX (g4klx@g4klx.demon.co.uk)
85 */
....@@ -40,6 +37,7 @@
4037 for (ax25_dev = ax25_dev_list; ax25_dev != NULL; ax25_dev = ax25_dev->next)
4138 if (ax25cmp(addr, (ax25_address *)ax25_dev->dev->dev_addr) == 0) {
4239 res = ax25_dev;
40
+ ax25_dev_hold(ax25_dev);
4341 }
4442 spin_unlock_bh(&ax25_dev_lock);
4543
....@@ -59,6 +57,7 @@
5957 return;
6058 }
6159
60
+ refcount_set(&ax25_dev->refcount, 1);
6261 dev->ax25_ptr = ax25_dev;
6362 ax25_dev->dev = dev;
6463 dev_hold(dev);
....@@ -87,6 +86,7 @@
8786 ax25_dev->next = ax25_dev_list;
8887 ax25_dev_list = ax25_dev;
8988 spin_unlock_bh(&ax25_dev_lock);
89
+ ax25_dev_hold(ax25_dev);
9090
9191 ax25_register_dev_sysctl(ax25_dev);
9292 }
....@@ -116,9 +116,10 @@
116116 if ((s = ax25_dev_list) == ax25_dev) {
117117 ax25_dev_list = s->next;
118118 spin_unlock_bh(&ax25_dev_lock);
119
+ ax25_dev_put(ax25_dev);
119120 dev->ax25_ptr = NULL;
120121 dev_put(dev);
121
- kfree(ax25_dev);
122
+ ax25_dev_put(ax25_dev);
122123 return;
123124 }
124125
....@@ -126,9 +127,10 @@
126127 if (s->next == ax25_dev) {
127128 s->next = ax25_dev->next;
128129 spin_unlock_bh(&ax25_dev_lock);
130
+ ax25_dev_put(ax25_dev);
129131 dev->ax25_ptr = NULL;
130132 dev_put(dev);
131
- kfree(ax25_dev);
133
+ ax25_dev_put(ax25_dev);
132134 return;
133135 }
134136
....@@ -136,6 +138,7 @@
136138 }
137139 spin_unlock_bh(&ax25_dev_lock);
138140 dev->ax25_ptr = NULL;
141
+ ax25_dev_put(ax25_dev);
139142 }
140143
141144 int ax25_fwd_ioctl(unsigned int cmd, struct ax25_fwd_struct *fwd)
....@@ -147,20 +150,32 @@
147150
148151 switch (cmd) {
149152 case SIOCAX25ADDFWD:
150
- if ((fwd_dev = ax25_addr_ax25dev(&fwd->port_to)) == NULL)
153
+ fwd_dev = ax25_addr_ax25dev(&fwd->port_to);
154
+ if (!fwd_dev) {
155
+ ax25_dev_put(ax25_dev);
151156 return -EINVAL;
152
- if (ax25_dev->forward != NULL)
157
+ }
158
+ if (ax25_dev->forward) {
159
+ ax25_dev_put(fwd_dev);
160
+ ax25_dev_put(ax25_dev);
153161 return -EINVAL;
162
+ }
154163 ax25_dev->forward = fwd_dev->dev;
164
+ ax25_dev_put(fwd_dev);
165
+ ax25_dev_put(ax25_dev);
155166 break;
156167
157168 case SIOCAX25DELFWD:
158
- if (ax25_dev->forward == NULL)
169
+ if (!ax25_dev->forward) {
170
+ ax25_dev_put(ax25_dev);
159171 return -EINVAL;
172
+ }
160173 ax25_dev->forward = NULL;
174
+ ax25_dev_put(ax25_dev);
161175 break;
162176
163177 default:
178
+ ax25_dev_put(ax25_dev);
164179 return -EINVAL;
165180 }
166181