<feed xmlns='http://www.w3.org/2005/Atom'>
<title>kernel/git/stable/linux.git/fs/exec.c, branch linux-2.6.29.y</title>
<subtitle>Linux kernel stable tree</subtitle>
<id>https://git.rulkc.org/pub/scm/linux/kernel/git/stable/linux.git/atom?h=linux-2.6.29.y</id>
<link rel='self' href='https://git.rulkc.org/pub/scm/linux/kernel/git/stable/linux.git/atom?h=linux-2.6.29.y'/>
<link rel='alternate' type='text/html' href='https://git.rulkc.org/pub/scm/linux/kernel/git/stable/linux.git/'/>
<updated>2009-05-08T22:45:09+00:00</updated>
<entry>
<title>check_unsafe_exec: s/lock_task_sighand/rcu_read_lock/</title>
<updated>2009-05-08T22:45:09+00:00</updated>
<author>
<name>Oleg Nesterov</name>
<email>oleg@redhat.com</email>
</author>
<published>2009-04-23T23:02:45+00:00</published>
<link rel='alternate' type='text/html' href='https://git.rulkc.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=4cc341cacb9288d4678e1b899af0a5ac66dbe2f2'/>
<id>urn:sha1:4cc341cacb9288d4678e1b899af0a5ac66dbe2f2</id>
<content type='text'>
commit 437f7fdb607f32b737e4da9f14bebcfdac2c90c3 upstream.

write_lock(&amp;current-&gt;fs-&gt;lock) guarantees we can't wrongly miss
LSM_UNSAFE_SHARE, this is what we care about. Use rcu_read_lock()
instead of -&gt;siglock to iterate over the sub-threads. We must see
all CLONE_THREAD|CLONE_FS threads which didn't pass exit_fs(), it
takes fs-&gt;lock too.

With or without this patch we can miss the freshly cloned thread
and set LSM_UNSAFE_SHARE, we don't care.

Signed-off-by: Oleg Nesterov &lt;oleg@redhat.com&gt;
Acked-by: Roland McGrath &lt;roland@redhat.com&gt;
[ Fixed lock/unlock typo  - Hugh ]
Acked-by: Hugh Dickins &lt;hugh@veritas.com&gt;
Signed-off-by: Linus Torvalds &lt;torvalds@linux-foundation.org&gt;
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@suse.de&gt;

</content>
</entry>
<entry>
<title>do_execve() must not clear fs-&gt;in_exec if it was set by another thread</title>
<updated>2009-05-08T22:45:08+00:00</updated>
<author>
<name>Oleg Nesterov</name>
<email>oleg@redhat.com</email>
</author>
<published>2009-04-23T23:01:56+00:00</published>
<link rel='alternate' type='text/html' href='https://git.rulkc.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=7fd619d45f54fc09dc7bb908edae518d8aa05516'/>
<id>urn:sha1:7fd619d45f54fc09dc7bb908edae518d8aa05516</id>
<content type='text'>
commit 8c652f96d3852b97a49c331cd0bb02d22f3cb31b upstream.

If do_execve() fails after check_unsafe_exec(), it clears fs-&gt;in_exec
unconditionally. This is wrong if we race with our sub-thread which
also does do_execve:

	Two threads T1 and T2 and another process P, all share the same
	-&gt;fs.

	T1 starts do_execve(BAD_FILE). It calls check_unsafe_exec(), since
	-&gt;fs is shared, we set LSM_UNSAFE but not -&gt;in_exec.

	P exits and decrements fs-&gt;users.

	T2 starts do_execve(), calls check_unsafe_exec(), now -&gt;fs is not
	shared, we set fs-&gt;in_exec.

	T1 continues, open_exec(BAD_FILE) fails, we clear -&gt;in_exec and
	return to the user-space.

	T1 does clone(CLONE_FS /* without CLONE_THREAD */).

	T2 continues without LSM_UNSAFE_SHARE while -&gt;fs is shared with
	another process.

Change check_unsafe_exec() to return res = 1 if we set -&gt;in_exec, and change
do_execve() to clear -&gt;in_exec depending on res.

When do_execve() suceeds, it is safe to clear -&gt;in_exec unconditionally.
It can be set only if we don't share -&gt;fs with another process, and since
we already killed all sub-threads either -&gt;in_exec == 0 or we are the
only user of this -&gt;fs.

Also, we do not need fs-&gt;lock to clear fs-&gt;in_exec.

Signed-off-by: Oleg Nesterov &lt;oleg@redhat.com&gt;
Acked-by: Roland McGrath &lt;roland@redhat.com&gt;
Acked-by: Hugh Dickins &lt;hugh@veritas.com&gt;
Signed-off-by: Linus Torvalds &lt;torvalds@linux-foundation.org&gt;
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@suse.de&gt;

</content>
</entry>
<entry>
<title>check_unsafe_exec() doesn't care about signal handlers sharing</title>
<updated>2009-05-08T22:45:08+00:00</updated>
<author>
<name>Al Viro</name>
<email>viro@zeniv.linux.org.uk</email>
</author>
<published>2009-03-30T11:35:18+00:00</published>
<link rel='alternate' type='text/html' href='https://git.rulkc.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=e5d1b9adb4dbee27ffa857c645efe00d6dea6eff'/>
<id>urn:sha1:e5d1b9adb4dbee27ffa857c645efe00d6dea6eff</id>
<content type='text'>
commit f1191b50ec11c8e2ca766d6d99eb5bb9d2c084a3 upstream.

... since we'll unshare sighand anyway

Signed-off-by: Al Viro &lt;viro@zeniv.linux.org.uk&gt;
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@suse.de&gt;

</content>
</entry>
<entry>
<title>New locking/refcounting for fs_struct</title>
<updated>2009-05-08T22:45:08+00:00</updated>
<author>
<name>Al Viro</name>
<email>viro@zeniv.linux.org.uk</email>
</author>
<published>2009-03-30T11:20:30+00:00</published>
<link rel='alternate' type='text/html' href='https://git.rulkc.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=d093166dbab62418c468481891cdfbc70e3c73f9'/>
<id>urn:sha1:d093166dbab62418c468481891cdfbc70e3c73f9</id>
<content type='text'>
commit 498052bba55ecaff58db6a1436b0e25bfd75a7ff upstream.

* all changes of current-&gt;fs are done under task_lock and write_lock of
  old fs-&gt;lock
* refcount is not atomic anymore (same protection)
* its decrements are done when removing reference from current; at the
  same time we decide whether to free it.
* put_fs_struct() is gone
* new field - -&gt;in_exec.  Set by check_unsafe_exec() if we are trying to do
  execve() and only subthreads share fs_struct.  Cleared when finishing exec
  (success and failure alike).  Makes CLONE_FS fail with -EAGAIN if set.
* check_unsafe_exec() may fail with -EAGAIN if another execve() from subthread
  is in progress.

Signed-off-by: Al Viro &lt;viro@zeniv.linux.org.uk&gt;
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@suse.de&gt;

</content>
</entry>
<entry>
<title>fix setuid sometimes doesn't</title>
<updated>2009-05-08T22:45:06+00:00</updated>
<author>
<name>Hugh Dickins</name>
<email>hugh@veritas.com</email>
</author>
<published>2009-03-28T23:20:19+00:00</published>
<link rel='alternate' type='text/html' href='https://git.rulkc.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=47fc5f8d08deb87841757643affa95eeeda3c39d'/>
<id>urn:sha1:47fc5f8d08deb87841757643affa95eeeda3c39d</id>
<content type='text'>
commit e426b64c412aaa3e9eb3e4b261dc5be0d5a83e78 upstream.

Joe Malicki reports that setuid sometimes doesn't: very rarely,
a setuid root program does not get root euid; and, by the way,
they have a health check running lsof every few minutes.

Right, check_unsafe_exec() notes whether the files_struct is being
shared by more threads than will get killed by the exec, and if so
sets LSM_UNSAFE_SHARE to make bprm_set_creds() careful about euid.
But /proc/&lt;pid&gt;/fd and /proc/&lt;pid&gt;/fdinfo lookups make transient
use of get_files_struct(), which also raises that sharing count.

There's a rather simple fix for this: exec's check on files-&gt;count
has been redundant ever since 2.6.1 made it unshare_files() (except
while compat_do_execve() omitted to do so) - just remove that check.

[Note to -stable: this patch will not apply before 2.6.29: earlier
releases should just remove the files-&gt;count line from unsafe_exec().]

Reported-by: Joe Malicki &lt;jmalicki@metacarta.com&gt;
Narrowed-down-by: Michael Itz &lt;mitz@metacarta.com&gt;
Tested-by: Joe Malicki &lt;jmalicki@metacarta.com&gt;
Signed-off-by: Hugh Dickins &lt;hugh@veritas.com&gt;
Cc: stable@kernel.org
Signed-off-by: Linus Torvalds &lt;torvalds@linux-foundation.org&gt;
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@suse.de&gt;

</content>
</entry>
<entry>
<title>CRED: Fix SUID exec regression</title>
<updated>2009-02-06T21:46:18+00:00</updated>
<author>
<name>David Howells</name>
<email>dhowells@redhat.com</email>
</author>
<published>2009-02-06T11:45:46+00:00</published>
<link rel='alternate' type='text/html' href='https://git.rulkc.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=0bf2f3aec5474da80a60e1baca629af87ecb67b6'/>
<id>urn:sha1:0bf2f3aec5474da80a60e1baca629af87ecb67b6</id>
<content type='text'>
The patch:

	commit a6f76f23d297f70e2a6b3ec607f7aeeea9e37e8d
	CRED: Make execve() take advantage of copy-on-write credentials

moved the place in which the 'safeness' of a SUID/SGID exec was performed to
before de_thread() was called.  This means that LSM_UNSAFE_SHARE is now
calculated incorrectly.  This flag is set if any of the usage counts for
fs_struct, files_struct and sighand_struct are greater than 1 at the time the
determination is made.  All of which are true for threads created by the
pthread library.

However, since we wish to make the security calculation before irrevocably
damaging the process so that we can return it an error code in the case where
we decide we want to reject the exec request on this basis, we have to make the
determination before calling de_thread().

So, instead, we count up the number of threads (CLONE_THREAD) that are sharing
our fs_struct (CLONE_FS), files_struct (CLONE_FILES) and sighand_structs
(CLONE_SIGHAND/CLONE_THREAD) with us.  These will be killed by de_thread() and
so can be discounted by check_unsafe_exec().

We do have to be careful because CLONE_THREAD does not imply FS or FILES.

We _assume_ that there will be no extra references to these structs held by the
threads we're going to kill.

This can be tested with the attached pair of programs.  Build the two programs
using the Makefile supplied, and run ./test1 as a non-root user.  If
successful, you should see something like:

	[dhowells@andromeda tmp]$ ./test1
	--TEST1--
	uid=4043, euid=4043 suid=4043
	exec ./test2
	--TEST2--
	uid=4043, euid=0 suid=0
	SUCCESS - Correct effective user ID

and if unsuccessful, something like:

	[dhowells@andromeda tmp]$ ./test1
	--TEST1--
	uid=4043, euid=4043 suid=4043
	exec ./test2
	--TEST2--
	uid=4043, euid=4043 suid=4043
	ERROR - Incorrect effective user ID!

The non-root user ID you see will depend on the user you run as.

[test1.c]
#include &lt;stdio.h&gt;
#include &lt;stdlib.h&gt;
#include &lt;unistd.h&gt;
#include &lt;pthread.h&gt;

static void *thread_func(void *arg)
{
	while (1) {}
}

int main(int argc, char **argv)
{
	pthread_t tid;
	uid_t uid, euid, suid;

	printf("--TEST1--\n");
	getresuid(&amp;uid, &amp;euid, &amp;suid);
	printf("uid=%d, euid=%d suid=%d\n", uid, euid, suid);

	if (pthread_create(&amp;tid, NULL, thread_func, NULL) &lt; 0) {
		perror("pthread_create");
		exit(1);
	}

	printf("exec ./test2\n");
	execlp("./test2", "test2", NULL);
	perror("./test2");
	_exit(1);
}

[test2.c]
#include &lt;stdio.h&gt;
#include &lt;stdlib.h&gt;
#include &lt;unistd.h&gt;

int main(int argc, char **argv)
{
	uid_t uid, euid, suid;

	getresuid(&amp;uid, &amp;euid, &amp;suid);
	printf("--TEST2--\n");
	printf("uid=%d, euid=%d suid=%d\n", uid, euid, suid);

	if (euid != 0) {
		fprintf(stderr, "ERROR - Incorrect effective user ID!\n");
		exit(1);
	}
	printf("SUCCESS - Correct effective user ID\n");
	exit(0);
}

[Makefile]
CFLAGS = -D_GNU_SOURCE -Wall -Werror -Wunused
all: test1 test2

test1: test1.c
	gcc $(CFLAGS) -o test1 test1.c -lpthread

test2: test2.c
	gcc $(CFLAGS) -o test2 test2.c
	sudo chown root.root test2
	sudo chmod +s test2

Reported-by: David Smith &lt;dsmith@redhat.com&gt;
Signed-off-by: David Howells &lt;dhowells@redhat.com&gt;
Acked-by: David Smith &lt;dsmith@redhat.com&gt;
Signed-off-by: James Morris &lt;jmorris@namei.org&gt;
</content>
</entry>
<entry>
<title>[CVE-2009-0029] System call wrappers part 27</title>
<updated>2009-01-14T13:15:29+00:00</updated>
<author>
<name>Heiko Carstens</name>
<email>heiko.carstens@de.ibm.com</email>
</author>
<published>2009-01-14T13:14:29+00:00</published>
<link rel='alternate' type='text/html' href='https://git.rulkc.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=1e7bfb2134dfec37ce04fb3a4ca89299e892d10c'/>
<id>urn:sha1:1e7bfb2134dfec37ce04fb3a4ca89299e892d10c</id>
<content type='text'>
Signed-off-by: Heiko Carstens &lt;heiko.carstens@de.ibm.com&gt;
</content>
</entry>
<entry>
<title>fs/exec.c: make do_coredump() void</title>
<updated>2009-01-06T23:59:29+00:00</updated>
<author>
<name>WANG Cong</name>
<email>wangcong@zeuux.org</email>
</author>
<published>2009-01-06T22:42:48+00:00</published>
<link rel='alternate' type='text/html' href='https://git.rulkc.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=8cd3ac3aca3f2afe8570708066d64d893da468e8'/>
<id>urn:sha1:8cd3ac3aca3f2afe8570708066d64d893da468e8</id>
<content type='text'>
No one cares do_coredump()'s return value, and also it seems that it
is also not necessary. So make it void.

[akpm@linux-foundation.org: coding-style fixes]
Signed-off-by: WANG Cong &lt;wangcong@zeuux.org&gt;
Cc: Alexander Viro &lt;viro@zeniv.linux.org.uk&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>do_coredump(): check return from argv_split()</title>
<updated>2009-01-06T23:59:14+00:00</updated>
<author>
<name>Tetsuo Handa</name>
<email>penguin-kernel@i-love.sakura.ne.jp</email>
</author>
<published>2009-01-06T22:41:11+00:00</published>
<link rel='alternate' type='text/html' href='https://git.rulkc.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=350eaf791bebccb9ad5999351f3e328319545f03'/>
<id>urn:sha1:350eaf791bebccb9ad5999351f3e328319545f03</id>
<content type='text'>
do_coredump() accesses helper_argv[0] without checking helper_argv !=
NULL.  This can happen if page allocation failed.

Signed-off-by: Tetsuo Handa &lt;penguin-kernel@I-love.SAKURA.ne.jp&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>fs/exec.c:__bprm_mm_init(): clean up error handling</title>
<updated>2009-01-06T23:59:11+00:00</updated>
<author>
<name>Luiz Fernando N. Capitulino</name>
<email>lcapitulino@mandriva.com.br</email>
</author>
<published>2009-01-06T22:40:44+00:00</published>
<link rel='alternate' type='text/html' href='https://git.rulkc.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=eaccbfa564e48c87626594511f42dc8c0ad2daae'/>
<id>urn:sha1:eaccbfa564e48c87626594511f42dc8c0ad2daae</id>
<content type='text'>
Untangle the error unwinding in this function, saving a test of local
variable `vma'.

Signed-off-by: Luiz Fernando N. Capitulino &lt;lcapitulino@mandriva.com.br&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>
</feed>
