diff options
author | naddy <naddy@FreeBSD.org> | 2006-03-04 22:59:42 +0800 |
---|---|---|
committer | naddy <naddy@FreeBSD.org> | 2006-03-04 22:59:42 +0800 |
commit | 663ddbc7c8c6f2dc7529151ae3963fce80933dce (patch) | |
tree | 1813bf5a6435e9730f77a20b4f6c4fedc0af66bc /archivers | |
parent | 82b358941ccbd68a8423452c1decc4115d37a648 (diff) | |
download | freebsd-ports-gnome-663ddbc7c8c6f2dc7529151ae3963fce80933dce.tar.gz freebsd-ports-gnome-663ddbc7c8c6f2dc7529151ae3963fce80933dce.tar.zst freebsd-ports-gnome-663ddbc7c8c6f2dc7529151ae3963fce80933dce.zip |
Fix a buffer overflow, caused by improper bounds checking of the
PAX extended headers. By tricking a user into processing a specially
crafted tar archive, this could be exploited to execute arbitrary
code with the privileges of the user.
Security: CVE-2006-0300
Approved by: portmgr (erwin)
Obtained from: Ubuntu
Diffstat (limited to 'archivers')
-rw-r--r-- | archivers/gtar/Makefile | 2 | ||||
-rw-r--r-- | archivers/gtar/files/patch-src_xheader.c | 124 |
2 files changed, 125 insertions, 1 deletions
diff --git a/archivers/gtar/Makefile b/archivers/gtar/Makefile index c51a701ad201..f40aaf7b4c05 100644 --- a/archivers/gtar/Makefile +++ b/archivers/gtar/Makefile @@ -7,7 +7,7 @@ PORTNAME= tar PORTVERSION= 1.15.1 -PORTREVISION= 1 +PORTREVISION= 2 CATEGORIES= archivers sysutils MASTER_SITES= ${MASTER_SITE_GNU} MASTER_SITE_SUBDIR= ${PORTNAME} diff --git a/archivers/gtar/files/patch-src_xheader.c b/archivers/gtar/files/patch-src_xheader.c new file mode 100644 index 000000000000..c64261b50cb8 --- /dev/null +++ b/archivers/gtar/files/patch-src_xheader.c @@ -0,0 +1,124 @@ + +$FreeBSD$ + +--- src/xheader.c.orig ++++ src/xheader.c +@@ -783,6 +783,32 @@ + xheader_print (xhdr, keyword, sbuf); + } + ++static bool ++decode_num (uintmax_t *num, char const *arg, uintmax_t maxval, ++ char const *keyword) ++{ ++ uintmax_t u; ++ char *arg_lim; ++ ++ if (! (ISDIGIT (*arg) ++ && (errno = 0, u = strtoumax (arg, &arg_lim, 10), !*arg_lim))) ++ { ++ ERROR ((0, 0, _("Malformed extended header: invalid %s=%s"), ++ keyword, arg)); ++ return false; ++ } ++ ++ if (! (u <= maxval && errno != ERANGE)) ++ { ++ ERROR ((0, 0, _("Extended header %s=%s is out of range"), ++ keyword, arg)); ++ return false; ++ } ++ ++ *num = u; ++ return true; ++} ++ + static void + dummy_coder (struct tar_stat_info const *st __attribute__ ((unused)), + char const *keyword __attribute__ ((unused)), +@@ -821,7 +847,7 @@ + gid_decoder (struct tar_stat_info *st, char const *arg) + { + uintmax_t u; +- if (xstrtoumax (arg, NULL, 10, &u, "") == LONGINT_OK) ++ if (decode_num (&u, arg, TYPE_MAXIMUM (gid_t), "gid")) + st->stat.st_gid = u; + } + +@@ -903,7 +929,7 @@ + size_decoder (struct tar_stat_info *st, char const *arg) + { + uintmax_t u; +- if (xstrtoumax (arg, NULL, 10, &u, "") == LONGINT_OK) ++ if (decode_num (&u, arg, TYPE_MAXIMUM (off_t), "size")) + st->archive_file_size = st->stat.st_size = u; + } + +@@ -918,7 +944,7 @@ + uid_decoder (struct tar_stat_info *st, char const *arg) + { + uintmax_t u; +- if (xstrtoumax (arg, NULL, 10, &u, "") == LONGINT_OK) ++ if (decode_num (&u, arg, TYPE_MAXIMUM (uid_t), "uid")) + st->stat.st_uid = u; + } + +@@ -946,7 +972,7 @@ + sparse_size_decoder (struct tar_stat_info *st, char const *arg) + { + uintmax_t u; +- if (xstrtoumax (arg, NULL, 10, &u, "") == LONGINT_OK) ++ if (decode_num (&u, arg, TYPE_MAXIMUM (off_t), "GNU.sparse.size")) + st->stat.st_size = u; + } + +@@ -962,10 +988,10 @@ + sparse_numblocks_decoder (struct tar_stat_info *st, char const *arg) + { + uintmax_t u; +- if (xstrtoumax (arg, NULL, 10, &u, "") == LONGINT_OK) ++ if (decode_num (&u, arg, SIZE_MAX, "GNU.sparse.numblocks")) + { + st->sparse_map_size = u; +- st->sparse_map = calloc(st->sparse_map_size, sizeof(st->sparse_map[0])); ++ st->sparse_map = xcalloc (u, sizeof st->sparse_map[0]); + st->sparse_map_avail = 0; + } + } +@@ -982,8 +1008,14 @@ + sparse_offset_decoder (struct tar_stat_info *st, char const *arg) + { + uintmax_t u; +- if (xstrtoumax (arg, NULL, 10, &u, "") == LONGINT_OK) ++ if (decode_num (&u, arg, TYPE_MAXIMUM (off_t), "GNU.sparse.offset")) ++ { ++ if (st->sparse_map_avail < st->sparse_map_size) + st->sparse_map[st->sparse_map_avail].offset = u; ++ else ++ ERROR ((0, 0, _("Malformed extended header: excess %s=%s"), ++ "GNU.sparse.offset", arg)); ++ } + } + + static void +@@ -998,15 +1030,13 @@ + sparse_numbytes_decoder (struct tar_stat_info *st, char const *arg) + { + uintmax_t u; +- if (xstrtoumax (arg, NULL, 10, &u, "") == LONGINT_OK) ++ if (decode_num (&u, arg, SIZE_MAX, "GNU.sparse.numbytes")) + { + if (st->sparse_map_avail == st->sparse_map_size) +- { +- st->sparse_map_size *= 2; +- st->sparse_map = xrealloc (st->sparse_map, +- st->sparse_map_size +- * sizeof st->sparse_map[0]); +- } ++ st->sparse_map = x2nrealloc (st->sparse_map, ++ &st->sparse_map_size, ++ sizeof st->sparse_map[0]); ++ + st->sparse_map[st->sparse_map_avail++].numbytes = u; + } + } |