The default user is service (uid \fB12\fR).
.RE
.PP
-\fBipc\fR \fI<ALL|ALL_SYS|NONE|label1 label2...labelN>\fR\fB;\fR
+\fBipc\fR \fI<ALL|ALL_SYS|NONE|name1 name2...nameN>\fR\fB;\fR
.PP
.RS
specifies the list of ipc targets (processes and kernel) the system service can
talk to. \fIALL\fR allows all the possible targets, \fIALL_SYS\fR is similar but
excludes user processes. When an explicit list is given, each target
-must be identified by its label (assigned to the corresponding system service).
-Exceptions are user processes (use pseudo-label \fIUSER\fR) and
-the kernel for kernel calls (use pseudo-label \fISYSTEM\fR). The default is
+must be identified by its process (binary) name.
+Exceptions are user processes (use pseudo-name \fIUSER\fR) and
+the kernel for kernel calls (use pseudo-name \fISYSTEM\fR). The default is
\fIALL_SYS\fR.
.RE
.PP
The default is to allow no PCI classes.
.RE
.PP
-\fBcontrol\fR \fI<label1 label2...labelN>\fR\fB;\fR
+\fBcontrol\fR \fI<name1 name2...nameN>\fR\fB;\fR
.PP
.RS
-specifies the list of system services (identified by their labels) that are
-allowed to control the system service. A controller service can ask RS
+specifies the list of system services (identified by their process names) that
+are allowed to control the system service. A controller service can ask RS
to perform privileged actions like immediately restarting the service.
The default is to allow no controller services.
.RE
/*===========================================================================*
* caller_is_root *
*===========================================================================*/
-PUBLIC int caller_is_root(endpoint)
+PRIVATE int caller_is_root(endpoint)
endpoint_t endpoint; /* caller endpoint */
{
uid_t euid;
/*===========================================================================*
* caller_can_control *
*===========================================================================*/
-PUBLIC int caller_can_control(endpoint, label)
+PRIVATE int caller_can_control(endpoint, target_rp)
endpoint_t endpoint;
-char *label;
+struct rproc *target_rp;
{
int control_allowed = 0;
register struct rproc *rp;
register struct rprocpub *rpub;
+ char *proc_name;
int c;
- char *progname;
-
- /* Find name of binary for given label. */
- rp = lookup_slot_by_label(label);
- if (!rp) return 0;
- progname = strrchr(rp->r_argv[0], '/');
- if (progname != NULL)
- progname++;
- else
- progname = rp->r_argv[0];
+
+ proc_name = target_rp->r_pub->proc_name;
/* Check if label is listed in caller's isolation policy. */
for (rp = BEG_RPROC_ADDR; rp < END_RPROC_ADDR; rp++) {
+ if (!(rp->r_flags & RS_IN_USE))
+ continue;
+
rpub = rp->r_pub;
if (rpub->endpoint == endpoint) {
break;
}
}
if (rp == END_RPROC_ADDR) return 0;
- if (rp->r_nr_control > 0) {
- for (c = 0; c < rp->r_nr_control; c++) {
- if (strcmp(rp->r_control[c], progname) == 0)
- control_allowed = 1;
+
+ for (c = 0; c < rp->r_nr_control; c++) {
+ if (strcmp(rp->r_control[c], proc_name) == 0) {
+ control_allowed = 1;
+ break;
}
}
if (rs_verbose)
printf("RS: allowing %u control over %s via policy: %s\n",
- endpoint, label, control_allowed ? "yes" : "no");
+ endpoint, target_rp->r_pub->label,
+ control_allowed ? "yes" : "no");
return control_allowed;
}
/* Caller should be either root or have control privileges. */
call_allowed = caller_is_root(caller);
if(rp) {
- call_allowed |= caller_can_control(caller, rp->r_pub->label);
+ call_allowed |= caller_can_control(caller, rp);
}
if(!call_allowed) {
return EPERM;
/*===========================================================================*
- * get_next_label *
+ * get_next_name *
*===========================================================================*/
-PUBLIC char *get_next_label(ptr, label, caller_label)
+PRIVATE char *get_next_name(ptr, name, caller_label)
char *ptr;
-char *label;
+char *name;
char *caller_label;
{
- /* Get the next label from the list of (IPC) labels.
+ /* Get the next name from the list of (IPC) program names.
*/
char *p, *q;
size_t len;
if (len > RS_MAX_LABEL_LEN)
{
printf(
- "rs:get_next_label: bad ipc list entry '%.*s' for %s: too long\n",
+ "rs:get_next_name: bad ipc list entry '%.*s' for %s: too long\n",
len, p, caller_label);
continue;
}
- memcpy(label, p, len);
- label[len]= '\0';
+ memcpy(name, p, len);
+ name[len]= '\0';
return q; /* found another */
}
/* Add IPC send permissions to a process based on that process's IPC
* list.
*/
- char label[RS_MAX_LABEL_LEN+1], *p;
- struct rproc *tmp_rp;
- struct rprocpub *tmp_rpub;
+ char name[RS_MAX_LABEL_LEN+1], *p;
+ struct rproc *rrp;
endpoint_t endpoint;
int r;
int priv_id;
rpub = rp->r_pub;
p = rp->r_ipc_list;
- while ((p = get_next_label(p, label, rpub->label)) != NULL) {
+ while ((p = get_next_name(p, name, rpub->label)) != NULL) {
- if (strcmp(label, "SYSTEM") == 0)
+ if (strcmp(name, "SYSTEM") == 0)
endpoint= SYSTEM;
- else if (strcmp(label, "USER") == 0)
+ else if (strcmp(name, "USER") == 0)
endpoint= INIT_PROC_NR; /* all user procs */
else
{
- /* Try to find process */
- tmp_rp = lookup_slot_by_label(label);
- if (!tmp_rp)
- continue;
- tmp_rpub = tmp_rp->r_pub;
- endpoint= tmp_rpub->endpoint;
+ /* Set a privilege bit for every process matching the
+ * given process name. It is perfectly fine if this
+ * loop does not find any matches, as the target
+ * process(es) may not have been started yet. See
+ * add_backward_ipc() below.
+ */
+ for (rrp=BEG_RPROC_ADDR; rrp<END_RPROC_ADDR; rrp++) {
+ if (!(rrp->r_flags & RS_IN_USE))
+ continue;
+
+ if (!strcmp(rrp->r_pub->proc_name, name)) {
+#if PRIV_DEBUG
+ printf(" RS: add_forward_ipc: setting"
+ " sendto bit for %d...\n",
+ rrp->r_pub->endpoint);
+#endif
+
+ priv_id= rrp->r_priv.s_id;
+ set_sys_bit(privp->s_ipc_to, priv_id);
+ }
+ }
+
+ continue;
}
+ /* This code only applies to the exception cases. */
if ((r = sys_getpriv(&priv, endpoint)) < 0)
{
printf(
"add_forward_ipc: unable to get priv_id for '%s': %d\n",
- label, r);
+ name, r);
continue;
}
+
#if PRIV_DEBUG
printf(" RS: add_forward_ipc: setting sendto bit for %d...\n",
endpoint);
* add these permissions now because the current process may not yet
* have existed at the time that the other process was initialized.
*/
- char label[RS_MAX_LABEL_LEN+1], *p;
+ char name[RS_MAX_LABEL_LEN+1], *p;
struct rproc *rrp;
struct rprocpub *rrpub;
- int priv_id, found;
+ char *proc_name;
+ int priv_id;
+
+ proc_name = rp->r_pub->proc_name;
for (rrp=BEG_RPROC_ADDR; rrp<END_RPROC_ADDR; rrp++) {
if (!(rrp->r_flags & RS_IN_USE))
continue;
/* If an IPC target list was provided for the process being
- * checked here, make sure that the label of the new process
- * is in that process's list.
+ * checked here, make sure that the name of the new process
+ * is in that process's list. There may be multiple matches.
*/
if (rrp->r_ipc_list[0]) {
- found = 0;
-
rrpub = rrp->r_pub;
p = rrp->r_ipc_list;
- while ((p = get_next_label(p, label,
+ while ((p = get_next_name(p, name,
rrpub->label)) != NULL) {
- if (!strcmp(rrpub->label, label)) {
- found = 1;
- break;
- }
- }
-
- if (!found)
- continue;
+ if (!strcmp(proc_name, name)) {
#if PRIV_DEBUG
- printf(" RS: add_backward_ipc: setting sendto bit for %d...\n",
- rrpub->endpoint);
+ printf(" RS: add_backward_ipc: setting"
+ " sendto bit for %d...\n",
+ rrpub->endpoint);
#endif
- priv_id= rrp->r_priv.s_id;
- set_sys_bit(privp->s_ipc_to, priv_id);
+ priv_id= rrp->r_priv.s_id;
+ set_sys_bit(privp->s_ipc_to, priv_id);
+ }
+ }
}
}
}