blob: fe72bf677d54cf931e23832586a57f5e2a6ade75 [file] [log] [blame]
#include <linux/kernel.h>
#include <linux/verify.h>
#include <linux/module.h>
#include <linux/fs.h>
int verify_super_block(const struct super_block *sb)
{
int ret;
ret = kernel_rodata_address((unsigned long)sb->s_op);
WARN_ONCE(!ret, "superblock: struct super_operations %pS is not const!", sb->s_op);
return ret;
}
int verify_file_operations(const struct file_operations *fops)
{
int ret = 0;
if (IS_ERR_OR_NULL(fops))
return 0;
if (!kernel_rodata_address((unsigned long)fops)) {
WARN_ONCE(1, "struct file_operations %pS (%p) is not const!", fops, fops);
ret = -EINVAL;
}
/* check if owner is set correctly */
if (fops->owner != __module_address((unsigned long)fops)) {
WARN_ONCE(1, "struct file_operations %pS has .owner not set correctly", fops);
ret = -EINVAL;
}
return ret;
}
int verify_struct_file(struct file *filp)
{
int ret = 0;
if (IS_ERR_OR_NULL(filp))
return 0;
if (verify_file_operations(filp->f_op)) {
WARN_ONCE(1, "struct file %pS does not have a const f_ops %pS\n", filp, filp->f_op);
ret = -EINVAL;
}
return ret;
}
int verify_address_space(struct address_space *as)
{
int ret = 0;
if (!kernel_rodata_address((unsigned long)as->a_ops)) {
WARN_ONCE(1, "struct address space %pS has non-const a_ops %pS\n", as, as->a_ops);
ret = -EINVAL;
}
return ret;
}