From b3f695b45cdd72bbcd86936d4630f9fd5c710e3e Mon Sep 17 00:00:00 2001 From: Tim Kientzle Date: Sun, 27 Jun 2004 23:36:39 +0000 Subject: [PATCH] Refuse to extract an entry from an archive on top of the archive being read. (This is the converse of the "don't add an archive to itself".) --- lib/libarchive/archive_read_open_fd.c | 13 +++++++++++-- lib/libarchive/archive_read_open_file.c | 11 +++++++++++ lib/libarchive/archive_read_open_filename.c | 11 +++++++++++ lib/libarchive/archive_write.c | 2 +- 4 files changed, 34 insertions(+), 3 deletions(-) diff --git a/lib/libarchive/archive_read_open_fd.c b/lib/libarchive/archive_read_open_fd.c index cab1f9f4eed5..e3b2527a5978 100644 --- a/lib/libarchive/archive_read_open_fd.c +++ b/lib/libarchive/archive_read_open_fd.c @@ -27,12 +27,14 @@ #include "archive_platform.h" __FBSDID("$FreeBSD$"); +#include #include #include #include #include #include "archive.h" +#include "archive_private.h" struct read_fd_data { int fd; @@ -63,9 +65,16 @@ archive_read_open_fd(struct archive *a, int fd, size_t block_size) static int file_open(struct archive *a, void *client_data) { - (void)client_data; /* UNUSED */ - (void)a; /* UNUSED */ + struct read_fd_data *mine = client_data; + struct stat st; + if (fstat(mine->fd, &st) != 0) { + archive_set_error(a, errno, "Can't stat fd %d", mine->fd); + return (ARCHIVE_FATAL); + } + + a->skip_file_dev = st.st_dev; + a->skip_file_ino = st.st_ino; return (ARCHIVE_OK); } diff --git a/lib/libarchive/archive_read_open_file.c b/lib/libarchive/archive_read_open_file.c index fa30bbbc1dc9..54e1239b5b57 100644 --- a/lib/libarchive/archive_read_open_file.c +++ b/lib/libarchive/archive_read_open_file.c @@ -27,6 +27,7 @@ #include "archive_platform.h" __FBSDID("$FreeBSD$"); +#include #include #include #include @@ -34,6 +35,7 @@ __FBSDID("$FreeBSD$"); #include #include "archive.h" +#include "archive_private.h" struct read_file_data { int fd; @@ -77,6 +79,7 @@ static int file_open(struct archive *a, void *client_data) { struct read_file_data *mine = client_data; + struct stat st; mine->buffer = malloc(mine->block_size); if (*mine->filename != 0) @@ -88,6 +91,14 @@ file_open(struct archive *a, void *client_data) mine->filename); return (ARCHIVE_FATAL); } + if (fstat(mine->fd, &st) == 0) { + a->skip_file_dev = st.st_dev; + a->skip_file_ino = st.st_ino; + } else { + archive_set_error(a, errno, "Can't stat '%s'", + mine->filename); + return (ARCHIVE_FATAL); + } return (0); } diff --git a/lib/libarchive/archive_read_open_filename.c b/lib/libarchive/archive_read_open_filename.c index fa30bbbc1dc9..54e1239b5b57 100644 --- a/lib/libarchive/archive_read_open_filename.c +++ b/lib/libarchive/archive_read_open_filename.c @@ -27,6 +27,7 @@ #include "archive_platform.h" __FBSDID("$FreeBSD$"); +#include #include #include #include @@ -34,6 +35,7 @@ __FBSDID("$FreeBSD$"); #include #include "archive.h" +#include "archive_private.h" struct read_file_data { int fd; @@ -77,6 +79,7 @@ static int file_open(struct archive *a, void *client_data) { struct read_file_data *mine = client_data; + struct stat st; mine->buffer = malloc(mine->block_size); if (*mine->filename != 0) @@ -88,6 +91,14 @@ file_open(struct archive *a, void *client_data) mine->filename); return (ARCHIVE_FATAL); } + if (fstat(mine->fd, &st) == 0) { + a->skip_file_dev = st.st_dev; + a->skip_file_ino = st.st_ino; + } else { + archive_set_error(a, errno, "Can't stat '%s'", + mine->filename); + return (ARCHIVE_FATAL); + } return (0); } diff --git a/lib/libarchive/archive_write.c b/lib/libarchive/archive_write.c index f910f145f569..eded384b758a 100644 --- a/lib/libarchive/archive_write.c +++ b/lib/libarchive/archive_write.c @@ -189,7 +189,7 @@ archive_write_header(struct archive *a, struct archive_entry *entry) if (archive_entry_dev(entry) == a->skip_file_dev && archive_entry_ino(entry) == a->skip_file_ino) { - archive_set_error(a, 0, "Can't add archive to itself."); + archive_set_error(a, 0, "Can't add archive to itself"); return (ARCHIVE_WARN); }