summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorbenno <benno@openbsd.org>2019-08-26 22:22:14 +0000
committerbenno <benno@openbsd.org>2019-08-26 22:22:14 +0000
commitc314c8030071bec0bc321323addce2d5bc49acf4 (patch)
tree22582eddbbbe90ad4132ac37c5d70df7bfb679c1
parentsync (diff)
downloadwireguard-openbsd-c314c8030071bec0bc321323addce2d5bc49acf4.tar.xz
wireguard-openbsd-c314c8030071bec0bc321323addce2d5bc49acf4.zip
replace a mmap() with pread(). The mmap() is not needed, the file is
read sequentially anyway, (hash-sized) block by block. This avoids counting potentially large files against the memory limits of the process. Problem reported by Jan Stary, thanks. ok deraadt@
-rw-r--r--usr.bin/rsync/uploader.c52
1 files changed, 32 insertions, 20 deletions
diff --git a/usr.bin/rsync/uploader.c b/usr.bin/rsync/uploader.c
index fd07b22caeb..38d5d24fcc7 100644
--- a/usr.bin/rsync/uploader.c
+++ b/usr.bin/rsync/uploader.c
@@ -1,4 +1,4 @@
-/* $Id: uploader.c,v 1.22 2019/05/08 21:30:11 benno Exp $ */
+/* $Id: uploader.c,v 1.23 2019/08/26 22:22:14 benno Exp $ */
/*
* Copyright (c) 2019 Kristaps Dzonsons <kristaps@bsd.lv>
* Copyright (c) 2019 Florian Obser <florian@openbsd.org>
@@ -158,8 +158,8 @@ init_blk(struct blk *p, const struct blkset *set, off_t offs,
p->len = idx < set->blksz - 1 ? set->len : set->rem;
p->offs = offs;
- p->chksum_short = hash_fast(map + offs, p->len);
- hash_slow(map + offs, p->len, p->chksum_long, sess);
+ p->chksum_short = hash_fast(map, p->len);
+ hash_slow(map, p->len, p->chksum_long, sess);
}
/*
@@ -741,8 +741,9 @@ rsync_uploader(struct upload *u, int *fileinfd,
{
struct blkset blk;
struct stat st;
- void *map, *bufp;
- size_t i, mapsz, pos, sz;
+ void *mbuf, *bufp;
+ ssize_t msz;
+ size_t i, pos, sz;
off_t offs;
int c;
const struct flist *f;
@@ -909,35 +910,46 @@ rsync_uploader(struct upload *u, int *fileinfd,
blk.csum = u->csumlen;
if (*fileinfd != -1 && st.st_size > 0) {
- mapsz = st.st_size;
- map = mmap(NULL, mapsz, PROT_READ, MAP_SHARED, *fileinfd, 0);
- if (map == MAP_FAILED) {
- ERR("%s: mmap", u->fl[u->idx].path);
- close(*fileinfd);
- *fileinfd = -1;
- return -1;
- }
-
init_blkset(&blk, st.st_size);
assert(blk.blksz);
blk.blks = calloc(blk.blksz, sizeof(struct blk));
if (blk.blks == NULL) {
ERR("calloc");
- munmap(map, mapsz);
+ close(*fileinfd);
+ *fileinfd = -1;
+ return -1;
+ }
+
+ if ((mbuf = calloc(1, blk.len)) == NULL) {
+ ERR("calloc");
close(*fileinfd);
*fileinfd = -1;
return -1;
}
offs = 0;
- for (i = 0; i < blk.blksz; i++) {
- init_blk(&blk.blks[i],
- &blk, offs, i, map, sess);
+ i = 0;
+ do {
+ msz = pread(*fileinfd, mbuf, blk.len, offs);
+ if (msz < 0) {
+ ERR("pread");
+ close(*fileinfd);
+ *fileinfd = -1;
+ return -1;
+ }
+ if ((size_t)msz != blk.len && (size_t)msz != blk.rem) {
+ /* short read, try again */
+ continue;
+ }
+ init_blk(&blk.blks[i], &blk, offs, i, mbuf, sess);
offs += blk.len;
- }
+ LOG3(
+ "i=%ld, offs=%lld, msz=%ld, blk.len=%lu, blk.rem=%lu",
+ i, offs, msz, blk.len, blk.rem);
+ i++;
+ } while (i < blk.blksz);
- munmap(map, mapsz);
close(*fileinfd);
*fileinfd = -1;
LOG3("%s: mapped %jd B with %zu blocks",