Android-x86
Fork
Faire un don

  • R/O
  • HTTP
  • SSH
  • HTTPS

bionic: Commit

bionic


Commit MetaInfo

Révisionf7946c07e39dc425522ab42928ed8262fae176c5 (tree)
l'heure2017-02-17 10:30:14
AuteurElliott Hughes <enh@goog...>
CommiterChih-Wei Huang

Message de Log

Don't receive structs containing pointers over sockets.

Fixes x86-64 netd.

Change-Id: Iee5ef802ebbf2e000b2593643de4eec46f296c04

Change Summary

Modification

--- a/libc/dns/net/getaddrinfo.c
+++ b/libc/dns/net/getaddrinfo.c
@@ -408,6 +408,15 @@ _have_ipv4(unsigned mark) {
408408 return _test_connect(PF_INET, &addr.generic, sizeof(addr.in), mark);
409409 }
410410
411+bool readBE32(FILE* fp, int32_t* result) {
412+ int32_t tmp;
413+ if (fread(&tmp, sizeof(tmp), 1, fp) != 1) {
414+ return false;
415+ }
416+ *result = ntohl(tmp);
417+ return true;
418+}
419+
411420 // Returns 0 on success, else returns on error.
412421 static int
413422 android_getaddrinfo_proxy(
@@ -486,61 +495,62 @@ android_getaddrinfo_proxy(
486495 struct addrinfo* ai = NULL;
487496 struct addrinfo** nextres = res;
488497 while (1) {
489- uint32_t addrinfo_len;
490- if (fread(&addrinfo_len, sizeof(addrinfo_len),
491- 1, proxy) != 1) {
498+ int32_t have_more;
499+ if (!readBE32(proxy, &have_more)) {
492500 break;
493501 }
494- addrinfo_len = ntohl(addrinfo_len);
495- if (addrinfo_len == 0) {
502+ if (have_more == 0) {
496503 success = 1;
497504 break;
498505 }
499506
500- if (addrinfo_len < sizeof(struct addrinfo)) {
501- break;
502- }
503- struct addrinfo* ai = calloc(1, addrinfo_len +
504- sizeof(struct sockaddr_storage));
507+ struct addrinfo* ai = calloc(1, sizeof(struct addrinfo) + sizeof(struct sockaddr_storage));
505508 if (ai == NULL) {
506509 break;
507510 }
508-
509- if (fread(ai, addrinfo_len, 1, proxy) != 1) {
510- // Error; fall through.
511+ ai->ai_addr = (struct sockaddr*)(ai + 1);
512+
513+ // struct addrinfo {
514+ // int ai_flags; /* AI_PASSIVE, AI_CANONNAME, AI_NUMERICHOST */
515+ // int ai_family; /* PF_xxx */
516+ // int ai_socktype; /* SOCK_xxx */
517+ // int ai_protocol; /* 0 or IPPROTO_xxx for IPv4 and IPv6 */
518+ // socklen_t ai_addrlen; /* length of ai_addr */
519+ // char *ai_canonname; /* canonical name for hostname */
520+ // struct sockaddr *ai_addr; /* binary address */
521+ // struct addrinfo *ai_next; /* next structure in linked list */
522+ // };
523+
524+ // Read the struct piece by piece because we might be a 32-bit process
525+ // talking to a 64-bit netd.
526+ int32_t addr_len;
527+ bool success =
528+ readBE32(proxy, &ai->ai_flags) &&
529+ readBE32(proxy, &ai->ai_family) &&
530+ readBE32(proxy, &ai->ai_socktype) &&
531+ readBE32(proxy, &ai->ai_protocol) &&
532+ readBE32(proxy, &addr_len);
533+ if (!success) {
511534 break;
512535 }
513536
514- // Zero out the pointer fields we copied which aren't
515- // valid in this address space.
516- ai->ai_addr = NULL;
517- ai->ai_canonname = NULL;
518- ai->ai_next = NULL;
519-
520- // struct sockaddr
521- uint32_t addr_len;
522- if (fread(&addr_len, sizeof(addr_len), 1, proxy) != 1) {
523- break;
524- }
525- addr_len = ntohl(addr_len);
537+ // Set ai_addrlen and read the ai_addr data.
538+ ai->ai_addrlen = addr_len;
526539 if (addr_len != 0) {
527- if (addr_len > sizeof(struct sockaddr_storage)) {
540+ if ((size_t) addr_len > sizeof(struct sockaddr_storage)) {
528541 // Bogus; too big.
529542 break;
530543 }
531- struct sockaddr* addr = (struct sockaddr*)(ai + 1);
532- if (fread(addr, addr_len, 1, proxy) != 1) {
544+ if (fread(ai->ai_addr, addr_len, 1, proxy) != 1) {
533545 break;
534546 }
535- ai->ai_addr = addr;
536547 }
537548
538- // cannonname
539- uint32_t name_len;
540- if (fread(&name_len, sizeof(name_len), 1, proxy) != 1) {
549+ // The string for ai_cannonname.
550+ int32_t name_len;
551+ if (!readBE32(proxy, &name_len)) {
541552 break;
542553 }
543- name_len = ntohl(name_len);
544554 if (name_len != 0) {
545555 ai->ai_canonname = (char*) malloc(name_len);
546556 if (fread(ai->ai_canonname, name_len, 1, proxy) != 1) {
Afficher sur ancien navigateur de dépôt.