Just a quick note for those of you using accept filters with a 4.4+ kernel
using the syncache: Your accept filters are broken, and easily DoSable.
The fix (attached) has now been committed to both 5.0 and 4.5, so I
recommend doing one of two things if you're using accept filters:
1. Stop using them.
2. Patch or cvsup and rebuild your kernel.
Mike "Silby" Silbersack
-- Forwarded message --
Date: Tue, 30 Apr 2002 20:27:35 -0700 (PDT)
From: Mike Silbersack <[EMAIL PROTECTED]>
To: [EMAIL PROTECTED], [EMAIL PROTECTED]
Subject: cvs commit: src/sys/kern uipc_socket.c uipc_socket2.c
silby 2002/04/30 20:27:35 PDT
Modified files:(Branch: RELENG_4)
sys/kern uipc_socket.c uipc_socket2.c
Log:
MFC:
Make sure that sockets undergoing accept filtering are aborted in a
LRU fashion when the listen queue fills up. Previously, there was
no mechanism to kick out old sockets, leading to an easy DoS of
daemons using accept filtering.
Revision ChangesPath
1.116 +1 -2 src/sys/kern/uipc_socket.c
1.87 +7 -1 src/sys/kern/uipc_socket2.c
Revision ChangesPath
1.68.2.21 +1 -2 src/sys/kern/uipc_socket.c
1.55.2.14 +7 -1 src/sys/kern/uipc_socket2.c
diff -u -r /usr/src/sys.old/kern/uipc_socket.c /usr/src/sys/kern/uipc_socket.c
--- /usr/src/sys.old/kern/uipc_socket.c Thu Apr 25 01:24:24 2002
+++ /usr/src/sys/kern/uipc_socket.c Thu Apr 25 01:28:40 2002
@@ -257,7 +257,6 @@
} else {
panic("sofree: not queued");
}
- head->so_qlen--;
so->so_state &= ~SS_INCOMP;
so->so_head = NULL;
}
@@ -1642,6 +1641,6 @@
{
struct socket *so = (struct socket *)kn->kn_fp->f_data;
- kn->kn_data = so->so_qlen - so->so_incqlen;
+ kn->kn_data = so->so_qlen;
return (! TAILQ_EMPTY(&so->so_comp));
}
diff -u -r /usr/src/sys.old/kern/uipc_socket2.c /usr/src/sys/kern/uipc_socket2.c
--- /usr/src/sys.old/kern/uipc_socket2.cThu Apr 25 01:24:24 2002
+++ /usr/src/sys/kern/uipc_socket2.cThu Apr 25 16:43:37 2002
@@ -123,6 +123,7 @@
head->so_incqlen--;
so->so_state &= ~SS_INCOMP;
TAILQ_INSERT_TAIL(&head->so_comp, so, so_list);
+ head->so_qlen++;
so->so_state |= SS_COMP;
sorwakeup(head);
wakeup_one(&head->so_timeo);
@@ -251,12 +252,17 @@
if (connstatus) {
TAILQ_INSERT_TAIL(&head->so_comp, so, so_list);
so->so_state |= SS_COMP;
+ head->so_qlen++;
} else {
+ if (head->so_incqlen >= head->so_qlimit) {
+ struct socket *sp;
+ sp = TAILQ_FIRST(&head->so_incomp);
+ (void) soabort(sp);
+ }
TAILQ_INSERT_TAIL(&head->so_incomp, so, so_list);
so->so_state |= SS_INCOMP;
head->so_incqlen++;
}
- head->so_qlen++;
if (connstatus) {
sorwakeup(head);
wakeup((caddr_t)&head->so_timeo);