From 648524d0186734dfe4e38a87138f45446038fbc4 Mon Sep 17 00:00:00 2001 From: Arjan van de Ven Date: Fri, 11 Nov 2011 13:11:42 -0800 Subject: verify: Start introducing flags to control what to verify --- drivers/char/misc.c | 4 ++-- fs/char_dev.c | 4 ++-- include/linux/verify.h | 12 ++++++++++-- lib/verify.c | 6 +++--- 4 files changed, 17 insertions(+), 9 deletions(-) diff --git a/drivers/char/misc.c b/drivers/char/misc.c index 4f21456699dd7f..89578da6d16090 100644 --- a/drivers/char/misc.c +++ b/drivers/char/misc.c @@ -126,7 +126,7 @@ static int misc_open(struct inode * inode, struct file * file) } } - verify_file_operations(new_fops); + verify_file_operations(new_fops, VERIFY_OWNER | VERIFY_ALWAYS); if (!new_fops) { mutex_unlock(&misc_mtx); @@ -190,7 +190,7 @@ int misc_register(struct miscdevice * misc) dev_t dev; int err = 0; - verify_file_operations(misc->fops); + verify_file_operations(misc->fops, VERIFY_OWNER | VERIFY_ALWAYS); INIT_LIST_HEAD(&misc->list); diff --git a/fs/char_dev.c b/fs/char_dev.c index d99850d015be8c..ecd30130e958a2 100644 --- a/fs/char_dev.c +++ b/fs/char_dev.c @@ -270,7 +270,7 @@ int __register_chrdev(unsigned int major, unsigned int baseminor, struct cdev *cdev; int err = -ENOMEM; - verify_file_operations(fops); + verify_file_operations(fops, VERIFY_OWNER | VERIFY_ALWAYS); cd = __register_chrdev_region(major, baseminor, count, name); if (IS_ERR(cd)) @@ -546,7 +546,7 @@ void cdev_init(struct cdev *cdev, const struct file_operations *fops) { memset(cdev, 0, sizeof *cdev); INIT_LIST_HEAD(&cdev->list); - verify_file_operations(fops); + verify_file_operations(fops, VERIFY_OWNER | VERIFY_ALWAYS); kobject_init(&cdev->kobj, &ktype_cdev_default); cdev->ops = fops; } diff --git a/include/linux/verify.h b/include/linux/verify.h index 3453ceddba3c90..8f0c27dd2e446a 100644 --- a/include/linux/verify.h +++ b/include/linux/verify.h @@ -7,11 +7,19 @@ struct file_operations; struct super_block; struct file; + +/* Various flags that control the verification behavior */ + +/* Disable statistical verification */ +#define VERIFY_ALWAYS 1 +/* verify the .owner field of structures */ +#define VERIFY_OWNER 2 + #ifdef CONFIG_VERIFY int verify_super_block(const struct super_block *sb); -int verify_file_operations(const struct file_operations *fops); +int verify_file_operations(const struct file_operations *fops, unsigned long flags); int verify_struct_file(struct file *filp); int verify_address_space(const struct address_space *as); int verify_function_ptr(void *ptr); @@ -20,7 +28,7 @@ int verify_seq_file_ops(const struct seq_operations *ops); #else static inline int verify_super_block(const struct super_block *sb) { return 0; } -static inline int verify_file_operations(const struct file_operations *fops) { return 0; } +static inline int verify_file_operations(const struct file_operations *fops, unsigned long flags) { return 0; } static inline int verify_struct_file(struct file *filp) { return 0; } static inline int verify_address_space(const struct address_space *as) { return 0; } static inline int verify_function_ptr(void *ptr) { return 0; } diff --git a/lib/verify.c b/lib/verify.c index f57e7541c84c16..74d4b3c250932a 100644 --- a/lib/verify.c +++ b/lib/verify.c @@ -16,7 +16,7 @@ int verify_super_block(const struct super_block *sb) return ret; } -int verify_file_operations(const struct file_operations *fops) +int verify_file_operations(const struct file_operations *fops, unsigned long flags) { int ret = 0; @@ -29,7 +29,7 @@ int verify_file_operations(const struct file_operations *fops) } /* check if owner is set correctly */ - if (fops->owner != __module_address((unsigned long)fops)) { + if (flags & VERIFY_OWNER && fops->owner != __module_address((unsigned long)fops)) { WARN_ONCE(1, "struct file_operations %pS has .owner not set correctly", fops); ret = -EINVAL; } @@ -44,7 +44,7 @@ int verify_struct_file(struct file *filp) if (IS_ERR_OR_NULL(filp)) return 0; - if (verify_file_operations(filp->f_op)) { + if (verify_file_operations(filp->f_op, VERIFY_ALWAYS)) { WARN_ONCE(1, "struct file %pS does not have a const f_ops %pS\n", filp, filp->f_op); ret = -EINVAL; } -- cgit 1.2.3-korg