Snap for 10447354 from f80bca6977750793d7ac884a9b57a1bfa93e0ec7 to mainline-cellbroadcast-release

Change-Id: If30efe98fab7bddc01c1fbdbd8d5bd39ba46759a
diff --git a/Android.bp b/Android.bp
index e0fb5d9..5c70abf 100644
--- a/Android.bp
+++ b/Android.bp
@@ -47,8 +47,8 @@
     "tests/libufdt_verify",
 ]
 
-cc_library_static {
-    name: "libufdt",
+cc_defaults {
+    name: "libufdt_defaults",
     host_supported: true,
     srcs: [
         "ufdt_overlay.c",
@@ -64,3 +64,16 @@
         "libufdt_sysdeps",
     ],
 }
+
+cc_library_static {
+    name: "libufdt",
+    defaults: [ "libufdt_defaults" ],
+}
+
+// Same library but without error messages.
+cc_library_static {
+    name: "libufdt_silent",
+    defaults: [ "libufdt_defaults" ],
+    cflags: ["-Wall", "-Werror", "-DDTO_DISABLE_ERROR_MSG"],
+}
+
diff --git a/sysdeps/include/libufdt_sysdeps.h b/sysdeps/include/libufdt_sysdeps.h
index 1e1ea6d..f337b1a 100644
--- a/sysdeps/include/libufdt_sysdeps.h
+++ b/sysdeps/include/libufdt_sysdeps.h
@@ -38,14 +38,22 @@
     dto_print(__VA_ARGS__);              \
   } while (0)
 #else
-#define dto_debug(...)
+#define dto_debug(...) \
+  do {                 \
+  } while (0)
 #endif
 
+#ifndef DTO_DISABLE_ERROR_MSG
 #define dto_error(...)                   \
   do {                                   \
     dto_print("ERROR: %s():", __func__); \
     dto_print(__VA_ARGS__);              \
   } while (0)
+#else
+#define dto_error(...) \
+  do {                 \
+  } while (0)
+#endif
 
 int dto_print(const char *fmt, ...);
 
diff --git a/tests/src/Android.bp b/tests/src/Android.bp
index 10ba099..3c4dc04 100644
--- a/tests/src/Android.bp
+++ b/tests/src/Android.bp
@@ -79,6 +79,7 @@
 
 cc_binary {
     name: "fdt_apply_overlay",
+    host_supported: true,
     cflags: libufdt_tests_cflags,
     srcs: [
         "fdt_overlay_test_app.c",
@@ -89,6 +90,15 @@
         "libufdt_sysdeps",
     ],
     required: ["dtc"],
+    target: {
+        host: {
+            stl: "none",
+            dist: {
+                targets: ["dist_files"],
+                dir: "libufdt",
+            },
+        },
+    },
 }
 
 cc_binary_host {
diff --git a/tests/src/extract_dtb.c b/tests/src/extract_dtb.c
index 8d74324..3e14618 100644
--- a/tests/src/extract_dtb.c
+++ b/tests/src/extract_dtb.c
@@ -22,8 +22,7 @@
 
 #include "util.h"
 
-
-int find_dtb_header_pos(const char *buf, size_t buf_size) {
+static int find_dtb_header_pos(const char *buf, size_t buf_size) {
   if (buf == NULL || buf_size == 0) {
     return -1;
   }
@@ -44,34 +43,44 @@
   return pos;
 }
 
-int find_and_write_dtb(const char *filename,
-                       const char *buf, size_t buf_size) {
+static int find_and_write_dtb(const char *filename, const char *buf,
+                              size_t buf_size) {
   int tag_pos = find_dtb_header_pos(buf, buf_size);
   if (tag_pos < 0) {
-    goto end;
+    return -1;
   }
 
+  buf_size -= tag_pos;
+
+  // Allocate and copy into new buffer to fix memory alignment
+  char *fdt_ptr = malloc(buf_size);
+  if (!fdt_ptr) {
+    fprintf(stderr, "malloc(%u) failed.\n", buf_size - tag_pos);
+    goto error;
+  }
+
+  memcpy(fdt_ptr, buf + tag_pos, buf_size);
+
   // Check FDT header
-  const char *fdt_ptr = buf + tag_pos;
-  if (fdt_check_header(fdt_ptr) != 0) {
-    fprintf(stderr, "Bad DTB header.\n");
-    goto end;
+  if (fdt_check_full(fdt_ptr, buf_size) != 0) {
+    fprintf(stderr, "Bad DTB.\n");
+    goto error;
   }
 
   // Check FDT size and actual size
   size_t fdt_size = fdt_totalsize(fdt_ptr);
-  size_t fdt_actual_size = buf_size - tag_pos;
-  int fdt_size_diff = (int)fdt_actual_size - (int)fdt_size;
-  if (fdt_size_diff) {
-    fprintf(stderr, "Wrong size: actual size = %d FDT size = %d(%d)\n",
-      fdt_actual_size, fdt_size, fdt_size_diff);
+  if (buf_size < fdt_size) {
+    fprintf(stderr,
+            "Wrong size: fdt truncated: buffer size = %zu < FDT size = %zu\n",
+            buf_size, fdt_size);
+    goto error;
   }
 
   // Print the DT basic information
   int root_node_off = fdt_path_offset(fdt_ptr, "/");
   if (root_node_off < 0) {
     fprintf(stderr, "Can not get the root node.\n");
-    goto end;
+    goto error;
   }
   printf("Output %s\n", filename);
   const char *model =
@@ -84,22 +93,26 @@
   // Output DTB file
   if (write_fdt_to_file(filename, fdt_ptr) != 0) {
     fprintf(stderr, "Write file error: %s\n", filename);
-    goto end;
+    goto error;
   }
 
-end:
+  free(fdt_ptr);
+
   return tag_pos;
+
+error:
+  if (fdt_ptr) free(fdt_ptr);
+  return -1;
 }
 
-int extract_dtbs(const char *in_filename,
-                 const char *out_dtb_filename,
-                 const char *out_image_filename) {
+static int extract_dtbs(const char *in_filename, const char *out_dtb_filename,
+                        const char *out_image_filename) {
   int ret = 1;
   char *buf = NULL;
 
   size_t buf_size;
   buf = load_file(in_filename, &buf_size);
-  if (!buf) {
+  if (!buf || fdt_check_full(buf, buf_size)) {
     fprintf(stderr, "Can not load file: %s\n", in_filename);
     goto end;
   }
diff --git a/tests/src/fdt_overlay_test_app.c b/tests/src/fdt_overlay_test_app.c
index 3b65a7d..04fcdd9 100644
--- a/tests/src/fdt_overlay_test_app.c
+++ b/tests/src/fdt_overlay_test_app.c
@@ -31,20 +31,25 @@
 
   size_t base_len;
   base_buf = load_file(base_filename, &base_len);
-  if (!base_buf) {
+  if (!base_buf || fdt_check_full(base_buf, base_len)) {
     fprintf(stderr, "Can not load base file: %s\n", base_filename);
     goto end;
   }
 
   size_t overlay_len;
   overlay_buf = load_file(overlay_filename, &overlay_len);
-  if (!overlay_buf) {
+  if (!overlay_buf || fdt_check_full(overlay_buf, overlay_len)) {
     fprintf(stderr, "Can not load overlay file: %s\n", overlay_filename);
     goto end;
   }
 
   size_t merged_buf_len = base_len + overlay_len;
   merged_buf = dto_malloc(merged_buf_len);
+  if (!merged_buf) {
+    fprintf(stderr, "Malloc failed: %zu bytes needed\n", merged_buf_len);
+    goto end;
+  }
+
   fdt_open_into(base_buf, merged_buf, merged_buf_len);
 
   clock_t start = clock();
diff --git a/tests/src/ufdt_overlay_test_app.c b/tests/src/ufdt_overlay_test_app.c
index d7c4437..9d47476 100644
--- a/tests/src/ufdt_overlay_test_app.c
+++ b/tests/src/ufdt_overlay_test_app.c
@@ -32,14 +32,14 @@
 
   size_t blob_len;
   base_buf = load_file(base_filename, &blob_len);
-  if (!base_buf) {
+  if (!base_buf || fdt_check_full(base_buf, blob_len)) {
     fprintf(stderr, "Can not load base file: %s\n", base_filename);
     goto end;
   }
 
   size_t overlay_len;
   overlay_buf = load_file(overlay_filename, &overlay_len);
-  if (!overlay_buf) {
+  if (!overlay_buf || fdt_check_full(overlay_buf, overlay_len)) {
     fprintf(stderr, "Can not load overlay file: %s\n", overlay_filename);
     goto end;
   }
@@ -54,6 +54,11 @@
   new_blob = ufdt_apply_overlay(blob, blob_len, overlay_buf, overlay_len);
   clock_t end = clock();
 
+  if (!new_blob) {
+    fprintf(stderr, "ufdt_apply_overlay() returned null: bad input?\n");
+    goto end;
+  }
+
   if (write_fdt_to_file(out_filename, new_blob) != 0) {
     fprintf(stderr, "Write file error: %s\n", out_filename);
     goto end;
diff --git a/tests/src/ufdt_verify_overlay_app.cpp b/tests/src/ufdt_verify_overlay_app.cpp
index ff48c1a..7b66f9b 100644
--- a/tests/src/ufdt_verify_overlay_app.cpp
+++ b/tests/src/ufdt_verify_overlay_app.cpp
@@ -98,11 +98,7 @@
     }
 
     const char *final_file = argv[1];
-    char** overlay_file_names = new char*[argc - 2];
-
-    for(int argv_idx = 2; argv_idx < argc; argv_idx++) {
-        overlay_file_names[argv_idx - 2] = argv[argv_idx];
-    }
+    char **overlay_file_names = &argv[2];
     int ret = verify_overlay_files(final_file, overlay_file_names, argc - 2);
 
     return ret == 0 ? ret : 1;
diff --git a/tests/verifyDTBO.sh b/tests/verifyDTBO.sh
index d1a4366..7c3dbfd 100755
--- a/tests/verifyDTBO.sh
+++ b/tests/verifyDTBO.sh
@@ -24,11 +24,15 @@
 adb pull /sys/firmware/fdt final_dt > /dev/null
 
 #decompile the DTBO image
-mkdtimg_path="${ANDROID_HOST_BIN_LOCATION}/mkdtboimg.py"
+mkdtimg_path="${ANDROID_HOST_BIN_LOCATION}/mkdtboimg"
 $mkdtimg_path dump dtbo.img -b dumped_dtbo > /dev/null
 
-#Get the index of the overlay applied from the kernel command line
-overlay_idx=$(adb shell cat /proc/cmdline | grep -o "androidboot.dtbo_idx=[^ ]*" | cut -d "=" -f 2)
+#Get the index of the overlay applied. Try bootconfig first, then cmdline.
+overlay_idx=$(adb shell cat /proc/bootconfig \
+    | grep 'androidboot.dtbo_idx = .*$' | cut -d "=" -f 2 | sed 's/[ \\\"]//g')
+if [[ ! $overlay_idx =~ [0-9]+ ]]; then
+  overlay_idx=$(adb shell cat /proc/cmdline | grep -o "androidboot.dtbo_idx=[^ ]*" | cut -d "=" -f 2)
+fi
 arg=""
 for idx in ${overlay_idx//,/ }
 do
diff --git a/ufdt_convert.c b/ufdt_convert.c
index 5c69f1f..8147f5b 100644
--- a/ufdt_convert.c
+++ b/ufdt_convert.c
@@ -40,6 +40,8 @@
   res_ufdt->mem_size_fdtps = DEFAULT_MEM_SIZE_FDTPS;
   res_ufdt->num_used_fdtps = (fdtp != NULL ? 1 : 0);
   res_ufdt->root = NULL;
+  res_ufdt->phandle_table.data = NULL;
+  res_ufdt->phandle_table.len = 0;
 
   return res_ufdt;
 
@@ -149,7 +151,13 @@
 
       do {
         cur_fdt_tag_offset = *next_fdt_tag_offset;
+
         tag = fdt_next_tag(fdtp, cur_fdt_tag_offset, next_fdt_tag_offset);
+        if (tag == FDT_END) {
+          dto_error("failed to get next tag\n");
+          break;
+        }
+
         child_node = fdt_to_ufdt_tree(fdtp, cur_fdt_tag_offset,
                                       next_fdt_tag_offset, tag, pool);
         ufdt_node_add_child(res, child_node);
@@ -196,13 +204,21 @@
     const char *alias_path =
         ufdt_node_get_fdt_prop_data(aliases_node, &path_len);
 
-    if (alias_path == NULL) {
-      dto_error("Failed to find alias %s\n", path);
+    if (alias_path == NULL || path_len == 0) {
+      dto_error("Failed to find valid alias %s\n", path);
+      return NULL;
+    }
+
+    /* property data must be a nul terminated string */
+    int alias_len = strnlen(alias_path, path_len);
+
+    if (alias_len != path_len - 1 || alias_len == 0) {
+      dto_error("Invalid alias for %s\n", path);
       return NULL;
     }
 
     struct ufdt_node *target_node =
-        ufdt_node_get_node_by_path_len(tree->root, alias_path, path_len);
+        ufdt_node_get_node_by_path_len(tree->root, alias_path, alias_len);
 
     return ufdt_node_get_node_by_path_len(target_node, next_slash,
                                           end - next_slash);
@@ -250,14 +266,14 @@
                                     struct ufdt_phandle_table_entry *data,
                                     int *cur) {
   if (node == NULL || ufdt_node_tag(node) != FDT_BEGIN_NODE) return;
-  int ph = ufdt_node_get_phandle(node);
+  uint32_t ph = ufdt_node_get_phandle(node);
   if (ph > 0) {
     data[*cur].phandle = ph;
     data[*cur].node = node;
     (*cur)++;
   }
   struct ufdt_node **it;
-  for_each_node(it, node) set_phandle_table_entry(*it, data, cur);
+  for_each_child(it, node) set_phandle_table_entry(*it, data, cur);
   return;
 }
 
@@ -292,9 +308,16 @@
     return ufdt_construct(NULL, pool);
   }
 
-  struct ufdt *res_tree = ufdt_construct(fdtp, pool);
   int end_offset;
   int start_tag = fdt_next_tag(fdtp, start_offset, &end_offset);
+
+  if (start_tag != FDT_BEGIN_NODE) {
+    return ufdt_construct(NULL, pool);
+  }
+
+  struct ufdt *res_tree = ufdt_construct(fdtp, pool);
+  if (res_tree == NULL) return NULL;
+
   res_tree->root =
       fdt_to_ufdt_tree(fdtp, start_offset, &end_offset, start_tag, pool);
 
@@ -329,10 +352,16 @@
 
   int data_len = 0;
   void *data = ufdt_node_get_fdt_prop_data(&prop_node->parent, &data_len);
-  int aligned_data_len = (data_len + (FDT_TAGSIZE - 1)) & ~(FDT_TAGSIZE - 1);
+  if (!data) {
+    dto_error("Failed to get property data.\n");
+    return -1;
+  }
 
-  int new_propoff = fdt_size_dt_struct(fdtp);
-  int new_prop_size = sizeof(struct fdt_property) + aligned_data_len;
+  unsigned int aligned_data_len =
+      ((unsigned int)data_len + (FDT_TAGSIZE - 1u)) & ~(FDT_TAGSIZE - 1u);
+
+  unsigned int new_propoff = fdt_size_dt_struct(fdtp);
+  unsigned int new_prop_size = sizeof(struct fdt_property) + aligned_data_len;
   struct fdt_property *new_prop =
       (struct fdt_property *)((char *)fdtp + fdt_off_dt_struct(fdtp) +
                               new_propoff);
@@ -415,6 +444,7 @@
 
 int ufdt_to_fdt(const struct ufdt *tree, void *buf, int buf_size) {
   if (tree->num_used_fdtps == 0) return -1;
+  if (tree->root == NULL) return -1;
 
   int err;
   err = fdt_create(buf, buf_size);
@@ -440,10 +470,12 @@
   if (err < 0) return -1;
 
   err = _ufdt_output_node_to_fdt(tree, buf, tree->root, &dict);
-  if (err < 0) return -1;
 
+  // Ensure property_dict is freed, even on error path.
   ufdt_prop_dict_destruct(&dict);
 
+  if (err < 0) return -1;
+
   err = fdt_finish(buf);
   if (err < 0) return -1;
 
diff --git a/ufdt_node.c b/ufdt_node.c
index 309c674..3568ad7 100644
--- a/ufdt_node.c
+++ b/ufdt_node.c
@@ -29,6 +29,14 @@
     res->parent.fdt_tag_ptr = fdt_tag_ptr;
     res->parent.sibling = NULL;
     res->name = fdt_string(fdtp, fdt32_to_cpu(prop->nameoff));
+
+    /* fdt_string() may fail */
+    if (!res->name) {
+      dto_error("Failed to get property name\n");
+      ufdt_node_pool_free(pool, res);
+      res = NULL;
+    }
+
     return (struct ufdt_node *)res;
   } else {
     struct ufdt_node_fdt_node *res = (struct ufdt_node_fdt_node *)buf;
@@ -118,7 +126,13 @@
   }
   const struct fdt_property *prop = (struct fdt_property *)node->fdt_tag_ptr;
   if (out_len != NULL) {
-    *out_len = fdt32_to_cpu(prop->len);
+    uint32_t prop_len = fdt32_to_cpu(prop->len);
+
+    if (prop_len > INT_MAX) {
+      return NULL;
+    }
+
+    *out_len = prop_len;
   }
   return (char *)prop->data;
 }
diff --git a/ufdt_overlay.c b/ufdt_overlay.c
index c432cd4..69467a6 100644
--- a/ufdt_overlay.c
+++ b/ufdt_overlay.c
@@ -163,7 +163,12 @@
 
   prop_offset = dto_strtoul(offset_ptr, &end_ptr, 10 /* base */);
   if (*end_ptr != '\0') {
-    dto_error("'%s' is not valid number\n", offset_ptr);
+    dto_error("'%s' is not a valid number\n", offset_ptr);
+    goto fail;
+  }
+
+  if (prop_offset < 0) {
+    dto_error("'%s' is not a valid offset\n", offset_ptr);
     goto fail;
   }
 
@@ -183,7 +188,8 @@
   /*
    * Note that prop_offset is the offset inside the property data.
    */
-  if (prop_len < prop_offset + (int)sizeof(uint32_t)) {
+  if (prop_len < (int)sizeof(uint32_t) ||
+      prop_offset > prop_len - (int)sizeof(uint32_t)) {
     dto_error("%s: property length is too small for fixup\n", path);
     goto fail;
   }
@@ -448,12 +454,14 @@
   int len = 0;
   prop_offsets_ptr = ufdt_node_get_fdt_prop_data(local_fixup_prop_node, &len);
 
+  if (prop_offsets_ptr == NULL || len % sizeof(fdt32_t) != 0) return -1;
+
   char *prop_data;
   int target_length = 0;
 
   prop_data = ufdt_node_get_fdt_prop_data(target_prop_node, &target_length);
 
-  if (prop_offsets_ptr == NULL || prop_data == NULL) return -1;
+  if (prop_data == NULL) return -1;
 
   int i;
   for (i = 0; i < len; i += sizeof(fdt32_t)) {
@@ -609,11 +617,11 @@
   err = fdt_check_header(pHeader);
   if (err < 0) {
     if (err == -FDT_ERR_BADVERSION) {
-      dto_error("incompatible blob version: %d, should be: %d",
+      dto_error("incompatible blob version: %d, should be: %d\n",
                 fdt_version(pHeader), FDT_LAST_SUPPORTED_VERSION);
 
     } else {
-      dto_error("error validating blob: %s", fdt_strerror(err));
+      dto_error("error validating blob: %s\n", fdt_strerror(err));
     }
     return NULL;
   }
diff --git a/ufdt_prop_dict.c b/ufdt_prop_dict.c
index 2d412cd..fbd346a 100644
--- a/ufdt_prop_dict.c
+++ b/ufdt_prop_dict.c
@@ -29,14 +29,14 @@
 #define DICT_LIMIT_DEN 3
 
 static int _ufdt_prop_dict_str_hash(const char *str) {
-  int res = 0;
+  unsigned int res = 0;
 
   for (; *str != '\0'; str++) {
     res *= HASH_BASE;
     res += *str;
   }
 
-  return res;
+  return (int)res;
 }
 
 static const struct fdt_property **_ufdt_prop_dict_find_index_by_name(
@@ -52,7 +52,7 @@
     if (prop == NULL) return prop_ptr;
 
     const char *prop_name = fdt_string(dict->fdtp, fdt32_to_cpu(prop->nameoff));
-    if (dto_strcmp(prop_name, name) == 0) return prop_ptr;
+    if (prop_name != NULL && dto_strcmp(prop_name, name) == 0) return prop_ptr;
 
     idx = (idx + 1) & (size - 1);
   }
@@ -62,6 +62,7 @@
 static const struct fdt_property **_ufdt_prop_dict_find_index(
     struct ufdt_prop_dict *dict, const struct fdt_property *prop) {
   const char *name = fdt_string(dict->fdtp, fdt32_to_cpu(prop->nameoff));
+  if (name == NULL) return NULL;
 
   return _ufdt_prop_dict_find_index_by_name(dict, name);
 }
diff --git a/utils/src/Android.bp b/utils/src/Android.bp
index 997121b..bd79167 100644
--- a/utils/src/Android.bp
+++ b/utils/src/Android.bp
@@ -55,7 +55,7 @@
 
 //##################################################
 python_binary_host {
-    name: "mkdtboimg.py",
+    name: "mkdtboimg",
     main: "mkdtboimg.py",
     srcs: ["mkdtboimg.py"],
     version: {
@@ -64,10 +64,3 @@
         },
     },
 }
-
-//##################################################
-// TODO(b/153848038): Remove once we can use python binary as data for java_test_host
-filegroup {
-    name: "mkdtboimg",
-    srcs: ["mkdtboimg.py"],
-}
diff --git a/utils/src/mkdtboimg.py b/utils/src/mkdtboimg.py
index 5eeb5ea..2634c76 100755
--- a/utils/src/mkdtboimg.py
+++ b/utils/src/mkdtboimg.py
@@ -1018,7 +1018,7 @@
 def main():
     """Main entry point for mkdtboimg."""
 
-    parser = argparse.ArgumentParser(prog='mkdtboimg.py')
+    parser = argparse.ArgumentParser()
 
     subparser = parser.add_subparsers(title='subcommand',
                                       description='Valid subcommands')
diff --git a/utils/src/mkdtimg_dump.c b/utils/src/mkdtimg_dump.c
index b28e3cf..14d4d5a 100644
--- a/utils/src/mkdtimg_dump.c
+++ b/utils/src/mkdtimg_dump.c
@@ -15,15 +15,14 @@
  */
 
 #include <getopt.h>
+#include <inttypes.h>
+#include <stdint.h>
 #include <stdio.h>
 #include <stdlib.h>
-#include <stdint.h>
-
-#include "libacpi.h"
-#include "libfdt.h"
 
 #include "dt_table.h"
-
+#include "libacpi.h"
+#include "libfdt.h"
 
 struct dump_params {
   const char *img_filename;
@@ -41,6 +40,10 @@
   void *fdt = NULL;
 
   fdt = malloc(dt_size);
+  if (fdt == NULL) {
+    fprintf(stderr, "malloc(%" PRIu32 ") failed.\n", dt_size);
+    return NULL;
+  }
 
   fseek(img_fp, dt_offset, SEEK_SET);
   if (fread(fdt, dt_size, 1, img_fp) == 0) {
@@ -189,16 +192,18 @@
     uint32_t dt_offset = fdt32_to_cpu(entry.dt_offset);
     if (dt_size > 0 && dt_offset > 0) {
       void *fdt = read_fdt_from_image(img_fp, dt_offset, dt_size);
-      output_fdt_info(out_fp, fdt, get_fdt_size);
+      if (fdt) {
+        output_fdt_info(out_fp, fdt, get_fdt_size);
 
-      if (params->out_dtb_filename != NULL) {
-        char filename[256];
-        snprintf(filename, sizeof(filename), "%s.%d",
-                 params->out_dtb_filename, i);
-        write_fdt_to_file(filename, fdt, get_fdt_size);
+        if (params->out_dtb_filename != NULL) {
+          char filename[256];
+          snprintf(filename, sizeof(filename), "%s.%d",
+                   params->out_dtb_filename, i);
+          write_fdt_to_file(filename, fdt, get_fdt_size);
+        }
+
+        free_fdt(fdt);
       }
-
-      free_fdt(fdt);
     }
 
     entry_offset += entry_size;