#define PM_SETGROUPS_REPLY (PM_RS_BASE + 11)
/* Standard parameters for all requests and replies, except PM_REBOOT */
-# define PM_PROC m1_i1 /* process endpoint */
+# define PM_PROC m7_i1 /* process endpoint */
/* Additional parameters for PM_INIT */
-# define PM_SLOT m1_i2 /* process slot number */
-# define PM_PID m1_i3 /* process pid */
+# define PM_SLOT m7_i2 /* process slot number */
+# define PM_PID m7_i3 /* process pid */
/* Additional parameters for PM_SETUID and PM_SETGID */
-# define PM_EID m1_i2 /* effective user/group id */
-# define PM_RID m1_i3 /* real user/group id */
+# define PM_EID m7_i2 /* effective user/group id */
+# define PM_RID m7_i3 /* real user/group id */
/* Additional parameter for PM_SETGROUPS */
-# define PM_GROUP_NO m1_i2 /* number of groups */
-# define PM_GROUP_ADDR m1_p1 /* struct holding group data */
+# define PM_GROUP_NO m7_i2 /* number of groups */
+# define PM_GROUP_ADDR m7_p1 /* struct holding group data */
/* Additional parameters for PM_EXEC */
-# define PM_PATH m1_p1 /* executable */
-# define PM_PATH_LEN m1_i2 /* length of path including
+# define PM_PATH m7_p1 /* executable */
+# define PM_PATH_LEN m7_i2 /* length of path including
* terminating null character
*/
-# define PM_FRAME m1_p2 /* arguments and environment */
-# define PM_FRAME_LEN m1_i3 /* size of frame */
+# define PM_FRAME m7_p2 /* arguments and environment */
+# define PM_FRAME_LEN m7_i3 /* size of frame */
/* Additional parameters for PM_EXEC_REPLY and PM_CORE_REPLY */
-# define PM_STATUS m1_i2 /* OK or failure */
-# define PM_PC m1_p1 /* program counter */
+# define PM_STATUS m7_i2 /* OK or failure */
+# define PM_PC m7_p1 /* program counter */
/* Additional parameters for PM_FORK and PM_SRV_FORK */
-# define PM_PPROC m1_i2 /* parent process endpoint */
-# define PM_CPID m1_i3 /* child pid */
+# define PM_PPROC m7_i2 /* parent process endpoint */
+# define PM_CPID m7_i3 /* child pid */
+# define PM_REUID m7_i4 /* real and effective uid */
+# define PM_REGID m7_i5 /* real and effective gid */
/* Additional parameters for PM_DUMPCORE */
-# define PM_TERM_SIG m1_i2 /* process's termination signal */
-# define PM_TRACED_PROC m1_i3 /* required for T_DUMPCORE */
+# define PM_TERM_SIG m7_i2 /* process's termination signal */
+# define PM_TRACED_PROC m7_i3 /* required for T_DUMPCORE */
/* Parameters for the EXEC_NEWMEM call */
#define EXC_NM_PROC m1_i1 /* process that needs new map */
service mfs
{
- uid 0;
ipc ALL_SYS; # All system ipc targets allowed
system BASIC; # Only basic kernel calls allowed
vm BASIC; # Only basic VM calls allowed
service pfs
{
- uid 0;
ipc ALL_SYS; # All system ipc targets allowed
system BASIC; # Only basic kernel calls allowed
vm BASIC; # Only basic VM calls allowed
case PM_FORK:
case PM_SRV_FORK:
pm_fork(m_in.PM_PPROC, m_in.PM_PROC, m_in.PM_CPID);
+ m_out.m_type = PM_FORK_REPLY;
+
+ if (call_nr == PM_SRV_FORK) {
+ m_out.m_type = PM_SRV_FORK_REPLY;
+ pm_setuid(m_in.PM_PROC, m_in.PM_REUID, m_in.PM_REUID);
+ pm_setgid(m_in.PM_PROC, m_in.PM_REGID, m_in.PM_REGID);
+ }
- m_out.m_type = (call_nr == PM_FORK) ? PM_FORK_REPLY : PM_SRV_FORK_REPLY;
m_out.PM_PROC = m_in.PM_PROC;
break;
if (rmp->mp_tracer == NO_TRACER) {
/* Okay, setuid execution is allowed */
allow_setuid = 1;
+ }
+ if (allow_setuid && args.setugid) {
rmp->mp_effuid = args.new_uid;
rmp->mp_effgid = args.new_gid;
}
mp->mp_reply.reply_res2= (vir_bytes) stack_top;
mp->mp_reply.reply_res3= flags;
- if (allow_setuid)
+ if (allow_setuid && args.setugid)
mp->mp_reply.reply_res3 |= EXC_NM_RF_ALLOW_SETUID;
} else {
printf("PM: newmem failed for %s\n", args.progname);
m.PM_PROC = rmc->mp_endpoint;
m.PM_PPROC = rmp->mp_endpoint;
m.PM_CPID = rmc->mp_pid;
+ m.PM_REUID = -1; /* Not used by PM_FORK */
+ m.PM_REGID = -1; /* Not used by PM_FORK */
tell_vfs(rmc, &m);
rmc->mp_exitstatus = 0;
rmc->mp_sigstatus = 0;
rmc->mp_endpoint = child_ep; /* passed back by VM */
+ rmc->mp_realuid = (uid_t) m_in.m1_i1;
+ rmc->mp_effuid = (uid_t) m_in.m1_i1;
+ rmc->mp_realgid = (uid_t) m_in.m1_i2;
+ rmc->mp_effgid = (uid_t) m_in.m1_i2;
for (i = 0; i < NR_ITIMERS; i++)
rmc->mp_interval[i] = 0; /* reset timer intervals */
m.PM_PROC = rmc->mp_endpoint;
m.PM_PPROC = rmp->mp_endpoint;
m.PM_CPID = rmc->mp_pid;
+ m.PM_REUID = m_in.m1_i1;
+ m.PM_REGID = m_in.m1_i2;
tell_vfs(rmc, &m);
new_uid= getuid();
new_gid= getgid();
+ allow_setuid = 0;
/* XXX what should we use to identify the executable? */
r= exec_newmem(proc_e, 0 /*text_addr*/, text_bytes,
new_uid= getuid();
new_gid= getgid();
+ allow_setuid = 0;
sep_id = 0;
is_elf = 1;
e.enst_ctime= ctime;
e.new_uid= new_uid;
e.new_gid= new_gid;
+ e.setugid= *allow_setuidp;
strncpy(e.progname, progname, sizeof(e.progname)-1);
e.progname[sizeof(e.progname)-1]= '\0';
panic("unable to clone current RS instance: %d", s);
}
- /* Fork a new RS instance. */
- pid = srv_fork();
+ /* Fork a new RS instance with root:operator. */
+ pid = srv_fork(0, 0);
if(pid == -1) {
panic("unable to fork a new RS instance");
}
/*===========================================================================*
* srv_fork *
*===========================================================================*/
-PUBLIC pid_t srv_fork()
+PUBLIC pid_t srv_fork(uid_t reuid, gid_t regid)
{
message m;
- return(_syscall(PM_PROC_NR, SRV_FORK, &m));
+ m.m1_i1 = (int) reuid;
+ m.m1_i2 = (int) regid;
+ return _syscall(PM_PROC_NR, SRV_FORK, &m);
}
/*===========================================================================*
*/
if(rs_verbose)
printf("RS: forking child with srv_fork()...\n");
- child_pid= srv_fork();
+ child_pid= srv_fork(rp->r_uid, 0); /* Force group to operator for now */
if(child_pid == -1) {
printf("RS: srv_fork() failed (error %d)\n", errno);
free_slot(rp);
_PROTOTYPE( int copy_label, (endpoint_t src_e, char *src_label, size_t src_len,
char *dst_label, size_t dst_len) );
_PROTOTYPE( void build_cmd_dep, (struct rproc *rp) );
-_PROTOTYPE( int srv_fork, (void) );
+_PROTOTYPE( int srv_fork, (uid_t reuid, gid_t regid) );
_PROTOTYPE( int srv_kill, (pid_t pid, int sig) );
_PROTOTYPE( int srv_update, (endpoint_t src_e, endpoint_t dst_e) );
#define kill_service(rp, errstr, err) \
case PM_FORK:
case PM_SRV_FORK:
pm_fork(m_in.PM_PPROC, m_in.PM_PROC, m_in.PM_CPID);
+ m_out.m_type = PM_FORK_REPLY;
+
+ if (call_nr == PM_SRV_FORK) {
+ m_out.m_type = PM_SRV_FORK_REPLY;
+ pm_setuid(m_in.PM_PROC, m_in.PM_REUID, m_in.PM_REUID);
+ pm_setgid(m_in.PM_PROC, m_in.PM_REGID, m_in.PM_REGID);
+ }
- m_out.m_type = (call_nr == PM_FORK) ? PM_FORK_REPLY : PM_SRV_FORK_REPLY;
m_out.PM_PROC = m_in.PM_PROC;
break;