Bug 806190

Summary: gethostbyaddr sets h_errno to 3, not HOST_NOT_FOUND
Product: [Fedora] Fedora Reporter: Xibo Ning <xning>
Component: nss-myhostnameAssignee: Lennart Poettering <lpoetter>
Status: CLOSED NOTABUG QA Contact: Fedora Extras Quality Assurance <extras-qa>
Severity: medium Docs Contact:
Priority: unspecified    
Version: 17CC: amlau, dbn.lists, jakub, lpoetter, metanoite, mitr, mnewsome, nsoranzo, rkagan
Target Milestone: ---Keywords: Reopened
Target Release: ---   
Hardware: x86_64   
OS: Linux   
Whiteboard:
Fixed In Version: Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of: Environment:
Last Closed: 2013-03-08 02:38:53 UTC Type: ---
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Embargoed:
Bug Depends On:    
Bug Blocks: 807951    
Attachments:
Description Flags
Simple c file to test this bug none

Description Xibo Ning 2012-03-23 07:21:20 UTC
Description of problem:
gethostbyaddr sets h_errno to 3, not HOST_NOT_FOUND

Version-Release number of selected component (if applicable):
glibc-2.14.90-24

How reproducible:
always 

Steps to Reproduce:
1.gcc -ggdb -o test test.c
2../test
  
Actual results:
h_errno = 3

Expected results:
h_errno = 1

Additional info:

Comment 1 Xibo Ning 2012-03-23 07:28:51 UTC
Created attachment 572176 [details]
Simple c file to test this bug

Comment 2 Jeff Law 2012-03-23 20:40:17 UTC
This is a problem with nss-myhostname AFAICT.  Reassigned to the nss-myhostname component.

If you look at your /etc/resolv.conf file at the hosts entry, you'll see something similar to this:

hosts:      files mdns4_minimal [NOTFOUND=return] dns myhostname


It's the last one, myhostname which sets the bogus error return code.  This can be verified by changing that line to

hosts: myhostname

The startup the test program and place a breakpoint in gethostbyaddr


Breakpoint 2, gethostbyaddr (addr=0x7fffffffdbe4, len=16, type=2)
    at ../nss/getXXbyYY.c:89
89      {
(gdb) p &h_errno_tmp
$1 = (int *) 0x7fffffffdb90
(gdb) watch *$1
Hardware watchpoint 3: *$1
(gdb) c
Continuing.
Hardware watchpoint 3: *$1

Old value = -9244
New value = 0
gethostbyaddr (addr=0x7fffffffdbe4, len=16, type=2) at ../nss/getXXbyYY.c:98
98        __libc_lock_lock (lock);
(gdb) c
Continuing.
Hardware watchpoint 3: *$1

Old value = 0
New value = 3
0x00007ffff7dd6715 in _nss_myhostname_gethostbyaddr2_r ()
   from /lib64/libnss_myhostname.so.2

Comment 3 Xibo Ning 2012-03-26 00:56:31 UTC
(In reply to comment #2)
> This is a problem with nss-myhostname AFAICT.  Reassigned to the nss-myhostname
> component.
> 
> If you look at your /etc/resolv.conf file at the hosts entry, you'll see
> something similar to this:
> 
> hosts:      files mdns4_minimal [NOTFOUND=return] dns myhostname
> 
> 
> It's the last one, myhostname which sets the bogus error return code.  This can
> be verified by changing that line to
> 
> hosts: myhostname
> 
> The startup the test program and place a breakpoint in gethostbyaddr
> 
> 
> Breakpoint 2, gethostbyaddr (addr=0x7fffffffdbe4, len=16, type=2)
>     at ../nss/getXXbyYY.c:89
> 89      {
> (gdb) p &h_errno_tmp
> $1 = (int *) 0x7fffffffdb90
> (gdb) watch *$1
> Hardware watchpoint 3: *$1
> (gdb) c
> Continuing.
> Hardware watchpoint 3: *$1
> 
> Old value = -9244
> New value = 0
> gethostbyaddr (addr=0x7fffffffdbe4, len=16, type=2) at ../nss/getXXbyYY.c:98
> 98        __libc_lock_lock (lock);
> (gdb) c
> Continuing.
> Hardware watchpoint 3: *$1
> 
> Old value = 0
> New value = 3
> 0x00007ffff7dd6715 in _nss_myhostname_gethostbyaddr2_r ()
>    from /lib64/libnss_myhostname.so.2

Thank you, Jeff

Comment 4 Xibo Ning 2012-03-29 09:43:26 UTC
(In reply to comment #2)
> This is a problem with nss-myhostname AFAICT.  Reassigned to the nss-myhostname
> component.
> 
> If you look at your /etc/resolv.conf file at the hosts entry, you'll see
> something similar to this:
> 
> hosts:      files mdns4_minimal [NOTFOUND=return] dns myhostname
> 
> 
> It's the last one, myhostname which sets the bogus error return code.  This can
> be verified by changing that line to
> 
> hosts: myhostname
> 
> The startup the test program and place a breakpoint in gethostbyaddr
> 
> 
> Breakpoint 2, gethostbyaddr (addr=0x7fffffffdbe4, len=16, type=2)
>     at ../nss/getXXbyYY.c:89
> 89      {
> (gdb) p &h_errno_tmp
> $1 = (int *) 0x7fffffffdb90
> (gdb) watch *$1
> Hardware watchpoint 3: *$1
> (gdb) c
> Continuing.
> Hardware watchpoint 3: *$1
> 
> Old value = -9244
> New value = 0
> gethostbyaddr (addr=0x7fffffffdbe4, len=16, type=2) at ../nss/getXXbyYY.c:98
> 98        __libc_lock_lock (lock);
> (gdb) c
> Continuing.
> Hardware watchpoint 3: *$1
> 
> Old value = 0
> New value = 3
> 0x00007ffff7dd6715 in _nss_myhostname_gethostbyaddr2_r ()
>    from /lib64/libnss_myhostname.so.2

Thanks, Jeff. I modified /etc/nsswitch.conf, and got the right result.
--- /etc/nsswitch.conf.bak      2011-10-19 19:04:41.000000000 +0800
+++ /etc/nsswitch.conf  2012-03-29 17:37:50.881967095 +0800
@@ -36,7 +36,7 @@
 initgroups: files

 #hosts:     db files nisplus nis dns
-hosts:      files dns
+hosts:      files dns [NOTFOUND=return] myhostname

 # Example - obey only what nisplus tells us...
 #services:   nisplus [NOTFOUND=return] files

Lennart, I think this is ok. Your advice, pls?

Comment 5 Xibo Ning 2012-03-29 09:46:13 UTC
(In reply to comment #2)
> This is a problem with nss-myhostname AFAICT.  Reassigned to the nss-myhostname
> component.
> 
> If you look at your /etc/resolv.conf file at the hosts entry, you'll see
> something similar to this:
> 
> hosts:      files mdns4_minimal [NOTFOUND=return] dns myhostname
> 
> 
> It's the last one, myhostname which sets the bogus error return code.  This can
> be verified by changing that line to
> 
> hosts: myhostname
> 
> The startup the test program and place a breakpoint in gethostbyaddr
> 
> 
> Breakpoint 2, gethostbyaddr (addr=0x7fffffffdbe4, len=16, type=2)
>     at ../nss/getXXbyYY.c:89
> 89      {
> (gdb) p &h_errno_tmp
> $1 = (int *) 0x7fffffffdb90
> (gdb) watch *$1
> Hardware watchpoint 3: *$1
> (gdb) c
> Continuing.
> Hardware watchpoint 3: *$1
> 
> Old value = -9244
> New value = 0
> gethostbyaddr (addr=0x7fffffffdbe4, len=16, type=2) at ../nss/getXXbyYY.c:98
> 98        __libc_lock_lock (lock);
> (gdb) c
> Continuing.
> Hardware watchpoint 3: *$1
> 
> Old value = 0
> New value = 3
> 0x00007ffff7dd6715 in _nss_myhostname_gethostbyaddr2_r ()
>    from /lib64/libnss_myhostname.so.2

Thanks, Jeff. I modified /etc/nsswitch.conf, and got the right result.
--- /etc/nsswitch.conf.bak      2011-10-19 19:04:41.000000000 +0800
+++ /etc/nsswitch.conf  2012-03-29 17:37:50.881967095 +0800
@@ -36,7 +36,7 @@
 initgroups: files

 #hosts:     db files nisplus nis dns
-hosts:      files dns myhostname
+hosts:      files dns [NOTFOUND=return] myhostname

 # Example - obey only what nisplus tells us...
 #services:   nisplus [NOTFOUND=return] files

Lennart, I think this is ok. Your advice, pls?

Comment 6 Roman Kagan 2012-06-19 07:56:48 UTC
(In reply to comment #5)
> I modified /etc/nsswitch.conf, and got the right result.
> --- /etc/nsswitch.conf.bak      2011-10-19 19:04:41.000000000 +0800
> +++ /etc/nsswitch.conf  2012-03-29 17:37:50.881967095 +0800
> @@ -36,7 +36,7 @@
>  initgroups: files
> 
>  #hosts:     db files nisplus nis dns
> -hosts:      files dns myhostname
> +hosts:      files dns [NOTFOUND=return] myhostname
> 
>  # Example - obey only what nisplus tells us...
>  #services:   nisplus [NOTFOUND=return] files

No this isn't the right result.

nss_dns will return HOST_NOT_FOUND for any valid IP address.  That is, in the above configuration myhostname becomes essentially unreachable.

So the original problem is a bug in nss-myhostname; if its assumed usage is the last in the lookup order (and according to its post-install script, it is), it should just return HOST_NOT_FOUND for everything well-formed.

IMO this bug needs reopening and a proper fix in nss-myhostname.

Comment 7 Fedora Update System 2012-07-02 14:57:45 UTC
redhat-lsb-4.1-5.fc17 has been submitted as an update for Fedora 17.
https://admin.fedoraproject.org/updates/redhat-lsb-4.1-5.fc17

Comment 8 Fedora Update System 2012-07-02 22:33:49 UTC
Package redhat-lsb-4.1-5.fc17:
* should fix your issue,
* was pushed to the Fedora 17 testing repository,
* should be available at your local mirror within two days.
Update it with:
# su -c 'yum update --enablerepo=updates-testing redhat-lsb-4.1-5.fc17'
as soon as you are able to.
Please go to the following url:
https://admin.fedoraproject.org/updates/FEDORA-2012-10194/redhat-lsb-4.1-5.fc17
then log in and leave karma (feedback).

Comment 9 Roman Kagan 2012-07-03 05:22:25 UTC
This is a bug in nss-myhostname, it can't be fixed by redhat-lsb.  Please don't do it again.

This must've been a typo, and you wanted to claim fixing bug 825261 (I'm not happy about the fix but I'll comment there).

Comment 10 Roman Kagan 2012-07-03 05:41:27 UTC
(In reply to comment #9)
> (I'm not happy about the fix but I'll comment there).

Please ignore this part; I took a closer look at the code and find the fix OK for that bug.

Comment 11 Xibo Ning 2012-07-03 05:56:53 UTC
(In reply to comment #9)
> This is a bug in nss-myhostname, it can't be fixed by redhat-lsb.  Please
> don't do it again.
> 
> This must've been a typo, and you wanted to claim fixing bug 825261 (I'm not
> happy about the fix but I'll comment there).

Roman, from package redhat-lsb-4.1-5, we have removed scriptlets that will modify /etc/nsswitch.conf. I don't try to resolve bug 806190 in redhat-lsb package. Thank you for the explanation and suggestion.

Comment 12 Roman Kagan 2012-07-03 10:50:49 UTC
(In reply to comment #11)
> Roman, from package redhat-lsb-4.1-5, we have removed scriptlets that will
> modify /etc/nsswitch.conf. I don't try to resolve bug 806190 in redhat-lsb
> package.

But it *is* mentioned in bodhi among "Bugs fixed", and the robot has made *this* bug transition to ON_QA status, so it will disappear from the developer's radar once the update is pushed to stable.

OTOH bug 825261, which is being fixed by the update, is not mentioned anywhere.

Comment 13 Roman Kagan 2012-07-16 11:51:38 UTC
Just had a bit of spare time and looked into this again.

It turns out it's a bug in your testcase which uses struct sockaddr_in where struct in_addr is due.

As a result, you pass sizeof(struct sockaddr_in) which is equal to 16 as the second argument to gethostbyaddr(); _nss_myhostname_gethostbyaddr2_r() rejects it as invalid since the expected value for AF_INET is 4.

IMO this bug can be resolved as INVALID.

Comment 14 Fedora Update System 2012-07-17 17:23:36 UTC
redhat-lsb-4.1-5.fc17 has been pushed to the Fedora 17 stable repository.  If problems still persist, please make note of it in this bug report.

Comment 15 Roman Kagan 2012-07-17 23:26:02 UTC
So it did happen as I warned: this bug has got automatically resolved as fixed, while bug 825261 is left open.

Could someone with the necessary rights please resolve bug 825261 instead, and reopen this one, which, in turn, per my comment 13 should either get resolved as invalid, or reformulated as a bug in the lsb compliance test suite?

Comment 16 Nicola Soranzo 2012-07-18 13:14:38 UTC
(In reply to comment #15)
> So it did happen as I warned: this bug has got automatically resolved as
> fixed, while bug 825261 is left open.
> 
> Could someone with the necessary rights please resolve bug 825261 instead,
> and reopen this one, which, in turn, per my comment 13 should either get
> resolved as invalid, or reformulated as a bug in the lsb compliance test
> suite?

Reopened.

Comment 17 Dan Nicholson 2013-02-21 13:56:18 UTC
(In reply to comment #13)
> Just had a bit of spare time and looked into this again.
> 
> It turns out it's a bug in your testcase which uses struct sockaddr_in where
> struct in_addr is due.
> 
> As a result, you pass sizeof(struct sockaddr_in) which is equal to 16 as the
> second argument to gethostbyaddr(); _nss_myhostname_gethostbyaddr2_r()
> rejects it as invalid since the expected value for AF_INET is 4.
> 
> IMO this bug can be resolved as INVALID.

I agree. This is a bug in the test. The test is telling gethostbyaddr to write to a struct in_addr at myaddr.sin_addr.s_addr (somewhat wrong as s_addr is really the in_addr_t inside the struct in_addr, but they're the same) then telling it that the length it should use is a struct sockaddr_in. Fixing this to use sizeof(myaddr.sin_addr.s_addr), the test returns h_errno = 1 as expected.

$ grep ^hosts: /etc/nsswitch.conf
hosts:      files dns myhostname
$ diff -pu rhbz806190-orig.c rhbz806190.c
--- rhbz806190-orig.c	2013-02-21 05:25:01.728633897 -0800
+++ rhbz806190.c	2013-02-21 05:26:12.361761819 -0800
@@ -9,8 +9,8 @@ int main() {
   myaddr.sin_addr.s_addr=htonl(0x7F000002);
   int err;
   h_errno=0;
-  gethostbyaddr((struct in_addr
-		 *)&myaddr.sin_addr.s_addr,(socklen_t)sizeof(myaddr),AF_INET);
+  gethostbyaddr((struct in_addr *)&myaddr.sin_addr.s_addr,
+                (socklen_t)sizeof(myaddr.sin_addr.s_addr), AF_INET);
   err=h_errno;
   printf("h_errno =  %d\n", err);
   return 0;
$ ./rhbz806190-orig 
h_errno =  3
$ ./rhbz806190
h_errno =  1

Just for kicks:
$ cat socksz.c
#include <stdio.h>
#include <netinet/in.h>

int main(int argc, char *argv[])
{
    printf("sizeof(struct sockaddr_in): %lu\n", sizeof(struct sockaddr_in));
    printf("sizeof(struct in_addr):     %lu\n", sizeof(struct in_addr));
    printf("sizeof(in_addr_t):          %lu\n", sizeof(in_addr_t));

    return 0;
}
$ ./socksz 
sizeof(struct sockaddr_in): 16
sizeof(struct in_addr):     4
sizeof(in_addr_t):          4

It seems that nss_myhostname is just more strict about writing to a struct in_addr. Presumably it could be fixed to be less strict since the size it's being told to use is bigger than necessary. However, I really think this should just be closed as NOTABUG and redhat-lsb should stop playing around with my /etc/nsswitch.conf.

I really don't need another package silently removing my settings from it. I can't see how it's valid in any way that a compliance suite needs to change the configuration of my nss modules. It seems far more likely the compliance suite should make itself more insulated from this configuration. Fixing this test to do the right thing hopefully helps that.