Print this page
uts: Allow for address space randomisation.
Randomise the base addresses of shared objects, non-fixed mappings, the
stack and the heap.  Introduce a service, svc:/system/process-security,
and a tool psecflags(1) to control and observe it

@@ -201,10 +201,11 @@
 #include <alloca.h>
 #include <sys/mount.h>
 #include <sys/stat.h>
 #include <sys/types.h>
 #include <sys/wait.h>
+#include <sys/proc.h>
 #include <assert.h>
 #include <errno.h>
 #include <fcntl.h>
 #include <ftw.h>
 #include <libintl.h>

@@ -222,10 +223,12 @@
 #include <unistd.h>
 
 #include "startd.h"
 #include "protocol.h"
 
+extern int psecflags(idtype_t, id_t, psecflags_cmd_t, uint_t);
+
 ssize_t max_scf_name_size;
 ssize_t max_scf_fmri_size;
 ssize_t max_scf_value_size;
 
 mode_t fmask;

@@ -470,10 +473,73 @@
         return (tid);
 }
 
 extern int info_events_all;
 
+struct psf_desc {
+        char *name;
+        uint_t flag;
+} procsec_flag_tbl[] = {
+        { "aslr",       PROC_SEC_ASLR },
+        { NULL, NULL }
+};
+
+static void
+init_secflags(scf_handle_t *hndl)
+{
+        scf_property_t *prop;
+        scf_value_t *val;
+        struct psf_desc *psfd = NULL;
+        char *proc_sec_fmri = "svc:/system/process-security/"
+            ":properties/secflags";
+
+        for (psfd = procsec_flag_tbl; psfd->name != NULL; psfd++) {
+                char *pfmri;
+                uint8_t flag;
+
+                prop = safe_scf_property_create(hndl);
+                val = safe_scf_value_create(hndl);
+
+                if ((pfmri = uu_msprintf("%s/%s", proc_sec_fmri, psfd->name)) == NULL)
+                        uu_die("Allocation failure\n");
+
+                if (scf_handle_decode_fmri(hndl, pfmri,
+                    NULL, NULL, NULL, NULL, prop, NULL) != 0)
+                        goto next;
+
+                if (scf_property_get_value(prop, val) != 0)
+                        goto next;
+
+                (void) scf_value_get_boolean(val, &flag);
+
+                /*
+                 * XXX: This will fail if the zone had PRIV_PROC_SECFLAGS
+                 * removed.
+                 *
+                 * I'm not sure what we should do in that case -- I'd still
+                 * like this to be settable based on a zonecfg setting, too.
+                 *
+                 * We only set things explicitly _on_ here, rather than
+                 * explicitly _off_ such that a zone's settings do not
+                 * permanently override those from the GZ.
+                 *
+                 * XXX: This might be a bit crap, we sorta want a tri-state
+                 */
+                if (flag != 0) {
+                        if (psecflags(P_PID, P_MYID,
+                            PSECFLAGS_ENABLE, psfd->flag) != 0) {
+                                uu_warn("couldn't set security flags: %s\n",
+                                    strerror(errno));
+                        }
+                }
+next:
+                uu_free(pfmri);
+                scf_value_destroy(val);
+                scf_property_destroy(prop);
+        }
+}
+
 static int
 read_startd_config(void)
 {
         scf_handle_t *hndl;
         scf_instance_t *inst;

@@ -599,10 +665,17 @@
         if (scf_handle_decode_fmri(hndl, startd_reconfigure_fmri, NULL, NULL,
             NULL, NULL, prop, NULL) != -1 &&
             scf_property_get_value(prop, val) == 0)
                 (void) scf_value_get_boolean(val, &prop_reconfig);
 
+        /*
+         * Set up the initial process secflags.  We do this super early, and
+         * in svc.startd, so that it's inherited by as much stuff as possible
+         * upon boot.
+         */
+        init_secflags(hndl);
+
         if (scf_handle_decode_fmri(hndl, startd_options_fmri, NULL, NULL, NULL,
             pg, NULL, SCF_DECODE_FMRI_TRUNCATE) == -1) {
                 /*
                  * No configuration options defined.
                  */