Compare commits

...

2 Commits

Author SHA1 Message Date
Nilesh Poddar
023c327cbb DO NOT MERGE ANYWHERE - bionic: resolver: exclude a range of ports from random_bind in DNS
Add a new API to set a range of ports which the DNS resolver should
never try to bind

Bug: 20127213
Change-Id: Ie3fca0ec2ee2523625816edd9417a0b5d5f91614
2015-04-23 21:46:36 +09:00
Christopher Ferris
3da136aa47 Modify test to avoid race condition.
There is a possible race if a timer is set to trigger at nearly the same
time as it is set. Since nobody uses the timers like this, modify the test
so this doesn't happen. The race that this can provoke has been fixed in
aosp.

Bug: 19423618
Change-Id: I21084c99da5ae46f404936d673dae6bad7c82caa
2015-02-18 17:45:50 -08:00
3 changed files with 38 additions and 4 deletions

View File

@@ -75,6 +75,9 @@ int android_getnameinfofornet(const struct sockaddr *, socklen_t, char *, size_t
/* delete the cache associated with a certain network */
extern void _resolv_delete_cache_for_net(unsigned netid);
/* set a port range for exclusion in the random_bind */
int _resolv_set_port_exclusion_range(in_port_t min, in_port_t max) __used_in_netd;
__END_DECLS
#endif /* _RESOLV_NETID_H */

View File

@@ -137,6 +137,10 @@ __RCSID("$NetBSD: res_send.c,v 1.9 2006/01/24 17:41:25 christos Exp $");
#define EXT(res) ((res)->_u._ext)
#define DBG 0
#define MAX_PORT (1 << (sizeof(in_port_t)*8))-1
#define DNS_MIN_PORT (IPPORT_RESERVED+1)
#define DNS_MAX_EXCLUDED_PORTS 5000
static const int highestFD = FD_SETSIZE - 1;
/* Forward. */
@@ -164,6 +168,27 @@ static int retrying_select(const int sock, fd_set *readset, fd_set *writeset,
const struct timespec *finish);
/* BIONIC-BEGIN: implement source port randomization */
static volatile in_port_t exclusion_min = 0;
static volatile in_port_t exclusion_max = 0;
int _resolv_set_port_exclusion_range(in_port_t min, in_port_t max)
{
if (min == 0 && max == 0) {
exclusion_min = exclusion_max = 0;
return 0;
}
if (min < DNS_MIN_PORT || min > max
|| (max - min > DNS_MAX_EXCLUDED_PORTS)) {
errno = ERANGE;
return -1;
}
exclusion_min = min;
exclusion_max = max;
return 0;
}
typedef union {
struct sockaddr sa;
struct sockaddr_in sin;
@@ -197,7 +222,13 @@ random_bind( int s, int family )
/* first try to bind to a random source port a few times */
for (j = 0; j < 10; j++) {
/* find a random port between 1025 .. 65534 */
int port = 1025 + (res_randomid() % (65535-1025));
in_port_t port;
do {
port = DNS_MIN_PORT + (res_randomid() % (MAX_PORT - DNS_MIN_PORT));
} while (exclusion_min
&& exclusion_max
&& port >= exclusion_min && port <= exclusion_max);
if (family == AF_INET)
u.sin.sin_port = htons(port);
else

View File

@@ -386,11 +386,11 @@ TEST(time, timer_delete_from_timer_thread) {
ASSERT_EQ(0, timer_create(CLOCK_REALTIME, &se, &tdd.timer_id));
itimerspec ts;
ts.it_value.tv_sec = 0;
ts.it_value.tv_nsec = 100;
ts.it_value.tv_sec = 1;
ts.it_value.tv_nsec = 0;
ts.it_interval.tv_sec = 0;
ts.it_interval.tv_nsec = 0;
ASSERT_EQ(0, timer_settime(tdd.timer_id, TIMER_ABSTIME, &ts, NULL));
ASSERT_EQ(0, timer_settime(tdd.timer_id, 0, &ts, NULL));
time_t cur_time = time(NULL);
while (!tdd.complete && (time(NULL) - cur_time) < 5);