Hi,
> >My problem is that instead of the sender's email address, qmail-remote
puts
> ><........lo0.......> in the initial MAIL FROM: command when it forwards
an
> >email.
Here is a piece of code that will test if your implementation is subject to
the bug I experienced on my FreeBSD installation. This bug can manifest
itself with a few interfaces (one can be enough) with non-IPv4 configuration
(such as netatalk). I just submitted a patch for FreeBSD (both 4.0 and 3.x).
If your system contains the bug, let me know (as well as the vendor of
course).
This bug is probably present in most of the BSD socket implementations...
There are 2 variants of it:
- pure and simple buffer overflow (this is the one present on FreeBSD 3.x)
- no buffer overflow, but the announced size of the returned buffer is
incorrect (this one is present in the latest FreeBSD 4.0 [after feb 28,
2000]).
Patrick.
#include <errno.h>
#include <sys/types.h>
#include <sys/param.h>
#include <sys/time.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <net/if.h>
#include <netinet/in.h>
#include <sys/sockio.h>
#define VERBOSE_CHECK_
int check55(char *start,char *end)
{
int startoff=-1,endoff=0;
int off=0,c=0;
int ret = 0;
#ifdef VERY_VERBOSE_CHECK
printf("%03d\t",off);
#endif
for(;start<end;start++,off++)
{
if(*start != 0x55)
{
if(startoff<0)
{
startoff=off;
}
endoff=off;
}
#ifdef VERY_VERBOSE_CHECK
if(++c>=33)
{
printf("\n%03d\t",off);
c=1;
}
printf("%02x ",*(unsigned char*)start);
#endif
}
if(startoff>=0)
{
#ifdef VERBOSE_CHECK
printf(" ** buffer changed from %d to %d => %d bytes modified
**\n",startoff,endoff, endoff - startoff + 1);
#endif
ret = endoff-startoff+1;
}
return ret;
}
main()
{
struct ifconf ifc;
char *x;
struct ifreq *ifr;
struct sockaddr_in *sin;
int len,ret;
int s;
char buf[16000];
int bug=0;
int mod=0;
#define END_TEST 8000
if ((s = socket(AF_INET,SOCK_STREAM,0)) == -1) return -1;
for (len=1;len<=END_TEST;len++) {
ifc.ifc_buf = buf;
ifc.ifc_len = len;
memset(buf,0x55,sizeof(buf));
#ifdef VERBOSE_CHECK
printf("\n[Try with len=%d]\n",len);
#else
printf("try %4d\t", len);
#endif
if ((ret=ioctl(s,SIOCGIFCONF,&ifc)) < 0)
{
printf("\n\n => ioctl failed (returned %d, errno=%d)\n",ret,errno);
}
#ifdef VERBOSE_CHECK
printf(" => ioctl succeeded, pretends it wrote %d bytes\n",ifc.ifc_len);
#else
printf("pretends %4d\t\t", ifc.ifc_len);
#endif
mod = check55(buf,buf+sizeof(buf));
printf("modified %4d\t", mod);
if (bug < 2 && mod < ifc.ifc_len)
{
bug = 2;
}
else if (bug < 1 && ifc.ifc_len > len)
{
bug = 1;
}
printf("bug %4d\n", bug);
}
switch (bug)
{
case 0:
printf("\n\n*** Implementation OK (FIXED)*** \n\n");
break;
case 1:
printf("\n\n*** Implementation corrupts buffer ***\n\n");
break;
case 2:
printf("\n\n*** Implementation returns incorrect ifc.ifc_len, but
buffer OK ***\n\n");
break;
default:
printf("\n\n*** Huh ??? %d ***", bug);
break;
}
return bug;
}