tCheck for collision before unpacking - pm - barely a pack manager
(HTM) git clone git://z3bra.org/pm
(DIR) Log
(DIR) Files
(DIR) Refs
(DIR) README
(DIR) LICENSE
---
(DIR) commit e6ba7b3f0f832855bd1ea7323644fcf0c9d39258
(DIR) parent e7c528b75ba86304b270abc8181868ed3f5efd32
(HTM) Author: z3bra <willyatmailoodotorg>
Date: Tue, 12 Jan 2016 10:27:00 +0100
Check for collision before unpacking
Diffstat:
M pm.c | 50 ++++++++++++++++++++++++++-----
1 file changed, 43 insertions(+), 7 deletions(-)
---
(DIR) diff --git a/pm.c b/pm.c
t@@ -51,6 +51,7 @@ char *base_name(char *path);
struct pack *pack_load(char *path);
void pack_free(struct pack *p);
+int inspect_collision(char *rootfs, struct pack *p);
int inspect_system(int fd, char *datadir);
int inspect_files(int fd, char *datadir, char *packname);
int inspect(char *datadir, char *packname);
t@@ -134,6 +135,41 @@ base_name(char *path)
/*
+ * Check for collisions between the filesystem and the tarball
+ */
+int
+inspect_collision(char *rootfs, struct pack *p)
+{
+ int r = 0;
+ struct stat st;
+ struct archive *a;
+ struct archive_entry *e;
+
+ a = archive_read_new();
+ archive_read_support_filter_bzip2(a);
+ archive_read_support_format_tar(a);
+
+ r = archive_read_open_filename(a, p->path, 0);
+ if (r != ARCHIVE_OK)
+ return -1;
+
+ chdir(rootfs);
+ while (archive_read_next_header(a, &e) == ARCHIVE_OK) {
+ if (stat(archive_entry_pathname(e), &st) == 0 && !S_ISDIR(st.st_mode)) {
+ fprintf(stderr, "%s: File exists\n", archive_entry_pathname(e));
+ r = -1;
+ break;
+ }
+ archive_read_data_skip(a);
+ }
+
+ archive_read_free(a);
+
+ return r;
+}
+
+
+/*
* Write files installed by a pack to a file descriptor
*/
int
t@@ -273,19 +309,16 @@ write_entry(struct archive *a, struct archive *w)
}
+/*
+ * Extract a tarball to the given directory
+ */
int
unpack(struct archive *a, char *meta, int mask)
{
int r, fd;
- struct stat st;
struct archive *w;
struct archive_entry *e;
- if (stat(meta, &st) == 0 && (mask & ARCHIVE_EXTRACT_NO_OVERWRITE)) {
- fprintf(stderr, "%s: File exists\n", meta);
- return -1;
- }
-
if ((fd = open(meta, O_WRONLY|O_CREAT|O_TRUNC, 0644)) < 0) {
perror(meta);
return -1;
t@@ -337,8 +370,11 @@ install(char *rootfs, char *datadir, struct pack *p, int overwrite)
int mask = ARCHIVE_EXTRACT_PERM
|ARCHIVE_EXTRACT_SECURE_NODOTDOT;
- if (overwrite == 0)
+ if (overwrite == 0) {
+ if (inspect_collision(rootfs, p) != 0)
+ return -1;
mask |= ARCHIVE_EXTRACT_NO_OVERWRITE;
+ }
/*
* ensure we can chdir to the rootfs and write metadata