1This patch is Copyright (C) 2004 by James Craig Burley. License 2below. 3 42004-01-19 0040 EST James Craig Burley <craig-qmail@jcb-sc.com> 5 6This patch improves ISO C conformance of qmail code -- specifically, 7of qmail-lspawn, qmail-newmrh, qmail-newu, qmail-pop3d, qmail-popup, 8qmail-rspawn, and qmail-smtpd. This fixes two known bugs: 9 10 - qmail-smtpd can be crashed by a client sending a sufficiently 11 long (e.g. 2GB) header line in an email. 12 13 - qmail_lspawn, qmail-newmrh, qmail-newu, and qmail-rspawn might 14 crash or otherwise misbehave on hosts with a smaller "int" type 15 than "char *" type, e.g. 64-bit hosts with 32-bit "int"s. 16 17The other changes are unlikely to have any effect, except possibly on 18unusual architectures and/or in the presence of rare optimizations. 19 20This is Version 1 of this patch. It adds the changes to 21cdbmake_add.c, spawn.c, and, correspondingly, Makefile, which pertain 22to the second bug listed above. 23 24See all my qmail patches at <http://www.jcb-sc.com/qmail/patches/>. 25 26License: 27 28Permission is hereby granted, free of charge, to any person obtaining a 29copy of this software and associated documentation files (the 30"Software"), to deal in the Software without restriction, including 31without limitation the rights to use, copy, modify, merge, publish, 32distribute, sublicense, and/or sell copies of the Software, and to 33permit persons to whom the Software is furnished to do so, subject to 34the following conditions: 35 36The above copyright notice and this permission notice shall be included 37in all copies or substantial portions of the Software. 38 39THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 40OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 41MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 42IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 43CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 44TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 45SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 46 47 48*** qmail-1.03/cdbmake_add.c Mon Jun 15 06:53:16 1998 49--- qmail-1.03.0/cdbmake_add.c Mon Jan 19 00:35:38 2004 50*************** 51*** 1,2 **** 52--- 1,3 ---- 53+ #include "alloc.h" 54 #include "cdbmake.h" 55 56*** qmail-1.03/Makefile Mon Jun 15 06:53:16 1998 57--- qmail-1.03.0/Makefile Mon Jan 19 00:35:35 2004 58*************** makelib cdbmake_pack.o cdbmake_hash.o cd 59*** 264,268 **** 60 61 cdbmake_add.o: \ 62! compile cdbmake_add.c cdbmake.h uint32.h 63 ./compile cdbmake_add.c 64 65--- 264,268 ---- 66 67 cdbmake_add.o: \ 68! compile cdbmake_add.c cdbmake.h alloc.h uint32.h 69 ./compile cdbmake_add.c 70 71*************** trylsock.c compile load 72*** 1893,1897 **** 73 spawn.o: \ 74 compile chkspawn spawn.c sig.h wait.h substdio.h byte.h str.h \ 75! stralloc.h gen_alloc.h select.h exit.h coe.h open.h error.h \ 76 auto_qmail.h auto_uids.h auto_spawn.h 77 ./chkspawn 78--- 1893,1897 ---- 79 spawn.o: \ 80 compile chkspawn spawn.c sig.h wait.h substdio.h byte.h str.h \ 81! stralloc.h gen_alloc.h select.h exit.h alloc.h coe.h open.h error.h \ 82 auto_qmail.h auto_uids.h auto_spawn.h 83 ./chkspawn 84*** qmail-1.03/qmail-pop3d.c Mon Jun 15 06:53:16 1998 85--- qmail-1.03.0/qmail-pop3d.c Thu Jan 15 22:08:57 2004 86*************** void die_scan() { err("unable to scan $H 87*** 67,71 **** 88 89 void err_syntax() { err("syntax error"); } 90! void err_unimpl() { err("unimplemented"); } 91 void err_deleted() { err("already deleted"); } 92 void err_nozero() { err("messages are counted from 1"); } 93--- 67,71 ---- 94 95 void err_syntax() { err("syntax error"); } 96! void err_unimpl(arg) char *arg; { err("unimplemented"); } 97 void err_deleted() { err("already deleted"); } 98 void err_nozero() { err("messages are counted from 1"); } 99*************** void err_nosuch() { err("unable to open 100*** 74,78 **** 101 void err_nounlink() { err("unable to unlink all deleted messages"); } 102 103! void okay() { puts("+OK \r\n"); flush(); } 104 105 void printfn(fn) char *fn; 106--- 74,78 ---- 107 void err_nounlink() { err("unable to unlink all deleted messages"); } 108 109! void okay(arg) char *arg; { puts("+OK \r\n"); flush(); } 110 111 void printfn(fn) char *fn; 112*************** void getlist() 113*** 147,151 **** 114 } 115 116! void pop3_stat() 117 { 118 int i; 119--- 147,151 ---- 120 } 121 122! void pop3_stat(arg) char *arg; 123 { 124 int i; 125*************** void pop3_stat() 126*** 162,174 **** 127 } 128 129! void pop3_rset() 130 { 131 int i; 132 for (i = 0;i < numm;++i) m[i].flagdeleted = 0; 133 last = 0; 134! okay(); 135 } 136 137! void pop3_last() 138 { 139 puts("+OK "); 140--- 162,174 ---- 141 } 142 143! void pop3_rset(arg) char *arg; 144 { 145 int i; 146 for (i = 0;i < numm;++i) m[i].flagdeleted = 0; 147 last = 0; 148! okay(0); 149 } 150 151! void pop3_last(arg) char *arg; 152 { 153 puts("+OK "); 154*************** void pop3_last() 155*** 178,182 **** 156 } 157 158! void pop3_quit() 159 { 160 int i; 161--- 178,182 ---- 162 } 163 164! void pop3_quit(arg) char *arg; 165 { 166 int i; 167*************** void pop3_quit() 168*** 193,197 **** 169 rename(m[i].fn,line.s); /* if it fails, bummer */ 170 } 171! okay(); 172 die(); 173 } 174--- 193,197 ---- 175 rename(m[i].fn,line.s); /* if it fails, bummer */ 176 } 177! okay(0); 178 die(); 179 } 180*************** void pop3_dele(arg) char *arg; 181*** 215,219 **** 182 m[i].flagdeleted = 1; 183 if (i + 1 > last) last = i + 1; 184! okay(); 185 } 186 187--- 215,219 ---- 188 m[i].flagdeleted = 1; 189 if (i + 1 > last) last = i + 1; 190! okay(0); 191 } 192 193*************** void dolisting(arg,flaguidl) char *arg; 194*** 239,243 **** 195 } 196 else { 197! okay(); 198 for (i = 0;i < numm;++i) 199 if (!m[i].flagdeleted) 200--- 239,243 ---- 201 } 202 else { 203! okay(0); 204 for (i = 0;i < numm;++i) 205 if (!m[i].flagdeleted) 206*************** void pop3_top(arg) char *arg; 207*** 268,272 **** 208 fd = open_read(m[i].fn); 209 if (fd == -1) { err_nosuch(); return; } 210! okay(); 211 substdio_fdbuf(&ssmsg,read,fd,ssmsgbuf,sizeof(ssmsgbuf)); 212 blast(&ssmsg,limit); 213--- 268,272 ---- 214 fd = open_read(m[i].fn); 215 if (fd == -1) { err_nosuch(); return; } 216! okay(0); 217 substdio_fdbuf(&ssmsg,read,fd,ssmsgbuf,sizeof(ssmsgbuf)); 218 blast(&ssmsg,limit); 219*************** char **argv; 220*** 300,304 **** 221 getlist(); 222 223! okay(); 224 commands(&ssin,pop3commands); 225 die(); 226--- 300,304 ---- 227 getlist(); 228 229! okay(0); 230 commands(&ssin,pop3commands); 231 die(); 232*** qmail-1.03/qmail-popup.c Mon Jun 15 06:53:16 1998 233--- qmail-1.03.0/qmail-popup.c Thu Jan 15 22:09:21 2004 234*************** void die_badauth() { err("authorization 235*** 65,72 **** 236 void err_syntax() { err("syntax error"); } 237 void err_wantuser() { err("USER first"); } 238! void err_authoriz() { err("authorization first"); } 239 240! void okay() { puts("+OK \r\n"); flush(); } 241! void pop3_quit() { okay(); die(); } 242 243 244--- 65,72 ---- 245 void err_syntax() { err("syntax error"); } 246 void err_wantuser() { err("USER first"); } 247! void err_authoriz(arg) char *arg; { err("authorization first"); } 248 249! void okay(arg) char *arg; { puts("+OK \r\n"); flush(); } 250! void pop3_quit(arg) char *arg; { okay(0); die(); } 251 252 253*************** void pop3_user(arg) char *arg; 254*** 137,141 **** 255 { 256 if (!*arg) { err_syntax(); return; } 257! okay(); 258 seenuser = 1; 259 if (!stralloc_copys(&username,arg)) die_nomem(); 260--- 137,141 ---- 261 { 262 if (!*arg) { err_syntax(); return; } 263! okay(0); 264 seenuser = 1; 265 if (!stralloc_copys(&username,arg)) die_nomem(); 266*** qmail-1.03/qmail-smtpd.c Mon Jun 15 06:53:16 1998 267--- qmail-1.03.0/qmail-smtpd.c Thu Jan 15 22:12:02 2004 268*************** void straynewline() { out("451 See http: 269*** 52,61 **** 270 void err_bmf() { out("553 sorry, your envelope sender is in my badmailfrom list (#5.7.1)\r\n"); } 271 void err_nogateway() { out("553 sorry, that domain isn't in my list of allowed rcpthosts (#5.7.1)\r\n"); } 272! void err_unimpl() { out("502 unimplemented (#5.5.1)\r\n"); } 273 void err_syntax() { out("555 syntax error (#5.5.4)\r\n"); } 274 void err_wantmail() { out("503 MAIL first (#5.5.1)\r\n"); } 275 void err_wantrcpt() { out("503 RCPT first (#5.5.1)\r\n"); } 276! void err_noop() { out("250 ok\r\n"); } 277! void err_vrfy() { out("252 send some mail, i'll try my best\r\n"); } 278 void err_qqt() { out("451 qqt failure (#4.3.0)\r\n"); } 279 280--- 52,61 ---- 281 void err_bmf() { out("553 sorry, your envelope sender is in my badmailfrom list (#5.7.1)\r\n"); } 282 void err_nogateway() { out("553 sorry, that domain isn't in my list of allowed rcpthosts (#5.7.1)\r\n"); } 283! void err_unimpl(arg) char *arg; { out("502 unimplemented (#5.5.1)\r\n"); } 284 void err_syntax() { out("555 syntax error (#5.5.4)\r\n"); } 285 void err_wantmail() { out("503 MAIL first (#5.5.1)\r\n"); } 286 void err_wantrcpt() { out("503 RCPT first (#5.5.1)\r\n"); } 287! void err_noop(arg) char *arg; { out("250 ok\r\n"); } 288! void err_vrfy(arg) char *arg; { out("252 send some mail, i'll try my best\r\n"); } 289 void err_qqt() { out("451 qqt failure (#4.3.0)\r\n"); } 290 291*************** void smtp_greet(code) char *code; 292*** 68,76 **** 293 substdio_put(&ssout,greeting.s,greeting.len); 294 } 295! void smtp_help() 296 { 297 out("214 qmail home page: http://pobox.com/~djb/qmail.html\r\n"); 298 } 299! void smtp_quit() 300 { 301 smtp_greet("221 "); out("\r\n"); flush(); _exit(0); 302--- 68,76 ---- 303 substdio_put(&ssout,greeting.s,greeting.len); 304 } 305! void smtp_help(arg) char *arg; 306 { 307 out("214 qmail home page: http://pobox.com/~djb/qmail.html\r\n"); 308 } 309! void smtp_quit(arg) char *arg; 310 { 311 smtp_greet("221 "); out("\r\n"); flush(); _exit(0); 312*************** void smtp_ehlo(arg) char *arg; 313*** 233,237 **** 314 seenmail = 0; dohelo(arg); 315 } 316! void smtp_rset() 317 { 318 seenmail = 0; 319--- 233,237 ---- 320 seenmail = 0; dohelo(arg); 321 } 322! void smtp_rset(arg) char *arg; 323 { 324 seenmail = 0; 325*************** int *hops; 326*** 317,322 **** 327 if (pos < 2) if (ch != "\r\n"[pos]) flagmaybey = 0; 328 if (flagmaybey) if (pos == 1) flaginheader = 0; 329 } 330- ++pos; 331 if (ch == '\n') { pos = 0; flagmaybex = flagmaybey = flagmaybez = 1; } 332 } 333--- 317,322 ---- 334 if (pos < 2) if (ch != "\r\n"[pos]) flagmaybey = 0; 335 if (flagmaybey) if (pos == 1) flaginheader = 0; 336+ ++pos; 337 } 338 if (ch == '\n') { pos = 0; flagmaybex = flagmaybey = flagmaybez = 1; } 339 } 340*************** void acceptmessage(qp) unsigned long qp; 341*** 366,370 **** 342 } 343 344! void smtp_data() { 345 int hops; 346 unsigned long qp; 347--- 366,370 ---- 348 } 349 350! void smtp_data(arg) char *arg; { 351 int hops; 352 unsigned long qp; 353*** qmail-1.03/spawn.c Mon Jun 15 06:53:16 1998 354--- qmail-1.03.0/spawn.c Mon Jan 19 00:35:38 2004 355*************** 356*** 6,9 **** 357--- 6,10 ---- 358 #include "byte.h" 359 #include "str.h" 360+ #include "alloc.h" 361 #include "stralloc.h" 362 #include "select.h" 363