cherry-pick.FILE5_30-19-g7605984c.although-i-can-t-reproduce-it-oss-fuzz-complains-about-is-tar.patch 2.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. Subject: Although I can't reproduce it, oss-fuzz complains about is_tar
  2. Origin: FILE5_30-19-g7605984c
  3. Upstream-Author: Christos Zoulas <christos@zoulas.com>
  4. Date: Fri Mar 17 20:45:01 2017 +0000
  5. Although I can't reproduce it, oss-fuzz complains about is_tar. So rewrite
  6. it to make it more obvious what's going on.
  7. --- a/src/is_tar.c
  8. +++ b/src/is_tar.c
  9. @@ -51,7 +51,7 @@
  10. #define isodigit(c) ( ((c) >= '0') && ((c) <= '7') )
  11. private int is_tar(const unsigned char *, size_t);
  12. -private int from_oct(int, const char *); /* Decode octal number */
  13. +private int from_oct(const char *, size_t); /* Decode octal number */
  14. static const char tartype[][32] = {
  15. "tar archive",
  16. @@ -93,31 +93,35 @@
  17. is_tar(const unsigned char *buf, size_t nbytes)
  18. {
  19. const union record *header = (const union record *)(const void *)buf;
  20. - int i;
  21. - int sum, recsum;
  22. - const unsigned char *p;
  23. + size_t i;
  24. + int sum, recsum;
  25. + const unsigned char *p, *ep;
  26. - if (nbytes < sizeof(union record))
  27. + if (nbytes < sizeof(*header))
  28. return 0;
  29. - recsum = from_oct(8, header->header.chksum);
  30. + recsum = from_oct(header->header.chksum, sizeof(header->header.chksum));
  31. sum = 0;
  32. p = header->charptr;
  33. - for (i = sizeof(union record); --i >= 0;)
  34. + ep = header->charptr + sizeof(*header);
  35. + while (p < ep)
  36. sum += *p++;
  37. /* Adjust checksum to count the "chksum" field as blanks. */
  38. - for (i = sizeof(header->header.chksum); --i >= 0;)
  39. + for (i = 0; i < sizeof(header->header.chksum); i++)
  40. sum -= header->header.chksum[i];
  41. - sum += ' ' * sizeof header->header.chksum;
  42. + sum += ' ' * sizeof(header->header.chksum);
  43. if (sum != recsum)
  44. return 0; /* Not a tar archive */
  45. - if (strcmp(header->header.magic, GNUTMAGIC) == 0)
  46. + if (strncmp(header->header.magic, GNUTMAGIC,
  47. + sizeof(header->header.magic)) == 0)
  48. return 3; /* GNU Unix Standard tar archive */
  49. - if (strcmp(header->header.magic, TMAGIC) == 0)
  50. +
  51. + if (strncmp(header->header.magic, TMAGIC,
  52. + sizeof(header->header.magic)) == 0)
  53. return 2; /* Unix Standard tar archive */
  54. return 1; /* Old fashioned tar archive */
  55. @@ -130,19 +134,22 @@
  56. * Result is -1 if the field is invalid (all blank, or non-octal).
  57. */
  58. private int
  59. -from_oct(int digs, const char *where)
  60. +from_oct(const char *where, size_t digs)
  61. {
  62. int value;
  63. + if (digs == 0)
  64. + return -1;
  65. +
  66. while (isspace((unsigned char)*where)) { /* Skip spaces */
  67. where++;
  68. - if (--digs <= 0)
  69. + if (digs-- == 0)
  70. return -1; /* All blank field */
  71. }
  72. value = 0;
  73. while (digs > 0 && isodigit(*where)) { /* Scan til non-octal */
  74. value = (value << 3) | (*where++ - '0');
  75. - --digs;
  76. + digs--;
  77. }
  78. if (digs > 0 && *where && !isspace((unsigned char)*where))