summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChris Mason <clm@fb.com>2017-06-26 17:24:35 -0700
committerChris Mason <clm@fb.com>2017-06-26 17:25:37 -0700
commit03fcf9d16974646dacb927b1b1ee12fc4fd0944f (patch)
tree85d03ec2adfa7af999991bc61e8924a0a7860c86
parentcdee006c84dac5e9e00f6eb908953d1a012c4753 (diff)
downloadsimoop-03fcf9d16974646dacb927b1b1ee12fc4fd0944f.tar.gz
simoop: fix use-after-free for xxhash
Signed-off-by: Chris Mason <clm@fb.com>
-rw-r--r--simoop.c22
1 files changed, 14 insertions, 8 deletions
diff --git a/simoop.c b/simoop.c
index 697a096..3b9b88b 100644
--- a/simoop.c
+++ b/simoop.c
@@ -563,7 +563,7 @@ static void parse_options(int ac, char **av)
print_usage();
exit(1);
}
- paths = malloc(sizeof(char *) * total_paths + 1);
+ paths = malloc(sizeof(char *) * (total_paths + 1));
paths[total_paths] = NULL;
for (i = 0; i < total_paths; i++) {
paths[i] = strdup(av[optind++]);
@@ -991,7 +991,6 @@ static void send_pwrite(int fd, char *buf, loff_t start, ssize_t bytes)
ret = pwrite(fd, buf, this_write, start);
if (ret <= 0) {
perror("pwrite");
- abort();
exit(1);
}
start += ret;
@@ -1006,7 +1005,6 @@ static void send_pwrite(int fd, char *buf, loff_t start, ssize_t bytes)
ret = pwrite(fd, buf, bytes, start);
if (ret <= 0) {
perror("pwrite");
- abort();
exit(1);
}
start += ret;
@@ -1064,6 +1062,9 @@ static void read_and_crc(int fd, char *filename,
ssize_t this_read;
ssize_t cur_len;
+ if (!read_size)
+ return;
+
aligned_start = verify_align(start);
length += start - aligned_start;
length = verify_align_up(length);
@@ -1076,9 +1077,10 @@ static void read_and_crc(int fd, char *filename,
maybe_toggle_odirect(fd, aligned_start, this_read);
ret = pread(fd, buf, this_read, aligned_start);
if (ret != this_read) {
- perror("pread");
- fprintf(stderr, "pread start %lu bytes %lu ret %d\n", aligned_start, this_read, errno);
- exit(1);
+ /* someone is deleting this file at the same time
+ * we're reading it
+ */
+ break;
}
p = buf;
cur_len = 0;
@@ -1234,6 +1236,9 @@ static void read_whole_file(char *path, int seq, char *postfix,
void *xxhash_state;
char name[NAME_LEN];
+ if (read_size == 0)
+ return;
+
join_path(name, path, seq, postfix);
fd = open(name, O_RDONLY, 0600);
if (fd < 0)
@@ -1284,12 +1289,12 @@ static void write_to_file(char *path, int seq, char *buf)
}
write_pattern(fd, xxhash_state, buf, write_size, offset, write_bytes * 4);
- XXH32_digest(xxhash_state);
join_path(name, path, seq, postfix);
read_and_crc(fd, name, xxhash_state, buf, write_size, offset,
write_bytes * 4);
+ XXH32_digest(xxhash_state);
close(fd);
/* make some dirty inodes */
@@ -1320,7 +1325,8 @@ static void make_files(char *path, unsigned long seq_start,
for (seq = seq_start; seq < seq_start + seq_num; seq++) {
- read_whole_file(path, seq, DATA_FILE, buf, BUF_SIZE);
+ if (read_size)
+ read_whole_file(path, seq, DATA_FILE, buf, BUF_SIZE);
fd = open_path(path, seq, DATA_FILE, O_APPEND);
fill_one_file(fd, xxhash_state, buf, BUF_SIZE);