* commit '4dcb9c781143d30cc05f225557da0d86c2ccb93e': Don't receive structs containing pointers over sockets.
This commit is contained in:
		@@ -408,6 +408,15 @@ _have_ipv4(unsigned mark) {
 | 
				
			|||||||
	return _test_connect(PF_INET, &addr.generic, sizeof(addr.in), mark);
 | 
						return _test_connect(PF_INET, &addr.generic, sizeof(addr.in), mark);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool readBE32(FILE* fp, int32_t* result) {
 | 
				
			||||||
 | 
					  int32_t tmp;
 | 
				
			||||||
 | 
					  if (fread(&tmp, sizeof(tmp), 1, fp) != 1) {
 | 
				
			||||||
 | 
					    return false;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  *result = ntohl(tmp);
 | 
				
			||||||
 | 
					  return true;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Returns 0 on success, else returns on error.
 | 
					// Returns 0 on success, else returns on error.
 | 
				
			||||||
static int
 | 
					static int
 | 
				
			||||||
android_getaddrinfo_proxy(
 | 
					android_getaddrinfo_proxy(
 | 
				
			||||||
@@ -486,61 +495,62 @@ android_getaddrinfo_proxy(
 | 
				
			|||||||
	struct addrinfo* ai = NULL;
 | 
						struct addrinfo* ai = NULL;
 | 
				
			||||||
	struct addrinfo** nextres = res;
 | 
						struct addrinfo** nextres = res;
 | 
				
			||||||
	while (1) {
 | 
						while (1) {
 | 
				
			||||||
		uint32_t addrinfo_len;
 | 
							int32_t have_more;
 | 
				
			||||||
		if (fread(&addrinfo_len, sizeof(addrinfo_len),
 | 
							if (!readBE32(proxy, &have_more)) {
 | 
				
			||||||
			  1, proxy) != 1) {
 | 
					 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		addrinfo_len = ntohl(addrinfo_len);
 | 
							if (have_more == 0) {
 | 
				
			||||||
		if (addrinfo_len == 0) {
 | 
					 | 
				
			||||||
			success = 1;
 | 
								success = 1;
 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (addrinfo_len < sizeof(struct addrinfo)) {
 | 
							struct addrinfo* ai = calloc(1, sizeof(struct addrinfo) + sizeof(struct sockaddr_storage));
 | 
				
			||||||
			break;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		struct addrinfo* ai = calloc(1, addrinfo_len +
 | 
					 | 
				
			||||||
					     sizeof(struct sockaddr_storage));
 | 
					 | 
				
			||||||
		if (ai == NULL) {
 | 
							if (ai == NULL) {
 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
							ai->ai_addr = (struct sockaddr*)(ai + 1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (fread(ai, addrinfo_len, 1, proxy) != 1) {
 | 
							// struct addrinfo {
 | 
				
			||||||
			// Error; fall through.
 | 
							//	int	ai_flags;	/* AI_PASSIVE, AI_CANONNAME, AI_NUMERICHOST */
 | 
				
			||||||
 | 
							//	int	ai_family;	/* PF_xxx */
 | 
				
			||||||
 | 
							//	int	ai_socktype;	/* SOCK_xxx */
 | 
				
			||||||
 | 
							//	int	ai_protocol;	/* 0 or IPPROTO_xxx for IPv4 and IPv6 */
 | 
				
			||||||
 | 
							//	socklen_t ai_addrlen;	/* length of ai_addr */
 | 
				
			||||||
 | 
							//	char	*ai_canonname;	/* canonical name for hostname */
 | 
				
			||||||
 | 
							//	struct	sockaddr *ai_addr;	/* binary address */
 | 
				
			||||||
 | 
							//	struct	addrinfo *ai_next;	/* next structure in linked list */
 | 
				
			||||||
 | 
							// };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							// Read the struct piece by piece because we might be a 32-bit process
 | 
				
			||||||
 | 
							// talking to a 64-bit netd.
 | 
				
			||||||
 | 
							int32_t addr_len;
 | 
				
			||||||
 | 
							bool success =
 | 
				
			||||||
 | 
									readBE32(proxy, &ai->ai_flags) &&
 | 
				
			||||||
 | 
									readBE32(proxy, &ai->ai_family) &&
 | 
				
			||||||
 | 
									readBE32(proxy, &ai->ai_socktype) &&
 | 
				
			||||||
 | 
									readBE32(proxy, &ai->ai_protocol) &&
 | 
				
			||||||
 | 
									readBE32(proxy, &addr_len);
 | 
				
			||||||
 | 
							if (!success) {
 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// Zero out the pointer fields we copied which aren't
 | 
							// Set ai_addrlen and read the ai_addr data.
 | 
				
			||||||
		// valid in this address space.
 | 
							ai->ai_addrlen = addr_len;
 | 
				
			||||||
		ai->ai_addr = NULL;
 | 
					 | 
				
			||||||
		ai->ai_canonname = NULL;
 | 
					 | 
				
			||||||
		ai->ai_next = NULL;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		// struct sockaddr
 | 
					 | 
				
			||||||
		uint32_t addr_len;
 | 
					 | 
				
			||||||
		if (fread(&addr_len, sizeof(addr_len), 1, proxy) != 1) {
 | 
					 | 
				
			||||||
			break;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		addr_len = ntohl(addr_len);
 | 
					 | 
				
			||||||
		if (addr_len != 0) {
 | 
							if (addr_len != 0) {
 | 
				
			||||||
			if (addr_len > sizeof(struct sockaddr_storage)) {
 | 
								if ((size_t) addr_len > sizeof(struct sockaddr_storage)) {
 | 
				
			||||||
				// Bogus; too big.
 | 
									// Bogus; too big.
 | 
				
			||||||
				break;
 | 
									break;
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			struct sockaddr* addr = (struct sockaddr*)(ai + 1);
 | 
								if (fread(ai->ai_addr, addr_len, 1, proxy) != 1) {
 | 
				
			||||||
			if (fread(addr, addr_len, 1, proxy) != 1) {
 | 
					 | 
				
			||||||
				break;
 | 
									break;
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			ai->ai_addr = addr;
 | 
					 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// cannonname
 | 
							// The string for ai_cannonname.
 | 
				
			||||||
		uint32_t name_len;
 | 
							int32_t name_len;
 | 
				
			||||||
		if (fread(&name_len, sizeof(name_len), 1, proxy) != 1) {
 | 
							if (!readBE32(proxy, &name_len)) {
 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		name_len = ntohl(name_len);
 | 
					 | 
				
			||||||
		if (name_len != 0) {
 | 
							if (name_len != 0) {
 | 
				
			||||||
			ai->ai_canonname = (char*) malloc(name_len);
 | 
								ai->ai_canonname = (char*) malloc(name_len);
 | 
				
			||||||
			if (fread(ai->ai_canonname, name_len, 1, proxy) != 1) {
 | 
								if (fread(ai->ai_canonname, name_len, 1, proxy) != 1) {
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user