kernel-packages team mailing list archive
-
kernel-packages team
-
Mailing list archive
-
Message #108081
[Bug 1432378] [NEW] libresolv res_init() does not correctly inititalize internals
Public bug reported:
As reported here: https://sourceware.org/bugzilla/show_bug.cgi?id=18126
The bug, however, is not in the sourceware sourcecode, but in the Ubuntu
one.
https://sourceware.org/git/?p=glibc.git;a=blob;f=resolv/res_libc.c;h=ee3fa2114b7051b86f6f9676f1151d1435dedb9d;hb=HEAD#l97
Contrary to what one would think, res_init() does not correctly
inititialize the internals for further use by the libresolv family, and
others.
When you call res_init(), it correctly "keeps" these:
if (!_res.retrans)
_res.retrans = RES_TIMEOUT;
if (!_res.retry)
_res.retry = 4;
if (!(_res.options & RES_INIT))
_res.options = RES_DEFAULT;
else if (_res.nscount > 0)
__res_iclose (&_res, true); /* Close any VC sockets. */
then calls __res_vinit():
return (__res_vinit(&_res, 1));
However, programs that use the libresolv family and others, use the
hidden function, "__res_maybe_init".
__res_maybe_init determines if res_init(__res_vinit()) needs to be
called or not.
It does this:
static time_t last_mtime;
struct stat statbuf;
int ret;
if (resp->options & RES_INIT) {
ret = stat (_PATH_RESCONF, &statbuf);
__libc_lock_lock (lock);
if ((ret == 0) && (last_mtime != statbuf.st_mtime)) {
last_mtime = statbuf.st_mtime;
atomicinc (__res_initstamp);
}
__libc_lock_unlock (lock);
if (__res_initstamp != resp->_u._ext.initstamp) {
if (resp->nscount > 0)
__res_iclose (resp, true);
return __res_vinit (resp, 1);
}
return 0;
Since the internals have been initialized by res_init(), we don't need to reinitalize, normally. The program checks if we do need to reinitalize, such as due to the change in modifcation date of /etc/resolv.conf.
However, "last_mtime" is never set when using res_init(), so upon the
first run of __res_maybe_init(), it will always run __res_vinit(). This
will wipe all changes except for the ones that are kept, mentioned
above.
"last_mtime" should be taken into consideration and handled, when calling res_init().
(for reference)
Only these are kept on res_init(), and thus are only kept with the first call to __res_maybe_init:
int retrans; /* retransmition time interval */
int retry; /* number of times to retransmit */
u_long options; /* option flags - see below. */
These are wiped, due to this bug:
int nscount; /* number of name servers */
struct sockaddr_in
nsaddr_list[MAXNS]; /* address of name server */
# define nsaddr nsaddr_list[0] /* for backward compatibility */
u_short id; /* current message id */
/* 2 byte hole here. */
char *dnsrch[MAXDNSRCH+1]; /* components of domain to search */
char defdname[256]; /* default domain (deprecated) */
u_long pfcode; /* RES_PRF_ flags - see below. */
unsigned ndots:4; /* threshold for initial abs. query */
unsigned nsort:4; /* number of elements in sort_list[] */
unsigned ipv6_unavail:1; /* connecting to IPv6 server failed */
** Affects: linux (Ubuntu)
Importance: Undecided
Status: New
** Tags: libc libresolv
--
You received this bug notification because you are a member of Kernel
Packages, which is subscribed to linux in Ubuntu.
https://bugs.launchpad.net/bugs/1432378
Title:
libresolv res_init() does not correctly inititalize internals
Status in linux package in Ubuntu:
New
Bug description:
As reported here:
https://sourceware.org/bugzilla/show_bug.cgi?id=18126
The bug, however, is not in the sourceware sourcecode, but in the
Ubuntu one.
https://sourceware.org/git/?p=glibc.git;a=blob;f=resolv/res_libc.c;h=ee3fa2114b7051b86f6f9676f1151d1435dedb9d;hb=HEAD#l97
Contrary to what one would think, res_init() does not correctly inititialize the internals for further use by the libresolv family, and others.
When you call res_init(), it correctly "keeps" these:
if (!_res.retrans)
_res.retrans = RES_TIMEOUT;
if (!_res.retry)
_res.retry = 4;
if (!(_res.options & RES_INIT))
_res.options = RES_DEFAULT;
else if (_res.nscount > 0)
__res_iclose (&_res, true); /* Close any VC sockets. */
then calls __res_vinit():
return (__res_vinit(&_res, 1));
However, programs that use the libresolv family and others, use the
hidden function, "__res_maybe_init".
__res_maybe_init determines if res_init(__res_vinit()) needs to be
called or not.
It does this:
static time_t last_mtime;
struct stat statbuf;
int ret;
if (resp->options & RES_INIT) {
ret = stat (_PATH_RESCONF, &statbuf);
__libc_lock_lock (lock);
if ((ret == 0) && (last_mtime != statbuf.st_mtime)) {
last_mtime = statbuf.st_mtime;
atomicinc (__res_initstamp);
}
__libc_lock_unlock (lock);
if (__res_initstamp != resp->_u._ext.initstamp) {
if (resp->nscount > 0)
__res_iclose (resp, true);
return __res_vinit (resp, 1);
}
return 0;
Since the internals have been initialized by res_init(), we don't need to reinitalize, normally. The program checks if we do need to reinitalize, such as due to the change in modifcation date of /etc/resolv.conf.
However, "last_mtime" is never set when using res_init(), so upon the
first run of __res_maybe_init(), it will always run __res_vinit().
This will wipe all changes except for the ones that are kept,
mentioned above.
"last_mtime" should be taken into consideration and handled, when calling res_init().
(for reference)
Only these are kept on res_init(), and thus are only kept with the first call to __res_maybe_init:
int retrans; /* retransmition time interval */
int retry; /* number of times to retransmit */
u_long options; /* option flags - see below. */
These are wiped, due to this bug:
int nscount; /* number of name servers */
struct sockaddr_in
nsaddr_list[MAXNS]; /* address of name server */
# define nsaddr nsaddr_list[0] /* for backward compatibility */
u_short id; /* current message id */
/* 2 byte hole here. */
char *dnsrch[MAXDNSRCH+1]; /* components of domain to search */
char defdname[256]; /* default domain (deprecated) */
u_long pfcode; /* RES_PRF_ flags - see below. */
unsigned ndots:4; /* threshold for initial abs. query */
unsigned nsort:4; /* number of elements in sort_list[] */
unsigned ipv6_unavail:1; /* connecting to IPv6 server failed */
To manage notifications about this bug go to:
https://bugs.launchpad.net/ubuntu/+source/linux/+bug/1432378/+subscriptions
Follow ups
References