Bug 31981 - [libc] [patch] (mis)feature in getnetent parsing -- comments affect parsing results
Summary: [libc] [patch] (mis)feature in getnetent parsing -- comments affect parsing r...
Status: Closed FIXED
Alias: None
Product: Base System
Classification: Unclassified
Component: kern (show other bugs)
Version: 4.1-RELEASE
Hardware: Any Any
: Normal Affects Only Me
Assignee: Marcelo Araujo
Depends on:
Reported: 2001-11-14 15:40 UTC by James Carlson
Modified: 2015-12-28 03:33 UTC (History)
3 users (show)

See Also:

Updated patch (452 bytes, patch)
2015-02-21 18:19 UTC, Pedro F. Giffuni
no flags Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description James Carlson 2001-11-14 15:40:03 UTC
The problem actually goes back to ancient releases of BSD.  I looked
back to 4.2BSD, and the problem exists there.

Consider the following two entries in /etc/networks:

	test1	10
	test2	11	alias2
	test3	12	# hi there

On Solaris getnetbyname (and getnetent), we treat "test1", "test2",
and "test3" as the real network names, and "alias2" as an alias for
just network "test2."  This appears to be fairly reasonable.

On BSD, it interprets the second entry the same way we do -- network
"test2", single alias "alias2", and "test3" with no aliases.  However,
it *intentionally* treats the first case differently.  On BSD, that's
interpreted as network "test1" with alias "10".

The offending lines in /usr/src/lib/libc/net/getnetbyht.c are:

	p = strpbrk(cp, " \t");
	if (p != NULL)
		*p++ = '\0';
	net.n_net = inet_network(cp);
	net.n_addrtype = AF_INET;
	q = net.n_aliases = net_aliases;
	if (p != NULL) 
--->		cp = p;

This sets the initial pointer to the next character after the first
blank following the network number.  If there is no such character,
then this is NULL, and we just fall through with cp set to the start
of the network number.


Remove the "if (p != NULL)" line.
How-To-Repeat: #include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>

main(int argc, char **argv)
	struct netent *np;
	unsigned char *cp;
	unsigned long ina;
	char **cpp;

	np = getnetbyname(argv[1]);
	if (np == NULL) {
		printf("getnetbyname: NULL\n");
	} else {
		cp = (unsigned char *)&np->n_net;
		printf("getnetbyname: %d %d %d %d '%s'\n", cp[0], cp[1], cp[2],
		    cp[3], np->n_name);
		if (*np->n_aliases != NULL) {
			printf("     aliases:");
			for (cpp = np->n_aliases; *cpp != NULL; cpp++)
				printf(" '%s'", *cpp);
	ina = inet_network(argv[1]);
	cp = (unsigned char *)&ina;
	printf("inet_network: %d %d %d %d\n", cp[0], cp[1], cp[2],
	return 0;
Comment 1 Pedro F. Giffuni freebsd_committer 2015-02-19 20:15:20 UTC
This appears to have been fixed somewhat differently by r145477:

"if last line didn't have trailing space, network address was also
treated as an alias."

I am closing it but will assign it to the revision committer for reference.
Comment 2 Pedro F. Giffuni freebsd_committer 2015-02-21 18:19:20 UTC
Created attachment 153285 [details]
Updated patch

Actually, this should work ... but it needs testing.
Comment 3 Marcelo Araujo freebsd_committer 2015-11-17 02:29:32 UTC
I will take it.
Comment 4 Marcelo Araujo freebsd_committer 2015-12-14 06:52:53 UTC
I have tested it, and I can't find where is the bug, my tests were made with/without the patch and using the software provided by the submitter, I still can't find where is the bug.

The output is always the same for me, and it looks right:
 araujo@coxinha:/tmp# ./t test1
getnetbyname: 10 0 0 0 'test1'
inet_network: 255 255 255 255
araujo@coxinha:/tmp# ./t test2
getnetbyname: 11 0 0 0 'test2'
     aliases: 'alias2'
inet_network: 255 255 255 255
araujo@coxinha:/tmp# ./t test3
getnetbyname: 12 0 0 0 'test3'
inet_network: 255 255 255 255

If no reply from you guys in the next couple weeks, I will consider this problem as solved.

Comment 5 Marcelo Araujo freebsd_committer 2015-12-28 03:33:32 UTC
I can't replicate this issue.