Hi. I don''t know if this one is known, but I can''t recall seeing anything about it. If it is old news I apologize. I discovered a bug in the inetd that comes with NetKit-B-0-08 and older. If a single SYN is sent to port 13 of the server, inetd will die of Broken Pipe: write(3, "Sun Jan 12 21:50:35 1997\r\n", 26) = -1 EPIPE (Broken pipe) --- SIGPIPE (Broken pipe) --- I am no C-guru but I think this patch to inetd would fix it without adding any other problems: 1426c1426,1427 < sprintf(buffer, "%.24s\r\n", ctime(&clocc)); ---> (void) sprintf(buffer, "%.24s\r\n", ctime(&clocc)); > signal(SIGPIPE, SIG_IGN);1427a1429> signal(SIGPIPE, 13);Correct me if I am wrong... :) Regards //Tri [mod: This looks like a quick hack to me. How can a USER process like inetd get a socket to play with when the 3-way handshake hasn''t been completed? -- REW]
[Magnus Bergman] | | Hi. | | I don''t know if this one is known, but I can''t recall seeing anything | about it. If it is old news I apologize. | | I discovered a bug in the inetd that comes with NetKit-B-0-08 and older. | | If a single SYN is sent to port 13 of the server, inetd will die of Broken | Pipe: If you send a SYN to *any* internally maintained inetd service and immediately follow it up with a RST, inetd will DIE upon receiving the next connection request. See Phrack 49 (my last venture into DOS attacks) for a brief synopsis and code... -- guild/phrack
Magnus Bergman writes: > I discovered a bug in the inetd that comes with NetKit-B-0-08 and older. > > If a single SYN is sent to port 13 or 37 > of the server, inetd will die of Broken > Pipe: > > write(3, "Sun Jan 12 21:50:35 1997\r\n", 26) = -1 EPIPE (Broken pipe) > --- SIGPIPE (Broken pipe) --- > > I am no C-guru but I think this patch to inetd would fix it without adding > any other problems: > > 1426c1426,1427 > < sprintf(buffer, "%.24s\r\n", ctime(&clocc)); > --- > > (void) sprintf(buffer, "%.24s\r\n", ctime(&clocc)); > > signal(SIGPIPE, SIG_IGN); > 1427a1429 > > signal(SIGPIPE, 13); That last line shouldn''t work. If you want to set SIGPIPE back to the default behavior, use SIG_DFL instead of 13. [mod: Yes, but actually whenever inetd recieves a sigpipe it should NOT exit. I''d say moving the "signal(SIGPIPE, SIG_IGN);" over to the initialization, and leaving out the "put it back code" would be best --REW] Better fixes: 1) Disable the TCP time and daytime services (comment out their lines in inetd.conf and restart inetd). or 2) Make inetd fork before running the time and daytime servers. The time and daytime processes should then _exit(0) (not return or exit) when finished. [mod: I have objections to both suggestions: 1) Inetd is a program that simply shouldn''t crash. Saying that YOU don''t need the offending service is not really fixing anything. 2) The internal services are internal because the overhead of forking an external program was considered too much for these simple services.... (ok now you''re forking an internal program...) -- REW] > [mod: This looks like a quick hack to me. How can a USER process like > inetd get a socket to play with when the 3-way handshake hasn''t been > completed? -- REW] Good question, but some other systems seem to have this kernel behavior too. It''s probably better to fix inetd not to assume that the write will always be successful than to change the kernel.
On Sun, 12 Jan 1997, Magnus Bergman wrote:> I discovered a bug in the inetd that comes with NetKit-B-0-08 and older. > > If a single SYN is sent to port 13 of the server, inetd will die of Broken > Pipe:Try the gnu inetutils (1.2f, as found of alpha.gnu.ai.mit.edu/gnu will work with Linux). Shouldn''t have this bug. LLaP bero
> [mod: I have objections to both suggestions: 1) Inetd is a program > that simply shouldn''t crash.I went through similar heartache years ago with an, "unstable", SYSV inetd. Ever since I have put such programs in /etc/inittab as respawn jobs thereby making them "SHOULD NOT" exit rather than "MUST NOT". Mike -- .----------------------------------------------------------------------. | Mike Jagdis | Internet: mailto:mike@roan.co.uk | | Roan Technology Ltd. | | | 54A Peach Street, Wokingham | Telephone: +44 118 989 0403 | | RG40 1XG, ENGLAND | Fax: +44 118 989 1195 | `----------------------------------------------------------------------''
> Try the gnu inetutils (1.2f, as found of alpha.gnu.ai.mit.edu/gnu will > work with Linux). Shouldn''t have this bug.GNU inet utils had almost every bug going derived from the 4.4 networking. The netkit-0.09 kit should fix the inetd problem. It and the fixed libc5.3.12 also fix a pile of other problems. The Red Hat netkit-0.08-8 has most of the netkit-0.09 security changes in it. Alan
> > I discovered a bug in the inetd that comes with NetKit-B-0-08 and older.> > > > If a single SYN is sent to port 13 of the server, inetd will die of Broken > > Pipe: > > Try the gnu inetutils (1.2f, as found of alpha.gnu.ai.mit.edu/gnu will > work with Linux). Shouldn''t have this bug. Far as I can tell, it does. Worse, it has all sorts of other bugs that the netkit fixed ages and ages ago, including at least one remote root leak with a published exploit. So... use gnu inetutils at your peril. -- - David A. Holland | VINO project home page: dholland@eecs.harvard.edu | http://www.eecs.harvard.edu/vino
> The netkit-0.09 kit should fix the inetd problem.According to reports, it doesn''t. However, my question is: why is this happening? A single SYN shouldn''t have any visible effect at user level. [mod: Could it be that what is happening is this?: client server -- SYN -> <- SYNACK -- -- ACKRST -> The third packet could complete the 3-way handshake, and result in the listen call returning. However the "RST" part of that third packet immediately closes the resulting socket. Thus writing to that socket would cause a SIGPIPE. -- REW] -- - David A. Holland | VINO project home page: dholland@eecs.harvard.edu | http://www.eecs.harvard.edu/vino
> [mod: Yes, but actually whenever inetd recieves a sigpipe it should > NOT exit. I''d say moving the "signal(SIGPIPE, SIG_IGN);" over to the > initialization, and leaving out the "put it back code" would be best --REW]This would disable SIGPIPE signals in all inetd child processes. If you want to inetd to implement policies for signals, core dumps and whatnot, the policy had better be configurable per service. In the absence of such a configuration mechanism, it seems better to restore signal handling before inetd forks/execs an external server. [mod: I didn''t know that these got carried over fork/exec. My mistake -- REW] Wietse
On Sun, 19 Jan 1997, Alexander O. Yuriev wrote:> > Uh no... Now you mention it it''s one of those little patches that > > I never quite get round to sending anywhere (in spite of the > > ridulous length of time I''ve had it :-) ). I guess I should do > > all the "MUST NOT" crash daemons really. Restarting things is > > _exactly_ what inittab is for - init even knows to back off if > > something has to be restarted too often. > > Sorry took so long. Feel like making that quick patch publically available > so we cab close this inetd discussion?Yeah, it''s mailbox clearing time again :-). This one is against inet.c from the linux NetKit-0.09. It adds a -D option to prevent inetd from self-daemonizing so you can just add "inetd -D" as a respawn job in /etc/inittab (and stop it starting elsewhere as well of course!). This one isn''t actually tested either. (Of course, if you hammer inetd into the ground init will disable it for about 5 minutes so starvation attacks are possible but not quite so completely fatal.) Mike [mod: Isn''t the "-d" flag already there, and does exactly what we''d want here? Are there more references to the "debug" or options variables? --REW] --- inetd.c.old Wed Feb 5 14:41:22 1997 +++ inetd.c Wed Feb 5 14:46:19 1997 @@ -320,7 +320,7 @@ struct group *grp = NULL; int tmpint; struct sigaction sa; - int ch, pid, dofork; + int ch, pid, dofork, nodaemon = 0; char buf[50]; Argv = argv; @@ -333,8 +333,11 @@ progname = strrchr(argv[0], ''/''); progname = progname ? progname + 1 : argv[0]; - while ((ch = getopt(argc, argv, "dq:")) != EOF) + while ((ch = getopt(argc, argv, "Ddq:")) != EOF) switch(ch) { + case ''D'': + nodaemon = 1; + break; case ''d'': debug = 1; options |= SO_DEBUG; @@ -355,7 +358,7 @@ if (argc > 0) CONFIG = argv[0]; - if (debug == 0) + if (debug == 0 && !nodaemon) daemon(0, 0); openlog(progname, LOG_PID | LOG_NOWAIT, LOG_DAEMON); logpid(); -- .----------------------------------------------------------------------. | Mike Jagdis | Internet: mailto:mike@roan.co.uk | | Roan Technology Ltd. | | | 54A Peach Street, Wokingham | Telephone: +44 118 989 0403 | | RG40 1XG, ENGLAND | Fax: +44 118 989 1195 | `----------------------------------------------------------------------''