diff options
author | Xi Wang <xi.wang@gmail.com> | 2013-01-11 14:31:48 -0800 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2013-01-11 14:54:55 -0800 |
commit | 6d92d4f6a74766cc885b18218268e0c47fbca399 (patch) | |
tree | 9feb7c205f8062ffc1982948d2ffc446cbf94a6b /fs | |
parent | 7964c06d66c76507d8b6b662bffea770c29ef0ce (diff) | |
download | op-kernel-dev-6d92d4f6a74766cc885b18218268e0c47fbca399.zip op-kernel-dev-6d92d4f6a74766cc885b18218268e0c47fbca399.tar.gz |
fs/exec.c: work around icc miscompilation
The tricky problem is this check:
if (i++ >= max)
icc (mis)optimizes this check as:
if (++i > max)
The check now becomes a no-op since max is MAX_ARG_STRINGS (0x7FFFFFFF).
This is "allowed" by the C standard, assuming i++ never overflows,
because signed integer overflow is undefined behavior. This
optimization effectively reverts the previous commit 362e6663ef23
("exec.c, compat.c: fix count(), compat_count() bounds checking") that
tries to fix the check.
This patch simply moves ++ after the check.
Signed-off-by: Xi Wang <xi.wang@gmail.com>
Cc: Jason Baron <jbaron@redhat.com>
Cc: Al Viro <viro@zeniv.linux.org.uk>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'fs')
-rw-r--r-- | fs/exec.c | 3 |
1 files changed, 2 insertions, 1 deletions
@@ -434,8 +434,9 @@ static int count(struct user_arg_ptr argv, int max) if (IS_ERR(p)) return -EFAULT; - if (i++ >= max) + if (i >= max) return -E2BIG; + ++i; if (fatal_signal_pending(current)) return -ERESTARTNOHAND; |