diff options
author | Alexander Larsson <alexl@redhat.com> | 2016-02-19 10:51:37 +0100 |
---|---|---|
committer | Alexander Larsson <alexl@redhat.com> | 2016-02-19 10:51:37 +0100 |
commit | c3dd820adff53837967e62497fa903bc9ff6b167 (patch) | |
tree | 4ac6f6fb0a006df72b1cf598682976802420dc8e | |
parent | 57f9d6c29416b7252085ddf41644b65f783e82f7 (diff) | |
download | bubblewrap-c3dd820adff53837967e62497fa903bc9ff6b167.tar.gz |
When creating file bind mount destinations, check if they already exist
If they already exist as a regular file then we don't need to create
it, which is good because doing so would break if the filesystem
is readonly. I.e. that returns EROFS instead of EEXISTS in that case.
-rw-r--r-- | bubblewrap.c | 4 | ||||
-rw-r--r-- | utils.c | 20 | ||||
-rw-r--r-- | utils.h | 2 |
3 files changed, 24 insertions, 2 deletions
diff --git a/bubblewrap.c b/bubblewrap.c index c016992..cbfe70d 100644 --- a/bubblewrap.c +++ b/bubblewrap.c @@ -550,7 +550,7 @@ setup_newroot (bool unshare_pid, } else { - if (create_file (dest, 0666, NULL) != 0 && errno != EEXIST) + if (ensure_file (dest, 0666) != 0) die_with_error ("Can't create file at %s", op->dest); } @@ -617,7 +617,7 @@ setup_newroot (bool unshare_pid, } else { - if (create_file (dst_path, 0666, NULL) != 0) + if (ensure_file (dst_path, 0666) != 0) die_with_error ("Can't create file at %s", dst_path); } @@ -330,6 +330,26 @@ create_file (const char *path, return res; } +int +ensure_file (const char *path, + mode_t mode) +{ + struct stat buf; + + /* We check this ahead of time, otherwise + the create file will fail in the read-only + case with EROFD instead of EEXIST */ + if (stat (path, &buf) == 0 && + S_ISREG (buf.st_mode)) + return 0; + + if (create_file (path, mode, NULL) != 0 && errno != EEXIST) + return -1; + + return 0; +} + + #define BUFSIZE 8192 /* Sets errno on error (!= 0), ENOSPC on short write */ int @@ -89,6 +89,8 @@ int copy_file (const char *src_path, int create_file (const char *path, mode_t mode, const char *content); +int ensure_file (const char *path, + mode_t mode); int get_file_mode (const char *pathname); int mkdir_with_parents (const char *pathname, int mode, |