Note: This bug is displayed in read-only format because
the product is no longer active in Red Hat Bugzilla.
RHEL Engineering is moving the tracking of its product development work on RHEL 6 through RHEL 9 to Red Hat Jira (issues.redhat.com). If you're a Red Hat customer, please continue to file support cases via the Red Hat customer portal. If you're not, please head to the "RHEL project" in Red Hat Jira and file new tickets here. Individual Bugzilla bugs in the statuses "NEW", "ASSIGNED", and "POST" are being migrated throughout September 2023. Bugs of Red Hat partners with an assigned Engineering Partner Manager (EPM) are migrated in late September as per pre-agreed dates. Bugs against components "kernel", "kernel-rt", and "kpatch" are only migrated if still in "NEW" or "ASSIGNED". If you cannot log in to RH Jira, please consult article #7032570. That failing, please send an e-mail to the RH Jira admins at rh-issues@redhat.com to troubleshoot your issue as a user management inquiry. The email creates a ServiceNow ticket with Red Hat. Individual Bugzilla bugs that are migrated will be moved to status "CLOSED", resolution "MIGRATED", and set with "MigratedToJIRA" in "Keywords". The link to the successor Jira issue will be found under "Links", have a little "two-footprint" icon next to it, and direct you to the "RHEL project" in Red Hat Jira (issue links are of type "https://issues.redhat.com/browse/RHEL-XXXX", where "X" is a digit). This same link will be available in a blue banner at the top of the page informing you that that bug has been migrated.
A defect in the implementation of protocol and port data handling resulted in functions including getnameinfo and getservbyport ignoring the protocol associated with a port. The implementation has been fixed to correctly handle protocol and port data. Calls to getnameinfo and getservbyport now correctly take protocol into account.
To reproduce the issue:
1. Edit /etc/services commenting out:
#ndmp 10000/tcp # Network Data Management Protocol
#ndmp 10000/udp # Network Data Management Protocol
and adding this entry:
service-example 10000/tcp
2. Disable nscd if running, make sure to have:
# grep services /etc/nscd.conf
enable-cache services yes
3. Use this example program:
"""
#include <netdb.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#include <net/if.h>
#include <stdio.h>
#include <strings.h>
int main()
{
char service[ NI_MAXSERV + 1 ];
struct sockaddr_in sa;
bzero(&sa, sizeof(sa));
sa.sin_family = AF_INET;
sa.sin_port = htons(10000);
sa.sin_addr.s_addr = INADDR_ANY;
int res = getnameinfo((struct sockaddr const *)&sa, sizeof(sa), 0, 0, service, NI_MAXSERV, NI_DGRAM);
if (res != 0)
{
printf("error: %s\n", gai_strerror(res));
return 1;
}
printf(":%s\n", service);
return 0;
}
"""
3. You can go directly debugging nscd:
# rm -f /var/db/nscd/services
# gdb --args nscd -d
...
(gdb) run
4. In another terminal run the example C code:
$ ./a.out
:service-example
It should have printed:
:10000
-----
Inspecting it in gdb, I see:
(gdb) b lookup
(gdb) run
(gdb) frame 4
(gdb) frame 4
#4 nscd_run_worker (p=<optimized out>) at connections.c:1831
1831 handle_request (fd, &req, keybuf, uid, pid);
(gdb) p keybuf
$1 = "4135\000/udp", '\000' <repeats 1015 times>
Note the '\000'. Then, when searching:
gdb) frame 0
#0 lookup (type=17, key=0x7fffe33c49c0 "4135", resultbufp=0x7fffe33c4730,
buffer=0x7fffe33c42d0 "\tGETSERVBYPORT (4135)", buflen=1024,
serv=0x7fffe33c4720) at servicescache.c:341
341 {
(gdb) list
336
337
338 static int
339 lookup (int type, char *key, struct servent *resultbufp, char *buffer,
340 size_t buflen, struct servent **serv)
341 {
342 char *proto = strrchr (key, '/');
343 if (proto != NULL && proto != key)
344 {
345 key = strndupa (key, proto - key);
(gdb) p key
$2 = 0x7fffe33c49c0 "4135"
The information about key length is not available and because of the embedded nul,
it does not find the correct proto value:
(gdb) frame 2
#2 0x0000555555565564 in addservbyport (
db=db@entry=0x55555577a4e0 <dbs+1056>, fd=fd@entry=23,
req=req@entry=0x7fffe33c4830, key=key@entry=0x7fffe33c49c0,
uid=uid@entry=4294967295) at servicescache.c:451
451 addservbyX (db, fd, req, key, uid, NULL, NULL);
(gdb) p *req
$3 = {version = 2, type = GETSERVBYPORT, key_len = 10}
This looks like a bug, not sure if either key_len should have been 9 to remove
the nul or if it should have been padded.
As an extra note, if the string were changed to remove the nul, it would not match
the entry in /etc/services, that has only a tcp entry. So, the gdb information above
is probably not much useful, other than as an example on how to possibly start
debugging it.
Since the problem described in this bug report should be
resolved in a recent advisory, it has been closed with a
resolution of ERRATA.
For information on the advisory, and where to find the updated
files, follow the link below.
If the solution does not work for you, open a new bug report.
https://access.redhat.com/errata/RHBA-2020:0989
To reproduce the issue: 1. Edit /etc/services commenting out: #ndmp 10000/tcp # Network Data Management Protocol #ndmp 10000/udp # Network Data Management Protocol and adding this entry: service-example 10000/tcp 2. Disable nscd if running, make sure to have: # grep services /etc/nscd.conf enable-cache services yes 3. Use this example program: """ #include <netdb.h> #include <sys/types.h> #include <sys/ioctl.h> #include <net/if.h> #include <stdio.h> #include <strings.h> int main() { char service[ NI_MAXSERV + 1 ]; struct sockaddr_in sa; bzero(&sa, sizeof(sa)); sa.sin_family = AF_INET; sa.sin_port = htons(10000); sa.sin_addr.s_addr = INADDR_ANY; int res = getnameinfo((struct sockaddr const *)&sa, sizeof(sa), 0, 0, service, NI_MAXSERV, NI_DGRAM); if (res != 0) { printf("error: %s\n", gai_strerror(res)); return 1; } printf(":%s\n", service); return 0; } """ 3. You can go directly debugging nscd: # rm -f /var/db/nscd/services # gdb --args nscd -d ... (gdb) run 4. In another terminal run the example C code: $ ./a.out :service-example It should have printed: :10000 ----- Inspecting it in gdb, I see: (gdb) b lookup (gdb) run (gdb) frame 4 (gdb) frame 4 #4 nscd_run_worker (p=<optimized out>) at connections.c:1831 1831 handle_request (fd, &req, keybuf, uid, pid); (gdb) p keybuf $1 = "4135\000/udp", '\000' <repeats 1015 times> Note the '\000'. Then, when searching: gdb) frame 0 #0 lookup (type=17, key=0x7fffe33c49c0 "4135", resultbufp=0x7fffe33c4730, buffer=0x7fffe33c42d0 "\tGETSERVBYPORT (4135)", buflen=1024, serv=0x7fffe33c4720) at servicescache.c:341 341 { (gdb) list 336 337 338 static int 339 lookup (int type, char *key, struct servent *resultbufp, char *buffer, 340 size_t buflen, struct servent **serv) 341 { 342 char *proto = strrchr (key, '/'); 343 if (proto != NULL && proto != key) 344 { 345 key = strndupa (key, proto - key); (gdb) p key $2 = 0x7fffe33c49c0 "4135" The information about key length is not available and because of the embedded nul, it does not find the correct proto value: (gdb) frame 2 #2 0x0000555555565564 in addservbyport ( db=db@entry=0x55555577a4e0 <dbs+1056>, fd=fd@entry=23, req=req@entry=0x7fffe33c4830, key=key@entry=0x7fffe33c49c0, uid=uid@entry=4294967295) at servicescache.c:451 451 addservbyX (db, fd, req, key, uid, NULL, NULL); (gdb) p *req $3 = {version = 2, type = GETSERVBYPORT, key_len = 10} This looks like a bug, not sure if either key_len should have been 9 to remove the nul or if it should have been padded.