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


 186  * should communicate the event to their callers (usually by returning
 187  * ECONNRESET) so they may reset their state appropriately.
 188  *
 189  * External references
 190  *
 191  * svc.configd generates special security audit events for changes to some
 192  * restarter related properties.  See the special_props_list array in
 193  * usr/src/cmd/svc/configd/rc_node.c for the properties that cause these audit
 194  * events.  If you change the semantics of these propereties within startd, you
 195  * will probably need to update rc_node.c
 196  */
 197 
 198 #include <stdio.h>
 199 #include <stdio_ext.h>
 200 #include <sys/mnttab.h>           /* uses FILE * without including stdio.h */
 201 #include <alloca.h>
 202 #include <sys/mount.h>
 203 #include <sys/stat.h>
 204 #include <sys/types.h>
 205 #include <sys/wait.h>

 206 #include <assert.h>
 207 #include <errno.h>
 208 #include <fcntl.h>
 209 #include <ftw.h>
 210 #include <libintl.h>
 211 #include <libscf.h>
 212 #include <libscf_priv.h>
 213 #include <libuutil.h>
 214 #include <locale.h>
 215 #include <poll.h>
 216 #include <pthread.h>
 217 #include <signal.h>
 218 #include <stdarg.h>
 219 #include <stdlib.h>
 220 #include <string.h>
 221 #include <strings.h>
 222 #include <unistd.h>
 223 
 224 #include "startd.h"
 225 #include "protocol.h"
 226 


 227 ssize_t max_scf_name_size;
 228 ssize_t max_scf_fmri_size;
 229 ssize_t max_scf_value_size;
 230 
 231 mode_t fmask;
 232 mode_t dmask;
 233 
 234 graph_update_t *gu;
 235 restarter_update_t *ru;
 236 
 237 startd_state_t *st;
 238 
 239 boolean_t booting_to_single_user = B_FALSE;
 240 
 241 const char * const admin_actions[] = {
 242     SCF_PROPERTY_DEGRADED,
 243     SCF_PROPERTY_MAINT_OFF,
 244     SCF_PROPERTY_MAINT_ON,
 245     SCF_PROPERTY_MAINT_ON_IMMEDIATE,
 246     SCF_PROPERTY_REFRESH,


 455 pthread_t
 456 startd_thread_create(void *(*func)(void *), void *ptr)
 457 {
 458         int err;
 459         pthread_t tid;
 460 
 461         err = pthread_create(&tid, NULL, func, ptr);
 462         if (err != 0) {
 463                 assert(err == EAGAIN);
 464                 uu_die("Could not create thread.\n");
 465         }
 466 
 467         err = pthread_detach(tid);
 468         assert(err == 0);
 469 
 470         return (tid);
 471 }
 472 
 473 extern int info_events_all;
 474 































































 475 static int
 476 read_startd_config(void)
 477 {
 478         scf_handle_t *hndl;
 479         scf_instance_t *inst;
 480         scf_propertygroup_t *pg;
 481         scf_property_t *prop;
 482         scf_value_t *val;
 483         scf_iter_t *iter, *piter;
 484         instance_data_t idata;
 485         char *buf, *vbuf;
 486         char *startd_options_fmri = uu_msprintf("%s/:properties/options",
 487             SCF_SERVICE_STARTD);
 488         char *startd_reconfigure_fmri = uu_msprintf(
 489             "%s/:properties/system/reconfigure", SCF_SERVICE_STARTD);
 490         char *env_opts, *lasts, *cp;
 491         int bind_fails = 0;
 492         int ret = 0, r;
 493         uint_t count = 0, msecs = ALLOC_DELAY;
 494         size_t sz;


 584                 ctid = proc_get_ctid();
 585                 if (ctid != -1) {
 586                         uint64 = (uint64_t)ctid;
 587                         (void) libscf_inst_set_count_prop(inst,
 588                             SCF_PG_RESTARTER, SCF_PG_RESTARTER_TYPE,
 589                             SCF_PG_RESTARTER_FLAGS, SCF_PROPERTY_CONTRACT,
 590                             uint64);
 591                 }
 592                 (void) libscf_note_method_log(inst, LOG_PREFIX_EARLY,
 593                     STARTD_DEFAULT_LOG);
 594                 (void) libscf_note_method_log(inst, LOG_PREFIX_NORMAL,
 595                     STARTD_DEFAULT_LOG);
 596         }
 597 
 598         /* Read reconfigure property for recovery. */
 599         if (scf_handle_decode_fmri(hndl, startd_reconfigure_fmri, NULL, NULL,
 600             NULL, NULL, prop, NULL) != -1 &&
 601             scf_property_get_value(prop, val) == 0)
 602                 (void) scf_value_get_boolean(val, &prop_reconfig);
 603 







 604         if (scf_handle_decode_fmri(hndl, startd_options_fmri, NULL, NULL, NULL,
 605             pg, NULL, SCF_DECODE_FMRI_TRUNCATE) == -1) {
 606                 /*
 607                  * No configuration options defined.
 608                  */
 609                 if (scf_error() != SCF_ERROR_NOT_FOUND)
 610                         uu_warn("Couldn't read configuration from 'options' "
 611                             "group: %s\n", scf_strerror(scf_error()));
 612                 goto scfout;
 613         }
 614 
 615         /*
 616          * If there is no "options" group defined, then our defaults are fine.
 617          */
 618         if (scf_pg_get_name(pg, NULL, 0) < 0)
 619                 goto scfout;
 620 
 621         /* get info_events_all */
 622         info_events_all = libscf_get_info_events_all(pg);
 623 




 186  * should communicate the event to their callers (usually by returning
 187  * ECONNRESET) so they may reset their state appropriately.
 188  *
 189  * External references
 190  *
 191  * svc.configd generates special security audit events for changes to some
 192  * restarter related properties.  See the special_props_list array in
 193  * usr/src/cmd/svc/configd/rc_node.c for the properties that cause these audit
 194  * events.  If you change the semantics of these propereties within startd, you
 195  * will probably need to update rc_node.c
 196  */
 197 
 198 #include <stdio.h>
 199 #include <stdio_ext.h>
 200 #include <sys/mnttab.h>           /* uses FILE * without including stdio.h */
 201 #include <alloca.h>
 202 #include <sys/mount.h>
 203 #include <sys/stat.h>
 204 #include <sys/types.h>
 205 #include <sys/wait.h>
 206 #include <sys/proc.h>
 207 #include <assert.h>
 208 #include <errno.h>
 209 #include <fcntl.h>
 210 #include <ftw.h>
 211 #include <libintl.h>
 212 #include <libscf.h>
 213 #include <libscf_priv.h>
 214 #include <libuutil.h>
 215 #include <locale.h>
 216 #include <poll.h>
 217 #include <pthread.h>
 218 #include <signal.h>
 219 #include <stdarg.h>
 220 #include <stdlib.h>
 221 #include <string.h>
 222 #include <strings.h>
 223 #include <unistd.h>
 224 
 225 #include "startd.h"
 226 #include "protocol.h"
 227 
 228 extern int psecflags(idtype_t, id_t, psecflags_cmd_t, uint_t);
 229 
 230 ssize_t max_scf_name_size;
 231 ssize_t max_scf_fmri_size;
 232 ssize_t max_scf_value_size;
 233 
 234 mode_t fmask;
 235 mode_t dmask;
 236 
 237 graph_update_t *gu;
 238 restarter_update_t *ru;
 239 
 240 startd_state_t *st;
 241 
 242 boolean_t booting_to_single_user = B_FALSE;
 243 
 244 const char * const admin_actions[] = {
 245     SCF_PROPERTY_DEGRADED,
 246     SCF_PROPERTY_MAINT_OFF,
 247     SCF_PROPERTY_MAINT_ON,
 248     SCF_PROPERTY_MAINT_ON_IMMEDIATE,
 249     SCF_PROPERTY_REFRESH,


 458 pthread_t
 459 startd_thread_create(void *(*func)(void *), void *ptr)
 460 {
 461         int err;
 462         pthread_t tid;
 463 
 464         err = pthread_create(&tid, NULL, func, ptr);
 465         if (err != 0) {
 466                 assert(err == EAGAIN);
 467                 uu_die("Could not create thread.\n");
 468         }
 469 
 470         err = pthread_detach(tid);
 471         assert(err == 0);
 472 
 473         return (tid);
 474 }
 475 
 476 extern int info_events_all;
 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 
 541 static int
 542 read_startd_config(void)
 543 {
 544         scf_handle_t *hndl;
 545         scf_instance_t *inst;
 546         scf_propertygroup_t *pg;
 547         scf_property_t *prop;
 548         scf_value_t *val;
 549         scf_iter_t *iter, *piter;
 550         instance_data_t idata;
 551         char *buf, *vbuf;
 552         char *startd_options_fmri = uu_msprintf("%s/:properties/options",
 553             SCF_SERVICE_STARTD);
 554         char *startd_reconfigure_fmri = uu_msprintf(
 555             "%s/:properties/system/reconfigure", SCF_SERVICE_STARTD);
 556         char *env_opts, *lasts, *cp;
 557         int bind_fails = 0;
 558         int ret = 0, r;
 559         uint_t count = 0, msecs = ALLOC_DELAY;
 560         size_t sz;


 650                 ctid = proc_get_ctid();
 651                 if (ctid != -1) {
 652                         uint64 = (uint64_t)ctid;
 653                         (void) libscf_inst_set_count_prop(inst,
 654                             SCF_PG_RESTARTER, SCF_PG_RESTARTER_TYPE,
 655                             SCF_PG_RESTARTER_FLAGS, SCF_PROPERTY_CONTRACT,
 656                             uint64);
 657                 }
 658                 (void) libscf_note_method_log(inst, LOG_PREFIX_EARLY,
 659                     STARTD_DEFAULT_LOG);
 660                 (void) libscf_note_method_log(inst, LOG_PREFIX_NORMAL,
 661                     STARTD_DEFAULT_LOG);
 662         }
 663 
 664         /* Read reconfigure property for recovery. */
 665         if (scf_handle_decode_fmri(hndl, startd_reconfigure_fmri, NULL, NULL,
 666             NULL, NULL, prop, NULL) != -1 &&
 667             scf_property_get_value(prop, val) == 0)
 668                 (void) scf_value_get_boolean(val, &prop_reconfig);
 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 
 677         if (scf_handle_decode_fmri(hndl, startd_options_fmri, NULL, NULL, NULL,
 678             pg, NULL, SCF_DECODE_FMRI_TRUNCATE) == -1) {
 679                 /*
 680                  * No configuration options defined.
 681                  */
 682                 if (scf_error() != SCF_ERROR_NOT_FOUND)
 683                         uu_warn("Couldn't read configuration from 'options' "
 684                             "group: %s\n", scf_strerror(scf_error()));
 685                 goto scfout;
 686         }
 687 
 688         /*
 689          * If there is no "options" group defined, then our defaults are fine.
 690          */
 691         if (scf_pg_get_name(pg, NULL, 0) < 0)
 692                 goto scfout;
 693 
 694         /* get info_events_all */
 695         info_events_all = libscf_get_info_events_all(pg);
 696