Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
linux
Commits
09d25c03
Commit
09d25c03
authored
Sep 28, 2002
by
Arnaldo Carvalho de Melo
Committed by
David S. Miller
Sep 28, 2002
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
o X25: protect x25 sockets and list with refcnt and rwlock
parent
b498a583
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
55 additions
and
38 deletions
+55
-38
net/x25/af_x25.c
net/x25/af_x25.c
+55
-38
No files found.
net/x25/af_x25.c
View file @
09d25c03
...
@@ -65,7 +65,8 @@ int sysctl_x25_reset_request_timeout = X25_DEFAULT_T22;
...
@@ -65,7 +65,8 @@ int sysctl_x25_reset_request_timeout = X25_DEFAULT_T22;
int
sysctl_x25_clear_request_timeout
=
X25_DEFAULT_T23
;
int
sysctl_x25_clear_request_timeout
=
X25_DEFAULT_T23
;
int
sysctl_x25_ack_holdback_timeout
=
X25_DEFAULT_T2
;
int
sysctl_x25_ack_holdback_timeout
=
X25_DEFAULT_T2
;
static
struct
sock
*
volatile
x25_list
/* = NULL initially */
;
static
struct
sock
*
x25_list
;
static
rwlock_t
x25_list_lock
=
RW_LOCK_UNLOCKED
;
static
struct
proto_ops
x25_proto_ops
;
static
struct
proto_ops
x25_proto_ops
;
...
@@ -152,22 +153,22 @@ int x25_addr_aton(unsigned char *p, struct x25_address *called_addr,
...
@@ -152,22 +153,22 @@ int x25_addr_aton(unsigned char *p, struct x25_address *called_addr,
static
void
x25_remove_socket
(
struct
sock
*
sk
)
static
void
x25_remove_socket
(
struct
sock
*
sk
)
{
{
struct
sock
*
s
;
struct
sock
*
s
;
unsigned
long
flags
;
save_flags
(
flags
);
write_lock_bh
(
&
x25_list_lock
);
cli
();
if
((
s
=
x25_list
)
==
sk
)
if
((
s
=
x25_list
)
==
sk
)
x25_list
=
s
->
next
;
x25_list
=
s
->
next
;
else
while
(
s
&&
s
->
next
)
{
else
while
(
s
&&
s
->
next
)
{
if
(
s
->
next
==
sk
)
{
if
(
s
->
next
==
sk
)
{
s
->
next
=
sk
->
next
;
s
->
next
=
sk
->
next
;
sock_put
(
sk
);
break
;
break
;
}
}
s
=
s
->
next
;
s
=
s
->
next
;
}
}
restore_flags
(
flags
);
write_unlock_bh
(
&
x25_list_lock
);
}
}
/*
/*
...
@@ -177,15 +178,20 @@ static void x25_kill_by_device(struct net_device *dev)
...
@@ -177,15 +178,20 @@ static void x25_kill_by_device(struct net_device *dev)
{
{
struct
sock
*
s
;
struct
sock
*
s
;
write_lock_bh
(
&
x25_list_lock
);
for
(
s
=
x25_list
;
s
;
s
=
s
->
next
)
for
(
s
=
x25_list
;
s
;
s
=
s
->
next
)
if
(
x25_sk
(
s
)
->
neighbour
&&
x25_sk
(
s
)
->
neighbour
->
dev
==
dev
)
if
(
x25_sk
(
s
)
->
neighbour
&&
x25_sk
(
s
)
->
neighbour
->
dev
==
dev
)
x25_disconnect
(
s
,
ENETUNREACH
,
0
,
0
);
x25_disconnect
(
s
,
ENETUNREACH
,
0
,
0
);
write_unlock_bh
(
&
x25_list_lock
);
}
}
/*
/*
* Handle device status changes.
* Handle device status changes.
*/
*/
static
int
x25_device_event
(
struct
notifier_block
*
this
,
unsigned
long
event
,
void
*
ptr
)
static
int
x25_device_event
(
struct
notifier_block
*
this
,
unsigned
long
event
,
void
*
ptr
)
{
{
struct
net_device
*
dev
=
ptr
;
struct
net_device
*
dev
=
ptr
;
struct
x25_neigh
*
nb
;
struct
x25_neigh
*
nb
;
...
@@ -222,15 +228,11 @@ static int x25_device_event(struct notifier_block *this, unsigned long event, vo
...
@@ -222,15 +228,11 @@ static int x25_device_event(struct notifier_block *this, unsigned long event, vo
*/
*/
static
void
x25_insert_socket
(
struct
sock
*
sk
)
static
void
x25_insert_socket
(
struct
sock
*
sk
)
{
{
unsigned
long
flags
;
write_lock_bh
(
&
x25_list_lock
);
save_flags
(
flags
);
cli
();
sk
->
next
=
x25_list
;
sk
->
next
=
x25_list
;
x25_list
=
sk
;
x25_list
=
sk
;
sock_hold
(
sk
);
restore_flags
(
flags
);
write_unlock_bh
(
&
x25_list_lock
);
}
}
/*
/*
...
@@ -239,11 +241,9 @@ static void x25_insert_socket(struct sock *sk)
...
@@ -239,11 +241,9 @@ static void x25_insert_socket(struct sock *sk)
*/
*/
static
struct
sock
*
x25_find_listener
(
struct
x25_address
*
addr
)
static
struct
sock
*
x25_find_listener
(
struct
x25_address
*
addr
)
{
{
unsigned
long
flags
;
struct
sock
*
s
;
struct
sock
*
s
;
save_flags
(
flags
);
read_lock_bh
(
&
x25_list_lock
);
cli
();
for
(
s
=
x25_list
;
s
;
s
=
s
->
next
)
for
(
s
=
x25_list
;
s
;
s
=
s
->
next
)
if
((
!
strcmp
(
addr
->
x25_addr
,
x25_sk
(
s
)
->
source_addr
.
x25_addr
)
||
if
((
!
strcmp
(
addr
->
x25_addr
,
x25_sk
(
s
)
->
source_addr
.
x25_addr
)
||
...
@@ -251,26 +251,34 @@ static struct sock *x25_find_listener(struct x25_address *addr)
...
@@ -251,26 +251,34 @@ static struct sock *x25_find_listener(struct x25_address *addr)
s
->
state
==
TCP_LISTEN
)
s
->
state
==
TCP_LISTEN
)
break
;
break
;
restore_flags
(
flags
);
if
(
s
)
sock_hold
(
s
);
read_unlock_bh
(
&
x25_list_lock
);
return
s
;
return
s
;
}
}
/*
/*
* Find a connected X.25 socket given my LCI and neighbour.
* Find a connected X.25 socket given my LCI and neighbour.
*/
*/
struct
sock
*
x25_find_socket
(
unsigned
int
lci
,
struct
x25_neigh
*
nb
)
struct
sock
*
__
x25_find_socket
(
unsigned
int
lci
,
struct
x25_neigh
*
nb
)
{
{
struct
sock
*
s
;
struct
sock
*
s
;
unsigned
long
flags
;
save_flags
(
flags
);
cli
();
for
(
s
=
x25_list
;
s
;
s
=
s
->
next
)
for
(
s
=
x25_list
;
s
;
s
=
s
->
next
)
if
(
x25_sk
(
s
)
->
lci
==
lci
&&
x25_sk
(
s
)
->
neighbour
==
nb
)
if
(
x25_sk
(
s
)
->
lci
==
lci
&&
x25_sk
(
s
)
->
neighbour
==
nb
)
break
;
break
;
if
(
s
)
sock_hold
(
s
);
return
s
;
}
struct
sock
*
x25_find_socket
(
unsigned
int
lci
,
struct
x25_neigh
*
nb
)
{
struct
sock
*
s
;
restore_flags
(
flags
);
read_lock_bh
(
&
x25_list_lock
);
s
=
__x25_find_socket
(
lci
,
nb
);
read_unlock_bh
(
&
x25_list_lock
);
return
s
;
return
s
;
}
}
...
@@ -280,13 +288,19 @@ struct sock *x25_find_socket(unsigned int lci, struct x25_neigh *nb)
...
@@ -280,13 +288,19 @@ struct sock *x25_find_socket(unsigned int lci, struct x25_neigh *nb)
unsigned
int
x25_new_lci
(
struct
x25_neigh
*
nb
)
unsigned
int
x25_new_lci
(
struct
x25_neigh
*
nb
)
{
{
unsigned
int
lci
=
1
;
unsigned
int
lci
=
1
;
struct
sock
*
sk
;
read_lock_bh
(
&
x25_list_lock
);
while
(
x25_find_socket
(
lci
,
nb
))
while
((
sk
=
__x25_find_socket
(
lci
,
nb
))
!=
NULL
)
{
sock_put
(
sk
);
if
(
++
lci
==
4096
)
{
if
(
++
lci
==
4096
)
{
lci
=
0
;
lci
=
0
;
break
;
break
;
}
}
}
read_unlock_bh
(
&
x25_list_lock
);
return
lci
;
return
lci
;
}
}
...
@@ -312,11 +326,9 @@ static void x25_destroy_timer(unsigned long data)
...
@@ -312,11 +326,9 @@ static void x25_destroy_timer(unsigned long data)
void
x25_destroy_socket
(
struct
sock
*
sk
)
/* Not static as it's used by the timer */
void
x25_destroy_socket
(
struct
sock
*
sk
)
/* Not static as it's used by the timer */
{
{
struct
sk_buff
*
skb
;
struct
sk_buff
*
skb
;
unsigned
long
flags
;
save_flags
(
flags
);
cli
();
sock_hold
(
sk
);
lock_sock
(
sk
);
x25_stop_heartbeat
(
sk
);
x25_stop_heartbeat
(
sk
);
x25_stop_timer
(
sk
);
x25_stop_timer
(
sk
);
...
@@ -344,8 +356,8 @@ void x25_destroy_socket(struct sock *sk) /* Not static as it's used by the timer
...
@@ -344,8 +356,8 @@ void x25_destroy_socket(struct sock *sk) /* Not static as it's used by the timer
sk_free
(
sk
);
sk_free
(
sk
);
MOD_DEC_USE_COUNT
;
MOD_DEC_USE_COUNT
;
}
}
release_sock
(
sk
);
restore_flags
(
flags
);
sock_put
(
sk
);
}
}
/*
/*
...
@@ -799,7 +811,7 @@ int x25_rx_call_request(struct sk_buff *skb, struct x25_neigh *nb, unsigned int
...
@@ -799,7 +811,7 @@ int x25_rx_call_request(struct sk_buff *skb, struct x25_neigh *nb, unsigned int
* Try to reach a compromise on the requested facilities.
* Try to reach a compromise on the requested facilities.
*/
*/
if
((
len
=
x25_negotiate_facilities
(
skb
,
sk
,
&
facilities
))
==
-
1
)
if
((
len
=
x25_negotiate_facilities
(
skb
,
sk
,
&
facilities
))
==
-
1
)
goto
out_
clear_reques
t
;
goto
out_
sock_pu
t
;
/*
/*
* current neighbour/link might impose additional limits
* current neighbour/link might impose additional limits
...
@@ -813,7 +825,7 @@ int x25_rx_call_request(struct sk_buff *skb, struct x25_neigh *nb, unsigned int
...
@@ -813,7 +825,7 @@ int x25_rx_call_request(struct sk_buff *skb, struct x25_neigh *nb, unsigned int
*/
*/
make
=
x25_make_new
(
sk
);
make
=
x25_make_new
(
sk
);
if
(
!
make
)
if
(
!
make
)
goto
out_
clear_reques
t
;
goto
out_
sock_pu
t
;
/*
/*
* Remove the facilities, leaving any Call User Data.
* Remove the facilities, leaving any Call User Data.
...
@@ -855,8 +867,11 @@ int x25_rx_call_request(struct sk_buff *skb, struct x25_neigh *nb, unsigned int
...
@@ -855,8 +867,11 @@ int x25_rx_call_request(struct sk_buff *skb, struct x25_neigh *nb, unsigned int
if
(
!
sk
->
dead
)
if
(
!
sk
->
dead
)
sk
->
data_ready
(
sk
,
skb
->
len
);
sk
->
data_ready
(
sk
,
skb
->
len
);
rc
=
1
;
rc
=
1
;
sock_put
(
sk
);
out:
out:
return
rc
;
return
rc
;
out_sock_put:
sock_put
(
sk
);
out_clear_request:
out_clear_request:
rc
=
0
;
rc
=
0
;
x25_transmit_clear_request
(
nb
,
lci
,
0x01
);
x25_transmit_clear_request
(
nb
,
lci
,
0x01
);
...
@@ -1264,14 +1279,12 @@ static int x25_get_info(char *buffer, char **start, off_t offset, int length)
...
@@ -1264,14 +1279,12 @@ static int x25_get_info(char *buffer, char **start, off_t offset, int length)
struct
sock
*
s
;
struct
sock
*
s
;
struct
net_device
*
dev
;
struct
net_device
*
dev
;
const
char
*
devname
;
const
char
*
devname
;
int
len
;
off_t
pos
=
0
;
off_t
pos
=
0
;
off_t
begin
=
0
;
off_t
begin
=
0
;
int
len
=
sprintf
(
buffer
,
"dest_addr src_addr dev lci st vs vr "
"va t t2 t21 t22 t23 Snd-Q Rcv-Q inode
\n
"
);
cli
();
read_lock_bh
(
&
x25_list_lock
);
len
=
sprintf
(
buffer
,
"dest_addr src_addr dev lci st vs vr va "
"t t2 t21 t22 t23 Snd-Q Rcv-Q inode
\n
"
);
for
(
s
=
x25_list
;
s
;
s
=
s
->
next
)
{
for
(
s
=
x25_list
;
s
;
s
=
s
->
next
)
{
struct
x25_opt
*
x25
=
x25_sk
(
s
);
struct
x25_opt
*
x25
=
x25_sk
(
s
);
...
@@ -1314,7 +1327,7 @@ static int x25_get_info(char *buffer, char **start, off_t offset, int length)
...
@@ -1314,7 +1327,7 @@ static int x25_get_info(char *buffer, char **start, off_t offset, int length)
break
;
break
;
}
}
sti
(
);
read_unlock_bh
(
&
x25_list_lock
);
*
start
=
buffer
+
(
offset
-
begin
);
*
start
=
buffer
+
(
offset
-
begin
);
len
-=
(
offset
-
begin
);
len
-=
(
offset
-
begin
);
...
@@ -1368,9 +1381,13 @@ void x25_kill_by_neigh(struct x25_neigh *nb)
...
@@ -1368,9 +1381,13 @@ void x25_kill_by_neigh(struct x25_neigh *nb)
{
{
struct
sock
*
s
;
struct
sock
*
s
;
write_lock_bh
(
&
x25_list_lock
);
for
(
s
=
x25_list
;
s
;
s
=
s
->
next
)
for
(
s
=
x25_list
;
s
;
s
=
s
->
next
)
if
(
x25_sk
(
s
)
->
neighbour
==
nb
)
if
(
x25_sk
(
s
)
->
neighbour
==
nb
)
x25_disconnect
(
s
,
ENETUNREACH
,
0
,
0
);
x25_disconnect
(
s
,
ENETUNREACH
,
0
,
0
);
write_unlock_bh
(
&
x25_list_lock
);
}
}
static
int
__init
x25_init
(
void
)
static
int
__init
x25_init
(
void
)
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment