Print this page
OS-4818 contract template disappears on exec
OS-5311 docker init children not always in the correct contract
Reviewed by: Patrick Mooney <patrick.mooney@joyent.com>
OS-4937 lxbrand ptracer count updates can race
Reviewed by: Jerry Jelinek <jerry.jelinek@joyent.com>
Reviewed by: Joshua M. Clulow <jmc@joyent.com>
OS-4534 lwp_exit P_PR_LOCK assertion failure
OS-4188 NULL dereference in lwp_hash_in
Reviewed by: Jerry Jelinek <jerry.jelinek@joyent.com>
Reviewed by: Joshua M. Clulow <jmc@joyent.com>
OS-4151 setbrand hooks should be sane during fork
Reviewed by: Jerry Jelinek <jerry.jelinek@joyent.com>
Reviewed by: Joshua M. Clulow <jmc@joyent.com>
OS-4129 lxbrand should not abuse p_brand_data for storing exit signal
Reviewed by: Jerry Jelinek <jerry.jelinek@joyent.com>
Reviewed by: Joshua M. Clulow <jmc@joyent.com>

Split Close
Expand all
Collapse all
          --- old/usr/src/uts/common/os/lwp.c
          +++ new/usr/src/uts/common/os/lwp.c
↓ open down ↓ 17 lines elided ↑ open up ↑
  18   18   *
  19   19   * CDDL HEADER END
  20   20   */
  21   21  
  22   22  /*
  23   23   * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
  24   24   * Use is subject to license terms.
  25   25   */
  26   26  
  27   27  /*
  28      - * Copyright (c) 2013, Joyent, Inc. All rights reserved.
       28 + * Copyright 2016, Joyent, Inc.
  29   29   */
  30   30  
  31   31  #include <sys/param.h>
  32   32  #include <sys/types.h>
  33   33  #include <sys/sysmacros.h>
  34   34  #include <sys/systm.h>
  35   35  #include <sys/thread.h>
  36   36  #include <sys/proc.h>
  37   37  #include <sys/task.h>
  38   38  #include <sys/project.h>
↓ open down ↓ 11 lines elided ↑ open up ↑
  50   50  #include <sys/debug.h>
  51   51  #include <sys/tnf.h>
  52   52  #include <sys/schedctl.h>
  53   53  #include <sys/poll.h>
  54   54  #include <sys/copyops.h>
  55   55  #include <sys/lwp_upimutex_impl.h>
  56   56  #include <sys/cpupart.h>
  57   57  #include <sys/lgrp.h>
  58   58  #include <sys/rctl.h>
  59   59  #include <sys/contract_impl.h>
       60 +#include <sys/contract/process.h>
       61 +#include <sys/contract/process_impl.h>
  60   62  #include <sys/cpc_impl.h>
  61   63  #include <sys/sdt.h>
  62   64  #include <sys/cmn_err.h>
  63   65  #include <sys/brand.h>
  64   66  #include <sys/cyclic.h>
  65   67  #include <sys/pool.h>
  66   68  
  67   69  /* hash function for the lwpid hash table, p->p_tidhash[] */
  68   70  #define TIDHASH(tid, hash_sz)   ((tid) & ((hash_sz) - 1))
  69   71  
↓ open down ↓ 38 lines elided ↑ open up ↑
 108  110          void *bufp = NULL;
 109  111          klwp_t *curlwp;
 110  112          lwpent_t *lep;
 111  113          lwpdir_t *old_dir = NULL;
 112  114          uint_t old_dirsz = 0;
 113  115          tidhash_t *old_hash = NULL;
 114  116          uint_t old_hashsz = 0;
 115  117          ret_tidhash_t *ret_tidhash = NULL;
 116  118          int i;
 117  119          int rctlfail = 0;
 118      -        boolean_t branded = 0;
      120 +        void *brand_data = NULL;
 119  121          struct ctxop *ctx = NULL;
 120  122  
 121  123          ASSERT(cid != sysdccid);        /* system threads must start in SYS */
 122  124  
 123  125          ASSERT(p != &p0);               /* No new LWPs in p0. */
 124  126  
 125  127          mutex_enter(&p->p_lock);
 126  128          mutex_enter(&p->p_zone->zone_nlwps_lock);
 127  129          /*
 128  130           * don't enforce rctl limits on system processes
↓ open down ↓ 147 lines elided ↑ open up ↑
 276  278                  t->t_rprof = kmem_zalloc(sizeof (struct rprof), KM_SLEEP);
 277  279  
 278  280          if (cid != NOCLASS)
 279  281                  (void) CL_ALLOC(&bufp, cid, KM_SLEEP);
 280  282  
 281  283          /*
 282  284           * Allocate an lwp directory entry for the new lwp.
 283  285           */
 284  286          lep = kmem_zalloc(sizeof (*lep), KM_SLEEP);
 285  287  
      288 +        /*
      289 +         * If necessary, speculatively allocate lwp brand data.  This is done
      290 +         * ahead of time so p_lock need not be dropped during lwp branding.
      291 +         */
      292 +        if (PROC_IS_BRANDED(p) && BROP(p)->b_lwpdata_alloc != NULL) {
      293 +                if ((brand_data = BROP(p)->b_lwpdata_alloc(p)) == NULL) {
      294 +                        mutex_enter(&p->p_lock);
      295 +                        err = 1;
      296 +                        atomic_inc_32(&p->p_zone->zone_ffmisc);
      297 +                        goto error;
      298 +                }
      299 +        }
      300 +
 286  301          mutex_enter(&p->p_lock);
 287  302  grow:
 288  303          /*
 289  304           * Grow the lwp (thread) directory and lwpid hash table if necessary.
 290  305           * A note on the growth algorithm:
 291  306           *      The new lwp directory size is computed as:
 292  307           *              new = 2 * old + 2
 293  308           *      Starting with an initial size of 2 (see exec_common()),
 294  309           *      this yields numbers that are a power of two minus 2:
 295  310           *              2, 6, 14, 30, 62, 126, 254, 510, 1022, ...
↓ open down ↓ 327 lines elided ↑ open up ↑
 623  638                          /*
 624  639                           * We only need to worry about colliding with an id
 625  640                           * that's already in use if this process has
 626  641                           * cycled through all available lwp ids.
 627  642                           */
 628  643                          if ((p->p_flag & SLWPWRAP) == 0)
 629  644                                  break;
 630  645                  } while (lwp_hash_lookup(p, t->t_tid) != NULL);
 631  646          }
 632  647  
 633      -        /*
 634      -         * If this is a branded process, let the brand do any necessary lwp
 635      -         * initialization.
 636      -         */
 637      -        if (PROC_IS_BRANDED(p)) {
 638      -                if (BROP(p)->b_initlwp(lwp)) {
 639      -                        err = 1;
 640      -                        atomic_inc_32(&p->p_zone->zone_ffmisc);
 641      -                        goto error;
 642      -                }
 643      -                branded = 1;
 644      -        }
 645  648  
 646  649          if (t->t_tid == 1) {
 647  650                  kpreempt_disable();
 648  651                  ASSERT(t->t_lpl != NULL);
 649  652                  p->p_t1_lgrpid = t->t_lpl->lpl_lgrpid;
 650  653                  kpreempt_enable();
 651  654                  if (p->p_tr_lgrpid != LGRP_NONE &&
 652  655                      p->p_tr_lgrpid != p->p_t1_lgrpid) {
 653  656                          lgrp_update_trthr_migrations(1);
 654  657                  }
 655  658          }
 656  659  
 657      -        p->p_lwpcnt++;
 658  660          t->t_waitfor = -1;
 659  661  
 660  662          /*
 661  663           * Turn microstate accounting on for thread if on for process.
 662  664           */
 663  665          if (p->p_flag & SMSACCT)
 664  666                  t->t_proc_flag |= TP_MSACCT;
 665  667  
 666  668          /*
 667  669           * If the process has watchpoints, mark the new thread as such.
↓ open down ↓ 21 lines elided ↑ open up ↑
 689  691  
 690  692          /*
 691  693           * Set system call processing flags in case tracing or profiling
 692  694           * is set.  The first system call will evaluate these and turn
 693  695           * them off if they aren't needed.
 694  696           */
 695  697          t->t_pre_sys = 1;
 696  698          t->t_post_sys = 1;
 697  699  
 698  700          /*
      701 +         * Perform lwp branding
      702 +         *
      703 +         * The b_initlwp hook is _not_ allowed to drop p->p_lock as it must be
      704 +         * continuously held between when the tidhash is sized and when the lwp
      705 +         * is inserted into it.  Operations requiring p->p_lock to be
      706 +         * temporarily dropped can be performed in b_initlwp_post.
      707 +         */
      708 +        if (PROC_IS_BRANDED(p)) {
      709 +                BROP(p)->b_initlwp(lwp, brand_data);
      710 +                /*
      711 +                 * The b_initlwp hook is expected to consume any preallocated
      712 +                 * brand_data in a way that prepares it for deallocation by the
      713 +                 * b_freelwp hook.
      714 +                 */
      715 +                brand_data = NULL;
      716 +        }
      717 +
      718 +        /*
 699  719           * Insert the new thread into the list of all threads.
 700  720           */
      721 +        p->p_lwpcnt++;
 701  722          if ((tx = p->p_tlist) == NULL) {
 702  723                  t->t_back = t;
 703  724                  t->t_forw = t;
 704  725                  p->p_tlist = t;
 705  726          } else {
 706  727                  t->t_forw = tx;
 707  728                  t->t_back = tx->t_back;
 708  729                  tx->t_back->t_forw = t;
 709  730                  tx->t_back = t;
 710  731          }
 711  732  
 712  733          /*
 713  734           * Insert the new lwp into an lwp directory slot position
 714  735           * and into the lwpid hash table.
 715  736           */
 716  737          lep->le_thread = t;
 717  738          lep->le_lwpid = t->t_tid;
 718  739          lep->le_start = t->t_start;
 719  740          lwp_hash_in(p, lep, p->p_tidhash, p->p_tidhash_sz, 1);
 720  741  
      742 +        /*
      743 +         * Complete lwp branding
      744 +         */
      745 +        if (PROC_IS_BRANDED(p) && BROP(p)->b_initlwp_post != NULL) {
      746 +                BROP(p)->b_initlwp_post(lwp);
      747 +        }
      748 +
 721  749          if (state == TS_RUN) {
 722  750                  /*
 723  751                   * We set the new lwp running immediately.
 724  752                   */
 725  753                  t->t_proc_flag &= ~TP_HOLDLWP;
 726  754                  lwp_create_done(t);
 727  755          }
 728  756  
 729  757  error:
 730  758          if (err) {
↓ open down ↓ 15 lines elided ↑ open up ↑
 746  774  
 747  775                  ASSERT(MUTEX_HELD(&p->p_lock));
 748  776                  mutex_enter(&p->p_zone->zone_nlwps_lock);
 749  777                  p->p_task->tk_nlwps--;
 750  778                  p->p_task->tk_proj->kpj_nlwps--;
 751  779                  p->p_zone->zone_nlwps--;
 752  780                  mutex_exit(&p->p_zone->zone_nlwps_lock);
 753  781                  if (cid != NOCLASS && bufp != NULL)
 754  782                          CL_FREE(cid, bufp);
 755  783  
 756      -                if (branded)
 757      -                        BROP(p)->b_freelwp(lwp);
      784 +                if (brand_data != NULL) {
      785 +                        BROP(p)->b_lwpdata_free(brand_data);
      786 +                }
 758  787  
 759  788                  mutex_exit(&p->p_lock);
 760  789                  t->t_state = TS_FREE;
 761  790                  thread_rele(t);
 762  791  
 763  792                  /*
 764  793                   * We need to remove t from the list of all threads
 765  794                   * because thread_exit()/lwp_exit() isn't called on t.
 766  795                   */
 767  796                  mutex_enter(&pidlock);
↓ open down ↓ 52 lines elided ↑ open up ↑
 820  849  
 821  850  /*
 822  851   * Copy an LWP's active templates, and clear the latest contracts.
 823  852   */
 824  853  void
 825  854  lwp_ctmpl_copy(klwp_t *dst, klwp_t *src)
 826  855  {
 827  856          int i;
 828  857  
 829  858          for (i = 0; i < ct_ntypes; i++) {
 830      -                dst->lwp_ct_active[i] = ctmpl_dup(src->lwp_ct_active[i]);
      859 +                ct_template_t *tmpl = src->lwp_ct_active[i];
      860 +
      861 +                /*
      862 +                 * If the process contract template is setup to be preserved
      863 +                 * across exec, then if we're forking, perform an implicit
      864 +                 * template_clear now. This ensures that future children of
      865 +                 * this child will remain in the same contract unless they're
      866 +                 * explicitly setup differently. We know we're forking if the
      867 +                 * two LWPs belong to different processes.
      868 +                 */
      869 +                if (i == CTT_PROCESS && tmpl != NULL) {
      870 +                        ctmpl_process_t *ctp = tmpl->ctmpl_data;
      871 +
      872 +                        if (dst->lwp_procp != src->lwp_procp &&
      873 +                            (ctp->ctp_params & CT_PR_KEEP_EXEC) != 0)
      874 +                                tmpl = NULL;
      875 +                }
      876 +
      877 +                dst->lwp_ct_active[i] = ctmpl_dup(tmpl);
 831  878                  dst->lwp_ct_latest[i] = NULL;
      879 +
 832  880          }
 833  881  }
 834  882  
 835  883  /*
 836  884   * Clear an LWP's contract template state.
 837  885   */
 838  886  void
 839      -lwp_ctmpl_clear(klwp_t *lwp)
      887 +lwp_ctmpl_clear(klwp_t *lwp, boolean_t is_exec)
 840  888  {
 841  889          ct_template_t *tmpl;
 842  890          int i;
 843  891  
 844  892          for (i = 0; i < ct_ntypes; i++) {
 845      -                if ((tmpl = lwp->lwp_ct_active[i]) != NULL) {
 846      -                        ctmpl_free(tmpl);
 847      -                        lwp->lwp_ct_active[i] = NULL;
 848      -                }
 849      -
 850  893                  if (lwp->lwp_ct_latest[i] != NULL) {
 851  894                          contract_rele(lwp->lwp_ct_latest[i]);
 852  895                          lwp->lwp_ct_latest[i] = NULL;
 853  896                  }
      897 +
      898 +                if ((tmpl = lwp->lwp_ct_active[i]) != NULL) {
      899 +                        /*
      900 +                         * If we're exec-ing a new program and the process
      901 +                         * contract template is setup to be preserved across
      902 +                         * exec, then don't clear it.
      903 +                         */
      904 +                        if (is_exec && i == CTT_PROCESS) {
      905 +                                ctmpl_process_t *ctp = tmpl->ctmpl_data;
      906 +
      907 +                                if ((ctp->ctp_params & CT_PR_KEEP_EXEC) != 0)
      908 +                                        continue;
      909 +                        }
      910 +
      911 +                        ctmpl_free(tmpl);
      912 +                        lwp->lwp_ct_active[i] = NULL;
      913 +                }
 854  914          }
 855  915  }
 856  916  
 857  917  /*
 858  918   * Individual lwp exit.
 859  919   * If this is the last lwp, exit the whole process.
 860  920   */
 861  921  void
 862  922  lwp_exit(void)
 863  923  {
↓ open down ↓ 20 lines elided ↑ open up ↑
 884  944  
 885  945          if (t->t_door)
 886  946                  door_slam();
 887  947  
 888  948          if (t->t_schedctl != NULL)
 889  949                  schedctl_lwp_cleanup(t);
 890  950  
 891  951          if (t->t_upimutex != NULL)
 892  952                  upimutex_cleanup();
 893  953  
 894      -        /*
 895      -         * Perform any brand specific exit processing, then release any
 896      -         * brand data associated with the lwp
 897      -         */
 898      -        if (PROC_IS_BRANDED(p))
 899      -                BROP(p)->b_lwpexit(lwp);
 900      -
 901  954          lwp_pcb_exit();
 902  955  
 903  956          mutex_enter(&p->p_lock);
 904  957          lwp_cleanup();
 905  958  
 906  959          /*
 907  960           * When this process is dumping core, its lwps are held here
 908  961           * until the core dump is finished. Then exitlwps() is called
 909  962           * again to release these lwps so that they can finish exiting.
 910  963           */
↓ open down ↓ 23 lines elided ↑ open up ↑
 934  987                   * lwp_exit().
 935  988                   */
 936  989                  mutex_enter(&p->p_lock);
 937  990                  ASSERT(curproc->p_flag & SEXITLWPS);
 938  991                  prbarrier(p);
 939  992          }
 940  993  
 941  994          DTRACE_PROC(lwp__exit);
 942  995  
 943  996          /*
      997 +         * Perform any brand specific exit processing, then release any
      998 +         * brand data associated with the lwp
      999 +         */
     1000 +        if (PROC_IS_BRANDED(p)) {
     1001 +                mutex_exit(&p->p_lock);
     1002 +                BROP(p)->b_lwpexit(lwp);
     1003 +                BROP(p)->b_freelwp(lwp);
     1004 +                mutex_enter(&p->p_lock);
     1005 +                prbarrier(p);
     1006 +        }
     1007 +
     1008 +        /*
 944 1009           * If the lwp is a detached lwp or if the process is exiting,
 945 1010           * remove (lwp_hash_out()) the lwp from the lwp directory.
 946 1011           * Otherwise null out the lwp's le_thread pointer in the lwp
 947 1012           * directory so that other threads will see it as a zombie lwp.
 948 1013           */
 949 1014          prlwpexit(t);           /* notify /proc */
 950 1015          if (!(t->t_proc_flag & TP_TWAIT) || (p->p_flag & SEXITLWPS))
 951 1016                  lwp_hash_out(p, t->t_tid);
 952 1017          else {
 953 1018                  ASSERT(!(t->t_proc_flag & TP_DAEMON));
↓ open down ↓ 140 lines elided ↑ open up ↑
1094 1159          /*
1095 1160           * Do lgroup bookkeeping to account for thread exiting.
1096 1161           */
1097 1162          kpreempt_disable();
1098 1163          lgrp_move_thread(t, NULL, 1);
1099 1164          if (t->t_tid == 1) {
1100 1165                  p->p_t1_lgrpid = LGRP_NONE;
1101 1166          }
1102 1167          kpreempt_enable();
1103 1168  
1104      -        lwp_ctmpl_clear(ttolwp(t));
     1169 +        lwp_ctmpl_clear(ttolwp(t), B_FALSE);
1105 1170  }
1106 1171  
1107 1172  int
1108 1173  lwp_suspend(kthread_t *t)
1109 1174  {
1110 1175          int tid;
1111 1176          proc_t *p = ttoproc(t);
1112 1177  
1113 1178          ASSERT(MUTEX_HELD(&p->p_lock));
1114 1179  
↓ open down ↓ 980 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX