From: Jann Horn Date: Sun, 19 May 2013 01:34:31 +0000 (+0200) Subject: let the kernel module return the symbol name X-Git-Url: http://git.thejh.net/?p=moctel.git;a=commitdiff_plain;h=d20cca0688694acb09484232ada3aa4d13ac0954 let the kernel module return the symbol name --- diff --git a/moctel_mod.c b/moctel_mod.c index 7498584..1273ff3 100644 --- a/moctel_mod.c +++ b/moctel_mod.c @@ -15,6 +15,8 @@ #include #include #include +#include +#include struct fetch_fops_args { int fd; @@ -27,21 +29,29 @@ static int ioctl_open(struct inode *nodp, struct file *filp) { return 0; } -static const struct file_operations dummy_fops = {}; - static long ioctl_ioctl(struct file *filp_, unsigned int cmd, unsigned long arg) { struct fetch_fops_args args; struct file *filp; - const struct file_operations *fops; + void *ioctl_method = NULL; + char ioctl_method_name[KSYM_NAME_LEN]; + int (*lookup_symbol_name_)(unsigned long addr, char *symname); + + lookup_symbol_name_ = (void*)kallsyms_lookup_name("lookup_symbol_name"); if (cmd != MOCTEL_FETCH_FOPS) return -EINVAL; + memset(ioctl_method_name, 0, sizeof(ioctl_method_name)); if (copy_from_user(&args, (struct fetch_fops_args __user *)arg, sizeof(args))) return -EINVAL; filp = fget(args.fd); if (!filp) return -EBADF; - fops = filp->f_op; - if (!fops) fops = &dummy_fops; + if (filp->f_op) ioctl_method = filp->f_op->unlocked_ioctl; + lookup_symbol_name_((unsigned long)ioctl_method, ioctl_method_name); + if (strcmp(ioctl_method_name, "block_ioctl") == 0) { + struct block_device *bdev = I_BDEV(filp->f_mapping->host); + ioctl_method = bdev->bd_disk->fops->ioctl; + lookup_symbol_name_((unsigned long)ioctl_method, ioctl_method_name); + } fput(filp); - if (copy_to_user((struct file_operations __user *)args.retp, fops, sizeof(*fops))) return -EINVAL; + if (copy_to_user((struct file_operations __user *)args.retp, ioctl_method_name, KSYM_NAME_LEN)) return -EINVAL; return 0; } @@ -77,3 +87,5 @@ static void __exit cleanup_ioctl(void) { module_init(init_ioctl); module_exit(cleanup_ioctl); + +MODULE_LICENSE("GPL v2"); diff --git a/show_ioctl.c b/show_ioctl.c index d83c860..8e36dbf 100644 --- a/show_ioctl.c +++ b/show_ioctl.c @@ -10,6 +10,8 @@ #include #include +#define KSYM_NAME_LEN 128 + struct fetch_fops_args { int fd; uint64_t retp; @@ -17,37 +19,6 @@ struct fetch_fops_args { #define MOCTEL_FETCH_FOPS _IOR('m', 1, struct fetch_fops_args) -struct file_operations { - void *owner; - void *llseek; - void *read; - void *write; - void *aio_read; - void *aio_write; - void *readdir; - void *poll; - void *unlocked_ioctl; - void *compat_ioctl; - void *mmap; - void *open; - void *flush; - void *release; - void *fsync; - void *aio_fsync; - void *fasync; - void *lock; - void *sendpage; - void *get_unmapped_area; - void *check_flags; - void *flock; - void *splice_write; - void *splice_read; - void *setlease; - void *fallocate; -}; - - - int main(int argc, char **argv) { if (argc != 2) fputs("Usage: show_ioctl \n", stderr), exit(1); @@ -58,10 +29,10 @@ int main(int argc, char **argv) { int ioctlfd = open("/dev/ioctl_info", O_RDONLY); if (ioctlfd == -1) fprintf(stderr, "Can't open /dev/ioctl_info: %m\n"), exit(1); - struct file_operations fops; + char resbuf[KSYM_NAME_LEN]; struct fetch_fops_args ioctl_args = { .fd = devfd, - .retp = (uint64_t)&fops + .retp = (uint64_t)resbuf }; int ret = ioctl(ioctlfd, MOCTEL_FETCH_FOPS, &ioctl_args); if (ret) fprintf(stderr, "can't perform MOCTEL_FETCH_FOPS: %m\n"), exit(1); @@ -69,7 +40,7 @@ int main(int argc, char **argv) { close(ioctlfd); close(devfd); - printf("unlocked_ioctl: %llx\n", (unsigned long long)fops.unlocked_ioctl); + printf("%s\n", resbuf); return 0; }