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