STUN: stun_getifaddrs() can return uninitialised bits which are subsequently used
Categories
(Core :: WebRTC, defect, P2)
Tracking
()
Tracking | Status | |
---|---|---|
firefox74 | --- | fixed |
People
(Reporter: jseward, Assigned: jseward)
Details
Attachments
(4 files)
media/mtransport/third_party/nICEr/src/stun/addrs.c:
stun_getifaddrs()
is used on all non-WIN32 targets. It extracts from the
kernel an array describing network connections, or addresses, or something
like that (doesn't really matter what). These are written into its
out-parameter nr_local_addr addrs[]
and the number of entries is written to
int *count
.
There is a path through the main loop in stun_getifaddrs()
which can cause a
nr_local_addr
record to be returned with its .interface.type
field being
uninitialized, but which nevertheless is later used. It also looks to me as
if the .interface.estimated_speed
field is not initialised.
The path is simple: first this ioctl fails (returns nonzero):
e = ioctl(s, SIOCETHTOOL, &ifr);
and then
e = ioctl(s, SIOCGIWRATE, &wrq);
also fails.
The uninitialised .interface.type
is subsequently used in
nr_local_addr_fmt_info_string()
:
int addr_type = addr->interface.type;
const char *vpn = (addr_type & NR_INTERFACE_TYPE_VPN) ? "VPN on " : "";
const char *type = (addr_type & NR_INTERFACE_TYPE_WIRED) ? "wired" :
(addr_type & NR_INTERFACE_TYPE_WIFI) ? "wifi" :
(addr_type & NR_INTERFACE_TYPE_MOBILE) ? "mobile" :
"unknown";
Assignee | ||
Updated•6 years ago
|
Assignee | ||
Comment 1•6 years ago
|
||
Assignee | ||
Comment 2•6 years ago
|
||
Standalone test program extracted from addrs.c
, that shows the problem.
I suspect it is for a loopback mount, that both ioctls fail. I confirmed that
they both can fail by adding debug printing.
An obvious fix is to zero out the record we might be about to write to, at
the top of the main loop:
while (if_addr && *count < maxaddrs) {
memset(&addrs[*count], 0, sizeof(addrs[*count])); <-----------
I don't know if 'zero' is a safe fill value for those otherwise-uninitialised
fields, but at least doing this would make it fail repeatably (if it would
have failed anyway), rather than non-deterministically.
A quick scan of stun_get_win32_addrs
suggests it doesn't suffer from
the same problem.
Assignee | ||
Comment 3•6 years ago
|
||
Removing needinfo. Not sure why I added it. Sorry for the noise.
Assignee | ||
Comment 4•6 years ago
|
||
Would a fix along these lines be appropriate?
Comment 5•6 years ago
|
||
Comment 6•6 years ago
|
||
As it's an ongoing task and I assume that might be landed in this cycle, so mark it as P2.
Assignee | ||
Comment 7•6 years ago
|
||
In media/mtransport/third_party/nICEr/src/stun/addrs.c:
stun_getifaddrs() is used on all non-WIN32 targets. It extracts from the
kernel an array describing network interfaces (I think). These are written
into its out-parameter nr_local_addr addrs[] and the number of entries is
written to int *count.
There is a path through the main loop in stun_getifaddrs() which can cause a
nr_local_addr record to be returned with its .interface.type field being
uninitialized, but which nevertheless is later used. It also looks as if the
.interface.estimated_speed field is not initialised.
This commit zero-initialises the entire output array before writing anything
into it, to avoid such problems, on all targets.
Comment 9•6 years ago
|
||
bugherder |
Description
•