| [5c5752c] | 1 | Submitted By: Ken Moffat <ken at linuxfromscratch dot org> | 
|---|
|  | 2 | Date: 2006-04-14 | 
|---|
|  | 3 | Initial Package Version: 1.15.1 | 
|---|
|  | 4 | Origin: gentoo, backported from CVS, rediffed to apply with -p1 | 
|---|
|  | 5 | Description: addresses vulnerability CVE-2006-0300 | 
|---|
|  | 6 |  | 
|---|
|  | 7 | diff -Naurp tar-1.15.1-vanilla/src/xheader.c tar-1.15.1/src/xheader.c | 
|---|
|  | 8 | --- tar-1.15.1-vanilla/src/xheader.c    2004-09-06 12:31:14.000000000 +0100 | 
|---|
|  | 9 | +++ tar-1.15.1/src/xheader.c    2006-04-14 16:26:26.000000000 +0100 | 
|---|
|  | 10 | @@ -783,6 +783,32 @@ code_num (uintmax_t value, char const *k | 
|---|
|  | 11 | xheader_print (xhdr, keyword, sbuf); | 
|---|
|  | 12 | } | 
|---|
|  | 13 |  | 
|---|
|  | 14 | +static bool | 
|---|
|  | 15 | +decode_num (uintmax_t *num, char const *arg, uintmax_t maxval, | 
|---|
|  | 16 | +        char const *keyword) | 
|---|
|  | 17 | +{ | 
|---|
|  | 18 | +  uintmax_t u; | 
|---|
|  | 19 | +  char *arg_lim; | 
|---|
|  | 20 | + | 
|---|
|  | 21 | +  if (! (ISDIGIT (*arg) | 
|---|
|  | 22 | +     && (errno = 0, u = strtoumax (arg, &arg_lim, 10), !*arg_lim))) | 
|---|
|  | 23 | +    { | 
|---|
|  | 24 | +      ERROR ((0, 0, _("Malformed extended header: invalid %s=%s"), | 
|---|
|  | 25 | +          keyword, arg)); | 
|---|
|  | 26 | +      return false; | 
|---|
|  | 27 | +    } | 
|---|
|  | 28 | + | 
|---|
|  | 29 | +  if (! (u <= maxval && errno != ERANGE)) | 
|---|
|  | 30 | +    { | 
|---|
|  | 31 | +      ERROR ((0, 0, _("Extended header %s=%s is out of range"), | 
|---|
|  | 32 | +        keyword, arg)); | 
|---|
|  | 33 | +      return false; | 
|---|
|  | 34 | +    } | 
|---|
|  | 35 | + | 
|---|
|  | 36 | +  *num = u; | 
|---|
|  | 37 | +  return true; | 
|---|
|  | 38 | +} | 
|---|
|  | 39 | + | 
|---|
|  | 40 | static void | 
|---|
|  | 41 | dummy_coder (struct tar_stat_info const *st __attribute__ ((unused)), | 
|---|
|  | 42 | char const *keyword __attribute__ ((unused)), | 
|---|
|  | 43 | @@ -821,7 +847,7 @@ static void | 
|---|
|  | 44 | gid_decoder (struct tar_stat_info *st, char const *arg) | 
|---|
|  | 45 | { | 
|---|
|  | 46 | uintmax_t u; | 
|---|
|  | 47 | -  if (xstrtoumax (arg, NULL, 10, &u, "") == LONGINT_OK) | 
|---|
|  | 48 | +  if (decode_num (&u, arg, TYPE_MAXIMUM (gid_t), "gid")) | 
|---|
|  | 49 | st->stat.st_gid = u; | 
|---|
|  | 50 | } | 
|---|
|  | 51 |  | 
|---|
|  | 52 | @@ -903,7 +929,7 @@ static void | 
|---|
|  | 53 | size_decoder (struct tar_stat_info *st, char const *arg) | 
|---|
|  | 54 | { | 
|---|
|  | 55 | uintmax_t u; | 
|---|
|  | 56 | -  if (xstrtoumax (arg, NULL, 10, &u, "") == LONGINT_OK) | 
|---|
|  | 57 | +  if (decode_num (&u, arg, TYPE_MAXIMUM (off_t), "size")) | 
|---|
|  | 58 | st->archive_file_size = st->stat.st_size = u; | 
|---|
|  | 59 | } | 
|---|
|  | 60 |  | 
|---|
|  | 61 | @@ -918,7 +944,7 @@ static void | 
|---|
|  | 62 | uid_decoder (struct tar_stat_info *st, char const *arg) | 
|---|
|  | 63 | { | 
|---|
|  | 64 | uintmax_t u; | 
|---|
|  | 65 | -  if (xstrtoumax (arg, NULL, 10, &u, "") == LONGINT_OK) | 
|---|
|  | 66 | +  if (decode_num (&u, arg, TYPE_MAXIMUM (uid_t), "uid")) | 
|---|
|  | 67 | st->stat.st_uid = u; | 
|---|
|  | 68 | } | 
|---|
|  | 69 |  | 
|---|
|  | 70 | @@ -946,7 +972,7 @@ static void | 
|---|
|  | 71 | sparse_size_decoder (struct tar_stat_info *st, char const *arg) | 
|---|
|  | 72 | { | 
|---|
|  | 73 | uintmax_t u; | 
|---|
|  | 74 | -  if (xstrtoumax (arg, NULL, 10, &u, "") == LONGINT_OK) | 
|---|
|  | 75 | +  if (decode_num (&u, arg, TYPE_MAXIMUM (off_t), "GNU.sparse.size")) | 
|---|
|  | 76 | st->stat.st_size = u; | 
|---|
|  | 77 | } | 
|---|
|  | 78 |  | 
|---|
|  | 79 | @@ -962,10 +988,10 @@ static void | 
|---|
|  | 80 | sparse_numblocks_decoder (struct tar_stat_info *st, char const *arg) | 
|---|
|  | 81 | { | 
|---|
|  | 82 | uintmax_t u; | 
|---|
|  | 83 | -  if (xstrtoumax (arg, NULL, 10, &u, "") == LONGINT_OK) | 
|---|
|  | 84 | +  if (decode_num (&u, arg, SIZE_MAX, "GNU.sparse.numblocks")) | 
|---|
|  | 85 | { | 
|---|
|  | 86 | st->sparse_map_size = u; | 
|---|
|  | 87 | -      st->sparse_map = calloc(st->sparse_map_size, sizeof(st->sparse_map[0])); | 
|---|
|  | 88 | +      st->sparse_map = xcalloc (u, sizeof st->sparse_map[0]); | 
|---|
|  | 89 | st->sparse_map_avail = 0; | 
|---|
|  | 90 | } | 
|---|
|  | 91 | } | 
|---|
|  | 92 | @@ -982,8 +1008,14 @@ static void | 
|---|
|  | 93 | sparse_offset_decoder (struct tar_stat_info *st, char const *arg) | 
|---|
|  | 94 | { | 
|---|
|  | 95 | uintmax_t u; | 
|---|
|  | 96 | -  if (xstrtoumax (arg, NULL, 10, &u, "") == LONGINT_OK) | 
|---|
|  | 97 | +  if (decode_num (&u, arg, TYPE_MAXIMUM (off_t), "GNU.sparse.offset")) | 
|---|
|  | 98 | +    { | 
|---|
|  | 99 | +      if (st->sparse_map_avail < st->sparse_map_size) | 
|---|
|  | 100 | st->sparse_map[st->sparse_map_avail].offset = u; | 
|---|
|  | 101 | +      else | 
|---|
|  | 102 | +    ERROR ((0, 0, _("Malformed extended header: excess %s=%s"), | 
|---|
|  | 103 | +        "GNU.sparse.offset", arg)); | 
|---|
|  | 104 | +    } | 
|---|
|  | 105 | } | 
|---|
|  | 106 |  | 
|---|
|  | 107 | static void | 
|---|
|  | 108 | @@ -998,15 +1030,13 @@ static void | 
|---|
|  | 109 | sparse_numbytes_decoder (struct tar_stat_info *st, char const *arg) | 
|---|
|  | 110 | { | 
|---|
|  | 111 | uintmax_t u; | 
|---|
|  | 112 | -  if (xstrtoumax (arg, NULL, 10, &u, "") == LONGINT_OK) | 
|---|
|  | 113 | +  if (decode_num (&u, arg, SIZE_MAX, "GNU.sparse.numbytes")) | 
|---|
|  | 114 | { | 
|---|
|  | 115 | if (st->sparse_map_avail == st->sparse_map_size) | 
|---|
|  | 116 | -       { | 
|---|
|  | 117 | -         st->sparse_map_size *= 2; | 
|---|
|  | 118 | -         st->sparse_map = xrealloc (st->sparse_map, | 
|---|
|  | 119 | -                                    st->sparse_map_size | 
|---|
|  | 120 | -                                    * sizeof st->sparse_map[0]); | 
|---|
|  | 121 | -       } | 
|---|
|  | 122 | +        st->sparse_map = x2nrealloc (st->sparse_map, | 
|---|
|  | 123 | +                                    &st->sparse_map_size, | 
|---|
|  | 124 | +                                    sizeof st->sparse_map[0]); | 
|---|
|  | 125 | + | 
|---|
|  | 126 | st->sparse_map[st->sparse_map_avail++].numbytes = u; | 
|---|
|  | 127 | } | 
|---|
|  | 128 | } | 
|---|