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

Split Close
Expand all
Collapse all
          --- old/usr/src/cmd/svc/startd/startd.c
          +++ new/usr/src/cmd/svc/startd/startd.c
↓ open down ↓ 195 lines elided ↑ open up ↑
 196  196   */
 197  197  
 198  198  #include <stdio.h>
 199  199  #include <stdio_ext.h>
 200  200  #include <sys/mnttab.h>         /* uses FILE * without including stdio.h */
 201  201  #include <alloca.h>
 202  202  #include <sys/mount.h>
 203  203  #include <sys/stat.h>
 204  204  #include <sys/types.h>
 205  205  #include <sys/wait.h>
      206 +#include <sys/proc.h>
 206  207  #include <assert.h>
 207  208  #include <errno.h>
 208  209  #include <fcntl.h>
 209  210  #include <ftw.h>
 210  211  #include <libintl.h>
 211  212  #include <libscf.h>
 212  213  #include <libscf_priv.h>
 213  214  #include <libuutil.h>
 214  215  #include <locale.h>
 215  216  #include <poll.h>
↓ open down ↓ 1 lines elided ↑ open up ↑
 217  218  #include <signal.h>
 218  219  #include <stdarg.h>
 219  220  #include <stdlib.h>
 220  221  #include <string.h>
 221  222  #include <strings.h>
 222  223  #include <unistd.h>
 223  224  
 224  225  #include "startd.h"
 225  226  #include "protocol.h"
 226  227  
      228 +extern int psecflags(idtype_t, id_t, psecflags_cmd_t, uint_t);
      229 +
 227  230  ssize_t max_scf_name_size;
 228  231  ssize_t max_scf_fmri_size;
 229  232  ssize_t max_scf_value_size;
 230  233  
 231  234  mode_t fmask;
 232  235  mode_t dmask;
 233  236  
 234  237  graph_update_t *gu;
 235  238  restarter_update_t *ru;
 236  239  
↓ open down ↓ 228 lines elided ↑ open up ↑
 465  468          }
 466  469  
 467  470          err = pthread_detach(tid);
 468  471          assert(err == 0);
 469  472  
 470  473          return (tid);
 471  474  }
 472  475  
 473  476  extern int info_events_all;
 474  477  
      478 +struct psf_desc {
      479 +        char *name;
      480 +        uint_t flag;
      481 +} procsec_flag_tbl[] = {
      482 +        { "aslr",       PROC_SEC_ASLR },
      483 +        { NULL, NULL }
      484 +};
      485 +
      486 +static void
      487 +init_secflags(scf_handle_t *hndl)
      488 +{
      489 +        scf_property_t *prop;
      490 +        scf_value_t *val;
      491 +        struct psf_desc *psfd = NULL;
      492 +        char *proc_sec_fmri = "svc:/system/process-security/"
      493 +            ":properties/secflags";
      494 +
      495 +        for (psfd = procsec_flag_tbl; psfd->name != NULL; psfd++) {
      496 +                char *pfmri;
      497 +                uint8_t flag;
      498 +
      499 +                prop = safe_scf_property_create(hndl);
      500 +                val = safe_scf_value_create(hndl);
      501 +
      502 +                if ((pfmri = uu_msprintf("%s/%s", proc_sec_fmri, psfd->name)) == NULL)
      503 +                        uu_die("Allocation failure\n");
      504 +
      505 +                if (scf_handle_decode_fmri(hndl, pfmri,
      506 +                    NULL, NULL, NULL, NULL, prop, NULL) != 0)
      507 +                        goto next;
      508 +
      509 +                if (scf_property_get_value(prop, val) != 0)
      510 +                        goto next;
      511 +
      512 +                (void) scf_value_get_boolean(val, &flag);
      513 +
      514 +                /*
      515 +                 * XXX: This will fail if the zone had PRIV_PROC_SECFLAGS
      516 +                 * removed.
      517 +                 *
      518 +                 * I'm not sure what we should do in that case -- I'd still
      519 +                 * like this to be settable based on a zonecfg setting, too.
      520 +                 *
      521 +                 * We only set things explicitly _on_ here, rather than
      522 +                 * explicitly _off_ such that a zone's settings do not
      523 +                 * permanently override those from the GZ.
      524 +                 *
      525 +                 * XXX: This might be a bit crap, we sorta want a tri-state
      526 +                 */
      527 +                if (flag != 0) {
      528 +                        if (psecflags(P_PID, P_MYID,
      529 +                            PSECFLAGS_ENABLE, psfd->flag) != 0) {
      530 +                                uu_warn("couldn't set security flags: %s\n",
      531 +                                    strerror(errno));
      532 +                        }
      533 +                }
      534 +next:
      535 +                uu_free(pfmri);
      536 +                scf_value_destroy(val);
      537 +                scf_property_destroy(prop);
      538 +        }
      539 +}
      540 +
 475  541  static int
 476  542  read_startd_config(void)
 477  543  {
 478  544          scf_handle_t *hndl;
 479  545          scf_instance_t *inst;
 480  546          scf_propertygroup_t *pg;
 481  547          scf_property_t *prop;
 482  548          scf_value_t *val;
 483  549          scf_iter_t *iter, *piter;
 484  550          instance_data_t idata;
↓ open down ↓ 109 lines elided ↑ open up ↑
 594  660                  (void) libscf_note_method_log(inst, LOG_PREFIX_NORMAL,
 595  661                      STARTD_DEFAULT_LOG);
 596  662          }
 597  663  
 598  664          /* Read reconfigure property for recovery. */
 599  665          if (scf_handle_decode_fmri(hndl, startd_reconfigure_fmri, NULL, NULL,
 600  666              NULL, NULL, prop, NULL) != -1 &&
 601  667              scf_property_get_value(prop, val) == 0)
 602  668                  (void) scf_value_get_boolean(val, &prop_reconfig);
 603  669  
      670 +        /*
      671 +         * Set up the initial process secflags.  We do this super early, and
      672 +         * in svc.startd, so that it's inherited by as much stuff as possible
      673 +         * upon boot.
      674 +         */
      675 +        init_secflags(hndl);
      676 +
 604  677          if (scf_handle_decode_fmri(hndl, startd_options_fmri, NULL, NULL, NULL,
 605  678              pg, NULL, SCF_DECODE_FMRI_TRUNCATE) == -1) {
 606  679                  /*
 607  680                   * No configuration options defined.
 608  681                   */
 609  682                  if (scf_error() != SCF_ERROR_NOT_FOUND)
 610  683                          uu_warn("Couldn't read configuration from 'options' "
 611  684                              "group: %s\n", scf_strerror(scf_error()));
 612  685                  goto scfout;
 613  686          }
↓ open down ↓ 474 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX