The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/bsd/kern/kern_panicinfo.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*
    2  * Copyright (c) 2002 Apple Computer, Inc. All rights reserved.
    3  *
    4  * @APPLE_LICENSE_HEADER_START@
    5  * 
    6  * Copyright (c) 1999-2003 Apple Computer, Inc.  All Rights Reserved.
    7  * 
    8  * This file contains Original Code and/or Modifications of Original Code
    9  * as defined in and that are subject to the Apple Public Source License
   10  * Version 2.0 (the 'License'). You may not use this file except in
   11  * compliance with the License. Please obtain a copy of the License at
   12  * http://www.opensource.apple.com/apsl/ and read it before using this
   13  * file.
   14  * 
   15  * The Original Code and all software distributed under the License are
   16  * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
   17  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
   18  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
   19  * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
   20  * Please see the License for the specific language governing rights and
   21  * limitations under the License.
   22  * 
   23  * @APPLE_LICENSE_HEADER_END@
   24  */
   25 
   26 #include <sys/param.h>
   27 #include <sys/fcntl.h>
   28 #include <sys/malloc.h>
   29 #include <sys/namei.h>
   30 #include <sys/proc.h>
   31 #include <sys/stat.h>
   32 #include <sys/sysctl.h>
   33 #include <sys/vnode.h>
   34 #include <sys/vm.h>
   35 
   36 #include <mach/kern_return.h>
   37 
   38 /* prototypes not exported by osfmk. */
   39 extern void kmem_free(vm_map_t, vm_offset_t, vm_size_t);
   40 extern kern_return_t kmem_alloc_wired(vm_map_t, vm_offset_t *, vm_size_t);
   41 
   42 
   43 /* Globals */
   44 static off_t imagesizelimit = (4 * 4096);
   45 
   46 /* Information about the current panic image */
   47 static int image_bits = 32;     /* Bitdepth */
   48 
   49 static char *image_pathname = NULL;     /* path to it */
   50 static size_t image_pathlen = 0;        /* and the length of the pathname */
   51 
   52 static vm_offset_t image_ptr = NULL; /* the image itself */
   53 static off_t image_size = 0; /* and the imagesize */
   54 
   55 
   56 __private_extern__ void
   57 get_panicimage(vm_offset_t *imageptr, vm_size_t *imagesize, int *imagebits)
   58 {
   59         *imageptr = image_ptr;
   60         *imagesize = image_size;
   61         *imagebits = image_bits;
   62 }
   63 
   64 static int
   65 panicimage_from_file(
   66         char *imname,
   67         off_t sizelimit,
   68         vm_offset_t *image,
   69         off_t *filesize,
   70         struct proc *p)
   71 {
   72         int error = 0;
   73         int error1 = 0;
   74         int aresid;
   75         struct nameidata nd;
   76         struct vattr    vattr;
   77         struct vnode * vp;
   78         kern_return_t   kret;
   79         struct pcred *pcred = p->p_cred;
   80         struct ucred *cred = pcred->pc_ucred;
   81         vm_offset_t iobuf;
   82 
   83         /* Open the file */
   84         NDINIT(&nd, LOOKUP, FOLLOW, UIO_SYSSPACE, imname, p);
   85         error = vn_open(&nd, FREAD, S_IRUSR);
   86         if (error)
   87                 return (error);
   88         vp = nd.ni_vp;
   89         
   90         if (vp->v_type != VREG) { 
   91                 error = EFAULT;
   92                 goto out;
   93         }
   94 
   95         /* get the file size */
   96         error = VOP_GETATTR(vp, &vattr, cred, p);
   97         if (error)
   98                 goto out;
   99 
  100         /* validate the file size */
  101         if (vattr.va_size > sizelimit) {
  102                 error = EFBIG;
  103                 goto out;
  104         }
  105 
  106         /* allocate kernel wired memory */
  107         kret = kmem_alloc_wired(kernel_map, &iobuf,
  108                                 (vm_size_t)vattr.va_size);
  109         if (kret != KERN_SUCCESS) {
  110                 switch (kret) {
  111                 default:
  112                         error = EINVAL;
  113                         break;
  114                 case KERN_NO_SPACE:
  115                 case KERN_RESOURCE_SHORTAGE:
  116                         error = ENOMEM;
  117                         break;
  118                 case KERN_PROTECTION_FAILURE:
  119                         error = EPERM;
  120                         break;
  121                 }
  122                 goto out;
  123         }
  124 
  125         /* read the file in the kernel buffer */
  126         error = vn_rdwr(UIO_READ, vp, (caddr_t)iobuf, (int)vattr.va_size,
  127                         (off_t)0, UIO_SYSSPACE, IO_NODELOCKED|IO_UNIT,
  128                         cred, &aresid, p);
  129         if (error) {
  130                 (void)kmem_free(kernel_map, iobuf, (vm_size_t)vattr.va_size);
  131                 goto out;
  132         }
  133 
  134         /*
  135          * return the image to the caller
  136          * freeing this memory is callers responsibility
  137          */
  138         *image = iobuf;
  139         *filesize = (off_t)vattr.va_size;
  140 
  141 out:
  142         VOP_UNLOCK(vp, 0, p);
  143         error1 = vn_close(vp, FREAD, cred, p);
  144         if (error == 0)
  145                 error = error1;
  146         return (error);
  147 }
  148 
  149 __private_extern__ int
  150 sysctl_dopanicinfo(name, namelen, oldp, oldlenp, newp, newlen, p)
  151         int *name;
  152         u_int namelen;
  153         void *oldp;
  154         size_t *oldlenp;
  155         void *newp;
  156         size_t newlen;
  157         struct proc *p;
  158 {
  159         int error = 0;
  160         int bitdepth = 32;      /* default is 32 bits */
  161         char *imname;
  162 
  163         /* all sysctl names at this level are terminal */
  164         if (namelen != 1)
  165                 return (ENOTDIR);               /* overloaded */
  166 
  167         switch (name[0]) {
  168         default:
  169                 return (EOPNOTSUPP);
  170         case KERN_PANICINFO_MAXSIZE:
  171                 if (newp != NULL && (error = suser(p->p_ucred, &p->p_acflag)))
  172                         return (error);
  173                 error = sysctl_quad(oldp, oldlenp, newp, newlen, &imagesizelimit);
  174                 return (error);
  175 
  176         case KERN_PANICINFO_IMAGE16:
  177                 bitdepth = 16;
  178                 /* and fall through */
  179         case KERN_PANICINFO_IMAGE32:
  180                 /* allocate a buffer for the image pathname */
  181                 MALLOC_ZONE(imname, char *, MAXPATHLEN, M_NAMEI, M_WAITOK);
  182 
  183                 if (!newp) {
  184                         bcopy(image_pathname, imname, image_pathlen);
  185                         imname[image_pathlen] = '\0';
  186                 } else
  187                         imname[0] = '\0';
  188                 error = sysctl_string(oldp, oldlenp, newp, newlen,
  189                     imname, MAXPATHLEN);
  190                 if (newp && !error) {
  191                         char *tmpstr, *oldstr;
  192                         off_t filesize = 0;
  193                         size_t len;
  194                         vm_offset_t image;
  195                         vm_offset_t oimage = NULL;
  196                         vm_size_t osize = 0;    /* covariable: quiet compiler */
  197 
  198                         len = strlen(imname);
  199                         oldstr = image_pathname;
  200 
  201                         error = panicimage_from_file(imname, imagesizelimit,
  202                                         &image, &filesize, p);
  203                         if (error)
  204                                 goto errout;
  205 
  206                         /* release the old image */
  207                         if (image_ptr) {
  208                                 oimage = image_ptr;
  209                                 osize = image_size;
  210                         }
  211 
  212                         /* remember the new one */
  213                         image_ptr = image;
  214                         image_bits = bitdepth;  /* new bith depth */
  215                         image_size = filesize; /* new imagesize */
  216 
  217                         if (oimage)
  218                                 kmem_free(kernel_map, oimage, osize);
  219 
  220                         /* save the new name */
  221                         MALLOC(tmpstr, char *, len+1, M_TEMP, M_WAITOK);
  222                         bcopy(imname, tmpstr, len);
  223                         tmpstr[len] = '\0';
  224 
  225                         image_pathname = tmpstr;        /* new pathname */
  226                         image_pathlen = len;    /* new pathname length */
  227 
  228                         /* free the old name */
  229                         FREE(oldstr, M_TEMP);
  230                 }
  231 errout:
  232                 FREE_ZONE(imname, MAXPATHLEN, M_NAMEI);
  233                 return (error);
  234         }
  235 }

Cache object: e475de151048355317e555740c505d45


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.