/* * 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; }
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; }