This patch is Copyright (C) 2004 by James Craig Burley. License below. 2004-01-19 0040 EST James Craig Burley This patch improves ISO C conformance of qmail code -- specifically, of qmail-lspawn, qmail-newmrh, qmail-newu, qmail-pop3d, qmail-popup, qmail-rspawn, and qmail-smtpd. This fixes two known bugs: - qmail-smtpd can be crashed by a client sending a sufficiently long (e.g. 2GB) header line in an email. - qmail_lspawn, qmail-newmrh, qmail-newu, and qmail-rspawn might crash or otherwise misbehave on hosts with a smaller "int" type than "char *" type, e.g. 64-bit hosts with 32-bit "int"s. The other changes are unlikely to have any effect, except possibly on unusual architectures and/or in the presence of rare optimizations. This is Version 1 of this patch. It adds the changes to cdbmake_add.c, spawn.c, and, correspondingly, Makefile, which pertain to the second bug listed above. See all my qmail patches at . License: Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *** qmail-1.03/cdbmake_add.c Mon Jun 15 06:53:16 1998 --- qmail-1.03.0/cdbmake_add.c Mon Jan 19 00:35:38 2004 *************** *** 1,2 **** --- 1,3 ---- + #include "alloc.h" #include "cdbmake.h" *** qmail-1.03/Makefile Mon Jun 15 06:53:16 1998 --- qmail-1.03.0/Makefile Mon Jan 19 00:35:35 2004 *************** makelib cdbmake_pack.o cdbmake_hash.o cd *** 264,268 **** cdbmake_add.o: \ ! compile cdbmake_add.c cdbmake.h uint32.h ./compile cdbmake_add.c --- 264,268 ---- cdbmake_add.o: \ ! compile cdbmake_add.c cdbmake.h alloc.h uint32.h ./compile cdbmake_add.c *************** trylsock.c compile load *** 1893,1897 **** spawn.o: \ compile chkspawn spawn.c sig.h wait.h substdio.h byte.h str.h \ ! stralloc.h gen_alloc.h select.h exit.h coe.h open.h error.h \ auto_qmail.h auto_uids.h auto_spawn.h ./chkspawn --- 1893,1897 ---- spawn.o: \ compile chkspawn spawn.c sig.h wait.h substdio.h byte.h str.h \ ! stralloc.h gen_alloc.h select.h exit.h alloc.h coe.h open.h error.h \ auto_qmail.h auto_uids.h auto_spawn.h ./chkspawn *** qmail-1.03/qmail-pop3d.c Mon Jun 15 06:53:16 1998 --- qmail-1.03.0/qmail-pop3d.c Thu Jan 15 22:08:57 2004 *************** void die_scan() { err("unable to scan $H *** 67,71 **** void err_syntax() { err("syntax error"); } ! void err_unimpl() { err("unimplemented"); } void err_deleted() { err("already deleted"); } void err_nozero() { err("messages are counted from 1"); } --- 67,71 ---- void err_syntax() { err("syntax error"); } ! void err_unimpl(arg) char *arg; { err("unimplemented"); } void err_deleted() { err("already deleted"); } void err_nozero() { err("messages are counted from 1"); } *************** void err_nosuch() { err("unable to open *** 74,78 **** void err_nounlink() { err("unable to unlink all deleted messages"); } ! void okay() { puts("+OK \r\n"); flush(); } void printfn(fn) char *fn; --- 74,78 ---- void err_nounlink() { err("unable to unlink all deleted messages"); } ! void okay(arg) char *arg; { puts("+OK \r\n"); flush(); } void printfn(fn) char *fn; *************** void getlist() *** 147,151 **** } ! void pop3_stat() { int i; --- 147,151 ---- } ! void pop3_stat(arg) char *arg; { int i; *************** void pop3_stat() *** 162,174 **** } ! void pop3_rset() { int i; for (i = 0;i < numm;++i) m[i].flagdeleted = 0; last = 0; ! okay(); } ! void pop3_last() { puts("+OK "); --- 162,174 ---- } ! void pop3_rset(arg) char *arg; { int i; for (i = 0;i < numm;++i) m[i].flagdeleted = 0; last = 0; ! okay(0); } ! void pop3_last(arg) char *arg; { puts("+OK "); *************** void pop3_last() *** 178,182 **** } ! void pop3_quit() { int i; --- 178,182 ---- } ! void pop3_quit(arg) char *arg; { int i; *************** void pop3_quit() *** 193,197 **** rename(m[i].fn,line.s); /* if it fails, bummer */ } ! okay(); die(); } --- 193,197 ---- rename(m[i].fn,line.s); /* if it fails, bummer */ } ! okay(0); die(); } *************** void pop3_dele(arg) char *arg; *** 215,219 **** m[i].flagdeleted = 1; if (i + 1 > last) last = i + 1; ! okay(); } --- 215,219 ---- m[i].flagdeleted = 1; if (i + 1 > last) last = i + 1; ! okay(0); } *************** void dolisting(arg,flaguidl) char *arg; *** 239,243 **** } else { ! okay(); for (i = 0;i < numm;++i) if (!m[i].flagdeleted) --- 239,243 ---- } else { ! okay(0); for (i = 0;i < numm;++i) if (!m[i].flagdeleted) *************** void pop3_top(arg) char *arg; *** 268,272 **** fd = open_read(m[i].fn); if (fd == -1) { err_nosuch(); return; } ! okay(); substdio_fdbuf(&ssmsg,read,fd,ssmsgbuf,sizeof(ssmsgbuf)); blast(&ssmsg,limit); --- 268,272 ---- fd = open_read(m[i].fn); if (fd == -1) { err_nosuch(); return; } ! okay(0); substdio_fdbuf(&ssmsg,read,fd,ssmsgbuf,sizeof(ssmsgbuf)); blast(&ssmsg,limit); *************** char **argv; *** 300,304 **** getlist(); ! okay(); commands(&ssin,pop3commands); die(); --- 300,304 ---- getlist(); ! okay(0); commands(&ssin,pop3commands); die(); *** qmail-1.03/qmail-popup.c Mon Jun 15 06:53:16 1998 --- qmail-1.03.0/qmail-popup.c Thu Jan 15 22:09:21 2004 *************** void die_badauth() { err("authorization *** 65,72 **** void err_syntax() { err("syntax error"); } void err_wantuser() { err("USER first"); } ! void err_authoriz() { err("authorization first"); } ! void okay() { puts("+OK \r\n"); flush(); } ! void pop3_quit() { okay(); die(); } --- 65,72 ---- void err_syntax() { err("syntax error"); } void err_wantuser() { err("USER first"); } ! void err_authoriz(arg) char *arg; { err("authorization first"); } ! void okay(arg) char *arg; { puts("+OK \r\n"); flush(); } ! void pop3_quit(arg) char *arg; { okay(0); die(); } *************** void pop3_user(arg) char *arg; *** 137,141 **** { if (!*arg) { err_syntax(); return; } ! okay(); seenuser = 1; if (!stralloc_copys(&username,arg)) die_nomem(); --- 137,141 ---- { if (!*arg) { err_syntax(); return; } ! okay(0); seenuser = 1; if (!stralloc_copys(&username,arg)) die_nomem(); *** qmail-1.03/qmail-smtpd.c Mon Jun 15 06:53:16 1998 --- qmail-1.03.0/qmail-smtpd.c Thu Jan 15 22:12:02 2004 *************** void straynewline() { out("451 See http: *** 52,61 **** void err_bmf() { out("553 sorry, your envelope sender is in my badmailfrom list (#5.7.1)\r\n"); } void err_nogateway() { out("553 sorry, that domain isn't in my list of allowed rcpthosts (#5.7.1)\r\n"); } ! void err_unimpl() { out("502 unimplemented (#5.5.1)\r\n"); } void err_syntax() { out("555 syntax error (#5.5.4)\r\n"); } void err_wantmail() { out("503 MAIL first (#5.5.1)\r\n"); } void err_wantrcpt() { out("503 RCPT first (#5.5.1)\r\n"); } ! void err_noop() { out("250 ok\r\n"); } ! void err_vrfy() { out("252 send some mail, i'll try my best\r\n"); } void err_qqt() { out("451 qqt failure (#4.3.0)\r\n"); } --- 52,61 ---- void err_bmf() { out("553 sorry, your envelope sender is in my badmailfrom list (#5.7.1)\r\n"); } void err_nogateway() { out("553 sorry, that domain isn't in my list of allowed rcpthosts (#5.7.1)\r\n"); } ! void err_unimpl(arg) char *arg; { out("502 unimplemented (#5.5.1)\r\n"); } void err_syntax() { out("555 syntax error (#5.5.4)\r\n"); } void err_wantmail() { out("503 MAIL first (#5.5.1)\r\n"); } void err_wantrcpt() { out("503 RCPT first (#5.5.1)\r\n"); } ! void err_noop(arg) char *arg; { out("250 ok\r\n"); } ! void err_vrfy(arg) char *arg; { out("252 send some mail, i'll try my best\r\n"); } void err_qqt() { out("451 qqt failure (#4.3.0)\r\n"); } *************** void smtp_greet(code) char *code; *** 68,76 **** substdio_put(&ssout,greeting.s,greeting.len); } ! void smtp_help() { out("214 qmail home page: http://pobox.com/~djb/qmail.html\r\n"); } ! void smtp_quit() { smtp_greet("221 "); out("\r\n"); flush(); _exit(0); --- 68,76 ---- substdio_put(&ssout,greeting.s,greeting.len); } ! void smtp_help(arg) char *arg; { out("214 qmail home page: http://pobox.com/~djb/qmail.html\r\n"); } ! void smtp_quit(arg) char *arg; { smtp_greet("221 "); out("\r\n"); flush(); _exit(0); *************** void smtp_ehlo(arg) char *arg; *** 233,237 **** seenmail = 0; dohelo(arg); } ! void smtp_rset() { seenmail = 0; --- 233,237 ---- seenmail = 0; dohelo(arg); } ! void smtp_rset(arg) char *arg; { seenmail = 0; *************** int *hops; *** 317,322 **** if (pos < 2) if (ch != "\r\n"[pos]) flagmaybey = 0; if (flagmaybey) if (pos == 1) flaginheader = 0; } - ++pos; if (ch == '\n') { pos = 0; flagmaybex = flagmaybey = flagmaybez = 1; } } --- 317,322 ---- if (pos < 2) if (ch != "\r\n"[pos]) flagmaybey = 0; if (flagmaybey) if (pos == 1) flaginheader = 0; + ++pos; } if (ch == '\n') { pos = 0; flagmaybex = flagmaybey = flagmaybez = 1; } } *************** void acceptmessage(qp) unsigned long qp; *** 366,370 **** } ! void smtp_data() { int hops; unsigned long qp; --- 366,370 ---- } ! void smtp_data(arg) char *arg; { int hops; unsigned long qp; *** qmail-1.03/spawn.c Mon Jun 15 06:53:16 1998 --- qmail-1.03.0/spawn.c Mon Jan 19 00:35:38 2004 *************** *** 6,9 **** --- 6,10 ---- #include "byte.h" #include "str.h" + #include "alloc.h" #include "stralloc.h" #include "select.h"