Linux 在调用 inet_csk_reqsk_queue_drop_and_put() 后崩溃
Linux crashes after calling inet_csk_reqsk_queue_drop_and_put()
我修改了 Linux 内核代码,如果 SYN 积压包含超过 9 个连接请求,它会丢弃第一个 TCP 连接请求,如下所示,但是当 8 个连接到达时系统挂起。
最后的输出是
Test : 3- SYN Queue Length = 8
原码为here.
修改代码:
tcp_rsk(req)->tfo_listener = false;
if (!want_cookie) {
struct inet_connection_sock *icsk = inet_csk(sk);
struct request_sock_queue *queue = &icsk->icsk_accept_queue;
printk("Test : 1- SYN Queue Length = %d\n", inet_csk_reqsk_queue_len(sk));
inet_csk_reqsk_queue_hash_add(sk, req,
tcp_timeout_init((struct sock *)req));
printk("Test : 2- SYN Queue Length = %d\n", inet_csk_reqsk_queue_len(sk));
// This is where i drop connection request
if (net->ipv4.sysctl_max_syn_backlog - inet_csk_reqsk_queue_len(sk) < 124) {
struct request_sock *first_request_sock = queue->rskq_accept_head;
printk("Test : First condition\n");
if (net->ipv4.sysctl_max_syn_backlog - inet_csk_reqsk_queue_len(sk) < 120) {
inet_csk_reqsk_queue_drop_and_put(sk, first_request_sock);
printk("Test : Second condition\n");
}
}
printk("Test : 3- SYN Queue Length = %d\n", inet_csk_reqsk_queue_len(sk));
}
af_ops->send_synack(sk, dst, &fl, req, &foc,
!want_cookie ? TCP_SYNACK_NORMAL :
TCP_SYNACK_COOKIE);
错误发生是因为变量 first_request_sock 由于我的逻辑错误而包含 NULL,这就是系统冻结的方式,正如@stark 和@red0ct 解释的那样,printk 延迟以避免死锁或无限递归这就是为什么它无法打印评论中提到的三行。
我修改了 Linux 内核代码,如果 SYN 积压包含超过 9 个连接请求,它会丢弃第一个 TCP 连接请求,如下所示,但是当 8 个连接到达时系统挂起。
最后的输出是
Test : 3- SYN Queue Length = 8
原码为here.
修改代码:
tcp_rsk(req)->tfo_listener = false;
if (!want_cookie) {
struct inet_connection_sock *icsk = inet_csk(sk);
struct request_sock_queue *queue = &icsk->icsk_accept_queue;
printk("Test : 1- SYN Queue Length = %d\n", inet_csk_reqsk_queue_len(sk));
inet_csk_reqsk_queue_hash_add(sk, req,
tcp_timeout_init((struct sock *)req));
printk("Test : 2- SYN Queue Length = %d\n", inet_csk_reqsk_queue_len(sk));
// This is where i drop connection request
if (net->ipv4.sysctl_max_syn_backlog - inet_csk_reqsk_queue_len(sk) < 124) {
struct request_sock *first_request_sock = queue->rskq_accept_head;
printk("Test : First condition\n");
if (net->ipv4.sysctl_max_syn_backlog - inet_csk_reqsk_queue_len(sk) < 120) {
inet_csk_reqsk_queue_drop_and_put(sk, first_request_sock);
printk("Test : Second condition\n");
}
}
printk("Test : 3- SYN Queue Length = %d\n", inet_csk_reqsk_queue_len(sk));
}
af_ops->send_synack(sk, dst, &fl, req, &foc,
!want_cookie ? TCP_SYNACK_NORMAL :
TCP_SYNACK_COOKIE);
错误发生是因为变量 first_request_sock 由于我的逻辑错误而包含 NULL,这就是系统冻结的方式,正如@stark 和@red0ct 解释的那样,printk 延迟以避免死锁或无限递归这就是为什么它无法打印评论中提到的三行。