|
|
31e40a |
From f16317f50e663ac0343bc96c01496f6b94c6211c Mon Sep 17 00:00:00 2001
|
|
|
31e40a |
From: =?UTF-8?q?Nikola=20Forr=C3=B3?= <nforro@redhat.com>
|
|
|
31e40a |
Date: Mon, 26 Nov 2018 17:10:36 +0100
|
|
|
31e40a |
Subject: [PATCH] execve.2: document EAGAIN error
|
|
|
31e40a |
MIME-Version: 1.0
|
|
|
31e40a |
Content-Type: text/plain; charset=UTF-8
|
|
|
31e40a |
Content-Transfer-Encoding: 8bit
|
|
|
31e40a |
|
|
|
31e40a |
---
|
|
|
31e40a |
man-pages/man2/execve.2 | 78 +++++++++++++++++++++++++++++++++++++++++
|
|
|
31e40a |
1 file changed, 78 insertions(+)
|
|
|
31e40a |
|
|
|
31e40a |
diff --git a/man-pages/man2/execve.2 b/man-pages/man2/execve.2
|
|
|
31e40a |
index 3343372..192b90a 100644
|
|
|
31e40a |
--- a/man-pages/man2/execve.2
|
|
|
31e40a |
+++ b/man-pages/man2/execve.2
|
|
|
31e40a |
@@ -384,6 +384,16 @@ Execute permission is denied for the file or a script or ELF interpreter.
|
|
|
31e40a |
The file system is mounted
|
|
|
31e40a |
.IR noexec .
|
|
|
31e40a |
.TP
|
|
|
31e40a |
+.BR EAGAIN " (since Linux 3.1)"
|
|
|
31e40a |
+.\" commit 72fa59970f8698023045ab0713d66f3f4f96945c
|
|
|
31e40a |
+Having changed its real UID using one of the
|
|
|
31e40a |
+.BR set*uid ()
|
|
|
31e40a |
+calls, the caller was\(emand is now still\(emabove its
|
|
|
31e40a |
+.BR RLIMIT_NPROC
|
|
|
31e40a |
+resource limit (see
|
|
|
31e40a |
+.BR setrlimit (2)).
|
|
|
31e40a |
+For a more detailed explanation of this error, see NOTES.
|
|
|
31e40a |
+.TP
|
|
|
31e40a |
.B EFAULT
|
|
|
31e40a |
.I filename
|
|
|
31e40a |
points outside your accessible address space.
|
|
|
31e40a |
@@ -530,6 +540,74 @@ command-line arguments and environment variables has changed.
|
|
|
31e40a |
.\" .BR execve ()
|
|
|
31e40a |
.\" that could be exploited for denial of service by a suitably crafted
|
|
|
31e40a |
.\" ELF binary. There are no known problems with 2.0.34 or 2.2.15.
|
|
|
31e40a |
+.SS execve() and EAGAIN
|
|
|
31e40a |
+A more detailed explanation of the
|
|
|
31e40a |
+.BR EAGAIN
|
|
|
31e40a |
+error that can occur (since Linux 3.1) when calling
|
|
|
31e40a |
+.BR execve ()
|
|
|
31e40a |
+is as follows.
|
|
|
31e40a |
+
|
|
|
31e40a |
+The
|
|
|
31e40a |
+.BR EAGAIN
|
|
|
31e40a |
+error can occur when a
|
|
|
31e40a |
+.I preceding
|
|
|
31e40a |
+call to
|
|
|
31e40a |
+.BR setuid (2),
|
|
|
31e40a |
+.BR setreuid (2),
|
|
|
31e40a |
+or
|
|
|
31e40a |
+.BR setresuid (2)
|
|
|
31e40a |
+caused the real user ID of the process to change,
|
|
|
31e40a |
+and that change caused the process to exceed its
|
|
|
31e40a |
+.BR RLIMIT_NPROC
|
|
|
31e40a |
+resource limit (i.e., the number of processes belonging
|
|
|
31e40a |
+to the new real UID exceeds the resource limit).
|
|
|
31e40a |
+In Linux 3.0 and earlier, this caused the
|
|
|
31e40a |
+.BR set*uid ()
|
|
|
31e40a |
+call to fail.
|
|
|
31e40a |
+
|
|
|
31e40a |
+Since Linux 3.1, the scenario just described no longer causes the
|
|
|
31e40a |
+.BR set*uid ()
|
|
|
31e40a |
+call to fail,
|
|
|
31e40a |
+because it too often led to security holes where buggy applications
|
|
|
31e40a |
+didn't check the return status and assumed
|
|
|
31e40a |
+that\(emif the caller had root privileges\(emthe call would always succeed.
|
|
|
31e40a |
+Instead, the
|
|
|
31e40a |
+.BR set*uid ()
|
|
|
31e40a |
+calls now successfully change the real UID,
|
|
|
31e40a |
+but the kernel sets an internal flag, named
|
|
|
31e40a |
+.BR PF_NPROC_EXCEEDED ,
|
|
|
31e40a |
+to note that the
|
|
|
31e40a |
+.BR RLIMIT_NPROC
|
|
|
31e40a |
+resource limit has been exceeded.
|
|
|
31e40a |
+If the resource limit is still exceeded at the time of a subsequent
|
|
|
31e40a |
+.BR execve ()
|
|
|
31e40a |
+call, that call fails with the error
|
|
|
31e40a |
+.BR EAGAIN .
|
|
|
31e40a |
+This kernel logic ensures that the
|
|
|
31e40a |
+.BR RLIMIT_NPROC
|
|
|
31e40a |
+resource limit is still enforced for the
|
|
|
31e40a |
+common privileged daemon workflow\(emnamely,
|
|
|
31e40a |
+.BR fork (2)
|
|
|
31e40a |
++
|
|
|
31e40a |
+.BR set*uid ()
|
|
|
31e40a |
++
|
|
|
31e40a |
+.BR execve ().
|
|
|
31e40a |
+
|
|
|
31e40a |
+If the resource limit was not still exceeded at the time of the
|
|
|
31e40a |
+.BR execve ()
|
|
|
31e40a |
+call
|
|
|
31e40a |
+(because other processes belonging to this real UID terminated between the
|
|
|
31e40a |
+.BR set*uid()
|
|
|
31e40a |
+call and the
|
|
|
31e40a |
+.BR execve ()
|
|
|
31e40a |
+call), then the
|
|
|
31e40a |
+.BR execve ()
|
|
|
31e40a |
+call succeeds and the kernel clears the
|
|
|
31e40a |
+.BR PF_NPROC_EXCEEDED
|
|
|
31e40a |
+process flag.
|
|
|
31e40a |
+The flag is also cleared if a subsequent call to
|
|
|
31e40a |
+.BR fork (2)
|
|
|
31e40a |
+by this process succeeds.
|
|
|
31e40a |
.SS Historical
|
|
|
31e40a |
With UNIX V6 the argument list of an
|
|
|
31e40a |
.BR exec ()
|
|
|
31e40a |
--
|
|
|
31e40a |
2.17.2
|
|
|
31e40a |
|