Add support for intercepting the system(3) function.
This also means we can log system(3) with log_subcmds.
This commit is contained in:
@@ -17,7 +17,7 @@
|
||||
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
.\"
|
||||
.nr SL @SEMAN@
|
||||
.TH "SUDO.CONF" "@mansectform@" "April 28, 2022" "Sudo @PACKAGE_VERSION@" "File Formats Manual"
|
||||
.TH "SUDO.CONF" "@mansectform@" "May 31, 2022" "Sudo @PACKAGE_VERSION@" "File Formats Manual"
|
||||
.nh
|
||||
.if n .ad l
|
||||
.SH "NAME"
|
||||
@@ -296,8 +296,9 @@ The fully-qualified path to a shared library containing a wrappers for the
|
||||
\fBexecv\fR(),
|
||||
\fBexecve\fR(),
|
||||
\fBexecvp\fR(),
|
||||
\fBexecvpe\fR(),
|
||||
and
|
||||
\fBexecvpe\fR()
|
||||
\fBsystem\fR()
|
||||
library functions that intercepts attempts to run further commands and
|
||||
performs a policy check before allowing them to be executed.
|
||||
This is used to implement the
|
||||
|
@@ -16,7 +16,7 @@
|
||||
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
.\"
|
||||
.nr SL @SEMAN@
|
||||
.Dd April 28, 2022
|
||||
.Dd May 31, 2022
|
||||
.Dt SUDO.CONF @mansectform@
|
||||
.Os Sudo @PACKAGE_VERSION@
|
||||
.Sh NAME
|
||||
@@ -271,8 +271,9 @@ The fully-qualified path to a shared library containing a wrappers for the
|
||||
.Fn execv ,
|
||||
.Fn execve ,
|
||||
.Fn execvp ,
|
||||
.Fn execvpe ,
|
||||
and
|
||||
.Fn execvpe
|
||||
.Fn system
|
||||
library functions that intercepts attempts to run further commands and
|
||||
performs a policy check before allowing them to be executed.
|
||||
This is used to implement the
|
||||
|
@@ -25,7 +25,7 @@
|
||||
.nr BA @BAMAN@
|
||||
.nr LC @LCMAN@
|
||||
.nr PS @PSMAN@
|
||||
.TH "SUDOERS" "@mansectform@" "May 24, 2022" "Sudo @PACKAGE_VERSION@" "File Formats Manual"
|
||||
.TH "SUDOERS" "@mansectform@" "May 31, 2022" "Sudo @PACKAGE_VERSION@" "File Formats Manual"
|
||||
.nh
|
||||
.if n .ad l
|
||||
.SH "NAME"
|
||||
@@ -3151,8 +3151,9 @@ using the
|
||||
\fBexecv\fR(),
|
||||
\fBexecve\fR(),
|
||||
\fBexecvp\fR(),
|
||||
\fBexecvpe\fR(),
|
||||
or
|
||||
\fBexecvpe\fR()
|
||||
\fBsystem\fR()
|
||||
library functions.
|
||||
For example, if a shell is run by
|
||||
\fBsudo\fR,
|
||||
@@ -4305,8 +4306,9 @@ Preload a dynamic shared object (shared library) that intercepts the
|
||||
\fBexecv\fR(),
|
||||
\fBexecve\fR(),
|
||||
\fBexecvp\fR(),
|
||||
\fBexecvpe\fR(),
|
||||
and
|
||||
\fBexecvpe\fR()
|
||||
\fBsystem\fR()
|
||||
library functions.
|
||||
A value of
|
||||
\fIdso\fR
|
||||
@@ -6929,8 +6931,9 @@ functionality only works for programs that use the
|
||||
\fBexecv\fR(),
|
||||
\fBexecve\fR(),
|
||||
\fBexecvp\fR(),
|
||||
\fBexecvpe\fR(),
|
||||
or
|
||||
\fBexecvpe\fR()
|
||||
\fBsystem\fR()
|
||||
library functions to run the new command.
|
||||
This may be expanded in a future release of
|
||||
\fBsudo\fR.
|
||||
|
@@ -25,7 +25,7 @@
|
||||
.nr BA @BAMAN@
|
||||
.nr LC @LCMAN@
|
||||
.nr PS @PSMAN@
|
||||
.Dd May 24, 2022
|
||||
.Dd May 31, 2022
|
||||
.Dt SUDOERS @mansectform@
|
||||
.Os Sudo @PACKAGE_VERSION@
|
||||
.Sh NAME
|
||||
@@ -2985,8 +2985,9 @@ using the
|
||||
.Fn execv ,
|
||||
.Fn execve ,
|
||||
.Fn execvp ,
|
||||
.Fn execvpe ,
|
||||
or
|
||||
.Fn execvpe
|
||||
.Fn system
|
||||
library functions.
|
||||
For example, if a shell is run by
|
||||
.Nm sudo ,
|
||||
@@ -4077,8 +4078,9 @@ Preload a dynamic shared object (shared library) that intercepts the
|
||||
.Fn execv ,
|
||||
.Fn execve ,
|
||||
.Fn execvp ,
|
||||
.Fn execvpe ,
|
||||
and
|
||||
.Fn execvpe
|
||||
.Fn system
|
||||
library functions.
|
||||
A value of
|
||||
.Em dso
|
||||
@@ -6420,8 +6422,9 @@ functionality only works for programs that use the
|
||||
.Fn execv ,
|
||||
.Fn execve ,
|
||||
.Fn execvp ,
|
||||
.Fn execvpe ,
|
||||
or
|
||||
.Fn execvpe
|
||||
.Fn system
|
||||
library functions to run the new command.
|
||||
This may be expanded in a future release of
|
||||
.Nm sudo .
|
||||
|
@@ -4,3 +4,4 @@ execlp
|
||||
execv
|
||||
execve
|
||||
execvp
|
||||
system
|
||||
|
@@ -25,6 +25,7 @@
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/wait.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdarg.h>
|
||||
@@ -34,6 +35,7 @@
|
||||
#include <unistd.h>
|
||||
#include <limits.h>
|
||||
#include <string.h>
|
||||
#include <signal.h>
|
||||
#ifdef HAVE_STDBOOL_H
|
||||
# include <stdbool.h>
|
||||
#else
|
||||
@@ -193,7 +195,8 @@ exec_wrapper(const char *cmnd, char * const argv[], char * const envp[],
|
||||
static int
|
||||
execl_wrapper(int type, const char *name, const char *arg, va_list ap)
|
||||
{
|
||||
char **argv, **envp = environ;
|
||||
char * const *envp = environ;
|
||||
char **argv;
|
||||
int argc = 1;
|
||||
va_list ap2;
|
||||
debug_decl(execl_wrapper, SUDO_DEBUG_EXEC);
|
||||
@@ -219,6 +222,72 @@ execl_wrapper(int type, const char *name, const char *arg, va_list ap)
|
||||
debug_return_int(-1);
|
||||
}
|
||||
|
||||
static int
|
||||
system_wrapper(const char *cmnd)
|
||||
{
|
||||
char * const argv[] = { "sh", "-c", (char *)cmnd, NULL };
|
||||
const char shell[] = _PATH_SUDO_BSHELL;
|
||||
struct sigaction saveint, savequit, sa;
|
||||
sigset_t mask, omask;
|
||||
pid_t child;
|
||||
int status;
|
||||
debug_decl(system_wrapper, SUDO_DEBUG_EXEC);
|
||||
|
||||
/* Special case for NULL command, just check whether shell exists. */
|
||||
if (cmnd == NULL)
|
||||
debug_return_int(access(shell, X_OK) == 0);
|
||||
|
||||
/* First, block signals to avoid potential race conditions. */
|
||||
sigemptyset(&mask);
|
||||
sigaddset(&mask, SIGCHLD);
|
||||
sigaddset(&mask, SIGINT);
|
||||
sigaddset(&mask, SIGQUIT);
|
||||
if (sigprocmask(SIG_BLOCK, &mask, &omask) == -1)
|
||||
debug_return_int(-1);
|
||||
|
||||
switch (child = vfork()) {
|
||||
case -1:
|
||||
/* error */
|
||||
(void)sigprocmask(SIG_SETMASK, &omask, NULL);
|
||||
debug_return_int(-1);
|
||||
case 0:
|
||||
/* child */
|
||||
if (sigprocmask(SIG_SETMASK, &omask, NULL) != -1)
|
||||
exec_wrapper(shell, argv, environ, false);
|
||||
_exit(127);
|
||||
default:
|
||||
/* parent */
|
||||
break;
|
||||
}
|
||||
|
||||
/* We must ignore SIGINT and SIGQUIT until the command finishes. */
|
||||
memset(&sa, 0, sizeof(sa));
|
||||
sigemptyset(&sa.sa_mask);
|
||||
sa.sa_handler = SIG_IGN;
|
||||
(void)sigaction(SIGINT, &sa, &saveint);
|
||||
(void)sigaction(SIGQUIT, &sa, &savequit);
|
||||
sigemptyset(&mask);
|
||||
sigaddset(&mask, SIGINT);
|
||||
sigaddset(&mask, SIGQUIT);
|
||||
(void)sigprocmask(SIG_UNBLOCK, &mask, NULL);
|
||||
|
||||
for (;;) {
|
||||
if (waitpid(child, &status, 0) == -1) {
|
||||
if (errno == EINTR)
|
||||
continue;
|
||||
status = -1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
/* Restore signal mask and handlers. */
|
||||
(void)sigprocmask(SIG_SETMASK, &omask, NULL);
|
||||
(void)sigaction(SIGINT, &saveint, NULL);
|
||||
(void)sigaction(SIGQUIT, &savequit, NULL);
|
||||
|
||||
debug_return_int(status);
|
||||
}
|
||||
|
||||
#ifdef HAVE___INTERPOSE
|
||||
/*
|
||||
* Mac OS X 10.4 and above has support for library symbol interposition.
|
||||
@@ -229,6 +298,12 @@ typedef struct interpose_s {
|
||||
void *orig_func;
|
||||
} interpose_t;
|
||||
|
||||
static int
|
||||
my_system(const char *cmnd)
|
||||
{
|
||||
return system_wrapper(cmnd);
|
||||
}
|
||||
|
||||
static int
|
||||
my_execve(const char *cmnd, char * const argv[], char * const envp[])
|
||||
{
|
||||
@@ -238,7 +313,7 @@ my_execve(const char *cmnd, char * const argv[], char * const envp[])
|
||||
static int
|
||||
my_execv(const char *cmnd, char * const argv[])
|
||||
{
|
||||
return execve(cmnd, argv, environ);
|
||||
return exec_wrapper(cmnd, argv, environ, false);
|
||||
}
|
||||
|
||||
#ifdef HAVE_EXECVPE
|
||||
@@ -294,6 +369,7 @@ my_execlp(const char *name, const char *arg, ...)
|
||||
/* Magic to tell dyld to do symbol interposition. */
|
||||
__attribute__((__used__)) static const interpose_t interposers[]
|
||||
__attribute__((__section__("__DATA,__interpose"))) = {
|
||||
{ (void *)my_system, (void *)system },
|
||||
{ (void *)my_execl, (void *)execl },
|
||||
{ (void *)my_execle, (void *)execle },
|
||||
{ (void *)my_execlp, (void *)execlp },
|
||||
@@ -332,6 +408,12 @@ sudo_shl_get_next(const char *symbol, short type)
|
||||
}
|
||||
# endif /* HAVE_SHL_LOAD */
|
||||
|
||||
sudo_dso_public int
|
||||
system(const char *cmnd)
|
||||
{
|
||||
return system_wrapper(cmnd);
|
||||
}
|
||||
|
||||
sudo_dso_public int
|
||||
execve(const char *cmnd, char * const argv[], char * const envp[])
|
||||
{
|
||||
|
Reference in New Issue
Block a user