Esempio n. 1
0
/*
 * analyze_object
 * Look at a library loaded into the current process, and determine as much as
 * possible about it. The disassembling, allocations are initiated here.
 *
 * This is a callback function, passed to dl_iterate_phdr(3).
 * data and size are just unused callback arguments.
 *
 *
 * From dl_iterate_phdr(3) man page:
 *
 * struct dl_phdr_info
 * {
 *     ElfW(Addr) dlpi_addr;             Base address of object
 *     const char *dlpi_name;            (Null-terminated) name of object
 *     const ElfW(Phdr) *dlpi_phdr;      Pointer to array of ELF program headers
 *     ElfW(Half) dlpi_phnum;            # of items in dlpi_phdr
 *     ...
 * }
 *
 */
static int
analyze_object(struct dl_phdr_info *info, size_t size, void *data)
{
	(void) data;
	(void) size;
	const char *path;

	debug_dump("analyze_object called on \"%s\" at 0x%016" PRIxPTR "\n",
	    info->dlpi_name, info->dlpi_addr);

	if ((path = get_object_path(info)) == NULL)
		return 0;

	debug_dump("analyze %s\n", path);

	if (!should_patch_object(info->dlpi_addr, path))
		return 0;

	struct intercept_desc *patches = allocate_next_obj_desc();

	patches->base_addr = (unsigned char *)info->dlpi_addr;
	patches->path = path;
	find_syscalls(patches);
	allocate_trampoline_table(patches);
	create_patch_wrappers(patches);

	return 0;
}
Esempio n. 2
0
static int __init init_ugidctl(void)
{
	dev_t dev;
	int rc;

	rc = find_syscalls();
	if (rc)
		return rc;

	dprintk("found sys_setuid() 0x%p", ugidctl_sys_setuid);
	dprintk("found sys_setgid() 0x%p", ugidctl_sys_setgid);
	dprintk("found sys_setgroups() 0x%p\n", ugidctl_sys_setgroups);

	rc = -ENOMEM;

	uid_cache = KMEM_CACHE(ugidctl_uid_node, 0);
	if (!uid_cache) {
		printk(KERN_ERR "%s: cannot allocate uid cache\n", MOD_NAME);
		goto out;
	}

	gid_cache = KMEM_CACHE(ugidctl_gid_node, 0);
	if (!gid_cache) {
		printk(KERN_ERR "%s: cannot allocate gid cache\n", MOD_NAME);
		goto out_uid_cache;
	}

	rc = alloc_chrdev_region(&dev, 0, 1, DEV_NAME);
	if (rc) {
		printk(KERN_ERR "%s: failed to register chrdev region\n", MOD_NAME);
		goto out_gid_cache;
	}

	ugidctl_major = MAJOR(dev);
	ugidctl_class = class_create(THIS_MODULE, DEV_NAME);

	if (IS_ERR(ugidctl_class)) {
		printk(KERN_ERR "%s: failed to register with sysfs\n", MOD_NAME);
		rc = PTR_ERR(ugidctl_class);
		goto out_region;
	}

	cdev_init(&ugidctl_cdev, &ugidctl_fops);

	rc = cdev_add(&ugidctl_cdev, dev, 1);
	if (rc) {
		printk(KERN_ERR "%s: failed to add char device\n", MOD_NAME);
		goto out_class;
	}

	device_create(ugidctl_class, NULL, dev, NULL, DEV_NAME);

	// printk(KERN_INFO "%s: v" MOD_VERSION " loaded\n", MOD_NAME);

	return 0;

out_class:
	class_destroy(ugidctl_class);
out_region:
	unregister_chrdev_region(dev, 1);
out_gid_cache:
	kmem_cache_destroy(gid_cache);
out_uid_cache:
	kmem_cache_destroy(uid_cache);
out:
	return rc;
}