Example #1
0
kern_return_t OsqueryStop(kmod_info_t *ki, void *d) {
    dbg_printf("Kernel module stoping!\n");

    lck_mtx_lock(osquery.mtx);
    if (osquery.open_count > 0) {
        lck_mtx_unlock(osquery.mtx);
        return KERN_FAILURE;
    }

    if (osquery_cqueue_teardown(&osquery.cqueue)) {
        lck_mtx_unlock(osquery.mtx);
        return KERN_FAILURE;
    }

    devfs_remove(osquery.devfs);
    osquery.devfs = NULL;

    if (cdevsw_remove(osquery.major_number, &osquery_cdevsw) < 0) {
        panic("osquery kext: Cannot remove osquery from cdevsw");
    }

    lck_mtx_unlock(osquery.mtx);
    teardown_locks();

    return KERN_SUCCESS;
}
Example #2
0
// Tries to free all resources and also passes through any errors
//
// args: the error arg will be overwritten with KERN_FAILURE in case of an error
//       or returned unmodified in case everything went well.
// return: the given error argument or KERN_FAILURE if anything went wrong
static int pmem_cleanup(int error) {
  if (pmem_zero_page) {
    OSFree(pmem_zero_page, PAGE_SIZE, pmem_tag);
  }
  if (pte_mmap != NULL) {
    pte_mmap_osx_delete(pte_mmap);
  }
  if (pmem_tag) {
    OSMalloc_Tagfree(pmem_tag);
  }
  if (pmem_devpmemnode) {
    devfs_remove(pmem_devpmemnode);
  }
  if (pmem_devmajor != -1) {
    int devindex = 0;
    devindex = cdevsw_remove(pmem_devmajor, &pmem_cdevsw);
    if (devindex != pmem_devmajor) {
      pmem_error("Failed to remove cdevsw, cdevsw_remove() returned %d,"
                 "should be %d", devindex, pmem_devmajor);
      pmem_error("Kext will not be unloaded as an uio could result"
                 " in calling non-existent code");
      error = KERN_FAILURE;
    }
  }

  return error;
}
Example #3
0
kern_return_t OsqueryStop(kmod_info_t *ki, void *d) {
  dbg_printf("Kernel module stopping!\n");

  // Only stop if there are no connected daemons.
  lck_mtx_lock(osquery.mtx);
  if (osquery.open_count > 0) {
    lck_mtx_unlock(osquery.mtx);
    return KERN_FAILURE;
  }

  // Stop sharing the queue and remove queue locks.
  // This will potentially block as heuristics are applied to make sure the
  // queue is no longer is use.
  if (osquery_cqueue_teardown(&osquery.cqueue)) {
    lck_mtx_unlock(osquery.mtx);
    return KERN_FAILURE;
  }

  // Remove the device node.
  devfs_remove(osquery.devfs);
  osquery.devfs = NULL;

  // Tear down the device node data.
  if (cdevsw_remove(osquery.major_number, &osquery_cdevsw) < 0) {
    panic("osquery kext: Cannot remove osquery from cdevsw");
  }

  // Deallocate the IOCTL and kernel API locks.
  lck_mtx_unlock(osquery.mtx);
  teardown_locks();

  return KERN_SUCCESS;
}
Example #4
0
static int
nsmb_dev_load(module_t mod, int cmd, void *arg)
{
	int error = 0;

	switch (cmd) {
	    case MOD_LOAD:
		error = smb_sm_init();
		if (error)
			break;
		error = smb_iod_init();
		if (error) {
			smb_sm_done();
			break;
		}
		cdevsw_add(&nsmb_cdevsw);
		nsmb_dev_tag = EVENTHANDLER_REGISTER(dev_clone, nsmb_dev_clone, 0, 1000);
		printf("netsmb_dev: loaded\n");
		break;
	    case MOD_UNLOAD:
		smb_iod_done();
		error = smb_sm_done();
		error = 0;
		EVENTHANDLER_DEREGISTER(dev_clone, nsmb_dev_tag);
		cdevsw_remove(&nsmb_cdevsw);
		printf("netsmb_dev: unloaded\n");
		break;
	    default:
		error = EINVAL;
		break;
	}
	return error;
}
/**
 * Stop the kernel module.
 */
static kern_return_t VBoxNetAdpDarwinStop(struct kmod_info *pKModInfo, void *pvData)
{
    Log(("VBoxNetAdpDarwinStop\n"));

    vboxNetAdpShutdown();
    /* Remove control device */
    devfs_remove(g_hCtlDev);
    cdevsw_remove(g_nCtlDev, &g_ChDev);

    RTR0Term();

    return KMOD_RETURN_SUCCESS;
}
Example #6
0
File: tty_ptmx.c Project: argp/xnu
int
ptmx_init( __unused int config_count)
{
	/*
	 * We start looking at slot 10, since there are inits that will
	 * stomp explicit slots (e.g. vndevice stomps 1) below that.
	 */

	/* Get a major number for /dev/ptmx */
	if ((ptmx_major = cdevsw_add(-15, &ptmx_cdev)) == -1) {
		printf("ptmx_init: failed to obtain /dev/ptmx major number\n");
		return (ENOENT);
	}

	if (cdevsw_setkqueueok(ptmx_major, &ptmx_cdev, CDEVSW_IS_PTC) == -1) {
		panic("Failed to set flags on ptmx cdevsw entry.");
	}

	/* Get a major number for /dev/pts/nnn */
	if ((ptsd_major = cdevsw_add(-15, &ptsd_cdev)) == -1) {
		(void)cdevsw_remove(ptmx_major, &ptmx_cdev);
		printf("ptmx_init: failed to obtain /dev/ptmx major number\n");
		return (ENOENT);
	}

	if (cdevsw_setkqueueok(ptsd_major, &ptsd_cdev, CDEVSW_IS_PTS) == -1) {
		panic("Failed to set flags on ptmx cdevsw entry.");
	}

	/* Create the /dev/ptmx device {<major>,0} */
	(void)devfs_make_node_clone(makedev(ptmx_major, 0),
				DEVFS_CHAR, UID_ROOT, GID_TTY, 0666,
				ptmx_clone, PTMX_TEMPLATE);

	_ptmx_driver.master = ptmx_major;
	_ptmx_driver.slave = ptsd_major;
	_ptmx_driver.fix_7828447 = 1;
	_ptmx_driver.fix_7070978 = 1;
#if CONFIG_MACF
	_ptmx_driver.mac_notify = 1;
#endif
	_ptmx_driver.open = &ptmx_get_ioctl;
	_ptmx_driver.free = &ptmx_free_ioctl;
	_ptmx_driver.name = &ptmx_get_name;
	_ptmx_driver.revoke = &ptsd_revoke_knotes;
	tty_dev_register(&_ptmx_driver);

	return (0);
}
Example #7
0
kern_return_t OsqueryStart(kmod_info_t *ki, void *d) {
  dbg_printf("Kernel module starting!\n");

  // Restart the queue and setup queue locks.
  // This does not allocate, share, or set the queue buffer or buffer values.
  osquery_cqueue_setup(&osquery.cqueue);

  // Initialize the IOCTL (and more) device node.
  osquery.major_number = cdevsw_add(osquery.major_number, &osquery_cdevsw);
  if (osquery.major_number < 0) {
    dbg_printf("Could not get a major number!\n");
    goto error_exit;
  }

  // Create the IOCTL (and more) device node.
  osquery.devfs = devfs_make_node(makedev(osquery.major_number, 0),
                                  DEVFS_CHAR,
                                  UID_ROOT,
                                  GID_WHEEL,
                                  0600,
                                  "osquery",
                                  0);
  if (osquery.devfs == NULL) {
    dbg_printf("Could not get a devfs entry!\n");
    goto error_exit;
  }

  // Set up the IOCTL and kernel API locks (not queue locks).
  setup_locks();

  return KERN_SUCCESS;
error_exit:
  // Upon error, remove the device node if it was allocated.
  if (osquery.devfs != NULL) {
    devfs_remove(osquery.devfs);
    osquery.devfs = NULL;
  }

  // Tear down device node data.
  if (!(osquery.major_number < 0)) {
    if (cdevsw_remove(osquery.major_number, &osquery_cdevsw) < 0) {
      panic("osquery kext: Cannot remove osquery from cdevsw");
    }
  }

  // Reset the queue and remove the queue locks.
  osquery_cqueue_teardown(&osquery.cqueue);
  return KERN_FAILURE;
}
Example #8
0
/**
 * Stop the kernel module.
 */
static kern_return_t    VBoxDrvDarwinStop(struct kmod_info *pKModInfo, void *pvData)
{
    int rc;
    LogFlow(("VBoxDrvDarwinStop\n"));

    /** @todo I've got a nagging feeling that we'll have to keep track of users and refuse
     * unloading if we're busy. Investigate and implement this! */

    /*
     * Undo the work done during start (in reverse order).
     */
    if (g_pSleepNotifier)
    {
        g_pSleepNotifier->remove();
        g_pSleepNotifier = NULL;
    }

    devfs_remove(g_hDevFsDeviceUsr);
    g_hDevFsDeviceUsr = NULL;

    devfs_remove(g_hDevFsDeviceSys);
    g_hDevFsDeviceSys = NULL;

    rc = cdevsw_remove(g_iMajorDeviceNo, &g_DevCW);
    Assert(rc == g_iMajorDeviceNo);
    g_iMajorDeviceNo = -1;

    supdrvDeleteDevExt(&g_DevExt);

    rc = RTSpinlockDestroy(g_Spinlock);
    AssertRC(rc);
    g_Spinlock = NIL_RTSPINLOCK;

    RTR0TermForced();

    memset(&g_DevExt, 0, sizeof(g_DevExt));
#ifdef DEBUG
    printf("VBoxDrvDarwinStop - done\n");
#endif
    return KMOD_RETURN_SUCCESS;
}
Example #9
0
/* Unregister VBoxGuest char device */
static int
VbgdDarwinCharDevRemove(void)
{
    int rc = KMOD_RETURN_SUCCESS;

    if (g_pSleepNotifier)
    {
        g_pSleepNotifier->remove();
        g_pSleepNotifier = NULL;
    }

    if (g_hDevFsDeviceSys)
    {
        devfs_remove(g_hDevFsDeviceSys);
        g_hDevFsDeviceSys = NULL;
    }

    if (g_hDevFsDeviceUsr)
    {
        devfs_remove(g_hDevFsDeviceUsr);
        g_hDevFsDeviceUsr = NULL;
    }

    if (g_iMajorDeviceNo != -1)
    {
        int rc2 = cdevsw_remove(g_iMajorDeviceNo, &g_DevCW);
        Assert(rc2 == g_iMajorDeviceNo);
        g_iMajorDeviceNo = -1;
    }

    if (g_Spinlock != NIL_RTSPINLOCK)
    {
        int rc2 = RTSpinlockDestroy(g_Spinlock); AssertRC(rc2);
        g_Spinlock = NIL_RTSPINLOCK;
    }

    return rc;
}
Example #10
0
kern_return_t OsqueryStart(kmod_info_t *ki, void *d) {
    dbg_printf("Kernel module starting!\n");

    osquery_cqueue_setup(&osquery.cqueue);

    osquery.major_number = cdevsw_add(osquery.major_number, &osquery_cdevsw);
    if (osquery.major_number < 0) {
        dbg_printf("Could not get a major number!\n");
        goto error_exit;
    }

    osquery.devfs = devfs_make_node(makedev(osquery.major_number, 0),
                                    DEVFS_CHAR, UID_ROOT, GID_WHEEL,
                                    0644, "osquery", 0);
    if (osquery.devfs == NULL) {
        dbg_printf("Could not get a devfs entry!\n");
        goto error_exit;
    }

    setup_locks();

    return KERN_SUCCESS;
error_exit:
    if (osquery.devfs != NULL) {
        devfs_remove(osquery.devfs);
        osquery.devfs = NULL;
    }

    if (!(osquery.major_number < 0)) {
        if (cdevsw_remove(osquery.major_number, &osquery_cdevsw) < 0) {
            panic("osquery kext: Cannot remove osquery from cdevsw");
        }
    }

    osquery_cqueue_teardown(&osquery.cqueue);
    return KERN_FAILURE;
}
Example #11
0
CdevMajorIniter::~CdevMajorIniter(void)
{
	cdevsw_remove(majorNumber, &cdevsw);
}
Example #12
0
/**
 * Start the kernel module.
 */
static kern_return_t    VBoxDrvDarwinStart(struct kmod_info *pKModInfo, void *pvData)
{
    int rc;
#ifdef DEBUG
    printf("VBoxDrvDarwinStart\n");
#endif

    /*
     * Initialize IPRT.
     */
    rc = RTR0Init(0);
    if (RT_SUCCESS(rc))
    {
        /*
         * Initialize the device extension.
         */
        rc = supdrvInitDevExt(&g_DevExt, sizeof(SUPDRVSESSION));
        if (RT_SUCCESS(rc))
        {
            /*
             * Initialize the session hash table.
             */
            memset(g_apSessionHashTab, 0, sizeof(g_apSessionHashTab)); /* paranoia */
            rc = RTSpinlockCreate(&g_Spinlock, RTSPINLOCK_FLAGS_INTERRUPT_SAFE, "VBoxDrvDarwin");
            if (RT_SUCCESS(rc))
            {
                /*
                 * Registering ourselves as a character device.
                 */
                g_iMajorDeviceNo = cdevsw_add(-1, &g_DevCW);
                if (g_iMajorDeviceNo >= 0)
                {
#ifdef VBOX_WITH_HARDENING
                    g_hDevFsDeviceSys = devfs_make_node(makedev(g_iMajorDeviceNo, 0), DEVFS_CHAR,
                                                        UID_ROOT, GID_WHEEL, 0600, DEVICE_NAME_SYS);
#else
                    g_hDevFsDeviceSys = devfs_make_node(makedev(g_iMajorDeviceNo, 0), DEVFS_CHAR,
                                                        UID_ROOT, GID_WHEEL, 0666, DEVICE_NAME_SYS);
#endif
                    if (g_hDevFsDeviceSys)
                    {
                        g_hDevFsDeviceUsr = devfs_make_node(makedev(g_iMajorDeviceNo, 1), DEVFS_CHAR,
                                                            UID_ROOT, GID_WHEEL, 0666, DEVICE_NAME_USR);
                        if (g_hDevFsDeviceUsr)
                        {
                            LogRel(("VBoxDrv: version " VBOX_VERSION_STRING " r%d; IOCtl version %#x; IDC version %#x; dev major=%d\n",
                                    VBOX_SVN_REV, SUPDRV_IOC_VERSION, SUPDRV_IDC_VERSION, g_iMajorDeviceNo));

                            /* Register a sleep/wakeup notification callback */
                            g_pSleepNotifier = registerPrioritySleepWakeInterest(&VBoxDrvDarwinSleepHandler, &g_DevExt, NULL);
                            if (g_pSleepNotifier == NULL)
                                LogRel(("VBoxDrv: register for sleep/wakeup events failed\n"));

                            /* Find kernel symbols that are kind of optional. */
                            vboxdrvDarwinResolveSymbols();
                            return KMOD_RETURN_SUCCESS;
                        }

                        LogRel(("VBoxDrv: devfs_make_node(makedev(%d,1),,,,%s) failed\n", g_iMajorDeviceNo, DEVICE_NAME_USR));
                        devfs_remove(g_hDevFsDeviceSys);
                        g_hDevFsDeviceSys = NULL;
                    }
                    else
                        LogRel(("VBoxDrv: devfs_make_node(makedev(%d,0),,,,%s) failed\n", g_iMajorDeviceNo, DEVICE_NAME_SYS));

                    cdevsw_remove(g_iMajorDeviceNo, &g_DevCW);
                    g_iMajorDeviceNo = -1;
                }
                else
                    LogRel(("VBoxDrv: cdevsw_add failed (%d)\n", g_iMajorDeviceNo));
                RTSpinlockDestroy(g_Spinlock);
                g_Spinlock = NIL_RTSPINLOCK;
            }
            else
                LogRel(("VBoxDrv: RTSpinlockCreate failed (rc=%d)\n", rc));
            supdrvDeleteDevExt(&g_DevExt);
        }
        else
            printf("VBoxDrv: failed to initialize device extension (rc=%d)\n", rc);
        RTR0TermForced();
    }
    else
        printf("VBoxDrv: failed to initialize IPRT (rc=%d)\n", rc);

    memset(&g_DevExt, 0, sizeof(g_DevExt));
    return KMOD_RETURN_FAILURE;
}