<feed xmlns='http://www.w3.org/2005/Atom'>
<title>linux/fs/exec.c, branch v3.12</title>
<subtitle>Mirror of https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/
</subtitle>
<id>https://git.shady.money/linux/atom?h=v3.12</id>
<link rel='self' href='https://git.shady.money/linux/atom?h=v3.12'/>
<link rel='alternate' type='text/html' href='https://git.shady.money/linux/'/>
<updated>2013-09-11T22:59:09Z</updated>
<entry>
<title>exec: cleanup the error handling in search_binary_handler()</title>
<updated>2013-09-11T22:59:09Z</updated>
<author>
<name>Oleg Nesterov</name>
<email>oleg@redhat.com</email>
</author>
<published>2013-09-11T21:24:46Z</published>
<link rel='alternate' type='text/html' href='https://git.shady.money/linux/commit/?id=6b3c538f5b2cfc53cb6803ec5001bbcf8f18a98e'/>
<id>urn:sha1:6b3c538f5b2cfc53cb6803ec5001bbcf8f18a98e</id>
<content type='text'>
The error hanling and ret-from-loop look confusing and inconsistent.

- "retval &gt;= 0" simply returns

- "!bprm-&gt;file" returns too but with read_unlock() because
   binfmt_lock was already re-acquired

- "retval != -ENOEXEC || bprm-&gt;mm == NULL" does "break" and
  relies on the same check after the main loop

Consolidate these checks into a single if/return statement.

need_retry still checks "retval == -ENOEXEC", but this and -ENOENT before
the main loop are not needed.  This is only for pathological and
impossible list_empty(&amp;formats) case.

It is not clear why do we check "bprm-&gt;mm == NULL", probably this
should be removed.

Signed-off-by: Oleg Nesterov &lt;oleg@redhat.com&gt;
Acked-by: Kees Cook &lt;keescook@chromium.org&gt;
Cc: Al Viro &lt;viro@ZenIV.linux.org.uk&gt;
Cc: Evgeniy Polyakov &lt;zbr@ioremap.net&gt;
Cc: Zach Levis &lt;zml@linux.vnet.ibm.com&gt;
Signed-off-by: Andrew Morton &lt;akpm@linux-foundation.org&gt;
Signed-off-by: Linus Torvalds &lt;torvalds@linux-foundation.org&gt;
</content>
</entry>
<entry>
<title>exec: don't retry if request_module() fails</title>
<updated>2013-09-11T22:59:07Z</updated>
<author>
<name>Oleg Nesterov</name>
<email>oleg@redhat.com</email>
</author>
<published>2013-09-11T21:24:45Z</published>
<link rel='alternate' type='text/html' href='https://git.shady.money/linux/commit/?id=4e0621a07ea58a0dc15859be3b743bdeb194a51b'/>
<id>urn:sha1:4e0621a07ea58a0dc15859be3b743bdeb194a51b</id>
<content type='text'>
A separate one-liner for better documentation.

It doesn't make sense to retry if request_module() fails to exec
/sbin/modprobe, add the additional "request_module() &lt; 0" check.

However, this logic still doesn't look exactly right:

1. It would be better to check "request_module() != 0", the user
   space modprobe process should report the correct exit code.
   But I didn't dare to add the user-visible change.

2. The whole ENOEXEC logic looks suboptimal. Suppose that we try
   to exec a "#!path-to-unsupported-binary" script. In this case
   request_module() + "retry" will be done twice: first by the
   "depth == 1" code, and then again by the "depth == 0" caller
   which doesn't make sense.

3. And note that in the case above bprm-&gt;buf was already changed
   by load_script()-&gt;prepare_binprm(), so this looks even more
   ugly.

Signed-off-by: Oleg Nesterov &lt;oleg@redhat.com&gt;
Acked-by: Kees Cook &lt;keescook@chromium.org&gt;
Cc: Al Viro &lt;viro@ZenIV.linux.org.uk&gt;
Cc: Evgeniy Polyakov &lt;zbr@ioremap.net&gt;
Cc: Zach Levis &lt;zml@linux.vnet.ibm.com&gt;
Signed-off-by: Andrew Morton &lt;akpm@linux-foundation.org&gt;
Signed-off-by: Linus Torvalds &lt;torvalds@linux-foundation.org&gt;
</content>
</entry>
<entry>
<title>exec: cleanup the CONFIG_MODULES logic</title>
<updated>2013-09-11T22:59:05Z</updated>
<author>
<name>Oleg Nesterov</name>
<email>oleg@redhat.com</email>
</author>
<published>2013-09-11T21:24:44Z</published>
<link rel='alternate' type='text/html' href='https://git.shady.money/linux/commit/?id=cb7b6b1cbc20a970c7124efae1c2478155604b54'/>
<id>urn:sha1:cb7b6b1cbc20a970c7124efae1c2478155604b54</id>
<content type='text'>
search_binary_handler() uses "for (try=0; try&lt;2; try++)" to avoid "goto"
but the code looks too complicated and horrible imho.  We still need to
check "try == 0" before request_module() and add the additional "break"
for !CONFIG_MODULES case.

Kill this loop and use a simple "bool need_retry" + "goto retry".  The
code looks much simpler and we do not even need ifdef's, gcc can optimize
out the "if (need_retry)" block if !IS_ENABLED().

Signed-off-by: Oleg Nesterov &lt;oleg@redhat.com&gt;
Acked-by: Kees Cook &lt;keescook@chromium.org&gt;
Cc: Al Viro &lt;viro@ZenIV.linux.org.uk&gt;
Cc: Evgeniy Polyakov &lt;zbr@ioremap.net&gt;
Cc: Zach Levis &lt;zml@linux.vnet.ibm.com&gt;
Signed-off-by: Andrew Morton &lt;akpm@linux-foundation.org&gt;
Signed-off-by: Linus Torvalds &lt;torvalds@linux-foundation.org&gt;
</content>
</entry>
<entry>
<title>exec: kill -&gt;load_binary != NULL check in search_binary_handler()</title>
<updated>2013-09-11T22:59:05Z</updated>
<author>
<name>Oleg Nesterov</name>
<email>oleg@redhat.com</email>
</author>
<published>2013-09-11T21:24:42Z</published>
<link rel='alternate' type='text/html' href='https://git.shady.money/linux/commit/?id=92eaa565add62d56b90987f58ea9feafc5a7c183'/>
<id>urn:sha1:92eaa565add62d56b90987f58ea9feafc5a7c183</id>
<content type='text'>
search_binary_handler() checks -&gt;load_binary != NULL for no reason, this
method should be always defined.  Turn this check into WARN_ON() and move
it into __register_binfmt().

Also, kill the function pointer.  The current code looks confusing, as if
-&gt;load_binary can go away after read_unlock(&amp;binfmt_lock).  But we rely on
module_get(fmt-&gt;module), this fmt can't be changed or unregistered,
otherwise this code is buggy anyway.

Signed-off-by: Oleg Nesterov &lt;oleg@redhat.com&gt;
Acked-by: Kees Cook &lt;keescook@chromium.org&gt;
Cc: Al Viro &lt;viro@ZenIV.linux.org.uk&gt;
Cc: Evgeniy Polyakov &lt;zbr@ioremap.net&gt;
Cc: Zach Levis &lt;zml@linux.vnet.ibm.com&gt;
Signed-off-by: Andrew Morton &lt;akpm@linux-foundation.org&gt;
Signed-off-by: Linus Torvalds &lt;torvalds@linux-foundation.org&gt;
</content>
</entry>
<entry>
<title>exec: move allow_write_access/fput to exec_binprm()</title>
<updated>2013-09-11T22:59:05Z</updated>
<author>
<name>Oleg Nesterov</name>
<email>oleg@redhat.com</email>
</author>
<published>2013-09-11T21:24:41Z</published>
<link rel='alternate' type='text/html' href='https://git.shady.money/linux/commit/?id=52f14282bb0c3d3e5ba2a9eaacb12ff37a033e7e'/>
<id>urn:sha1:52f14282bb0c3d3e5ba2a9eaacb12ff37a033e7e</id>
<content type='text'>
When search_binary_handler() succeeds it does allow_write_access() and
fput(), then it clears bprm-&gt;file to ensure the caller will not do the
same.

We can simply move this code to exec_binprm() which is called only once.
In fact we could move this to free_bprm() and remove the same code in
do_execve_common's error path.

Signed-off-by: Oleg Nesterov &lt;oleg@redhat.com&gt;
Acked-by: Kees Cook &lt;keescook@chromium.org&gt;
Cc: Al Viro &lt;viro@ZenIV.linux.org.uk&gt;
Cc: Evgeniy Polyakov &lt;zbr@ioremap.net&gt;
Cc: Zach Levis &lt;zml@linux.vnet.ibm.com&gt;
Signed-off-by: Andrew Morton &lt;akpm@linux-foundation.org&gt;
Signed-off-by: Linus Torvalds &lt;torvalds@linux-foundation.org&gt;
</content>
</entry>
<entry>
<title>exec: proc_exec_connector() should be called only once</title>
<updated>2013-09-11T22:59:05Z</updated>
<author>
<name>Oleg Nesterov</name>
<email>oleg@redhat.com</email>
</author>
<published>2013-09-11T21:24:40Z</published>
<link rel='alternate' type='text/html' href='https://git.shady.money/linux/commit/?id=9beb266f2d7e5362c5bb9f999255aa1af5318aef'/>
<id>urn:sha1:9beb266f2d7e5362c5bb9f999255aa1af5318aef</id>
<content type='text'>
A separate one-liner with the minor fix.

PROC_EVENT_EXEC reports the "exec" event, but this message is sent at
least twice if search_binary_handler() is called by -&gt;load_binary()
recursively, say, load_script().

Move it to exec_binprm(), this is "depth == 0" code too.

Signed-off-by: Oleg Nesterov &lt;oleg@redhat.com&gt;
Acked-by: Kees Cook &lt;keescook@chromium.org&gt;
Cc: Al Viro &lt;viro@ZenIV.linux.org.uk&gt;
Cc: Evgeniy Polyakov &lt;zbr@ioremap.net&gt;
Cc: Zach Levis &lt;zml@linux.vnet.ibm.com&gt;
Signed-off-by: Andrew Morton &lt;akpm@linux-foundation.org&gt;
Signed-off-by: Linus Torvalds &lt;torvalds@linux-foundation.org&gt;
</content>
</entry>
<entry>
<title>exec: kill "int depth" in search_binary_handler()</title>
<updated>2013-09-11T22:59:04Z</updated>
<author>
<name>Oleg Nesterov</name>
<email>oleg@redhat.com</email>
</author>
<published>2013-09-11T21:24:39Z</published>
<link rel='alternate' type='text/html' href='https://git.shady.money/linux/commit/?id=131b2f9f1214f338f0bf7c0d9760019f2b1d0c20'/>
<id>urn:sha1:131b2f9f1214f338f0bf7c0d9760019f2b1d0c20</id>
<content type='text'>
Nobody except search_binary_handler() should touch -&gt;recursion_depth, "int
depth" buys nothing but complicates the code, kill it.

Probably we should also kill "fn" and the !NULL check, -&gt;load_binary
should be always defined.  And it can not go away after read_unlock() or
this code is buggy anyway.

Signed-off-by: Oleg Nesterov &lt;oleg@redhat.com&gt;
Acked-by: Kees Cook &lt;keescook@chromium.org&gt;
Cc: Al Viro &lt;viro@ZenIV.linux.org.uk&gt;
Cc: Evgeniy Polyakov &lt;zbr@ioremap.net&gt;
Cc: Zach Levis &lt;zml@linux.vnet.ibm.com&gt;
Signed-off-by: Andrew Morton &lt;akpm@linux-foundation.org&gt;
Signed-off-by: Linus Torvalds &lt;torvalds@linux-foundation.org&gt;
</content>
</entry>
<entry>
<title>exec: introduce exec_binprm() for "depth == 0" code</title>
<updated>2013-09-11T22:59:03Z</updated>
<author>
<name>Oleg Nesterov</name>
<email>oleg@redhat.com</email>
</author>
<published>2013-09-11T21:24:38Z</published>
<link rel='alternate' type='text/html' href='https://git.shady.money/linux/commit/?id=5d1baf3b63bfc8c709dc44df85ff1475c7ef489d'/>
<id>urn:sha1:5d1baf3b63bfc8c709dc44df85ff1475c7ef489d</id>
<content type='text'>
task_pid_nr_ns() and trace/ptrace code in the middle of the recursive
search_binary_handler() looks confusing and imho annoying.  We only need
this code if "depth == 0", lets add a simple helper which calls
search_binary_handler() and does trace_sched_process_exec() +
ptrace_event().

The patch also moves the setting of task-&gt;did_exec, we need to do this
only once.

Note: we can kill either task-&gt;did_exec or PF_FORKNOEXEC.

Signed-off-by: Oleg Nesterov &lt;oleg@redhat.com&gt;
Acked-by: Kees Cook &lt;keescook@chromium.org&gt;
Cc: Al Viro &lt;viro@ZenIV.linux.org.uk&gt;
Cc: Evgeniy Polyakov &lt;zbr@ioremap.net&gt;
Cc: Zach Levis &lt;zml@linux.vnet.ibm.com&gt;
Signed-off-by: Andrew Morton &lt;akpm@linux-foundation.org&gt;
Signed-off-by: Linus Torvalds &lt;torvalds@linux-foundation.org&gt;
</content>
</entry>
<entry>
<title>mm: track vma changes with VM_SOFTDIRTY bit</title>
<updated>2013-09-11T22:57:56Z</updated>
<author>
<name>Cyrill Gorcunov</name>
<email>gorcunov@gmail.com</email>
</author>
<published>2013-09-11T21:22:24Z</published>
<link rel='alternate' type='text/html' href='https://git.shady.money/linux/commit/?id=d9104d1ca9662498339c0de975b4666c30485f4e'/>
<id>urn:sha1:d9104d1ca9662498339c0de975b4666c30485f4e</id>
<content type='text'>
Pavel reported that in case if vma area get unmapped and then mapped (or
expanded) in-place, the soft dirty tracker won't be able to recognize this
situation since it works on pte level and ptes are get zapped on unmap,
loosing soft dirty bit of course.

So to resolve this situation we need to track actions on vma level, there
VM_SOFTDIRTY flag comes in.  When new vma area created (or old expanded)
we set this bit, and keep it here until application calls for clearing
soft dirty bit.

Thus when user space application track memory changes now it can detect if
vma area is renewed.

Reported-by: Pavel Emelyanov &lt;xemul@parallels.com&gt;
Signed-off-by: Cyrill Gorcunov &lt;gorcunov@openvz.org&gt;
Cc: Andy Lutomirski &lt;luto@amacapital.net&gt;
Cc: Matt Mackall &lt;mpm@selenic.com&gt;
Cc: Xiao Guangrong &lt;xiaoguangrong@linux.vnet.ibm.com&gt;
Cc: Marcelo Tosatti &lt;mtosatti@redhat.com&gt;
Cc: KOSAKI Motohiro &lt;kosaki.motohiro@gmail.com&gt;
Cc: Stephen Rothwell &lt;sfr@canb.auug.org.au&gt;
Cc: Peter Zijlstra &lt;peterz@infradead.org&gt;
Cc: "Aneesh Kumar K.V" &lt;aneesh.kumar@linux.vnet.ibm.com&gt;
Cc: Rob Landley &lt;rob@landley.net&gt;
Signed-off-by: Andrew Morton &lt;akpm@linux-foundation.org&gt;
Signed-off-by: Linus Torvalds &lt;torvalds@linux-foundation.org&gt;
</content>
</entry>
<entry>
<title>Fix TLB gather virtual address range invalidation corner cases</title>
<updated>2013-08-16T15:52:46Z</updated>
<author>
<name>Linus Torvalds</name>
<email>torvalds@linux-foundation.org</email>
</author>
<published>2013-08-15T18:42:25Z</published>
<link rel='alternate' type='text/html' href='https://git.shady.money/linux/commit/?id=2b047252d087be7f2ba088b4933cd904f92e6fce'/>
<id>urn:sha1:2b047252d087be7f2ba088b4933cd904f92e6fce</id>
<content type='text'>
Ben Tebulin reported:

 "Since v3.7.2 on two independent machines a very specific Git
  repository fails in 9/10 cases on git-fsck due to an SHA1/memory
  failures.  This only occurs on a very specific repository and can be
  reproduced stably on two independent laptops.  Git mailing list ran
  out of ideas and for me this looks like some very exotic kernel issue"

and bisected the failure to the backport of commit 53a59fc67f97 ("mm:
limit mmu_gather batching to fix soft lockups on !CONFIG_PREEMPT").

That commit itself is not actually buggy, but what it does is to make it
much more likely to hit the partial TLB invalidation case, since it
introduces a new case in tlb_next_batch() that previously only ever
happened when running out of memory.

The real bug is that the TLB gather virtual memory range setup is subtly
buggered.  It was introduced in commit 597e1c3580b7 ("mm/mmu_gather:
enable tlb flush range in generic mmu_gather"), and the range handling
was already fixed at least once in commit e6c495a96ce0 ("mm: fix the TLB
range flushed when __tlb_remove_page() runs out of slots"), but that fix
was not complete.

The problem with the TLB gather virtual address range is that it isn't
set up by the initial tlb_gather_mmu() initialization (which didn't get
the TLB range information), but it is set up ad-hoc later by the
functions that actually flush the TLB.  And so any such case that forgot
to update the TLB range entries would potentially miss TLB invalidates.

Rather than try to figure out exactly which particular ad-hoc range
setup was missing (I personally suspect it's the hugetlb case in
zap_huge_pmd(), which didn't have the same logic as zap_pte_range()
did), this patch just gets rid of the problem at the source: make the
TLB range information available to tlb_gather_mmu(), and initialize it
when initializing all the other tlb gather fields.

This makes the patch larger, but conceptually much simpler.  And the end
result is much more understandable; even if you want to play games with
partial ranges when invalidating the TLB contents in chunks, now the
range information is always there, and anybody who doesn't want to
bother with it won't introduce subtle bugs.

Ben verified that this fixes his problem.

Reported-bisected-and-tested-by: Ben Tebulin &lt;tebulin@googlemail.com&gt;
Build-testing-by: Stephen Rothwell &lt;sfr@canb.auug.org.au&gt;
Build-testing-by: Richard Weinberger &lt;richard.weinberger@gmail.com&gt;
Reviewed-by: Michal Hocko &lt;mhocko@suse.cz&gt;
Acked-by: Peter Zijlstra &lt;peterz@infradead.org&gt;
Cc: stable@vger.kernel.org
Signed-off-by: Linus Torvalds &lt;torvalds@linux-foundation.org&gt;
</content>
</entry>
</feed>
