]> git.saurik.com Git - apple/xnu.git/blobdiff - bsd/kern/kern_panicinfo.c
xnu-1699.26.8.tar.gz
[apple/xnu.git] / bsd / kern / kern_panicinfo.c
index 9c7352b63340c78faa35b0cd14c151b9784c2fe3..eb5c5bfbd912d75efacc888b1d419dfbde53f4a8 100644 (file)
@@ -1,14 +1,19 @@
 /*
- * Copyright (c) 2002 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2002-2006 Apple Computer, Inc. All rights reserved.
  *
- * @APPLE_LICENSE_HEADER_START@
+ * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
  * 
  * This file contains Original Code and/or Modifications of Original Code
  * as defined in and that are subject to the Apple Public Source License
  * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
+ * compliance with the License. The rights granted to you under the License
+ * may not be used to create, or enable the creation or redistribution of,
+ * unlawful or unlicensed copies of an Apple operating system, or to
+ * circumvent, violate, or enable the circumvention or violation of, any
+ * terms of an Apple operating system software license agreement.
+ * 
+ * Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this file.
  * 
  * The Original Code and all software distributed under the License are
  * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
@@ -18,7 +23,7 @@
  * Please see the License for the specific language governing rights and
  * limitations under the License.
  * 
- * @APPLE_LICENSE_HEADER_END@
+ * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
  */
 
 #include <sys/param.h>
 
 /* prototypes not exported by osfmk/console. */
 extern void panic_dialog_test( void );
+extern void noroot_icon_test(void);
 extern int  panic_dialog_set_image( const unsigned char * ptr, unsigned int size );
 extern void panic_dialog_get_image( unsigned char ** ptr, unsigned int * size );
 
 /* make the compiler happy */
-extern int sysctl_dopanicinfo(int *, u_int, user_addr_t, size_t *, user_addr_t, size_t, struct proc *);
+static int sysctl_dopanicinfo SYSCTL_HANDLER_ARGS;
 
 
 #define PANIC_IMAGE_SIZE_LIMIT (32 * 4096)                             /* 128K - Maximum amount of memory consumed for the panic UI */
-#define KERN_PANICINFO_TEST    (KERN_PANICINFO_IMAGE+2)                /* Allow the panic UI to be tested by root without causing a panic */
 
 /* Local data */
 static int image_size_limit = PANIC_IMAGE_SIZE_LIMIT;
 
-__private_extern__ int
-sysctl_dopanicinfo(name, namelen, oldp, oldlenp, newp, newlen, p)
-       int *name;
-       u_int namelen;
-       user_addr_t oldp;
-       size_t *oldlenp;
-       user_addr_t newp;
-       size_t newlen;
-       struct proc *p;
+/* XXX Should be STATIC for dtrace debugging.. */
+static int
+sysctl_dopanicinfo SYSCTL_HANDLER_ARGS
 {
+       __unused int cmd = oidp->oid_arg2;      /* subcommand*/
+       int *name = arg1;               /* oid element argument vector */
+       int namelen = arg2;             /* number of oid element arguments */
+       user_addr_t oldp = req->oldptr; /* user buffer copy out address */
+       size_t *oldlenp = &req->oldlen; /* user buffer copy out size */
+       user_addr_t newp = req->newptr; /* user buffer copy in address */
+       size_t newlen = req->newlen;    /* user buffer copy in size */
        int error = 0;
+       proc_t p = current_proc();
+
        vm_offset_t newimage = (vm_offset_t )NULL;
        kern_return_t   kret;
        unsigned char * prev_image_ptr;
        unsigned int prev_image_size;
 
-
        /* all sysctl names at this level are terminal */
        if (namelen != 1)
                return (ENOTDIR);               /* overloaded */
 
-       if ( (error = proc_suser(p)) )  /* must be super user to muck with image */
+       /* must be super user to muck with image */
+       if ( (error = proc_suser(p)) )
                return (error);
 
        switch (name[0]) {
@@ -82,7 +90,13 @@ sysctl_dopanicinfo(name, namelen, oldp, oldlenp, newp, newlen, p)
        case KERN_PANICINFO_TEST:
                
                panic_dialog_test();
-               return (0);
+               break;
+
+       case KERN_PANICINFO_NOROOT_TEST:
+               printf("Testing noroot icon \n");
+
+               noroot_icon_test();
+               break;
 
        case KERN_PANICINFO_MAXSIZE:
 
@@ -93,7 +107,7 @@ sysctl_dopanicinfo(name, namelen, oldp, oldlenp, newp, newlen, p)
 
                error = sysctl_int(oldp, oldlenp, newp, newlen, &image_size_limit);
 
-               return (error);
+               break;
 
        case KERN_PANICINFO_IMAGE:
 
@@ -101,11 +115,13 @@ sysctl_dopanicinfo(name, namelen, oldp, oldlenp, newp, newlen, p)
                if ( newp != USER_ADDR_NULL ) {
 
                        /* check the length of the incoming image before allocating space for it. */
-                       if ( newlen > (size_t)image_size_limit )
-                               return (ENOMEM);
+                       if ( newlen > (size_t)image_size_limit ) {
+                               error = ENOMEM;
+                               break;
+                       }
 
                        /* allocate some kernel wired memory for the new image */
-                       kret = kmem_alloc(kernel_map, &newimage, (vm_size_t)round_page_32(newlen));
+                       kret = kmem_alloc(kernel_map, &newimage, (vm_size_t)round_page(newlen));
 
                        if (kret != KERN_SUCCESS) {
                                switch (kret) {
@@ -120,8 +136,7 @@ sysctl_dopanicinfo(name, namelen, oldp, oldlenp, newp, newlen, p)
                                        error = EPERM;
                                        break;
                                }
-       
-                               return (error);
+                               break;
                        }
 
                        /* copy the image in from user space */
@@ -166,17 +181,29 @@ sysctl_dopanicinfo(name, namelen, oldp, oldlenp, newp, newlen, p)
 
                        /* free the wired memory used by the previous image */
                        if ( prev_image_ptr != NULL ) {
-                               (void)kmem_free(kernel_map, (vm_offset_t) prev_image_ptr, (vm_size_t)round_page_32(prev_image_size));
-                               printf("Panic UI memory freed (%d)\n", round_page_32(prev_image_size));
+                               (void)kmem_free(kernel_map, (vm_offset_t) prev_image_ptr, (vm_size_t)round_page(prev_image_size));
+                               printf("Panic UI memory freed (%p)\n", (void *)round_page(prev_image_size));
                        }
                }
 
-               return (0);
+               break;
 
 errout:
                if ( newimage != (vm_offset_t )NULL )
-                       (void)kmem_free(kernel_map, newimage, (vm_size_t)round_page_32(newlen));
+                       (void)kmem_free(kernel_map, newimage, (vm_size_t)round_page(newlen));
 
-               return (error);
+               break;
        }
+
+       /* adjust index so we return the right required/consumed amount */
+       if (!error)
+               req->oldidx += req->oldlen;
+
+       return (error);
 }
+SYSCTL_PROC(_kern, KERN_PANICINFO, panicinfo, CTLTYPE_NODE|CTLFLAG_RW | CTLFLAG_LOCKED | CTLFLAG_ANYBODY,
+       0,                      /* Pointer argument (arg1) */
+       0,                      /* Integer argument (arg2) */
+       sysctl_dopanicinfo,     /* Handler function */
+       NULL,                   /* Data pointer */
+       "");