am b9e1688c: am 1d3d0360: am 081db840: Allow overlap in resolv uid => DNS iface mapping

* commit 'b9e1688cd9f8727bbe0dacafd194c7a571bedb14':
  Allow overlap in resolv uid => DNS iface mapping
This commit is contained in:
Chad Brubaker 2014-03-24 19:35:17 +00:00 committed by Android Git Automerger
commit efe4461364
2 changed files with 24 additions and 46 deletions

View File

@ -79,13 +79,12 @@ extern void _resolv_clear_iface_pid_mapping();
extern int _resolv_get_pids_associated_interface(int pid, char* buff, int buffLen); extern int _resolv_get_pids_associated_interface(int pid, char* buff, int buffLen);
/** set a uid range to use the name servers of the specified interface /** set a uid range to use the name servers of the specified interface */
* If [low,high] overlaps with an already existing rule -1 is returned */
extern int _resolv_set_iface_for_uid_range(const char* ifname, int uid_start, int uid_end); extern int _resolv_set_iface_for_uid_range(const char* ifname, int uid_start, int uid_end);
/* clear a uid range from being associated with an interface /** Remove a mapping added by _resolv_set_iface_for_uid_range.
* If the range given is not mapped -1 is returned. */ * If no such rule exists -1 is returned. */
extern int _resolv_clear_iface_for_uid_range(int uid_start, int uid_end); extern int _resolv_clear_iface_for_uid_range(const char* ifname, int uid_start, int uid_end);
/* clear the entire mapping of uid ranges to interfaces. */ /* clear the entire mapping of uid ranges to interfaces. */
extern void _resolv_clear_iface_uid_range_mapping(); extern void _resolv_clear_iface_uid_range_mapping();
@ -94,6 +93,7 @@ extern void _resolv_clear_iface_uid_range_mapping();
* On error, -1 is returned. * On error, -1 is returned.
* If no interface is found, 0 is returned and buff is set to empty ('\0'). * If no interface is found, 0 is returned and buff is set to empty ('\0').
* If an interface is found, the name is copied to buff and the length of the name is returned. * If an interface is found, the name is copied to buff and the length of the name is returned.
* If there are multiple rules covering uid the most recently added rule will be returned.
* Arguments: uid The uid to find an interface for * Arguments: uid The uid to find an interface for
* buff A buffer to copy the result to * buff A buffer to copy the result to
* buffLen Length of buff. An interface is at most IF_NAMESIZE in length */ * buffLen Length of buff. An interface is at most IF_NAMESIZE in length */

View File

@ -1829,9 +1829,7 @@ static void _remove_pidiface_info_locked(int pid);
static struct resolv_pidiface_info* _get_pid_iface_info_locked(int pid); static struct resolv_pidiface_info* _get_pid_iface_info_locked(int pid);
/* remove a resolv_pidiface_info structure from _res_uidiface_list */ /* remove a resolv_pidiface_info structure from _res_uidiface_list */
static int _remove_uidiface_info_locked(int uid_start, int uid_end); static int _remove_uidiface_info_locked(const char* iface, int uid_start, int uid_end);
/* check if a range [low,high] overlaps with any already existing ranges in the uid=>iface map*/
static int _resolv_check_uid_range_overlap_locked(int uid_start, int uid_end);
/* get a resolv_uidiface_info structure from _res_uidiface_list with a certain uid */ /* get a resolv_uidiface_info structure from _res_uidiface_list with a certain uid */
static struct resolv_uidiface_info* _get_uid_iface_info_locked(int uid); static struct resolv_uidiface_info* _get_uid_iface_info_locked(int uid);
@ -2410,11 +2408,11 @@ _resolv_get_pids_associated_interface(int pid, char* buff, int buffLen)
} }
static int static int
_remove_uidiface_info_locked(int uid_start, int uid_end) { _remove_uidiface_info_locked(const char* ifname, int uid_start, int uid_end) {
struct resolv_uidiface_info* result = _res_uidiface_list.next; struct resolv_uidiface_info* result = _res_uidiface_list.next;
struct resolv_uidiface_info* prev = &_res_uidiface_list; struct resolv_uidiface_info* prev = &_res_uidiface_list;
while (result != NULL && !(result->uid_start == uid_start && result->uid_end == uid_end &&
while (result != NULL && result->uid_start != uid_start && result->uid_end != uid_end) { !strcmp(result->ifname, ifname))) {
prev = result; prev = result;
result = result->next; result = result->next;
} }
@ -2438,19 +2436,6 @@ _get_uid_iface_info_locked(int uid)
return result; return result;
} }
static int
_resolv_check_uid_range_overlap_locked(int uid_start, int uid_end)
{
struct resolv_uidiface_info* cur = _res_uidiface_list.next;
while (cur != NULL) {
if (cur->uid_start <= uid_end && cur->uid_end >= uid_start) {
return -1;
}
cur = cur->next;
}
return 0;
}
void void
_resolv_clear_iface_uid_range_mapping() _resolv_clear_iface_uid_range_mapping()
{ {
@ -2495,8 +2480,6 @@ _resolv_set_iface_for_uid_range(const char* ifname, int uid_start, int uid_end)
return -1; return -1;
} }
pthread_mutex_lock(&_res_uidiface_list_lock); pthread_mutex_lock(&_res_uidiface_list_lock);
//check that we aren't adding an overlapping range
if (!_resolv_check_uid_range_overlap_locked(uid_start, uid_end)) {
uidiface_info = calloc(sizeof(*uidiface_info), 1); uidiface_info = calloc(sizeof(*uidiface_info), 1);
if (uidiface_info) { if (uidiface_info) {
uidiface_info->uid_start = uid_start; uidiface_info->uid_start = uid_start;
@ -2515,25 +2498,20 @@ _resolv_set_iface_for_uid_range(const char* ifname, int uid_start, int uid_end)
rv = -1; rv = -1;
errno = EINVAL; errno = EINVAL;
} }
} else {
XLOG("_resolv_set_iface_for_uid_range range [%d,%d] overlaps\n", uid_start, uid_end);
rv = -1;
errno = EINVAL;
}
pthread_mutex_unlock(&_res_uidiface_list_lock); pthread_mutex_unlock(&_res_uidiface_list_lock);
return rv; return rv;
} }
int int
_resolv_clear_iface_for_uid_range(int uid_start, int uid_end) _resolv_clear_iface_for_uid_range(const char* ifname, int uid_start, int uid_end)
{ {
pthread_once(&_res_cache_once, _res_cache_init); pthread_once(&_res_cache_once, _res_cache_init);
pthread_mutex_lock(&_res_uidiface_list_lock); pthread_mutex_lock(&_res_uidiface_list_lock);
int rv = _remove_uidiface_info_locked(uid_start, uid_end); int rv = _remove_uidiface_info_locked(ifname, uid_start, uid_end);
XLOG("_resolv_clear_iface_for_uid_range: [%d,%d]\n", uid_start, uid_end); XLOG("_resolv_clear_iface_for_uid_range: [%d,%d] iface %s\n", uid_start, uid_end, ifname);
pthread_mutex_unlock(&_res_uidiface_list_lock); pthread_mutex_unlock(&_res_uidiface_list_lock);