Skip to content

Commit

Permalink
Merge pull request #309 from abicky/fix-vulnerability-of-atomic_write…
Browse files Browse the repository at this point in the history
…_cache_file

Ensure that temporary file is used only by one process
  • Loading branch information
burke committed Jul 14, 2020
2 parents cd507c3 + cfd28c3 commit 993f454
Showing 1 changed file with 21 additions and 12 deletions.
33 changes: 21 additions & 12 deletions ext/bootsnap/bootsnap.c
Expand Up @@ -32,6 +32,8 @@

#define KEY_SIZE 64

#define MAX_CREATE_TEMPFILE_ATTEMPT 3

/*
* An instance of this key is written as the first 64 bytes of each cache file.
* The mtime and size members track whether the file contents have changed, and
Expand Down Expand Up @@ -499,25 +501,32 @@ atomic_write_cache_file(char * path, struct bs_cache_key * key, VALUE data, cons
{
char template[MAX_CACHEPATH_SIZE + 20];
char * tmp_path;
int fd, ret;
int fd, ret, attempt;
ssize_t nwrite;

tmp_path = strncpy(template, path, MAX_CACHEPATH_SIZE);
strcat(tmp_path, ".tmp.XXXXXX");
for (attempt = 0; attempt < MAX_CREATE_TEMPFILE_ATTEMPT; ++attempt) {
tmp_path = strncpy(template, path, MAX_CACHEPATH_SIZE);
strcat(tmp_path, ".tmp.XXXXXX");

// mkstemp modifies the template to be the actual created path
fd = mkstemp(tmp_path);
if (fd < 0) {
if (mkpath(tmp_path, 0775) < 0) {
// mkstemp modifies the template to be the actual created path
fd = mkstemp(tmp_path);
if (fd > 0) break;

if (attempt == 0 && mkpath(tmp_path, 0775) < 0) {
*errno_provenance = "bs_fetch:atomic_write_cache_file:mkpath";
return -1;
}
fd = open(tmp_path, O_WRONLY | O_CREAT, 0664);
if (fd < 0) {
*errno_provenance = "bs_fetch:atomic_write_cache_file:open";
return -1;
}
}
if (fd < 0) {
*errno_provenance = "bs_fetch:atomic_write_cache_file:mkstemp";
return -1;
}

if (chmod(tmp_path, 0644) < 0) {
*errno_provenance = "bs_fetch:atomic_write_cache_file:chmod";
return -1;
}

#ifdef _WIN32
setmode(fd, O_BINARY);
#endif
Expand Down

0 comments on commit 993f454

Please sign in to comment.