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;
}


Reply via email to