summaryrefslogtreecommitdiff
path: root/lib/tar/read_header.c
diff options
context:
space:
mode:
authorDavid Oberhollenzer <david.oberhollenzer@sigma-star.at>2019-07-25 23:35:15 +0200
committerDavid Oberhollenzer <david.oberhollenzer@sigma-star.at>2019-07-25 23:35:15 +0200
commitba82a3812d39acf6c865478f72d7e68838c14f69 (patch)
tree4e558c02e997e97b41b1b353cf15f67c660b968c /lib/tar/read_header.c
parent935131744634f9a29e5d53a06a411dbb455cb1ae (diff)
Enforce reasonable upper and low bounds on the size of tar headers
Since they are read directly into memory, blindly allocating the size from the tar ball is probably a bad idea. Signed-off-by: David Oberhollenzer <david.oberhollenzer@sigma-star.at>
Diffstat (limited to 'lib/tar/read_header.c')
-rw-r--r--lib/tar/read_header.c18
1 files changed, 18 insertions, 0 deletions
diff --git a/lib/tar/read_header.c b/lib/tar/read_header.c
index a083c2f..58e0230 100644
--- a/lib/tar/read_header.c
+++ b/lib/tar/read_header.c
@@ -386,6 +386,8 @@ int read_header(int fd, tar_header_decoded_t *out)
case TAR_TYPE_GNU_SLINK:
if (read_number(hdr.size, sizeof(hdr.size), &pax_size))
goto fail;
+ if (pax_size < 1 || pax_size > TAR_MAX_SYMLINK_LEN)
+ goto fail_slink_len;
free(out->link_target);
out->link_target = record_to_memory(fd, pax_size);
if (out->link_target == NULL)
@@ -395,6 +397,8 @@ int read_header(int fd, tar_header_decoded_t *out)
case TAR_TYPE_GNU_PATH:
if (read_number(hdr.size, sizeof(hdr.size), &pax_size))
goto fail;
+ if (pax_size < 1 || pax_size > TAR_MAX_PATH_LEN)
+ goto fail_path_len;
free(out->name);
out->name = record_to_memory(fd, pax_size);
if (out->name == NULL)
@@ -405,6 +409,8 @@ int read_header(int fd, tar_header_decoded_t *out)
clear_header(out);
if (read_number(hdr.size, sizeof(hdr.size), &pax_size))
goto fail;
+ if (pax_size < 1 || pax_size > TAR_MAX_PAX_LEN)
+ goto fail_pax_len;
set_by_pax = 0;
if (read_pax_header(fd, pax_size, &set_by_pax, out))
goto fail;
@@ -436,6 +442,18 @@ int read_header(int fd, tar_header_decoded_t *out)
out_eof:
clear_header(out);
return 1;
+fail_slink_len:
+ fprintf(stderr, "rejecting GNU symlink header with size %zu\n",
+ pax_size);
+ goto fail;
+fail_path_len:
+ fprintf(stderr, "rejecting GNU long path header with size %zu\n",
+ pax_size);
+ goto fail;
+fail_pax_len:
+ fprintf(stderr, "rejecting PAX header with size %zu\n",
+ pax_size);
+ goto fail;
fail_magic:
fputs("input is not a ustar tar archive!\n", stderr);
goto fail;