From 9327f7053e3993c125944fdb137a0618319ef2a0 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Fri, 4 Dec 2009 03:46:54 +0000 Subject: tcp: Fix a connect() race with timewait sockets First patch changes __inet_hash_nolisten() and __inet6_hash() to get a timewait parameter to be able to unhash it from ehash at same time the new socket is inserted in hash. This makes sure timewait socket wont be found by a concurrent writer in __inet_check_established() Reported-by: kapil dakhane Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- include/net/inet6_hashtables.h | 2 +- include/net/inet_hashtables.h | 8 +++++--- 2 files changed, 6 insertions(+), 4 deletions(-) (limited to 'include') diff --git a/include/net/inet6_hashtables.h b/include/net/inet6_hashtables.h index 92838d3..e46674d 100644 --- a/include/net/inet6_hashtables.h +++ b/include/net/inet6_hashtables.h @@ -53,7 +53,7 @@ static inline int inet6_sk_ehashfn(const struct sock *sk) return inet6_ehashfn(net, laddr, lport, faddr, fport); } -extern void __inet6_hash(struct sock *sk); +extern int __inet6_hash(struct sock *sk, struct inet_timewait_sock *twp); /* * Sockets in TCP_CLOSE state are _always_ taken out of the hash, so diff --git a/include/net/inet_hashtables.h b/include/net/inet_hashtables.h index 41cbddd..74358d1 100644 --- a/include/net/inet_hashtables.h +++ b/include/net/inet_hashtables.h @@ -251,7 +251,7 @@ extern void inet_put_port(struct sock *sk); void inet_hashinfo_init(struct inet_hashinfo *h); -extern void __inet_hash_nolisten(struct sock *sk); +extern int __inet_hash_nolisten(struct sock *sk, struct inet_timewait_sock *tw); extern void inet_hash(struct sock *sk); extern void inet_unhash(struct sock *sk); @@ -391,10 +391,12 @@ static inline struct sock *__inet_lookup_skb(struct inet_hashinfo *hashinfo, } extern int __inet_hash_connect(struct inet_timewait_death_row *death_row, - struct sock *sk, u32 port_offset, + struct sock *sk, + u32 port_offset, int (*check_established)(struct inet_timewait_death_row *, struct sock *, __u16, struct inet_timewait_sock **), - void (*hash)(struct sock *sk)); + int (*hash)(struct sock *sk, struct inet_timewait_sock *twp)); + extern int inet_hash_connect(struct inet_timewait_death_row *death_row, struct sock *sk); #endif /* _INET_HASHTABLES_H */ -- cgit v1.1 From 3cdaedae635b17ce23c738ce7d364b442310cdec Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Fri, 4 Dec 2009 03:47:42 +0000 Subject: tcp: Fix a connect() race with timewait sockets When we find a timewait connection in __inet_hash_connect() and reuse it for a new connection request, we have a race window, releasing bind list lock and reacquiring it in __inet_twsk_kill() to remove timewait socket from list. Another thread might find the timewait socket we already chose, leading to list corruption and crashes. Fix is to remove timewait socket from bind list before releasing the bind lock. Note: This problem happens if sysctl_tcp_tw_reuse is set. Reported-by: kapil dakhane Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- include/net/inet_timewait_sock.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'include') diff --git a/include/net/inet_timewait_sock.h b/include/net/inet_timewait_sock.h index b801ade..79f67ea 100644 --- a/include/net/inet_timewait_sock.h +++ b/include/net/inet_timewait_sock.h @@ -201,6 +201,9 @@ extern void inet_twsk_put(struct inet_timewait_sock *tw); extern int inet_twsk_unhash(struct inet_timewait_sock *tw); +extern int inet_twsk_bind_unhash(struct inet_timewait_sock *tw, + struct inet_hashinfo *hashinfo); + extern struct inet_timewait_sock *inet_twsk_alloc(const struct sock *sk, const int state); -- cgit v1.1 From 64f16603eae17e869d5fc8a60ae987394190e639 Mon Sep 17 00:00:00 2001 From: Tilman Schmidt Date: Sat, 5 Dec 2009 08:54:20 +0000 Subject: gigaset: documentation amendments Various additions and improvements to the Gigaset driver's README file, and added comments to its userspace visible include file. Signed-off-by: Tilman Schmidt Signed-off-by: David S. Miller --- include/linux/gigaset_dev.h | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) (limited to 'include') diff --git a/include/linux/gigaset_dev.h b/include/linux/gigaset_dev.h index 5dc4a31..258ba82 100644 --- a/include/linux/gigaset_dev.h +++ b/include/linux/gigaset_dev.h @@ -16,15 +16,23 @@ #include +/* The magic IOCTL value for this interface. */ #define GIGASET_IOCTL 0x47 -#define GIGVER_DRIVER 0 -#define GIGVER_COMPAT 1 -#define GIGVER_FWBASE 2 +/* enable/disable device control via character device (lock out ISDN subsys) */ +#define GIGASET_REDIR _IOWR(GIGASET_IOCTL, 0, int) -#define GIGASET_REDIR _IOWR (GIGASET_IOCTL, 0, int) -#define GIGASET_CONFIG _IOWR (GIGASET_IOCTL, 1, int) -#define GIGASET_BRKCHARS _IOW (GIGASET_IOCTL, 2, unsigned char[6]) //FIXME [6] okay? -#define GIGASET_VERSION _IOWR (GIGASET_IOCTL, 3, unsigned[4]) +/* enable adapter configuration mode (M10x only) */ +#define GIGASET_CONFIG _IOWR(GIGASET_IOCTL, 1, int) + +/* set break characters (M105 only) */ +#define GIGASET_BRKCHARS _IOW(GIGASET_IOCTL, 2, unsigned char[6]) + +/* get version information selected by arg[0] */ +#define GIGASET_VERSION _IOWR(GIGASET_IOCTL, 3, unsigned[4]) +/* values for GIGASET_VERSION arg[0] */ +#define GIGVER_DRIVER 0 /* get driver version */ +#define GIGVER_COMPAT 1 /* get interface compatibility version */ +#define GIGVER_FWBASE 2 /* get base station firmware version */ #endif -- cgit v1.1 From b38310e99ed09163062902285edd6d7b3fc136d6 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Sun, 6 Dec 2009 10:35:30 +0000 Subject: include/linux/if_ether.h: Remove unused defines MAC_BUF_SIZE and DECLARE_MAC_BUF Signed-off-by: Joe Perches Signed-off-by: David S. Miller --- include/linux/if_ether.h | 2 -- 1 file changed, 2 deletions(-) (limited to 'include') diff --git a/include/linux/if_ether.h b/include/linux/if_ether.h index 005e152..299b412 100644 --- a/include/linux/if_ether.h +++ b/include/linux/if_ether.h @@ -137,8 +137,6 @@ extern struct ctl_table ether_table[]; extern ssize_t sysfs_format_mac(char *buf, const unsigned char *addr, int len); #define MAC_FMT "%02x:%02x:%02x:%02x:%02x:%02x" -#define MAC_BUF_SIZE 18 -#define DECLARE_MAC_BUF(var) char var[MAC_BUF_SIZE] #endif -- cgit v1.1 From 07f29bc5bbae4e53e982ab956fed7207990a7786 Mon Sep 17 00:00:00 2001 From: Damian Lukowski Date: Mon, 7 Dec 2009 06:06:15 +0000 Subject: tcp: Stalling connections: Fix timeout calculation routine MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch fixes a problem in the TCP connection timeout calculation. Currently, timeout decisions are made on the basis of the current tcp_time_stamp and retrans_stamp, which is usually set at the first retransmission. However, if the retransmission fails in tcp_retransmit_skb(), retrans_stamp is not updated and remains zero. This leads to wrong decisions in retransmits_timed_out() if tcp_time_stamp is larger than the specified timeout, which is very likely. In this case, the TCP connection dies after the first attempted (and unsuccessful) retransmission. With this patch, tcp_skb_cb->when is used instead, when retrans_stamp is not available. This bug has been introduced together with retransmits_timed_out() in 2.6.32, as the number of retransmissions has been used for timeout decisions before. The corresponding commit was 6fa12c85031485dff38ce550c24f10da23b0adaa (Revert Backoff [v3]: Calculate TCP's connection close threshold as a time value.). Thanks to Ilpo Järvinen for code suggestions and Frederic Leroy for testing. Reported-by: Frederic Leroy Signed-off-by: Damian Lukowski Acked-by: Ilpo Järvinen Signed-off-by: David S. Miller --- include/net/tcp.h | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'include') diff --git a/include/net/tcp.h b/include/net/tcp.h index e2d2ca2..e54bd85 100644 --- a/include/net/tcp.h +++ b/include/net/tcp.h @@ -1265,14 +1265,20 @@ static inline struct sk_buff *tcp_write_queue_prev(struct sock *sk, struct sk_bu * TCP connection after "boundary" unsucessful, exponentially backed-off * retransmissions with an initial RTO of TCP_RTO_MIN. */ -static inline bool retransmits_timed_out(const struct sock *sk, +static inline bool retransmits_timed_out(struct sock *sk, unsigned int boundary) { unsigned int timeout, linear_backoff_thresh; + unsigned int start_ts; if (!inet_csk(sk)->icsk_retransmits) return false; + if (unlikely(!tcp_sk(sk)->retrans_stamp)) + start_ts = TCP_SKB_CB(tcp_write_queue_head(sk))->when; + else + start_ts = tcp_sk(sk)->retrans_stamp; + linear_backoff_thresh = ilog2(TCP_RTO_MAX/TCP_RTO_MIN); if (boundary <= linear_backoff_thresh) @@ -1281,7 +1287,7 @@ static inline bool retransmits_timed_out(const struct sock *sk, timeout = ((2 << linear_backoff_thresh) - 1) * TCP_RTO_MIN + (boundary - linear_backoff_thresh) * TCP_RTO_MAX; - return (tcp_time_stamp - tcp_sk(sk)->retrans_stamp) >= timeout; + return (tcp_time_stamp - start_ts) >= timeout; } static inline struct sk_buff *tcp_send_head(struct sock *sk) -- cgit v1.1 From 2f7de5710a4d394920405febc2a9937c69e16dda Mon Sep 17 00:00:00 2001 From: Damian Lukowski Date: Mon, 7 Dec 2009 06:06:16 +0000 Subject: tcp: Stalling connections: Move timeout calculation routine MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch moves retransmits_timed_out() from include/net/tcp.h to tcp_timer.c, where it is used. Reported-by: Frederic Leroy Signed-off-by: Damian Lukowski Acked-by: Ilpo Järvinen Signed-off-by: David S. Miller --- include/net/tcp.h | 28 ---------------------------- 1 file changed, 28 deletions(-) (limited to 'include') diff --git a/include/net/tcp.h b/include/net/tcp.h index e54bd85..0248c18 100644 --- a/include/net/tcp.h +++ b/include/net/tcp.h @@ -1261,34 +1261,6 @@ static inline struct sk_buff *tcp_write_queue_prev(struct sock *sk, struct sk_bu #define tcp_for_write_queue_from_safe(skb, tmp, sk) \ skb_queue_walk_from_safe(&(sk)->sk_write_queue, skb, tmp) -/* This function calculates a "timeout" which is equivalent to the timeout of a - * TCP connection after "boundary" unsucessful, exponentially backed-off - * retransmissions with an initial RTO of TCP_RTO_MIN. - */ -static inline bool retransmits_timed_out(struct sock *sk, - unsigned int boundary) -{ - unsigned int timeout, linear_backoff_thresh; - unsigned int start_ts; - - if (!inet_csk(sk)->icsk_retransmits) - return false; - - if (unlikely(!tcp_sk(sk)->retrans_stamp)) - start_ts = TCP_SKB_CB(tcp_write_queue_head(sk))->when; - else - start_ts = tcp_sk(sk)->retrans_stamp; - - linear_backoff_thresh = ilog2(TCP_RTO_MAX/TCP_RTO_MIN); - - if (boundary <= linear_backoff_thresh) - timeout = ((2 << boundary) - 1) * TCP_RTO_MIN; - else - timeout = ((2 << linear_backoff_thresh) - 1) * TCP_RTO_MIN + - (boundary - linear_backoff_thresh) * TCP_RTO_MAX; - - return (tcp_time_stamp - start_ts) >= timeout; -} static inline struct sk_buff *tcp_send_head(struct sock *sk) { -- cgit v1.1 From 60c2ffd3d2cf12008747d920ae118df119006003 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Wed, 9 Dec 2009 20:58:16 +0000 Subject: net: fix compat_sys_recvmmsg parameter type compat_sys_recvmmsg has a compat_timespec parameter and not a timespec parameter. This way we also get rid of an odd cast. Cc: Arnaldo Carvalho de Melo Signed-off-by: Heiko Carstens Acked-by: Arnaldo Carvalho de Melo Signed-off-by: David S. Miller --- include/net/compat.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include') diff --git a/include/net/compat.h b/include/net/compat.h index 3c7d4e3..28d5428 100644 --- a/include/net/compat.h +++ b/include/net/compat.h @@ -46,7 +46,7 @@ extern asmlinkage long compat_sys_sendmsg(int,struct compat_msghdr __user *,unsi extern asmlinkage long compat_sys_recvmsg(int,struct compat_msghdr __user *,unsigned); extern asmlinkage long compat_sys_recvmmsg(int, struct compat_mmsghdr __user *, unsigned, unsigned, - struct timespec __user *); + struct compat_timespec __user *); extern asmlinkage long compat_sys_getsockopt(int, int, int, char __user *, int __user *); extern int put_cmsg_compat(struct msghdr*, int, int, int, void *); -- cgit v1.1