diff options
author | Ralf Baechle <ralf@linux-mips.org> | 2005-08-23 13:11:45 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2005-08-23 13:11:45 -0400 |
commit | 01d7dd0e9f8c5f1888619d2649c7da389232b408 (patch) | |
tree | ee4f22a33557bae4883eb2f4fb1359e97ac74186 /include | |
parent | 53b924b31fa53ac3007df3fef6870d5074a9adf8 (diff) |
[AX25]: UID fixes
o Brown paperbag bug - ax25_findbyuid() was always returning a NULL pointer
as the result. Breaks ROSE completly and AX.25 if UID policy set to deny.
o While the list structure of AX.25's UID to callsign mapping table was
properly protected by a spinlock, it's elements were not refcounted
resulting in a race between removal and usage of an element.
Signed-off-by: Ralf Baechle DL5RB <ralf@linux-mips.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'include')
-rw-r--r-- | include/net/ax25.h | 18 |
1 files changed, 16 insertions, 2 deletions
diff --git a/include/net/ax25.h b/include/net/ax25.h index 828a3a93dda1..3696f988a9f1 100644 --- a/include/net/ax25.h +++ b/include/net/ax25.h | |||
@@ -139,11 +139,25 @@ enum { | |||
139 | #define AX25_DEF_DS_TIMEOUT (3 * 60 * HZ) /* DAMA timeout 3 minutes */ | 139 | #define AX25_DEF_DS_TIMEOUT (3 * 60 * HZ) /* DAMA timeout 3 minutes */ |
140 | 140 | ||
141 | typedef struct ax25_uid_assoc { | 141 | typedef struct ax25_uid_assoc { |
142 | struct ax25_uid_assoc *next; | 142 | struct hlist_node uid_node; |
143 | atomic_t refcount; | ||
143 | uid_t uid; | 144 | uid_t uid; |
144 | ax25_address call; | 145 | ax25_address call; |
145 | } ax25_uid_assoc; | 146 | } ax25_uid_assoc; |
146 | 147 | ||
148 | #define ax25_uid_for_each(__ax25, node, list) \ | ||
149 | hlist_for_each_entry(__ax25, node, list, uid_node) | ||
150 | |||
151 | #define ax25_uid_hold(ax25) \ | ||
152 | atomic_inc(&((ax25)->refcount)) | ||
153 | |||
154 | static inline void ax25_uid_put(ax25_uid_assoc *assoc) | ||
155 | { | ||
156 | if (atomic_dec_and_test(&assoc->refcount)) { | ||
157 | kfree(assoc); | ||
158 | } | ||
159 | } | ||
160 | |||
147 | typedef struct { | 161 | typedef struct { |
148 | ax25_address calls[AX25_MAX_DIGIS]; | 162 | ax25_address calls[AX25_MAX_DIGIS]; |
149 | unsigned char repeated[AX25_MAX_DIGIS]; | 163 | unsigned char repeated[AX25_MAX_DIGIS]; |
@@ -376,7 +390,7 @@ extern unsigned long ax25_display_timer(struct timer_list *); | |||
376 | 390 | ||
377 | /* ax25_uid.c */ | 391 | /* ax25_uid.c */ |
378 | extern int ax25_uid_policy; | 392 | extern int ax25_uid_policy; |
379 | extern ax25_address *ax25_findbyuid(uid_t); | 393 | extern ax25_uid_assoc *ax25_findbyuid(uid_t); |
380 | extern int ax25_uid_ioctl(int, struct sockaddr_ax25 *); | 394 | extern int ax25_uid_ioctl(int, struct sockaddr_ax25 *); |
381 | extern struct file_operations ax25_uid_fops; | 395 | extern struct file_operations ax25_uid_fops; |
382 | extern void ax25_uid_free(void); | 396 | extern void ax25_uid_free(void); |