Esempio n. 1
0
		void print_mod_table() 
		{
		
			print("MT n\tname\n");
			for (uint32_t i=0; i<32; ++i) {
				auto f = uint32_t(1 << i);
				print("MT %||\t%||\n", i, get_mod_name(f));				
			}						
			
		}
Esempio n. 2
0
/*
 * Allocate space for a module.
 */
asmlinkage unsigned long
sys_create_module(char *module_name, unsigned long size)
{
	struct module *mp;
	void* addr;
	int error;
	int npages;
	int sspace = sizeof(struct module) + MOD_MAX_NAME;
	char name[MOD_MAX_NAME];

	if (!suser())
		return -EPERM;
	if (module_name == NULL || size == 0)
		return -EINVAL;
	if ((error = get_mod_name(module_name, name)) != 0)
		return error;
	if (find_module(name) != NULL) {
		return -EEXIST;
	}

	if ((mp = (struct module*) kmalloc(sspace, GFP_KERNEL)) == NULL) {
		return -ENOMEM;
	}
	strcpy((char *)(mp + 1), name); /* why not? */

	npages = (size + sizeof (long) + PAGE_SIZE - 1) / PAGE_SIZE;
	if ((addr = vmalloc(npages * PAGE_SIZE)) == 0) {
		kfree_s(mp, sspace);
		return -ENOMEM;
	}

	mp->next = module_list;
	mp->ref = NULL;
	mp->symtab = NULL;
	mp->name = (char *)(mp + 1);
	mp->size = npages;
	mp->addr = addr;
	mp->state = MOD_UNINITIALIZED;
	mp->cleanup = NULL;

	* (long *) addr = 0;	/* set use count to zero */
	module_list = mp;	/* link it in */

	pr_debug("module `%s' (%lu pages @ 0x%08lx) created\n",
		mp->name, (unsigned long) mp->size, (unsigned long) mp->addr);
	return (unsigned long) addr;
}
Esempio n. 3
0
asmlinkage int
sys_delete_module(char *module_name)
{
	struct module *mp;
	char name[MOD_MAX_NAME];
	int error;

	if (!suser())
		return -EPERM;
	/* else */
	if (module_name != NULL) {
		if ((error = get_mod_name(module_name, name)) != 0)
			return error;
		if ((mp = find_module(name)) == NULL)
			return -ENOENT;
		if ((mp->ref != NULL) ||
		    ((GET_USE_COUNT(mp) & ~(MOD_AUTOCLEAN | MOD_VISITED)) != 0))
			return -EBUSY;
		GET_USE_COUNT(mp) &= ~(MOD_AUTOCLEAN | MOD_VISITED);
		if (mp->state == MOD_RUNNING)
			(*mp->cleanup)();
		mp->state = MOD_DELETED;
		free_modules();
	}
	/* for automatic reaping */
	else {
		struct module *mp_next;
		for (mp = module_list; mp != &kernel_module; mp = mp_next) {
			mp_next = mp->next;
			if ((mp->ref == NULL) && (mp->state == MOD_RUNNING) &&
			    ((GET_USE_COUNT(mp) & ~MOD_VISITED) == MOD_AUTOCLEAN)) {
			    	if ((GET_USE_COUNT(mp) & MOD_VISITED)) {
					/* Don't reap until one "cycle" after last _use_ */
			   		GET_USE_COUNT(mp) &= ~MOD_VISITED;
				}
				else {
					GET_USE_COUNT(mp) &= ~(MOD_AUTOCLEAN | MOD_VISITED);
					(*mp->cleanup)();
					mp->state = MOD_DELETED;
					free_modules();
				}
			}
		}
	}
	return 0;
}
Esempio n. 4
0
/*
 * Allocate space for a module.
 */
asmlinkage int
sys_create_module(char *module_name, unsigned long size)
{
	int npages;
	void* addr;
	int len;
	char name[MOD_MAX_NAME];
	char *savename;
	struct module *mp;
	int error;

	if (!suser())
		return -EPERM;
	if (module_name == NULL || size == 0)
		return -EINVAL;
	if ((error = get_mod_name(module_name, name)) != 0)
		return error;
	if (find_module(name) != NULL) {
		return -EEXIST;
	}
	len = strlen(name) + 1;
	if ((savename = (char*) kmalloc(len, GFP_KERNEL)) == NULL)
		return -ENOMEM;
	memcpy(savename, name, len);
	if ((mp = (struct module*) kmalloc(sizeof *mp, GFP_KERNEL)) == NULL) {
		kfree(savename);
		return -ENOMEM;
	}
	npages = (size + sizeof (int) + 4095) / 4096;
	if ((addr = vmalloc(npages * 4096)) == 0) {
		kfree_s(mp, sizeof *mp);
		kfree(savename);
		return -ENOMEM;
	}
	mp->name = savename;
	mp->size = npages;
	mp->addr = addr;
	mp->state = MOD_UNINITIALIZED;
	* (int *) addr = 0;		/* set use count to zero */
	mp->cleanup = NULL;
	mp->next = module_list;
	module_list = mp;
	printk("module `%s' (%lu pages @ 0x%08lx) created\n",
		mp->name, (unsigned long) mp->size, (unsigned long) mp->addr);
	return (int) addr;
}
Esempio n. 5
0
asmlinkage int
sys_delete_module(char *module_name)
{
	struct module *mp;
	char name[MOD_MAX_NAME];
	int error;

	if (!suser())
		return -EPERM;
	if (module_name != NULL) {
		if ((error = get_mod_name(module_name, name)) != 0)
			return error;
		if ((mp = find_module(name)) == NULL)
			return -ENOENT;
		if (mp->state == MOD_RUNNING)
			(*mp->cleanup)();
		mp->state = MOD_DELETED;
	}
	free_modules();
	return 0;
}
Esempio n. 6
0
/*
 * Initialize a module.
 */
asmlinkage int
sys_init_module(char *module_name, char *code, unsigned codesize,
		struct mod_routines *routines)
{
	struct module *mp;
	char name[MOD_MAX_NAME];
	int error;
	struct mod_routines rt;

	if (!suser())
		return -EPERM;
	/*
	 * First reclaim any memory from dead modules that where not
	 * freed when deleted. Should I think be done by timers when
	 * the module was deleted - Jon.
	 */
	free_modules();

	if ((error = get_mod_name(module_name, name)) != 0)
		return error;
	printk( "initializing module `%s', %d (0x%x) bytes\n",
		name, codesize, codesize);
	memcpy_fromfs(&rt, routines, sizeof rt);
	if ((mp = find_module(name)) == NULL)
		return -ENOENT;
	if ((codesize + sizeof (int) + 4095) / 4096 > mp->size)
		return -EINVAL;
	memcpy_fromfs((char *)mp->addr + sizeof (int), code, codesize);
	memset((char *)mp->addr + sizeof (int) + codesize, 0,
		mp->size * 4096 - (codesize + sizeof (int)));
	printk( "  init entry @ 0x%08lx, cleanup entry @ 0x%08lx\n",
		(unsigned long) rt.init, (unsigned long) rt.cleanup);
	mp->cleanup = rt.cleanup;
	if ((*rt.init)() != 0)
		return -EBUSY;
	mp->state = MOD_RUNNING;
	return 0;
}
Esempio n. 7
0
/*
 * Initialize a module.
 */
asmlinkage int
sys_init_module(char *module_name, char *code, unsigned codesize,
		struct mod_routines *routines,
		struct symbol_table *symtab)
{
	struct module *mp;
	struct symbol_table *newtab;
	char name[MOD_MAX_NAME];
	int error;
	struct mod_routines rt;

	if (!suser())
		return -EPERM;

#ifdef __i386__
	/* A little bit of protection... we "know" where the user stack is... */

	if (symtab && ((unsigned long)symtab > 0xb0000000)) {
		printk(KERN_WARNING "warning: you are using an old insmod, no symbols will be inserted!\n");
		symtab = NULL;
	}
#endif
	if ((error = get_mod_name(module_name, name)) != 0)
		return error;
	pr_debug("initializing module `%s', %d (0x%x) bytes\n",
		name, codesize, codesize);
	memcpy_fromfs(&rt, routines, sizeof rt);
	if ((mp = find_module(name)) == NULL)
		return -ENOENT;
	if (codesize & MOD_AUTOCLEAN) {
		/*
		 * set autoclean marker from codesize...
		 * set usage count to "zero"
		 */
		codesize &= ~MOD_AUTOCLEAN;
		GET_USE_COUNT(mp) = MOD_AUTOCLEAN;
	}
	if ((codesize + sizeof (long) + PAGE_SIZE - 1) / PAGE_SIZE > mp->size)
		return -EINVAL;
	memcpy_fromfs((char *)mp->addr + sizeof (long), code, codesize);
	memset((char *)mp->addr + sizeof (long) + codesize, 0,
		mp->size * PAGE_SIZE - (codesize + sizeof (long)));
	pr_debug("module init entry = 0x%08lx, cleanup entry = 0x%08lx\n",
		(unsigned long) rt.init, (unsigned long) rt.cleanup);
	mp->cleanup = rt.cleanup;

	/* update kernel symbol table */
	if (symtab) { /* symtab == NULL means no new entries to handle */
		struct internal_symbol *sym;
		struct module_ref *ref;
		int size;
		int i;
		int legal_start;

		if ((error = verify_area(VERIFY_READ, &symtab->size, sizeof(symtab->size))))
			return error;
		size = get_user(&symtab->size);

		if ((newtab = (struct symbol_table*) kmalloc(size, GFP_KERNEL)) == NULL) {
			return -ENOMEM;
		}

		if ((error = verify_area(VERIFY_READ, symtab, size))) {
			kfree_s(newtab, size);
			return error;
		}
		memcpy_fromfs((char *)(newtab), symtab, size);

		/* sanity check */
		legal_start = sizeof(struct symbol_table) +
			newtab->n_symbols * sizeof(struct internal_symbol) +
			newtab->n_refs * sizeof(struct module_ref);

		if ((newtab->n_symbols < 0) || (newtab->n_refs < 0) || (legal_start > size)) {
			printk(KERN_WARNING "Rejecting illegal symbol table (n_symbols=%d,n_refs=%d)\n",
			       newtab->n_symbols, newtab->n_refs);
			kfree_s(newtab, size);
			return -EINVAL;
		}

		/* relocate name pointers, index referred from start of table */
		for (sym = &(newtab->symbol[0]), i = 0; i < newtab->n_symbols; ++sym, ++i) {
			if ((unsigned long)sym->name < legal_start || size <= (unsigned long)sym->name) {
				printk(KERN_WARNING "Rejecting illegal symbol table\n");
				kfree_s(newtab, size);
				return -EINVAL;
			}
			/* else */
			sym->name += (long)newtab;
		}
		mp->symtab = newtab;

		/* Update module references.
		 * On entry, from "insmod", ref->module points to
		 * the referenced module!
		 * Now it will point to the current module instead!
		 * The ref structure becomes the first link in the linked
		 * list of references to the referenced module.
		 * Also, "sym" from above, points to the first ref entry!!!
		 */
		for (ref = (struct module_ref *)sym, i = 0;
			i < newtab->n_refs; ++ref, ++i) {

			/* Check for valid reference */
			struct module *link = module_list;
			while (link && (ref->module != link))
				link = link->next;

			if (link == (struct module *)0) {
				printk(KERN_WARNING "Non-module reference! Rejected!\n");
				return -EINVAL;
			}

			ref->next = ref->module->ref;
			ref->module->ref = ref;
			ref->module = mp;
		}
	}

	GET_USE_COUNT(mp) += 1;
	if ((*rt.init)() != 0) {
		GET_USE_COUNT(mp) = 0;
		return -EBUSY;
	}
	GET_USE_COUNT(mp) -= 1;
	mp->state = MOD_RUNNING;

	return 0;
}