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.
This commit is contained in:
parent
2bb7433cc9
commit
c4de3cc1ac
6 changed files with 28 additions and 26 deletions
4
Makefile
4
Makefile
|
|
@ -263,7 +263,7 @@ makelib cdbmake_pack.o cdbmake_hash.o cdbmake_add.o
|
||||||
cdbmake_add.o
|
cdbmake_add.o
|
||||||
|
|
||||||
cdbmake_add.o: \
|
cdbmake_add.o: \
|
||||||
compile cdbmake_add.c cdbmake.h uint32.h
|
compile cdbmake_add.c cdbmake.h alloc.h uint32.h
|
||||||
./compile cdbmake_add.c
|
./compile cdbmake_add.c
|
||||||
|
|
||||||
cdbmake_hash.o: \
|
cdbmake_hash.o: \
|
||||||
|
|
@ -1892,7 +1892,7 @@ trylsock.c compile load
|
||||||
|
|
||||||
spawn.o: \
|
spawn.o: \
|
||||||
compile chkspawn spawn.c sig.h wait.h substdio.h byte.h str.h \
|
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 \
|
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
|
auto_qmail.h auto_uids.h auto_spawn.h
|
||||||
./chkspawn
|
./chkspawn
|
||||||
./compile spawn.c
|
./compile spawn.c
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
#include "alloc.h"
|
||||||
#include "cdbmake.h"
|
#include "cdbmake.h"
|
||||||
|
|
||||||
void cdbmake_init(cdbm)
|
void cdbmake_init(cdbm)
|
||||||
|
|
|
||||||
|
|
@ -66,14 +66,14 @@ void die_nomaildir() { err("this user has no $HOME/Maildir"); die(); }
|
||||||
void die_scan() { err("unable to scan $HOME/Maildir"); die(); }
|
void die_scan() { err("unable to scan $HOME/Maildir"); die(); }
|
||||||
|
|
||||||
void err_syntax() { err("syntax error"); }
|
void err_syntax() { err("syntax error"); }
|
||||||
void err_unimpl() { err("unimplemented"); }
|
void err_unimpl(arg) char *arg; { err("unimplemented"); }
|
||||||
void err_deleted() { err("already deleted"); }
|
void err_deleted() { err("already deleted"); }
|
||||||
void err_nozero() { err("messages are counted from 1"); }
|
void err_nozero() { err("messages are counted from 1"); }
|
||||||
void err_toobig() { err("not that many messages"); }
|
void err_toobig() { err("not that many messages"); }
|
||||||
void err_nosuch() { err("unable to open that message"); }
|
void err_nosuch() { err("unable to open that message"); }
|
||||||
void err_nounlink() { err("unable to unlink all deleted messages"); }
|
void err_nounlink() { err("unable to unlink all deleted messages"); }
|
||||||
|
|
||||||
void okay() { puts("+OK \r\n"); flush(); }
|
void okay(arg) char *arg; { puts("+OK \r\n"); flush(); }
|
||||||
|
|
||||||
void printfn(fn) char *fn;
|
void printfn(fn) char *fn;
|
||||||
{
|
{
|
||||||
|
|
@ -146,7 +146,7 @@ void getlist()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void pop3_stat()
|
void pop3_stat(arg) char *arg;
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
unsigned long total;
|
unsigned long total;
|
||||||
|
|
@ -161,15 +161,15 @@ void pop3_stat()
|
||||||
flush();
|
flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
void pop3_rset()
|
void pop3_rset(arg) char *arg;
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
for (i = 0;i < numm;++i) m[i].flagdeleted = 0;
|
for (i = 0;i < numm;++i) m[i].flagdeleted = 0;
|
||||||
last = 0;
|
last = 0;
|
||||||
okay();
|
okay(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void pop3_last()
|
void pop3_last(arg) char *arg;
|
||||||
{
|
{
|
||||||
puts("+OK ");
|
puts("+OK ");
|
||||||
put(strnum,fmt_uint(strnum,last));
|
put(strnum,fmt_uint(strnum,last));
|
||||||
|
|
@ -177,7 +177,7 @@ void pop3_last()
|
||||||
flush();
|
flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
void pop3_quit()
|
void pop3_quit(arg) char *arg;
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
for (i = 0;i < numm;++i)
|
for (i = 0;i < numm;++i)
|
||||||
|
|
@ -192,7 +192,7 @@ void pop3_quit()
|
||||||
if (!stralloc_0(&line)) die_nomem();
|
if (!stralloc_0(&line)) die_nomem();
|
||||||
rename(m[i].fn,line.s); /* if it fails, bummer */
|
rename(m[i].fn,line.s); /* if it fails, bummer */
|
||||||
}
|
}
|
||||||
okay();
|
okay(0);
|
||||||
die();
|
die();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -214,7 +214,7 @@ void pop3_dele(arg) char *arg;
|
||||||
if (i == -1) return;
|
if (i == -1) return;
|
||||||
m[i].flagdeleted = 1;
|
m[i].flagdeleted = 1;
|
||||||
if (i + 1 > last) last = i + 1;
|
if (i + 1 > last) last = i + 1;
|
||||||
okay();
|
okay(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void list(i,flaguidl)
|
void list(i,flaguidl)
|
||||||
|
|
@ -238,7 +238,7 @@ void dolisting(arg,flaguidl) char *arg; int flaguidl;
|
||||||
list(i,flaguidl);
|
list(i,flaguidl);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
okay();
|
okay(0);
|
||||||
for (i = 0;i < numm;++i)
|
for (i = 0;i < numm;++i)
|
||||||
if (!m[i].flagdeleted)
|
if (!m[i].flagdeleted)
|
||||||
list(i,flaguidl);
|
list(i,flaguidl);
|
||||||
|
|
@ -267,7 +267,7 @@ void pop3_top(arg) char *arg;
|
||||||
|
|
||||||
fd = open_read(m[i].fn);
|
fd = open_read(m[i].fn);
|
||||||
if (fd == -1) { err_nosuch(); return; }
|
if (fd == -1) { err_nosuch(); return; }
|
||||||
okay();
|
okay(0);
|
||||||
substdio_fdbuf(&ssmsg,read,fd,ssmsgbuf,sizeof(ssmsgbuf));
|
substdio_fdbuf(&ssmsg,read,fd,ssmsgbuf,sizeof(ssmsgbuf));
|
||||||
blast(&ssmsg,limit);
|
blast(&ssmsg,limit);
|
||||||
close(fd);
|
close(fd);
|
||||||
|
|
@ -299,7 +299,7 @@ char **argv;
|
||||||
|
|
||||||
getlist();
|
getlist();
|
||||||
|
|
||||||
okay();
|
okay(0);
|
||||||
commands(&ssin,pop3commands);
|
commands(&ssin,pop3commands);
|
||||||
die();
|
die();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -64,10 +64,10 @@ void die_badauth() { err("authorization failed"); }
|
||||||
|
|
||||||
void err_syntax() { err("syntax error"); }
|
void err_syntax() { err("syntax error"); }
|
||||||
void err_wantuser() { err("USER first"); }
|
void err_wantuser() { err("USER first"); }
|
||||||
void err_authoriz() { err("authorization first"); }
|
void err_authoriz(arg) char *arg; { err("authorization first"); }
|
||||||
|
|
||||||
void okay() { puts("+OK \r\n"); flush(); }
|
void okay(arg) char *arg; { puts("+OK \r\n"); flush(); }
|
||||||
void pop3_quit() { okay(); die(); }
|
void pop3_quit(arg) char *arg; { okay(0); die(); }
|
||||||
|
|
||||||
|
|
||||||
char unique[FMT_ULONG + FMT_ULONG + 3];
|
char unique[FMT_ULONG + FMT_ULONG + 3];
|
||||||
|
|
@ -136,7 +136,7 @@ void pop3_greet()
|
||||||
void pop3_user(arg) char *arg;
|
void pop3_user(arg) char *arg;
|
||||||
{
|
{
|
||||||
if (!*arg) { err_syntax(); return; }
|
if (!*arg) { err_syntax(); return; }
|
||||||
okay();
|
okay(0);
|
||||||
seenuser = 1;
|
seenuser = 1;
|
||||||
if (!stralloc_copys(&username,arg)) die_nomem();
|
if (!stralloc_copys(&username,arg)) die_nomem();
|
||||||
if (!stralloc_0(&username)) die_nomem();
|
if (!stralloc_0(&username)) die_nomem();
|
||||||
|
|
|
||||||
|
|
@ -51,12 +51,12 @@ void straynewline() { out("451 See http://pobox.com/~djb/docs/smtplf.html.\r\n")
|
||||||
|
|
||||||
void err_bmf() { out("553 sorry, your envelope sender is in my badmailfrom list (#5.7.1)\r\n"); }
|
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_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_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_syntax() { out("555 syntax error (#5.5.4)\r\n"); }
|
||||||
void err_wantmail() { out("503 MAIL first (#5.5.1)\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_wantrcpt() { out("503 RCPT first (#5.5.1)\r\n"); }
|
||||||
void err_noop() { out("250 ok\r\n"); }
|
void err_noop(arg) char *arg; { out("250 ok\r\n"); }
|
||||||
void err_vrfy() { out("252 send some mail, i'll try my best\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 err_qqt() { out("451 qqt failure (#4.3.0)\r\n"); }
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -67,11 +67,11 @@ void smtp_greet(code) char *code;
|
||||||
substdio_puts(&ssout,code);
|
substdio_puts(&ssout,code);
|
||||||
substdio_put(&ssout,greeting.s,greeting.len);
|
substdio_put(&ssout,greeting.s,greeting.len);
|
||||||
}
|
}
|
||||||
void smtp_help()
|
void smtp_help(arg) char *arg;
|
||||||
{
|
{
|
||||||
out("214 netqmail home page: http://qmail.org/netqmail\r\n");
|
out("214 netqmail home page: http://qmail.org/netqmail\r\n");
|
||||||
}
|
}
|
||||||
void smtp_quit()
|
void smtp_quit(arg) char *arg;
|
||||||
{
|
{
|
||||||
smtp_greet("221 "); out("\r\n"); flush(); _exit(0);
|
smtp_greet("221 "); out("\r\n"); flush(); _exit(0);
|
||||||
}
|
}
|
||||||
|
|
@ -232,7 +232,7 @@ void smtp_ehlo(arg) char *arg;
|
||||||
smtp_greet("250-"); out("\r\n250-PIPELINING\r\n250 8BITMIME\r\n");
|
smtp_greet("250-"); out("\r\n250-PIPELINING\r\n250 8BITMIME\r\n");
|
||||||
seenmail = 0; dohelo(arg);
|
seenmail = 0; dohelo(arg);
|
||||||
}
|
}
|
||||||
void smtp_rset()
|
void smtp_rset(arg) char *arg;
|
||||||
{
|
{
|
||||||
seenmail = 0;
|
seenmail = 0;
|
||||||
out("250 flushed\r\n");
|
out("250 flushed\r\n");
|
||||||
|
|
@ -316,8 +316,8 @@ int *hops;
|
||||||
if (flagmaybex) if (pos == 7) ++*hops;
|
if (flagmaybex) if (pos == 7) ++*hops;
|
||||||
if (pos < 2) if (ch != "\r\n"[pos]) flagmaybey = 0;
|
if (pos < 2) if (ch != "\r\n"[pos]) flagmaybey = 0;
|
||||||
if (flagmaybey) if (pos == 1) flaginheader = 0;
|
if (flagmaybey) if (pos == 1) flaginheader = 0;
|
||||||
}
|
|
||||||
++pos;
|
++pos;
|
||||||
|
}
|
||||||
if (ch == '\n') { pos = 0; flagmaybex = flagmaybey = flagmaybez = 1; }
|
if (ch == '\n') { pos = 0; flagmaybex = flagmaybey = flagmaybez = 1; }
|
||||||
}
|
}
|
||||||
switch(state) {
|
switch(state) {
|
||||||
|
|
@ -365,7 +365,7 @@ void acceptmessage(qp) unsigned long qp;
|
||||||
out("\r\n");
|
out("\r\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
void smtp_data() {
|
void smtp_data(arg) char *arg; {
|
||||||
int hops;
|
int hops;
|
||||||
unsigned long qp;
|
unsigned long qp;
|
||||||
char *qqx;
|
char *qqx;
|
||||||
|
|
|
||||||
1
spawn.c
1
spawn.c
|
|
@ -5,6 +5,7 @@
|
||||||
#include "substdio.h"
|
#include "substdio.h"
|
||||||
#include "byte.h"
|
#include "byte.h"
|
||||||
#include "str.h"
|
#include "str.h"
|
||||||
|
#include "alloc.h"
|
||||||
#include "stralloc.h"
|
#include "stralloc.h"
|
||||||
#include "select.h"
|
#include "select.h"
|
||||||
#include "exit.h"
|
#include "exit.h"
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue