summaryrefslogtreecommitdiffstats
path: root/exec.c
diff options
context:
space:
mode:
authorTavian Barnes <tavianator@tavianator.com>2017-10-26 01:04:46 -0400
committerTavian Barnes <tavianator@tavianator.com>2017-10-26 01:04:46 -0400
commit462a2cb18ca51afec08e3c80acfe79dd69786332 (patch)
tree4c672f1d966b5cbe071dccb7e8cc0393ea0198b0 /exec.c
parenta3ed3e8dda52d39d3307a87b848b54606a6f0fed (diff)
downloadbfs-462a2cb18ca51afec08e3c80acfe79dd69786332.tar.xz
exec: Make argument size tracking robust to page-granularity accounting
From looking at the Linux exec() implementation, it seems a big part of the reason we needed extra headroom was that the arguments/environment are copied page-by-page, so even a small accounting difference could result in an error of an entire page size. Grow the headroom to two entire pages to account for this.
Diffstat (limited to 'exec.c')
-rw-r--r--exec.c11
1 files changed, 8 insertions, 3 deletions
diff --git a/exec.c b/exec.c
index b982f85..23ea0c7 100644
--- a/exec.c
+++ b/exec.c
@@ -89,9 +89,14 @@ static size_t bfs_exec_arg_max(const struct bfs_exec *execbuf) {
arg_max -= sizeof(char *);
bfs_exec_debug(execbuf, "ARG_MAX: %ld remaining after fixed arguments\n", arg_max);
- // POSIX recommends subtracting 2048, for some wiggle room
- // We subtract 4096 for extra insurance, based on some experimentation
- arg_max -= 4096;
+ // Assume arguments are counted with the granularity of a single page,
+ // and allow two pages of headroom to account for rounding as well as
+ // any other data we may not be counting
+ long page_size = sysconf(_SC_PAGESIZE);
+ if (page_size < 4096) {
+ page_size = 4096;
+ }
+ arg_max -= 2*page_size;
bfs_exec_debug(execbuf, "ARG_MAX: %ld remaining after headroom\n", arg_max);
if (arg_max < 0) {