projects
/
moctel.git
/ commitdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
| commitdiff |
tree
raw
|
patch
|
inline
| side by side (parent:
18a70c7
)
let the kernel module return the symbol name
author
Jann Horn
<jann@thejh.net>
Sun, 19 May 2013 01:34:31 +0000
(
03:34
+0200)
committer
Jann Horn
<jann@thejh.net>
Sun, 19 May 2013 01:34:31 +0000
(
03:34
+0200)
moctel_mod.c
patch
|
blob
|
history
show_ioctl.c
patch
|
blob
|
history
diff --git
a/moctel_mod.c
b/moctel_mod.c
index
7498584
..
1273ff3
100644
(file)
--- a/
moctel_mod.c
+++ b/
moctel_mod.c
@@
-15,6
+15,8
@@
#include <linux/ioctl.h>
#include <linux/uaccess.h>
#include <linux/miscdevice.h>
#include <linux/ioctl.h>
#include <linux/uaccess.h>
#include <linux/miscdevice.h>
+#include <linux/kallsyms.h>
+#include <linux/blkdev.h>
struct fetch_fops_args {
int fd;
struct fetch_fops_args {
int fd;
@@
-27,21
+29,29
@@
static int ioctl_open(struct inode *nodp, struct file *filp) {
return 0;
}
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;
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;
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;
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);
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;
}
return 0;
}
@@
-77,3
+87,5
@@
static void __exit cleanup_ioctl(void) {
module_init(init_ioctl);
module_exit(cleanup_ioctl);
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
(file)
--- a/
show_ioctl.c
+++ b/
show_ioctl.c
@@
-10,6
+10,8
@@
#include <fcntl.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <sys/ioctl.h>
+#define KSYM_NAME_LEN 128
+
struct fetch_fops_args {
int fd;
uint64_t retp;
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)
#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 <device>\n", stderr), exit(1);
int main(int argc, char **argv) {
if (argc != 2) fputs("Usage: show_ioctl <device>\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);
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,
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);
};
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);
close(ioctlfd);
close(devfd);
- printf("
unlocked_ioctl: %llx\n", (unsigned long long)fops.unlocked_ioctl
);
+ printf("
%s\n", resbuf
);
return 0;
}
return 0;
}