Replying to an old email from more than a year ago.

I'm about to release a new version of udns, and
thought I'd put some missing dots under "i"s and
address the concerns...

I'm quoting whole thing just to show context, I have
a question for only one point below, with a few short
comments.

13.07.2009 01:12, Florian Weimer wrote:
> 
> udns doesn't handle truncation, so it won't play well with the
> PowerDNS recursor (which doesn't support EDNS).

One of the limitations of simplicity of design - only one
socket and it's obviously UDP.  With deployment of DNSSEC
everywhere EDNS support becomes a requiriment, because of
the size of DNSSEC records, so this problem becomes less
and less of an issue.  Yes I understand this is where
udns does not conform to standards.

> It does not use a connected UDP socket, so it won't notice ICMP
> errors.  (This means that it's only suitable for long-running
> processes.)

When I wrote udns I tried hard to find a way for unconnected
socket to actually receive errors such as ECONNREFUSED when
no listener is present at the destination, and to process them
more or less reliable.  I think nowadays a way to do so
exists at least on linux - or maybe I'm dreaming again.

But even complete lack of error handling like that is
not really problematic - the timeout before trying
next server is just one second.

I don't actually understand this "for long-running processes
only" part too.  Stuff like logresolve (to convert, say,
apache access.log from ip.add.res.ses to domain names
isn't usually long-living.

> The escape sequences it uses inside TXT records are hexadecimal, not
> decimal, as it is standard for DNS software.

This is fixed, and it was only in dnsget utility (which
is something like dig or host).

> The domain name parser triggers undefined behavior for certain inputs
> because it performs out-of-bound pointer arithmetic.  This is unlikely
> to cause practical problems with current GCC versions (but LTO might
> change this).

And here goes my main question.

http://www.corpit.ru/mjt/udns_dn.c is the code in question, the
domain parser.  Florian, can you please tell me where do you think
it performs such oob arith?  I assume you're talking about dns_ptodn()
routine, which converts asciiz (string) representation of a domain
name to on-wire series-of- labels form (the "dn" form).  But I just
don't see where it goes OOB.

The only case I can think of is this: if dp after next input
char points to de (very end of the output buffer), next input
char is dot so we just increment dp and continue, and there's
one more char in input.  In this case dp will be equal to
de+1, and the if condition is triggered for return case.
Simplified code:

  dnsc_t *dp;           /* current position in dn (len byte first) */
  dnsc_t *const de      /* end of dn: last byte that can be filled up */
      = dn + (dnsiz >= DNS_MAXDN ? DNS_MAXDN : dnsiz) - 1;

  while(np < ne) {

    if (*np == '.') {   /* label delimiter */
      c = dp - llab;            /* length of the label */
      llab[-1] = (dnsc_t)c;     /* update len of last label */
      llab = ++dp; /* start new label, llab[-1] will be len of it */
      ++np;
      continue;
    }

    /* check whenever we may put out one more byte */
    if (dp >= de) /* too long? */
      return dnsiz >= DNS_MAXDN ? -1 : 0;

    /* handle next input character */
  }

So basically, if de = 0xffffffff (on 32bit platform),
i.e. when the output buffer is at the very end of
address space, de+1 is 0, which may be bad.  But this
should never happen in practice.

There are a few other possible candidates for this
oob conclusion - usage of llab[-1].  But there, the
-1th address is always valid due to the way llab is
initialized.

Can you point me to the right direction please?

Thank you!

/mjt



-- 
To UNSUBSCRIBE, email to debian-bugs-rc-requ...@lists.debian.org
with a subject of "unsubscribe". Trouble? Contact listmas...@lists.debian.org

Reply via email to