Pass resource limits values to the plugin in user_info[]
Sudo resets the resource limits early in its execution so the plugin cannot tell what the original limits were itself.
This commit is contained in:
5
NEWS
5
NEWS
@@ -44,6 +44,11 @@ What's new in Sudo 1.9.3
|
|||||||
for "sudoers_policy" but "sudoers_audit" is not listed, those
|
for "sudoers_policy" but "sudoers_audit" is not listed, those
|
||||||
arguments will be applied to "sudoers_audit" instead.
|
arguments will be applied to "sudoers_audit" instead.
|
||||||
|
|
||||||
|
* The user's resource limits are now passed to sudo plugins in
|
||||||
|
the user_info[] list. A plugin cannot determine the limits
|
||||||
|
itself because sudo changes the limits while it runs to prevent
|
||||||
|
resource starvation.
|
||||||
|
|
||||||
What's new in Sudo 1.9.2
|
What's new in Sudo 1.9.2
|
||||||
|
|
||||||
* Fixed package builds on RedHat Enterprise Linux 8.
|
* Fixed package builds on RedHat Enterprise Linux 8.
|
||||||
|
@@ -16,7 +16,7 @@
|
|||||||
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
.\"
|
.\"
|
||||||
.TH "SUDO_PLUGIN" "5" "June 16, 2020" "Sudo @PACKAGE_VERSION@" "File Formats Manual"
|
.TH "SUDO_PLUGIN" "5" "August 31, 2020" "Sudo @PACKAGE_VERSION@" "File Formats Manual"
|
||||||
.nh
|
.nh
|
||||||
.if n .ad l
|
.if n .ad l
|
||||||
.SH "NAME"
|
.SH "NAME"
|
||||||
@@ -513,6 +513,97 @@ The parent process ID of the running
|
|||||||
process.
|
process.
|
||||||
Only available starting with API version 1.2.
|
Only available starting with API version 1.2.
|
||||||
.TP 6n
|
.TP 6n
|
||||||
|
rlimit_as=soft,hard
|
||||||
|
The maximum size to which the process's address space may grow (in bytes),
|
||||||
|
if supported by the operating system.
|
||||||
|
The soft and hard limits are separated by a comma.
|
||||||
|
A value of
|
||||||
|
\(lqinfinity\(rq
|
||||||
|
indicates that there is no limit.
|
||||||
|
Only available starting with API version 1.16.
|
||||||
|
.TP 6n
|
||||||
|
rlimit_core=soft,hard
|
||||||
|
The largest size core dump file that may be created (in bytes).
|
||||||
|
The soft and hard limits are separated by a comma.
|
||||||
|
A value of
|
||||||
|
\(lqinfinity\(rq
|
||||||
|
indicates that there is no limit.
|
||||||
|
Only available starting with API version 1.16.
|
||||||
|
.TP 6n
|
||||||
|
rlimit_cpu=soft,hard
|
||||||
|
The maximum amount of CPU time that the process may use (in seconds).
|
||||||
|
The soft and hard limits are separated by a comma.
|
||||||
|
A value of
|
||||||
|
\(lqinfinity\(rq
|
||||||
|
indicates that there is no limit.
|
||||||
|
Only available starting with API version 1.16.
|
||||||
|
.TP 6n
|
||||||
|
rlimit_data=soft,hard
|
||||||
|
The maximum size of the data segment for the process (in bytes).
|
||||||
|
The soft and hard limits are separated by a comma.
|
||||||
|
A value of
|
||||||
|
\(lqinfinity\(rq
|
||||||
|
indicates that there is no limit.
|
||||||
|
Only available starting with API version 1.16.
|
||||||
|
.TP 6n
|
||||||
|
rlimit_fsize=soft,hard
|
||||||
|
The largest size file that the process may create (in bytes).
|
||||||
|
The soft and hard limits are separated by a comma.
|
||||||
|
A value of
|
||||||
|
\(lqinfinity\(rq
|
||||||
|
indicates that there is no limit.
|
||||||
|
Only available starting with API version 1.16.
|
||||||
|
.TP 6n
|
||||||
|
rlimit_locks=soft,hard
|
||||||
|
The maximum number of locks that the process may establish,
|
||||||
|
if supported by the operating system.
|
||||||
|
The soft and hard limits are separated by a comma.
|
||||||
|
A value of
|
||||||
|
\(lqinfinity\(rq
|
||||||
|
indicates that there is no limit.
|
||||||
|
Only available starting with API version 1.16.
|
||||||
|
.TP 6n
|
||||||
|
rlimit_memlock=soft,hard
|
||||||
|
The maximum size that the process may lock in memory (in bytes),
|
||||||
|
if supported by the operating system.
|
||||||
|
The soft and hard limits are separated by a comma.
|
||||||
|
A value of
|
||||||
|
\(lqinfinity\(rq
|
||||||
|
indicates that there is no limit.
|
||||||
|
Only available starting with API version 1.16.
|
||||||
|
.TP 6n
|
||||||
|
rlimit_nofile=soft,hard
|
||||||
|
The maximum number of files that the process may have open.
|
||||||
|
The soft and hard limits are separated by a comma.
|
||||||
|
A value of
|
||||||
|
\(lqinfinity\(rq
|
||||||
|
indicates that there is no limit.
|
||||||
|
Only available starting with API version 1.16.
|
||||||
|
.TP 6n
|
||||||
|
rlimit_nproc=soft,hard
|
||||||
|
The maximum number of processes that the user may run simultaneously.
|
||||||
|
The soft and hard limits are separated by a comma.
|
||||||
|
A value of
|
||||||
|
\(lqinfinity\(rq
|
||||||
|
indicates that there is no limit.
|
||||||
|
Only available starting with API version 1.16.
|
||||||
|
.TP 6n
|
||||||
|
rlimit_rss=soft,hard
|
||||||
|
The maximum size to which the process's resident set size may grow (in bytes).
|
||||||
|
The soft and hard limits are separated by a comma.
|
||||||
|
A value of
|
||||||
|
\(lqinfinity\(rq
|
||||||
|
indicates that there is no limit.
|
||||||
|
Only available starting with API version 1.16.
|
||||||
|
.TP 6n
|
||||||
|
rlimit_stack=soft,hard
|
||||||
|
The maximum size to which the process's stack may grow (in bytes).
|
||||||
|
The soft and hard limits are separated by a comma.
|
||||||
|
A value of
|
||||||
|
\(lqinfinity\(rq
|
||||||
|
indicates that there is no limit.
|
||||||
|
Only available starting with API version 1.16.
|
||||||
|
.TP 6n
|
||||||
sid=int
|
sid=int
|
||||||
The session ID of the running
|
The session ID of the running
|
||||||
\fBsudo\fR
|
\fBsudo\fR
|
||||||
@@ -4942,6 +5033,11 @@ command was not run.
|
|||||||
has increased from 255 to 1023 bytes.
|
has increased from 255 to 1023 bytes.
|
||||||
.sp
|
.sp
|
||||||
Support for audit and approval plugins was added.
|
Support for audit and approval plugins was added.
|
||||||
|
.TP 6n
|
||||||
|
Version 1.16 (sudo 1.9.3)
|
||||||
|
Initial resource limit values were added to the
|
||||||
|
\fRuser_info\fR
|
||||||
|
list.
|
||||||
.SH "SEE ALSO"
|
.SH "SEE ALSO"
|
||||||
sudo.conf(@mansectform@),
|
sudo.conf(@mansectform@),
|
||||||
sudoers(@mansectform@),
|
sudoers(@mansectform@),
|
||||||
|
@@ -15,7 +15,7 @@
|
|||||||
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
.\"
|
.\"
|
||||||
.Dd June 16, 2020
|
.Dd August 31, 2020
|
||||||
.Dt SUDO_PLUGIN @mansectform@
|
.Dt SUDO_PLUGIN @mansectform@
|
||||||
.Os Sudo @PACKAGE_VERSION@
|
.Os Sudo @PACKAGE_VERSION@
|
||||||
.Sh NAME
|
.Sh NAME
|
||||||
@@ -456,6 +456,86 @@ The parent process ID of the running
|
|||||||
.Nm sudo
|
.Nm sudo
|
||||||
process.
|
process.
|
||||||
Only available starting with API version 1.2.
|
Only available starting with API version 1.2.
|
||||||
|
.It rlimit_as=soft,hard
|
||||||
|
The maximum size to which the process's address space may grow (in bytes),
|
||||||
|
if supported by the operating system.
|
||||||
|
The soft and hard limits are separated by a comma.
|
||||||
|
A value of
|
||||||
|
.Dq infinity
|
||||||
|
indicates that there is no limit.
|
||||||
|
Only available starting with API version 1.16.
|
||||||
|
.It rlimit_core=soft,hard
|
||||||
|
The largest size core dump file that may be created (in bytes).
|
||||||
|
The soft and hard limits are separated by a comma.
|
||||||
|
A value of
|
||||||
|
.Dq infinity
|
||||||
|
indicates that there is no limit.
|
||||||
|
Only available starting with API version 1.16.
|
||||||
|
.It rlimit_cpu=soft,hard
|
||||||
|
The maximum amount of CPU time that the process may use (in seconds).
|
||||||
|
The soft and hard limits are separated by a comma.
|
||||||
|
A value of
|
||||||
|
.Dq infinity
|
||||||
|
indicates that there is no limit.
|
||||||
|
Only available starting with API version 1.16.
|
||||||
|
.It rlimit_data=soft,hard
|
||||||
|
The maximum size of the data segment for the process (in bytes).
|
||||||
|
The soft and hard limits are separated by a comma.
|
||||||
|
A value of
|
||||||
|
.Dq infinity
|
||||||
|
indicates that there is no limit.
|
||||||
|
Only available starting with API version 1.16.
|
||||||
|
.It rlimit_fsize=soft,hard
|
||||||
|
The largest size file that the process may create (in bytes).
|
||||||
|
The soft and hard limits are separated by a comma.
|
||||||
|
A value of
|
||||||
|
.Dq infinity
|
||||||
|
indicates that there is no limit.
|
||||||
|
Only available starting with API version 1.16.
|
||||||
|
.It rlimit_locks=soft,hard
|
||||||
|
The maximum number of locks that the process may establish,
|
||||||
|
if supported by the operating system.
|
||||||
|
The soft and hard limits are separated by a comma.
|
||||||
|
A value of
|
||||||
|
.Dq infinity
|
||||||
|
indicates that there is no limit.
|
||||||
|
Only available starting with API version 1.16.
|
||||||
|
.It rlimit_memlock=soft,hard
|
||||||
|
The maximum size that the process may lock in memory (in bytes),
|
||||||
|
if supported by the operating system.
|
||||||
|
The soft and hard limits are separated by a comma.
|
||||||
|
A value of
|
||||||
|
.Dq infinity
|
||||||
|
indicates that there is no limit.
|
||||||
|
Only available starting with API version 1.16.
|
||||||
|
.It rlimit_nofile=soft,hard
|
||||||
|
The maximum number of files that the process may have open.
|
||||||
|
The soft and hard limits are separated by a comma.
|
||||||
|
A value of
|
||||||
|
.Dq infinity
|
||||||
|
indicates that there is no limit.
|
||||||
|
Only available starting with API version 1.16.
|
||||||
|
.It rlimit_nproc=soft,hard
|
||||||
|
The maximum number of processes that the user may run simultaneously.
|
||||||
|
The soft and hard limits are separated by a comma.
|
||||||
|
A value of
|
||||||
|
.Dq infinity
|
||||||
|
indicates that there is no limit.
|
||||||
|
Only available starting with API version 1.16.
|
||||||
|
.It rlimit_rss=soft,hard
|
||||||
|
The maximum size to which the process's resident set size may grow (in bytes).
|
||||||
|
The soft and hard limits are separated by a comma.
|
||||||
|
A value of
|
||||||
|
.Dq infinity
|
||||||
|
indicates that there is no limit.
|
||||||
|
Only available starting with API version 1.16.
|
||||||
|
.It rlimit_stack=soft,hard
|
||||||
|
The maximum size to which the process's stack may grow (in bytes).
|
||||||
|
The soft and hard limits are separated by a comma.
|
||||||
|
A value of
|
||||||
|
.Dq infinity
|
||||||
|
indicates that there is no limit.
|
||||||
|
Only available starting with API version 1.16.
|
||||||
.It sid=int
|
.It sid=int
|
||||||
The session ID of the running
|
The session ID of the running
|
||||||
.Nm sudo
|
.Nm sudo
|
||||||
@@ -4367,6 +4447,10 @@ command was not run.
|
|||||||
has increased from 255 to 1023 bytes.
|
has increased from 255 to 1023 bytes.
|
||||||
.Pp
|
.Pp
|
||||||
Support for audit and approval plugins was added.
|
Support for audit and approval plugins was added.
|
||||||
|
.It Version 1.16 (sudo 1.9.3)
|
||||||
|
Initial resource limit values were added to the
|
||||||
|
.Li user_info
|
||||||
|
list.
|
||||||
.El
|
.El
|
||||||
.Sh SEE ALSO
|
.Sh SEE ALSO
|
||||||
.Xr sudo.conf @mansectform@ ,
|
.Xr sudo.conf @mansectform@ ,
|
||||||
|
@@ -21,7 +21,7 @@
|
|||||||
|
|
||||||
/* API version major/minor */
|
/* API version major/minor */
|
||||||
#define SUDO_API_VERSION_MAJOR 1
|
#define SUDO_API_VERSION_MAJOR 1
|
||||||
#define SUDO_API_VERSION_MINOR 15
|
#define SUDO_API_VERSION_MINOR 16
|
||||||
#define SUDO_API_MKVERSION(x, y) (((x) << 16) | (y))
|
#define SUDO_API_MKVERSION(x, y) (((x) << 16) | (y))
|
||||||
#define SUDO_API_VERSION SUDO_API_MKVERSION(SUDO_API_VERSION_MAJOR, SUDO_API_VERSION_MINOR)
|
#define SUDO_API_VERSION SUDO_API_MKVERSION(SUDO_API_VERSION_MAJOR, SUDO_API_VERSION_MINOR)
|
||||||
|
|
||||||
|
@@ -26,7 +26,7 @@
|
|||||||
"INFO1=VALUE1",
|
"INFO1=VALUE1",
|
||||||
"info2=value2"
|
"info2=value2"
|
||||||
\],
|
\],
|
||||||
"version": "1.15"
|
"version": "1.16"
|
||||||
}
|
}
|
||||||
(APPROVAL 2) Constructed:
|
(APPROVAL 2) Constructed:
|
||||||
{
|
{
|
||||||
@@ -56,7 +56,7 @@
|
|||||||
"INFO1=VALUE1",
|
"INFO1=VALUE1",
|
||||||
"info2=value2"
|
"info2=value2"
|
||||||
\],
|
\],
|
||||||
"version": "1.15"
|
"version": "1.16"
|
||||||
}
|
}
|
||||||
(APPROVAL 1) Show version was called with arguments: (0,)
|
(APPROVAL 1) Show version was called with arguments: (0,)
|
||||||
Python approval plugin (API 1.0): ApprovalTestPlugin (loaded from 'SRC_DIR/regress/plugin_approval_test.py')
|
Python approval plugin (API 1.0): ApprovalTestPlugin (loaded from 'SRC_DIR/regress/plugin_approval_test.py')
|
||||||
|
@@ -309,7 +309,7 @@ sudo_terminated(struct command_status *cstat)
|
|||||||
debug_return_bool(false);
|
debug_return_bool(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if SUDO_API_VERSION != SUDO_API_MKVERSION(1, 15)
|
#if SUDO_API_VERSION != SUDO_API_MKVERSION(1, 16)
|
||||||
# error "Update sudo_needs_pty() after changing the plugin API"
|
# error "Update sudo_needs_pty() after changing the plugin API"
|
||||||
#endif
|
#endif
|
||||||
static bool
|
static bool
|
||||||
|
89
src/limits.c
89
src/limits.c
@@ -24,6 +24,7 @@
|
|||||||
#include <config.h>
|
#include <config.h>
|
||||||
|
|
||||||
#include <sys/resource.h>
|
#include <sys/resource.h>
|
||||||
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#ifdef __linux__
|
#ifdef __linux__
|
||||||
@@ -55,6 +56,11 @@
|
|||||||
# define RLIM_INFINITY RLIM64_INFINITY
|
# define RLIM_INFINITY RLIM64_INFINITY
|
||||||
#endif /* HAVE_SETRLIMIT64 */
|
#endif /* HAVE_SETRLIMIT64 */
|
||||||
|
|
||||||
|
/* Older BSD systems have RLIMIT_VMEM, not RLIMIT_AS. */
|
||||||
|
#if !defined(RLIMIT_AS) && defined(RLIMIT_VMEM)
|
||||||
|
# define RLIMIT_AS RLIMIT_VMEM
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* macOS doesn't allow nofile soft limit to be infinite or
|
* macOS doesn't allow nofile soft limit to be infinite or
|
||||||
* the stack hard limit to be infinite.
|
* the stack hard limit to be infinite.
|
||||||
@@ -64,27 +70,35 @@ static struct rlimit nofile_fallback = { SUDO_OPEN_MAX, RLIM_INFINITY };
|
|||||||
static struct rlimit stack_fallback = { SUDO_STACK_MIN, 65532 * 1024 };
|
static struct rlimit stack_fallback = { SUDO_STACK_MIN, 65532 * 1024 };
|
||||||
|
|
||||||
static struct saved_limit {
|
static struct saved_limit {
|
||||||
const char *name;
|
const char *name; /* rlimit_foo in lower case */
|
||||||
int resource;
|
int resource; /* RLIMIT_FOO definition */
|
||||||
bool saved;
|
bool override; /* override limit while sudo executes? */
|
||||||
struct rlimit *fallback;
|
bool saved; /* true if we were able to get the value */
|
||||||
struct rlimit newlimit;
|
struct rlimit *fallback; /* fallback if we fail to set to newlimit */
|
||||||
struct rlimit oldlimit;
|
struct rlimit newlimit; /* new limit to use if override is true */
|
||||||
|
struct rlimit oldlimit; /* original limit, valid if saved is true */
|
||||||
} saved_limits[] = {
|
} saved_limits[] = {
|
||||||
#ifdef RLIMIT_AS
|
#ifdef RLIMIT_AS
|
||||||
{ "RLIMIT_AS", RLIMIT_AS, false, NULL, { RLIM_INFINITY, RLIM_INFINITY } },
|
{ "rlimit_as", RLIMIT_AS, true, false, NULL, { RLIM_INFINITY, RLIM_INFINITY } },
|
||||||
#endif
|
#endif
|
||||||
{ "RLIMIT_CPU", RLIMIT_CPU, false, NULL, { RLIM_INFINITY, RLIM_INFINITY } },
|
{ "rlimit_core", RLIMIT_CORE, false },
|
||||||
{ "RLIMIT_DATA", RLIMIT_DATA, false, NULL, { RLIM_INFINITY, RLIM_INFINITY } },
|
{ "rlimit_cpu", RLIMIT_CPU, true, false, NULL, { RLIM_INFINITY, RLIM_INFINITY } },
|
||||||
{ "RLIMIT_FSIZE", RLIMIT_FSIZE, false, NULL, { RLIM_INFINITY, RLIM_INFINITY } },
|
{ "rlimit_data", RLIMIT_DATA, true, false, NULL, { RLIM_INFINITY, RLIM_INFINITY } },
|
||||||
{ "RLIMIT_NOFILE", RLIMIT_NOFILE, false, &nofile_fallback, { RLIM_INFINITY, RLIM_INFINITY } },
|
{ "rlimit_fsize", RLIMIT_FSIZE, true, false, NULL, { RLIM_INFINITY, RLIM_INFINITY } },
|
||||||
|
#ifdef RLIMIT_LOCKS
|
||||||
|
{ "rlimit_locks", RLIMIT_LOCKS, false },
|
||||||
|
#endif
|
||||||
|
#ifdef RLIMIT_MEMLOCK
|
||||||
|
{ "rlimit_memlock", RLIMIT_MEMLOCK, false },
|
||||||
|
#endif
|
||||||
|
{ "rlimit_nofile", RLIMIT_NOFILE, true, false, &nofile_fallback, { RLIM_INFINITY, RLIM_INFINITY } },
|
||||||
#ifdef RLIMIT_NPROC
|
#ifdef RLIMIT_NPROC
|
||||||
{ "RLIMIT_NPROC", RLIMIT_NPROC, false, NULL, { RLIM_INFINITY, RLIM_INFINITY } },
|
{ "rlimit_nproc", RLIMIT_NPROC, true, false, NULL, { RLIM_INFINITY, RLIM_INFINITY } },
|
||||||
#endif
|
#endif
|
||||||
#ifdef RLIMIT_RSS
|
#ifdef RLIMIT_RSS
|
||||||
{ "RLIMIT_RSS", RLIMIT_RSS, false, NULL, { RLIM_INFINITY, RLIM_INFINITY } },
|
{ "rlimit_rss", RLIMIT_RSS, true, false, NULL, { RLIM_INFINITY, RLIM_INFINITY } },
|
||||||
#endif
|
#endif
|
||||||
{ "RLIMIT_STACK", RLIMIT_STACK, false, &stack_fallback, { SUDO_STACK_MIN, RLIM_INFINITY } }
|
{ "rlimit_stack", RLIMIT_STACK, true, false, &stack_fallback, { SUDO_STACK_MIN, RLIM_INFINITY } }
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct rlimit corelimit;
|
static struct rlimit corelimit;
|
||||||
@@ -228,6 +242,9 @@ unlimit_sudo(void)
|
|||||||
(long long)lim->oldlimit.rlim_max);
|
(long long)lim->oldlimit.rlim_max);
|
||||||
|
|
||||||
lim->saved = true;
|
lim->saved = true;
|
||||||
|
if (!lim->override)
|
||||||
|
continue;
|
||||||
|
|
||||||
if (lim->newlimit.rlim_cur != RLIM_INFINITY) {
|
if (lim->newlimit.rlim_cur != RLIM_INFINITY) {
|
||||||
/* Don't reduce the soft resource limit. */
|
/* Don't reduce the soft resource limit. */
|
||||||
if (lim->oldlimit.rlim_cur == RLIM_INFINITY ||
|
if (lim->oldlimit.rlim_cur == RLIM_INFINITY ||
|
||||||
@@ -284,7 +301,7 @@ restore_limits(void)
|
|||||||
/* Restore resource limits to saved values. */
|
/* Restore resource limits to saved values. */
|
||||||
for (idx = 0; idx < nitems(saved_limits); idx++) {
|
for (idx = 0; idx < nitems(saved_limits); idx++) {
|
||||||
struct saved_limit *lim = &saved_limits[idx];
|
struct saved_limit *lim = &saved_limits[idx];
|
||||||
if (lim->saved) {
|
if (lim->override && lim->saved) {
|
||||||
struct rlimit rl = lim->oldlimit;
|
struct rlimit rl = lim->oldlimit;
|
||||||
int i, rc;
|
int i, rc;
|
||||||
|
|
||||||
@@ -324,3 +341,45 @@ restore_limits(void)
|
|||||||
|
|
||||||
debug_return;
|
debug_return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
serialize_limits(char **info, size_t info_max)
|
||||||
|
{
|
||||||
|
char *str;
|
||||||
|
unsigned int idx, nstored = 0;
|
||||||
|
debug_decl(serialize_limits, SUDO_DEBUG_UTIL);
|
||||||
|
|
||||||
|
for (idx = 0; idx < nitems(saved_limits); idx++) {
|
||||||
|
const struct saved_limit *lim = &saved_limits[idx];
|
||||||
|
const struct rlimit *rl = &lim->oldlimit;
|
||||||
|
char curlim[(((sizeof(int) * 8) + 2) / 3) + 2];
|
||||||
|
char maxlim[(((sizeof(int) * 8) + 2) / 3) + 2];
|
||||||
|
|
||||||
|
if (!lim->saved)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (nstored == info_max)
|
||||||
|
goto oom;
|
||||||
|
|
||||||
|
if (rl->rlim_cur == RLIM_INFINITY) {
|
||||||
|
strlcpy(curlim, "infinity", sizeof(curlim));
|
||||||
|
} else {
|
||||||
|
snprintf(curlim, sizeof(curlim), "%llu",
|
||||||
|
(unsigned long long)rl->rlim_cur);
|
||||||
|
}
|
||||||
|
if (rl->rlim_max == RLIM_INFINITY) {
|
||||||
|
strlcpy(maxlim, "infinity", sizeof(maxlim));
|
||||||
|
} else {
|
||||||
|
snprintf(maxlim, sizeof(maxlim), "%llu",
|
||||||
|
(unsigned long long)rl->rlim_max);
|
||||||
|
}
|
||||||
|
if (asprintf(&str, "%s=%s,%s", lim->name, curlim, maxlim) == -1)
|
||||||
|
goto oom;
|
||||||
|
info[nstored++] = str;
|
||||||
|
}
|
||||||
|
debug_return_int(nstored);
|
||||||
|
oom:
|
||||||
|
while (nstored--)
|
||||||
|
free(info[nstored]);
|
||||||
|
debug_return_int(-1);
|
||||||
|
}
|
||||||
|
11
src/sudo.c
11
src/sudo.c
@@ -30,6 +30,7 @@
|
|||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <sys/wait.h>
|
#include <sys/wait.h>
|
||||||
|
#include <sys/resource.h>
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
@@ -490,10 +491,11 @@ static char **
|
|||||||
get_user_info(struct user_details *ud)
|
get_user_info(struct user_details *ud)
|
||||||
{
|
{
|
||||||
char *cp, **user_info, path[PATH_MAX];
|
char *cp, **user_info, path[PATH_MAX];
|
||||||
|
size_t user_info_max = 32 + RLIM_NLIMITS;
|
||||||
unsigned int i = 0;
|
unsigned int i = 0;
|
||||||
mode_t mask;
|
mode_t mask;
|
||||||
struct passwd *pw;
|
struct passwd *pw;
|
||||||
int fd;
|
int fd, n;
|
||||||
debug_decl(get_user_info, SUDO_DEBUG_UTIL);
|
debug_decl(get_user_info, SUDO_DEBUG_UTIL);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -512,7 +514,7 @@ get_user_info(struct user_details *ud)
|
|||||||
memset(ud, 0, sizeof(*ud));
|
memset(ud, 0, sizeof(*ud));
|
||||||
|
|
||||||
/* XXX - bound check number of entries */
|
/* XXX - bound check number of entries */
|
||||||
user_info = reallocarray(NULL, 32, sizeof(char *));
|
user_info = reallocarray(NULL, user_info_max, sizeof(char *));
|
||||||
if (user_info == NULL)
|
if (user_info == NULL)
|
||||||
goto oom;
|
goto oom;
|
||||||
|
|
||||||
@@ -614,6 +616,11 @@ get_user_info(struct user_details *ud)
|
|||||||
if (asprintf(&user_info[++i], "cols=%d", ud->ts_cols) == -1)
|
if (asprintf(&user_info[++i], "cols=%d", ud->ts_cols) == -1)
|
||||||
goto oom;
|
goto oom;
|
||||||
|
|
||||||
|
n = serialize_limits(&user_info[i + 1], user_info_max - (i + 1));
|
||||||
|
if (n == -1)
|
||||||
|
goto oom;
|
||||||
|
i += n;
|
||||||
|
|
||||||
user_info[++i] = NULL;
|
user_info[++i] = NULL;
|
||||||
|
|
||||||
/* Add to list of vectors to be garbage collected at exit. */
|
/* Add to list of vectors to be garbage collected at exit. */
|
||||||
|
@@ -293,5 +293,6 @@ void restore_limits(void);
|
|||||||
void restore_nproc(void);
|
void restore_nproc(void);
|
||||||
void unlimit_nproc(void);
|
void unlimit_nproc(void);
|
||||||
void unlimit_sudo(void);
|
void unlimit_sudo(void);
|
||||||
|
int serialize_limits(char **info, size_t info_max);
|
||||||
|
|
||||||
#endif /* SUDO_SUDO_H */
|
#endif /* SUDO_SUDO_H */
|
||||||
|
Reference in New Issue
Block a user