]> Zhao Yanbai Git Server - minix.git/commitdiff
system.conf: base ipc permissions on process names rather than labels
authorDavid van Moolenbroek <david@minix3.org>
Tue, 7 Dec 2010 12:16:31 +0000 (12:16 +0000)
committerDavid van Moolenbroek <david@minix3.org>
Tue, 7 Dec 2010 12:16:31 +0000 (12:16 +0000)
From now on, the "ipc" directive in system.conf refers to process names
instead of labels, similar to the "control" directive. The old, more
fine-grained approach is deemed unnecessary and cumbersome at this time.

As side effects, this patch unbreaks late IPC permission computation as
well as the filter driver.

man/man5/system.conf.5
servers/rs/manager.c
servers/rs/proto.h

index 797da4dcaca211fa19f4fc80e9b9893a70d923b6..ddf6aeeaed941e797bd7b69a49a4f85f6d4c4d70 100644 (file)
@@ -50,15 +50,15 @@ Many system services run with root privileges (uid \fB0\fR).
 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
@@ -158,11 +158,11 @@ specifies the PCI classes the system service is allowed to use
 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
index 2419de3842d09027269632dcfd3d10cfa4fdb541..110dfaea09090cf287dc93f5e7c338de3f12d8c7 100644 (file)
@@ -12,7 +12,7 @@
 /*===========================================================================*
  *                             caller_is_root                               *
  *===========================================================================*/
-PUBLIC int caller_is_root(endpoint)
+PRIVATE int caller_is_root(endpoint)
 endpoint_t endpoint;                           /* caller endpoint */
 {
   uid_t euid;
@@ -30,43 +30,41 @@ endpoint_t endpoint;                                /* caller endpoint */
 /*===========================================================================*
  *                             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;
 }
@@ -86,7 +84,7 @@ struct rproc *rp;
   /* 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;
@@ -1828,14 +1826,14 @@ struct rproc *rp;
 
 
 /*===========================================================================*
- *                             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;
@@ -1856,12 +1854,12 @@ char *caller_label;
                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 */
        }
@@ -1879,9 +1877,8 @@ struct priv *privp;
        /* 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;
@@ -1891,29 +1888,48 @@ struct priv *privp;
        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);
@@ -1937,41 +1953,38 @@ struct priv *privp;
         * 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);
+                               }
+                       }
                }
        }
 }
index 0dc45b56a95344e8e67978f19a8caa331c35a9dd..1a0fe047ef4890ca6863e4301d78807588280029 100644 (file)
@@ -27,8 +27,6 @@ _PROTOTYPE( int do_getsysinfo, (message *m));
 _PROTOTYPE( int do_lookup, (message *m));
 
 /* manager.c */
-_PROTOTYPE( int caller_is_root, (endpoint_t endpoint) );
-_PROTOTYPE( int caller_can_control, (endpoint_t endpoint, char *label) );
 _PROTOTYPE( int check_call_permission, (endpoint_t caller, int call,
        struct rproc *rp) );
 _PROTOTYPE( int copy_rs_start, (endpoint_t src_e, char *src_rs_start,