Print this page
NEX-9665 libcfgadm: memory leak in do_list_common()
Reviewed by: Jan Kryl <jan.kryl@nexenta.com>
Reviewed by: Dan Fields <dan.fields@nexenta.com>
NEX-9634 cfgadm_plugins/shp: memory leaks in cfga_list_ext()
Reviewed by: Jan Kryl <jan.kryl@nexenta.com>
Reviewed by: Dan Fields <dan.fields@nexenta.com>
NEX-8148 Alerts should be sent if cores are created on a system (lint fix)
NEX-8148 Alerts should be sent if cores are created on a system
Reviewed by: Roman Strashkin <roman.strashkin@nexenta.com>
Reviewed by: Yuri Pankov <yuri.pankov@nexenta.com>


   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 
  22 /*
  23  * Copyright (c) 1989, 2010, Oracle and/or its affiliates. All rights reserved.
  24  * Copyright (c) 2011, Joyent Inc. All rights reserved.
  25  * Copyright (c) 2016 by Delphix. All rights reserved.

  26  */
  27 
  28 /*      Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T     */
  29 /*        All Rights Reserved   */
  30 
  31 #include <sys/param.h>
  32 #include <sys/types.h>
  33 #include <sys/time.h>
  34 #include <sys/sysmacros.h>
  35 #include <sys/proc.h>
  36 #include <sys/systm.h>
  37 #include <sys/cred.h>
  38 #include <sys/user.h>
  39 #include <sys/utsname.h>
  40 #include <sys/errno.h>
  41 #include <sys/signal.h>
  42 #include <sys/siginfo.h>
  43 #include <sys/fault.h>
  44 #include <sys/syscall.h>
  45 #include <sys/ucontext.h>


  47 #include <sys/vnode.h>
  48 #include <sys/var.h>
  49 #include <sys/file.h>
  50 #include <sys/pathname.h>
  51 #include <sys/vfs.h>
  52 #include <sys/exec.h>
  53 #include <sys/debug.h>
  54 #include <sys/stack.h>
  55 #include <sys/kmem.h>
  56 #include <sys/schedctl.h>
  57 #include <sys/core.h>
  58 #include <sys/corectl.h>
  59 #include <sys/cmn_err.h>
  60 #include <vm/as.h>
  61 #include <sys/rctl.h>
  62 #include <sys/nbmlock.h>
  63 #include <sys/stat.h>
  64 #include <sys/zone.h>
  65 #include <sys/contract/process_impl.h>
  66 #include <sys/ddi.h>




  67 
  68 /*
  69  * Processes running within a zone potentially dump core in 3 locations,
  70  * based on the per-process, per-zone, and the global zone's core settings.
  71  *
  72  * Per-zone and global zone settings are often referred to as "global"
  73  * settings since they apply to the system (or zone) as a whole, as
  74  * opposed to a particular process.
  75  */
  76 enum core_types {
  77         CORE_PROC,      /* Use per-process settings */
  78         CORE_ZONE,      /* Use per-zone settings */
  79         CORE_GLOBAL     /* Use global zone settings */
  80 };
  81 
  82 /*
  83  * Log information about "global" core dumps to syslog.
  84  */
  85 static void
  86 core_log(struct core_globals *cg, int error, const char *why, const char *path,
  87     zoneid_t zoneid)
  88 {
  89         proc_t *p = curproc;
  90         pid_t pid = p->p_pid;
  91         char *fn = PTOU(p)->u_comm;
  92 
  93         if (!(cg->core_options & CC_GLOBAL_LOG))
  94                 return;
  95 
  96         if (path == NULL)
  97                 zcmn_err(zoneid, CE_NOTE, "core_log: %s[%d] %s", fn, pid, why);
  98         else if (error == 0)
  99                 zcmn_err(zoneid, CE_NOTE, "core_log: %s[%d] %s: %s", fn, pid,
 100                     why, path);
 101         else
 102                 zcmn_err(zoneid, CE_NOTE, "core_log: %s[%d] %s, errno=%d: %s",
 103                     fn, pid, why, error, path);
 104 }
 105 
 106 /*

















































 107  * Private version of vn_remove().
 108  * Refuse to unlink a directory or an unwritable file.
 109  * Also allow the process to access files normally inaccessible due to
 110  * chroot(2) or Zone limitations.
 111  */
 112 static int
 113 remove_core_file(char *fp, enum core_types core_type)
 114 {
 115         vnode_t *vp = NULL;             /* entry vnode */
 116         vnode_t *dvp;                   /* ptr to parent dir vnode */
 117         vfs_t *dvfsp;
 118         int error;
 119         int in_crit = 0;
 120         pathname_t pn;                  /* name of entry */
 121         vnode_t *startvp, *rootvp;
 122 
 123         if ((error = pn_get(fp, UIO_SYSSPACE, &pn)) != 0)
 124                 return (error);
 125         /*
 126          * Determine what rootvp to use.


 746         if (my_cg->core_options & CC_GLOBAL_PATH)
 747                 error2 = dump_one_core(sig, rlimit, CORE_ZONE, my_cg,
 748                     &fp_global);
 749         if (global_cg != my_cg && (global_cg->core_options & CC_GLOBAL_PATH))
 750                 error3 = dump_one_core(sig, rlimit, CORE_GLOBAL, global_cg,
 751                     &fp_zone);
 752 
 753         /*
 754          * Restore the signal hold mask.
 755          */
 756         mutex_enter(&p->p_lock);
 757         curthread->t_hold = sigmask;
 758         mutex_exit(&p->p_lock);
 759 
 760         if (!ext && p->p_ct_process != NULL)
 761                 contract_process_core(p->p_ct_process, p, sig,
 762                     error1 == 0 ? fp_process : NULL,
 763                     error2 == 0 ? fp_global : NULL,
 764                     error3 == 0 ? fp_zone : NULL);
 765 







 766         if (fp_process != NULL)
 767                 kmem_free(fp_process, MAXPATHLEN);
 768         if (fp_global != NULL)
 769                 kmem_free(fp_global, MAXPATHLEN);
 770         if (fp_zone != NULL)
 771                 kmem_free(fp_zone, MAXPATHLEN);
 772 
 773         /*
 774          * Return non-zero if no core file was created.
 775          */
 776         return (error1 != 0 && error2 != 0 && error3 != 0);
 777 }
 778 
 779 /*
 780  * Maximum chunk size for dumping core files,
 781  * size in pages, patchable in /etc/system
 782  */
 783 uint_t  core_chunk = 32;
 784 
 785 /*




   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 
  22 /*
  23  * Copyright (c) 1989, 2010, Oracle and/or its affiliates. All rights reserved.
  24  * Copyright (c) 2011, Joyent Inc. All rights reserved.
  25  * Copyright (c) 2016 by Delphix. All rights reserved.
  26  * Copyright 2017 Nexenta Systems, Inc.
  27  */
  28 
  29 /*      Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T     */
  30 /*        All Rights Reserved   */
  31 
  32 #include <sys/param.h>
  33 #include <sys/types.h>
  34 #include <sys/time.h>
  35 #include <sys/sysmacros.h>
  36 #include <sys/proc.h>
  37 #include <sys/systm.h>
  38 #include <sys/cred.h>
  39 #include <sys/user.h>
  40 #include <sys/utsname.h>
  41 #include <sys/errno.h>
  42 #include <sys/signal.h>
  43 #include <sys/siginfo.h>
  44 #include <sys/fault.h>
  45 #include <sys/syscall.h>
  46 #include <sys/ucontext.h>


  48 #include <sys/vnode.h>
  49 #include <sys/var.h>
  50 #include <sys/file.h>
  51 #include <sys/pathname.h>
  52 #include <sys/vfs.h>
  53 #include <sys/exec.h>
  54 #include <sys/debug.h>
  55 #include <sys/stack.h>
  56 #include <sys/kmem.h>
  57 #include <sys/schedctl.h>
  58 #include <sys/core.h>
  59 #include <sys/corectl.h>
  60 #include <sys/cmn_err.h>
  61 #include <vm/as.h>
  62 #include <sys/rctl.h>
  63 #include <sys/nbmlock.h>
  64 #include <sys/stat.h>
  65 #include <sys/zone.h>
  66 #include <sys/contract/process_impl.h>
  67 #include <sys/ddi.h>
  68 #include <sys/fm/protocol.h>
  69 #include <sys/fm/util.h>
  70 #include <sys/fm/sw/core.h>
  71 #include <sys/sysevent.h>
  72 
  73 /*
  74  * Processes running within a zone potentially dump core in 3 locations,
  75  * based on the per-process, per-zone, and the global zone's core settings.
  76  *
  77  * Per-zone and global zone settings are often referred to as "global"
  78  * settings since they apply to the system (or zone) as a whole, as
  79  * opposed to a particular process.
  80  */
  81 enum core_types {
  82         CORE_PROC,      /* Use per-process settings */
  83         CORE_ZONE,      /* Use per-zone settings */
  84         CORE_GLOBAL     /* Use global zone settings */
  85 };
  86 
  87 /*
  88  * Log information about "global" core dumps to syslog.
  89  */
  90 static void
  91 core_log(struct core_globals *cg, int error, const char *why, const char *path,
  92     zoneid_t zoneid)
  93 {
  94         proc_t *p = curproc;
  95         pid_t pid = p->p_pid;
  96         char *fn = PTOU(p)->u_comm;
  97 
  98         if (!(cg->core_options & CC_GLOBAL_LOG))
  99                 return;
 100 
 101         if (path == NULL)
 102                 zcmn_err(zoneid, CE_NOTE, "core_log: %s[%d] %s", fn, pid, why);
 103         else if (error == 0)
 104                 zcmn_err(zoneid, CE_NOTE, "core_log: %s[%d] %s: %s", fn, pid,
 105                     why, path);
 106         else
 107                 zcmn_err(zoneid, CE_NOTE, "core_log: %s[%d] %s, errno=%d: %s",
 108                     fn, pid, why, error, path);
 109 }
 110 
 111 /*
 112  * Generate FMA e-report for a core.
 113  */
 114 static void
 115 gen_ereport(const char *path, int sig)
 116 {
 117         nvlist_t *ereport = NULL;
 118         nvlist_t *fmri = NULL;
 119         nvlist_t *sw_obj = NULL;
 120         uint64_t ena;
 121         proc_t *p = curproc;
 122         int err = 0;
 123 
 124         if ((ereport = fm_nvlist_create(NULL)) == NULL)
 125                 return;
 126         if ((fmri = fm_nvlist_create(NULL)) == NULL)
 127                 goto out;
 128         if ((sw_obj = fm_nvlist_create(NULL)) == NULL)
 129                 goto out;
 130         ena = fm_ena_generate(0, FM_ENA_FMT1);
 131 
 132         err |= nvlist_add_uint8(fmri, FM_VERSION, FM_SW_SCHEME_VERSION);
 133         err |= nvlist_add_string(fmri, FM_FMRI_SCHEME, FM_FMRI_SCHEME_SW);
 134         err |= nvlist_add_string(sw_obj, FM_FMRI_SW_OBJ_PATH, path);
 135         err |= nvlist_add_nvlist(fmri, FM_FMRI_SW_OBJ, sw_obj);
 136 
 137         if (err != 0)
 138                 goto out;
 139 
 140         fm_ereport_set(ereport, FM_EREPORT_VERSION, CORE_ERROR_CLASS,
 141             ena, fmri, NULL);
 142 
 143         fm_payload_set(ereport,
 144             FM_EREPORT_PAYLOAD_CORE_COMMAND, DATA_TYPE_STRING,
 145             p->p_exec->v_path ? p->p_exec->v_path : p->p_user.u_comm,
 146             FM_EREPORT_PAYLOAD_CORE_PSARGS, DATA_TYPE_STRING,
 147             p->p_user.u_psargs,
 148             FM_EREPORT_PAYLOAD_CORE_SIGNAL, DATA_TYPE_INT32, sig,
 149             FM_EREPORT_PAYLOAD_CORE_PATH, DATA_TYPE_STRING, path,
 150             NULL);
 151 
 152         fm_ereport_post(ereport, EVCH_SLEEP);
 153 
 154 out:
 155         fm_nvlist_destroy(sw_obj, FM_NVA_FREE);
 156         fm_nvlist_destroy(ereport, FM_NVA_FREE);
 157         fm_nvlist_destroy(fmri, FM_NVA_FREE);
 158 }
 159 
 160 /*
 161  * Private version of vn_remove().
 162  * Refuse to unlink a directory or an unwritable file.
 163  * Also allow the process to access files normally inaccessible due to
 164  * chroot(2) or Zone limitations.
 165  */
 166 static int
 167 remove_core_file(char *fp, enum core_types core_type)
 168 {
 169         vnode_t *vp = NULL;             /* entry vnode */
 170         vnode_t *dvp;                   /* ptr to parent dir vnode */
 171         vfs_t *dvfsp;
 172         int error;
 173         int in_crit = 0;
 174         pathname_t pn;                  /* name of entry */
 175         vnode_t *startvp, *rootvp;
 176 
 177         if ((error = pn_get(fp, UIO_SYSSPACE, &pn)) != 0)
 178                 return (error);
 179         /*
 180          * Determine what rootvp to use.


 800         if (my_cg->core_options & CC_GLOBAL_PATH)
 801                 error2 = dump_one_core(sig, rlimit, CORE_ZONE, my_cg,
 802                     &fp_global);
 803         if (global_cg != my_cg && (global_cg->core_options & CC_GLOBAL_PATH))
 804                 error3 = dump_one_core(sig, rlimit, CORE_GLOBAL, global_cg,
 805                     &fp_zone);
 806 
 807         /*
 808          * Restore the signal hold mask.
 809          */
 810         mutex_enter(&p->p_lock);
 811         curthread->t_hold = sigmask;
 812         mutex_exit(&p->p_lock);
 813 
 814         if (!ext && p->p_ct_process != NULL)
 815                 contract_process_core(p->p_ct_process, p, sig,
 816                     error1 == 0 ? fp_process : NULL,
 817                     error2 == 0 ? fp_global : NULL,
 818                     error3 == 0 ? fp_zone : NULL);
 819 
 820         /*
 821          * FMA ereport is currently generated only for global zone cores
 822          * with global path.
 823          */
 824         if (error2 == 0 && global_cg == my_cg)
 825                 gen_ereport(fp_global, sig);
 826 
 827         if (fp_process != NULL)
 828                 kmem_free(fp_process, MAXPATHLEN);
 829         if (fp_global != NULL)
 830                 kmem_free(fp_global, MAXPATHLEN);
 831         if (fp_zone != NULL)
 832                 kmem_free(fp_zone, MAXPATHLEN);
 833 
 834         /*
 835          * Return non-zero if no core file was created.
 836          */
 837         return (error1 != 0 && error2 != 0 && error3 != 0);
 838 }
 839 
 840 /*
 841  * Maximum chunk size for dumping core files,
 842  * size in pages, patchable in /etc/system
 843  */
 844 uint_t  core_chunk = 32;
 845 
 846 /*