static const char rcsid[] = "$Sudo$";
#endif /* lint */
-struct listhead {
- void *first;
-};
-struct childinfo {
- pid_t pid;
- struct passwd *pw;
- struct syscallaction *action;
- struct childinfo *next;
-};
-
-void check_syscall __P((int, struct str_msg_ask *,
- struct systrace_answer *));
-int decode_args __P((int, pid_t, struct str_msg_ask *));
-int set_policy __P((int, struct childinfo *));
-int systrace_open __P((void));
-int systrace_read __P((int, pid_t, void *, void *, size_t));
-int systrace_run __P((char *, char **, int));
-int switch_emulation __P((int, struct str_message *));
-ssize_t read_string __P((int, pid_t, void *, char *, size_t));
-void new_child __P((pid_t, pid_t));
-void rm_child __P((pid_t));
-void update_child __P((pid_t, uid_t));
-struct childinfo *find_child __P((pid_t));
-
-extern struct passwd *sudo_pwdup __P((const struct passwd *, int));
-extern struct passwd *sudo_getpwuid __P((uid_t));
-
-static struct listhead children; /* list of children being traced */
-static int initialized; /* set to true when we are inited */
-
/*
* Open the systrace device and return the fd or -1 on failure.
* XXX - warn here on error or in caller?
*/
-int
+static int
systrace_open()
{
int serrno, fd;
return(-1);
}
-void
+static void
sigusr1(signo)
int signo;
{
* Fork a process that traces the command to be run and its descendents.
*
* TODO:
- * note euid changes and update runas info
* set SUDO_* env variables for sub-execs
*/
void
* Push a new child to the head of the list, inheriting the struct pw
* of its parent.
*/
-void
+static void
new_child(ppid, pid)
pid_t ppid;
pid_t pid;
children.first = entry;
}
-int
+static int
switch_emulation(fd, msgp)
int fd;
struct str_message *msgp;
/*
* Remove the named pid from the list.
*/
-void
+static void
rm_child(pid)
pid_t pid;
{
/*
* Find a child by pid.
*/
-struct childinfo *
+static struct childinfo *
find_child(pid)
pid_t pid;
{
/*
* Update the uid associated with a pid.
*/
-void
+static void
update_child(pid, uid)
pid_t pid;
uid_t uid;
/*
* Create a policy that intercepts execve and lets all others go free.
*/
-int
+static int
set_policy(fd, child)
int fd;
struct childinfo *child;
* Read from an address and store in buf.
* XXX - should deal with EBUSY from STRIOCIO
*/
-int
+static int
systrace_read(fd, pid, addr, buf, bufsiz)
int fd;
pid_t pid;
* XXX - could pass a hint for chunksiz
* XXX - need to indicate oflow
*/
-ssize_t
+static ssize_t
read_string(fd, pid, addr, buf, bufsiz)
int fd;
pid_t pid;
return(cp - buf);
}
-void
+static void
check_syscall(fd, askp, ansp)
int fd;
struct str_msg_ask *askp;
* Decode path and argv from systrace and fill in user_cmnd,
* user_base and user_args.
*/
-int
+static int
decode_args(fd, pid, askp)
int fd;
pid_t pid;
/*
* Decode the args to exec and check the command in sudoers.
*/
-void
+static void
check_exec(fd, askp, ansp)
int fd;
struct str_msg_ask *askp;
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
-void check_exec __P((int, struct str_msg_ask *,
- struct systrace_answer *));
+struct childinfo;
+
+extern struct passwd *sudo_pwdup __P((const struct passwd *, int));
+extern struct passwd *sudo_getpwuid __P((uid_t));
+
+static void check_exec __P((int, struct str_msg_ask *,
+ struct systrace_answer *));
+static void check_syscall __P((int, struct str_msg_ask *,
+ struct systrace_answer *));
+static int decode_args __P((int, pid_t, struct str_msg_ask *));
+static int set_policy __P((int, struct childinfo *));
+static int systrace_open __P((void));
+static int systrace_read __P((int, pid_t, void *, void *, size_t));
+static int switch_emulation __P((int, struct str_message *));
+static ssize_t read_string __P((int, pid_t, void *, char *, size_t));
+static void new_child __P((pid_t, pid_t));
+static void rm_child __P((pid_t));
+static void update_child __P((pid_t, uid_t));
+static struct childinfo *find_child __P((pid_t));
+
+static struct listhead children; /* list of children being traced */
+static int initialized; /* set to true when we are inited */
+
+struct listhead {
+ void *first;
+};
+
+struct childinfo {
+ pid_t pid;
+ struct passwd *pw;
+ struct syscallaction *action;
+ struct childinfo *next;
+};
+
+/*
+ * Each emulation has a list of actionable syscalls.
+ */
struct syscallaction {
int code;
int policy;
void (*handler) __P((int, struct str_msg_ask *, struct systrace_answer *));
};
-struct syscallaction syscalls_openbsd[] = {
+static struct syscallaction syscalls_openbsd[] = {
{ 23, SYSTR_POLICY_ASK, NULL}, /* OPENBSD_SYS_setuid */
{ 59, SYSTR_POLICY_ASK, check_exec}, /* OPENBSD_SYS_execve */
{ 126, SYSTR_POLICY_ASK, NULL}, /* OPENBSD_SYS_setreuid */
{ -1, -1, NULL}
};
-struct syscallaction syscalls_bsdos[] = {
+static struct syscallaction syscalls_bsdos[] = {
{ 23, SYSTR_POLICY_ASK, NULL}, /* BSDOS_SYS_setuid */
{ 59, SYSTR_POLICY_ASK, check_exec}, /* BSDOS_SYS_execve */
{ 126, SYSTR_POLICY_ASK, NULL}, /* BSDOS_SYS_setreuid */
{ -1, -1, NULL}
};
-struct syscallaction syscalls_freebsd[] = {
+static struct syscallaction syscalls_freebsd[] = {
{ 23, SYSTR_POLICY_ASK, NULL}, /* FREEBSD_SYS_setuid */
{ 59, SYSTR_POLICY_ASK, check_exec}, /* FREEBSD_SYS_execve */
{ 126, SYSTR_POLICY_ASK, NULL}, /* FREEBSD_SYS_setreuid */
{ -1, -1, NULL}
};
-struct syscallaction syscalls_netbsd[] = {
+static struct syscallaction syscalls_netbsd[] = {
{ 23, SYSTR_POLICY_ASK, NULL}, /* NETBSD_SYS_setuid */
{ 59, SYSTR_POLICY_ASK, check_exec}, /* NETBSD_SYS_execve */
{ 126, SYSTR_POLICY_ASK, NULL}, /* NETBSD_SYS_setreuid */
{ -1, -1, NULL}
};
-struct syscallaction syscalls_hpux[] = {
+static struct syscallaction syscalls_hpux[] = {
{ 11, SYSTR_POLICY_ASK, NULL}, /* HPUX_SYS_execv */
{ 23, SYSTR_POLICY_ASK, NULL}, /* HPUX_SYS_setuid */
{ 59, SYSTR_POLICY_ASK, check_exec}, /* HPUX_SYS_execve */
{ -1, -1, NULL}
};
-struct syscallaction syscalls_ibsc2[] = {
+static struct syscallaction syscalls_ibsc2[] = {
{ 11, SYSTR_POLICY_ASK, NULL}, /* ISCS2_SYS_execv */
{ 23, SYSTR_POLICY_ASK, NULL}, /* ISCS2_SYS_setuid */
{ 59, SYSTR_POLICY_ASK, check_exec}, /* ISCS2_SYS_execve */
{ -1, -1, NULL}
};
-struct syscallaction syscalls_linux[] = {
+static struct syscallaction syscalls_linux[] = {
{ 11, SYSTR_POLICY_ASK, check_exec}, /* LINUX_SYS_execve */
{ 23, SYSTR_POLICY_ASK, NULL}, /* LINUX_SYS_setuid16 */
{ 70, SYSTR_POLICY_ASK, NULL}, /* LINUX_SYS_setreuid16 */
{ -1, -1, NULL}
};
-struct syscallaction syscalls_osf1[] = {
+static struct syscallaction syscalls_osf1[] = {
{ 23, SYSTR_POLICY_ASK, NULL}, /* OSF1_SYS_setuid */
{ 59, SYSTR_POLICY_ASK, check_exec}, /* OSF1_SYS_execve */
{ 126, SYSTR_POLICY_ASK, NULL}, /* OSF1_SYS_setreuid */
{ -1, -1, NULL}
};
-struct syscallaction syscalls_sunos[] = {
+static struct syscallaction syscalls_sunos[] = {
{ 11, SYSTR_POLICY_ASK, NULL}, /* SUNOS_SYS_execv */
{ 23, SYSTR_POLICY_ASK, NULL}, /* SUNOS_SYS_setuid */
{ 59, SYSTR_POLICY_ASK, check_exec}, /* SUNOS_SYS_execve */
{ -1, -1, NULL}
};
-struct syscallaction syscalls_svr4[] = {
+static struct syscallaction syscalls_svr4[] = {
{ 11, SYSTR_POLICY_ASK, NULL}, /* SVR4_SYS_execv */
{ 23, SYSTR_POLICY_ASK, NULL}, /* SVR4_SYS_setuid */
{ 59, SYSTR_POLICY_ASK, check_exec}, /* SVR4_SYS_execve */
{ -1, -1, NULL}
};
-struct syscallaction syscalls_ultrix[] = {
+static struct syscallaction syscalls_ultrix[] = {
{ 11, SYSTR_POLICY_ASK, NULL}, /* ULTRIX_SYS_execv */
{ 23, SYSTR_POLICY_ASK, NULL}, /* ULTRIX_SYS_setuid */
{ 59, SYSTR_POLICY_ASK, check_exec}, /* ULTRIX_SYS_execve */
{ -1, -1, NULL}
};
-struct syscallaction syscalls_irix[] = {
+static struct syscallaction syscalls_irix[] = {
{ 11, SYSTR_POLICY_ASK, NULL}, /* IRIX_SYS_execv */
{ 23, SYSTR_POLICY_ASK, NULL}, /* IRIX_SYS_setuid */
{ 59, SYSTR_POLICY_ASK, check_exec}, /* IRIX_SYS_execve */
{ -1, -1, NULL}
};
-struct syscallaction syscalls_darwin[] = {
+static struct syscallaction syscalls_darwin[] = {
{ 23, SYSTR_POLICY_ASK, NULL}, /* DARWIN_SYS_setuid */
{ 59, SYSTR_POLICY_ASK, check_exec}, /* DARWIN_SYS_execve */
{ 126, SYSTR_POLICY_ASK, NULL}, /* DARWIN_SYS_setreuid */
{ -1, -1, NULL}
};
-struct emulation {
+/*
+ * List of emulations we support. Not all OSes support all emulations but
+ * they are all listed here to make things simpler.
+ * Attempts to run programs with unknown emulations will be rejected.
+ */
+static struct emulation {
const char *name;
struct syscallaction *action;
} emulations[] = {