Follow @Openwall on Twitter for new release announcements and other news
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date: Fri, 17 Apr 2020 14:46:40 -0400
From: Rich Felker <dalias@...c.org>
To: Wolf <wolf@...fsden.cz>
Cc: musl@...ts.openwall.com
Subject: Re: Proposal to match behaviour of gethostbyname to glibc

On Fri, Apr 17, 2020 at 02:42:22PM -0400, Rich Felker wrote:
> On Fri, Mar 13, 2020 at 10:46:48PM +0100, Wolf wrote:
> > Hello,
> > 
> > today I've noticed difference in behavior of gethostbyname in musl and
> > in glibc. Given /etc/hosts
> > 
> > 	127.0.0.1   foo.bar foo
> > 	127.0.0.1   bar.foo foo
> > 
> > and simple test program
> > 
> > 	#include <netdb.h>
> > 	#include <stdio.h>
> > 
> > 	int main(int argc, char **argv) {
> > 		struct hostent *he = gethostbyname(argv[1]);
> > 		printf("Hostname: %s\n", he->h_name);
> > 	}
> > 
> > , I've run it both under musl (alpine) and glibc (archlinux).
> > 
> > musl:
> > 
> > 	/test # ./test foo
> > 	Hostname: bar.foo
> > 
> > glibc:
> > 
> > 	[root@foo test]# ./test foo
> > 	Hostname: foo.bar
> > 
> > I don't think there is an actual reason to iterate through all of the
> > /etc/hosts and first match can be returned instead. Following patch
> > should in my opinion fix this.
> > 
> > 
> > 
> > diff --git a/src/network/lookup_name.c b/src/network/lookup_name.c
> > index c93263a9..da8db9d4 100644
> > --- a/src/network/lookup_name.c
> > +++ b/src/network/lookup_name.c
> > @@ -87,7 +87,10 @@ static int name_from_hosts(struct address buf[static MAXADDRS], char canon[stati
> >                 for (; *p && isspace(*p); p++);
> >                 for (z=p; *z && !isspace(*z); z++);
> >                 *z = 0;
> > -               if (is_valid_hostname(p)) memcpy(canon, p, z-p+1);
> > +               if (is_valid_hostname(p)) {
> > +                       memcpy(canon, p, z-p+1);
> > +                       break;
> > +               }
> >         }
> >         __fclose_ca(f);
> >         return cnt ? cnt : badfam;
> > 
> > 
> > 
> > While this is admittedly edge case that most users will not run into, I
> > still think it would be nice to behave the same way as glibc does on
> > this one. And as a bonus, it will be *tiny* bit faster, since there
> > would not be any need to iterate rest of the /etc/hosts file.
> > 
> > 
> > 
> > Thank you for considering this,
> 
> Patch does not apply as submitted (your mail software corrupted it in
> the message body; for future reference, use attachment if you don't
> have patch-clean mail software) but I'll apply it manually. Thanks.

Actually now that I'm doing this I'm not sure it's correct. The
existing code reports all matches from the hosts file, not just the
first one. This patch will prevent getting both ipv4 and ipv6 results,
or multiple results for the same address family, by stopping after the
first one.

If you want the canonical name to come from the first result, rather
than suppressing all but the first result, the code instead needs to
be changed to remember that it already found one name and not copy any
others.

So this needs more discussion to clarify what the actual intent is,
and whether that change is okay,  before it can move forward.

Rich

Powered by blists - more mailing lists

Confused about mailing lists and their use? Read about mailing lists on Wikipedia and check out these guidelines on proper formatting of your messages.