integrity: Linux Integrity Module(LIM)
Subsystems (9)
RFC PATCH 3/4 integrity: Linux Integrity Module(LIM)
This is a request for comments for a redesign of the integrity patches. The new version addresses a number of issues, including
- generalizing the measurement API beyond just inode measurements.
- separation of the measurement into distinct collection, appraisal, and commitment phases, for greater flexibility.
- redesigning the interactions with LSM modules (Selinux and Smack) to be acceptable to those groups.
Extended Verification Module(EVM) and the Integrity Measurement Architecture(IMA) were originally implemented as an LSM module. Based on discussions on the LSM mailing list, a decision was made that the LSM hooks should only be used to enforce mandatory access control decisions and a new set of hooks should be defined specifically for integrity.
EVM/IMA was limited to verifying and measuring a file's (i.e. an inode) integrity and the metadata associated with it. Current research is looking into other types of integrity measurements. (i.e. "Linux kernel integrity measurement using contextual inspection", by Peter A. Loscocco, Perry W. Wilson, J. Aaron Pendergrass, C. Durward McDonell,
http://doi.acm.org/10.1145/1314354.1314362.) As a result, a requirement of the new integrity framework is support for different types of integrity measurements.
Our work has shown that requests for integrity verification/measurement needs to be based on knowledge of the filesystem, requiring the system to either be labeled with integrity data or depend on the existent LSM security labels. The previous set of integrity patches modified the LSM modules to be integrity context aware, meaning that the LSM modules made integrity data/metadata verification and measurement API calls based on an understanding of the LSM security labels. Both of the LSM maintainers felt that the changes were too intrusive and that integrity enforcement should be made by the integrity provider, not the LSM module.
To address these concerns, Stephen Smalley suggested using the security_audit_rule_match(), renamed to security_filter_rule_match(), to define LSM specific integrity measurement policy rules, in lieu of modifying the LSM modules. In the current set of patches, the integrity API calls can be made either by the integrity provider (i.e. IMA), based on an LSM specific integrity policy, or by an integrity context aware LSM module.
This patch provides an integrity framework(api and hooks), placement of the integrity hooks in the appropriate places in the fs directory, and a dummy provider for an integrity service. Collecting, appraising, and storing of inode and other types of integrity data is supported. Multiple integrity templates, which implement the integrity API, may register themselves. For now, only a single integrity provider can register itself for the integrity hooks. (Support for multiple providers registering themselves for the integrity hooks would require some form of stacking.)
The ten integrity hooks are:
inode_setxattr, inode_post_setxattr, inode_alloc_integrity, inode_free_integrity, inode_init_integrity, file_free_integrity, d_instantiate, bprm_check_integrity, file_mmap, inode_permission
The five integrity API calls provided are:
integrity_must_measure, integrity_collect_measurement, integrity_appraise_measurement, integrity_store_measurement, and integrity_display_template.
The type of integrity data being collected, appraised, stored, or displayed is template dependent.
(Details on the calls and their exact arguments are in linux/integrity.h, included in the patch.)
---
include/linux/integrity.h new file +261 -0
@@ -0,0 +1,261 @@ +/* +* integrity.h +* +* Copyright (C) 2005,2006,2007,2008 IBM Corporation +* Author: Mimi Zohar <[email protected]> +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, version 2 of the License. +*/ + +#ifndef _LINUX_INTEGRITY_H +#define _LINUX_INTEGRITY_H + +#include <linux/fs.h> +#include <linux/audit.h> + +#ifdef CONFIG_INTEGRITY +void integrity_audit_msg (int audit_msgno,struct inode *inode, +const unsigned char *fname,char *op, +char *cause,int result); + +enum lim_hooks {INODE_PERMISSION =1 ,FILE_MMAP ,BPRM_CHECK }; +extern int integrity_measure_policy (struct inode *inode,enum lim_hooks func, +int mask); +extern int integrity_measure_rule_add (char *,char *,char *,char *); +extern void integrity_measure_policy_init (void ); +extern void integrity_measure_policy_complete (void ); + +/* +* Integrity API calls: +* +* @collect_measurement: +* Collect template specific measurement data. +* @data contains template specific data used for collecting the +* measurement. +* Return 0 if operation was successful. +* +* @appraise_measurement: +* Appraise the integrity of the template specific measurement data. +* @data contains template specific data used for appraising the +* measurement. +* Return 0 if operation was successful. +* +* @store_measurement: +* Store the template specific data. +* @data contains template specific data used for storing the +* measurement. +* +* @must_measure: +* Measurement decision based on an integrity policy. +* @data contains template specific data used for making policy +* decision. +* Return 0 if operation was successful. +* +* @display_template: +* Display template specific data. +* +*/ + +enum integrity_show_type {INTEGRITY_SHOW_BINARY ,INTEGRITY_SHOW_ASCII }; + +struct template_operations { +int (*collect_measurement)(void *); +int (*appraise_measurement)(void *); +void (*store_measurement)(void *); +int (*must_measure)(void *); +void (*display_template)(struct seq_file *m,void *, +enum integrity_show_type ); +}; +extern int register_template (char *template_name, +struct template_operations *ops); +extern int unregister_template (char *template_name); +extern int integrity_find_template (char *,struct template_operations **ops); + +/* +* Integrity hooks: +* +* @bprm_check_integrity: +* This hook mediates the point when a search for a binary handler will +* begin. At this point, the OS protects against an executable file, +* already open for write, from being executed; and an executable file +* already open for execute, from being modified. So we can be certain +* that any measurements(collect, appraise, store) done here are of +* the file being executed. +* @bprm contains the linux_binprm structure. +* Return 0 if the hook is successful and permission is granted. +* +* @inode_setxattr: +* Check permission before permitting an integrity extended attribute +* to be set. +* @value identified by @name for @dentry. +* +* @inode_post_setxattr: +* Update inode integrity xattr after successful setxattr operation. +* identified by @name for @dentry. +* +* @inode_alloc_integrity: +* Allocate and attach an integrity structure to @inode->i_integrity. The +* i_integrity field is initialized to NULL when the inode structure is +* allocated. +* @inode contains the inode structure. +* Return 0 if operation was successful. +* +* @inode_free_integrity: +* @inode contains the inode structure. +* Deallocate the inode integrity structure and set @inode->i_integrity to +* NULL. +* +* @inode_init_integrity: +* Create inode integrity xattr for a new inode based on the new security +* xattr information. +* @inode contains the inode structure of the newly created inode. +* @dir contains the inode structure of the parent directory. +* @name contains the security xattr name suffix. +* @value contains the security attribute value. +* @len contains the length of the security attribute value. +* +* @inode_permission: +* This hook is called by the existing Linux permission function, when +* a file is opened (as well as many other operations). At this point, +* measurements of files open for read(collect, appraise, store) can +* be made. +* @inode contains the inode structure to check. +* @mask contains the permission mask. +* @nd contains the nameidata (may be NULL). +* +* @file_free_integrity: +* Update the integrity xattr value as necessary. +* *file contains the file structure being closed. +* +* @file_mmap : +* Measurement(collect, appraise, store) of files mmaped for EXEC, +* could be measured at this point. +* @file contains the file structure for file to map (may be NULL). +* @reqprot contains the protection requested by the application. +* @prot contains the protection that will be applied by the kernel. +* @flags contains the operational flags. +* Return 0 if permission is granted. +* +* @d_instantiate: +* Initialize the integrity structure of an inode for a dentry. +* @dentry to complete. +* @inode to attach to this dentry. +* +*/ + +struct integrity_operations { +int (*bprm_check_integrity) (struct linux_binprm *bprm); +int (*inode_setxattr) (struct dentry *dentry,const char *name, +const void *value,size_t size,int flags); +void (*inode_post_setxattr) (struct dentry *dentry,const char *name); +int (*inode_alloc_integrity) (struct inode *inode); +void (*inode_free_integrity) (struct inode *inode); +void (*inode_init_integrity) (struct inode *inode,struct inode *dir, +char **name,void **value,size_t *len); +int (*inode_permission) (struct inode *inode,int mask, +struct nameidata *nd); +void (*file_free_integrity) (struct file *file); +int (*file_mmap) (struct file *file, +unsigned long reqprot,unsigned long prot, +unsigned long flags,unsigned long addr, +unsigned long addr_only); +void (*d_instantiate) (struct dentry *dentry,struct inode *inode); +}; +extern int register_integrity (struct integrity_operations *ops); +extern int unregister_integrity (struct integrity_operations *ops); + +/* global variables */ +extern struct integrity_operations *integrity_ops; + + +int integrity_collect_measurement (char *template_name,void *data); +int integrity_appraise_measurement (char *template_name,void *data); +int integrity_must_measure (char *template_name,void *data); +void integrity_store_measurement (char *template_name,void *data); + +int integrity_bprm_check (struct linux_binprm *bprm); +int integrity_inode_setxattr (struct dentry *dentry,const char *name, +const void *value,size_t size,int flags); +void integrity_inode_post_setxattr (struct dentry *dentry,const char *name); +int integrity_inode_alloc (struct inode *inode); +void integrity_inode_free (struct inode *inode); +void integrity_inode_init_integrity (struct inode *inode,struct inode *dir, +char **name,void **value,size_t *len); +int integrity_inode_permission (struct inode *inode,int mask, +struct nameidata *nd); +void integrity_file_free (struct file *file); +int integrity_file_mmap (struct file *file, +unsigned long reqprot,unsigned long prot, +unsigned long flags,unsigned long addr, +unsigned long addr_only); +void integrity_d_instantiate (struct dentry *dentry,struct inode *inode); + +#else + +static inline int integrity_bprm_check (struct linux_binprm *bprm) +{ +return 0 ; +} + +static inline int integrity_inode_setxattr (struct dentry *dentry, +const char *name,const void *value, +size_t size,int flags) +{ +return 0 ; +} + +static inline void integrity_inode_post_setxattr (struct dentry *dentry, +const char *name) +{ } + +static inline int integrity_inode_alloc (struct inode *inode) +{ +return 0 ; +} + +static inline void integrity_inode_free (struct inode *inode) +{ } + +static inline int integrity_inode_init_integrity (struct inode *inode, +struct inode *dir, +char **name, +void **value, +size_t *len) +{ +return -EOPNOTSUPP ; +} + +static inline int integrity_inode_permission (struct inode *inode,int mask, +struct nameidata *nd) +{ +return 0 ; +} + +static inline int integrity_file_permission (struct file *file,int mask) +{ +return 0 ; +} + +static inline void integrity_file_free (struct file *file) +{ +return ; +} + +static inline int integrity_file_mmap (struct file *file, +unsigned long reqprot,unsigned long prot, +unsigned long flags,unsigned long addr, +unsigned long addr_only) +{ +return 0 ; +} + +static inline void integrity_d_instantiate (struct dentry *dentry, +struct inode *inode) +{ +return ; +} + +#endif +#endif
security/integrity/integrity.c new file +244 -0
244 lines not on this page · raw message
security/integrity/integrity_dummy.c new file +112 -0
112 lines not on this page · raw message
security/integrity/integrity_dummy.h new file +13 -0
@@ -0,0 +1,13 @@ +/* +* integrity_dummy.h +* +* Copyright (C) 2005,2006,2007 IBM Corporation +* Author: Mimi Zohar <[email protected]> +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, version 2 of the License. +*/ + +extern struct integrity_operations dummy_integrity_ops; +extern void integrity_fixup_ops (struct integrity_operations *ops);
fs/dcache.c +6 -0
@@ -28,6 +28,7 @@#include <linux/file.h> #include <asm/uaccess.h> #include <linux/security.h> +#include <linux/integrity.h> #include <linux/seqlock.h> #include <linux/swap.h> #include <linux/bootmem.h>
@@ -972,6 +973,7 @@ void d_instantiate(struct dentry *entry, entry->d_inode = inode;fsnotify_d_instantiate (entry, inode);spin_unlock (&dcache_lock); +integrity_d_instantiate (entry, inode);security_d_instantiate (entry, inode); }
@@ -1036,6 +1038,7 @@ struct dentry *d_instantiate_unique(struspin_unlock (&dcache_lock);if (!result) { +integrity_d_instantiate (entry, inode);security_d_instantiate (entry, inode);return NULL ; }
@@ -1173,6 +1176,7 @@ struct dentry *d_splice_alias(struct inoBUG_ON (!(new->d_flags &DCACHE_DISCONNECTED ));fsnotify_d_instantiate (new, inode);spin_unlock (&dcache_lock); +integrity_d_instantiate (new, inode);security_d_instantiate (new, inode);d_rehash (dentry);d_move (new, dentry);
@@ -1183,6 +1187,7 @@ struct dentry *d_splice_alias(struct ino dentry->d_inode = inode;fsnotify_d_instantiate (dentry, inode);spin_unlock (&dcache_lock); +integrity_d_instantiate (dentry, inode);security_d_instantiate (dentry, inode);d_rehash (dentry); }
@@ -1733,6 +1738,7 @@ found:spin_unlock (&dcache_lock); out_nolock:if (actual == dentry) { +integrity_d_instantiate (dentry, inode);security_d_instantiate (dentry, inode);return NULL ; }
fs/ext3/xattr_security.c +8 -0
@@ -9,6 +9,7 @@#include <linux/ext3_jbd.h> #include <linux/ext3_fs.h> #include <linux/security.h> +#include <linux/integrity.h> #include "xattr.h" static size_t
@@ -57,12 +58,19 @@ ext3_init_security(handle_t *handle, str err =security_inode_init_security (inode, dir, &name, &value, &len);if (err) { +/* Even if creation of the security xattr fails, must +* indicate this is a new inode. */ +integrity_inode_init_integrity (inode, dir,NULL ,NULL ,NULL );if (err == -EOPNOTSUPP )return 0 ;return err; } err =ext3_xattr_set_handle (handle, inode,EXT3_XATTR_INDEX_SECURITY , name, value, len,0 ); + +integrity_inode_init_integrity (inode, dir, &name, &value, &len); + err =ext3_xattr_set_handle (handle, inode,EXT3_XATTR_INDEX_SECURITY , + name, value, len,0 );kfree (name);kfree (value);return err;
fs/file_table.c +3 -0
@@ -13,6 +13,7 @@#include <linux/module.h> #include <linux/fs.h> #include <linux/security.h> +#include <linux/integrity.h> #include <linux/eventpoll.h> #include <linux/rcupdate.h> #include <linux/mount.h>
@@ -272,6 +273,7 @@ void __fput(struct file *file)if (file->f_op && file->f_op->release) file->f_op->release (inode, file);security_file_free (file); +integrity_file_free (file);if (unlikely (S_ISCHR (inode->i_mode) && inode->i_cdev !=NULL ))cdev_put (inode->i_cdev);fops_put (file->f_op);
@@ -343,6 +345,7 @@ void put_filp(struct file *file) {if (atomic_dec_and_test (&file->f_count)) {security_file_free (file); +integrity_file_free (file);file_kill (file);file_free (file); }
fs/inode.c +10 -0
@@ -17,6 +17,7 @@#include <linux/hash.h> #include <linux/swap.h> #include <linux/security.h> +#include <linux/integrity.h> #include <linux/pagemap.h> #include <linux/cdev.h> #include <linux/bootmem.h>
@@ -160,6 +161,14 @@ static struct inode *alloc_inode(structinit_rwsem (&inode->i_alloc_sem);lockdep_set_class (&inode->i_alloc_sem, &sb->s_type->i_alloc_sem_key); +if (integrity_inode_alloc (inode)) { +if (inode->i_sb->s_op->destroy_inode) + inode->i_sb->s_op->destroy_inode (inode); +else +kmem_cache_free (inode_cachep, (inode)); +return NULL ; + } + mapping->a_ops = &empty_aops; mapping->host = inode; mapping->flags =0 ;
@@ -190,6 +199,7 @@ void destroy_inode(struct inode *inode) {BUG_ON (inode_has_buffers (inode));security_inode_free (inode); +integrity_inode_free (inode);if (inode->i_sb->s_op->destroy_inode) inode->i_sb->s_op->destroy_inode (inode);else
fs/xattr.c +9 -0
@@ -14,6 +14,7 @@#include <linux/mount.h> #include <linux/namei.h> #include <linux/security.h> +#include <linux/integrity.h> #include <linux/syscalls.h> #include <linux/module.h> #include <linux/fsnotify.h>
@@ -81,11 +82,17 @@ vfs_setxattr(struct dentry *dentry, cons error =security_inode_setxattr (dentry, name, value, size, flags);if (error) goto out; + + error =integrity_inode_setxattr (dentry, name, value, size, flags); +if (error) + goto out; + error = -EOPNOTSUPP ;if (inode->i_op->setxattr) { error = inode->i_op->setxattr (dentry, name, value, size, flags);if (!error) {fsnotify_xattr (dentry); +integrity_inode_post_setxattr (dentry, name);security_inode_post_setxattr (dentry, name, value, size, flags); }
@@ -205,6 +212,8 @@ vfs_removexattr(struct dentry *dentry, cmutex_lock (&inode->i_mutex); error = inode->i_op->removexattr (dentry, name); +if (!error) +integrity_inode_post_setxattr (dentry, name);mutex_unlock (&inode->i_mutex);if (!error)
include/linux/fs.h +3 -0
@@ -653,6 +653,9 @@ struct inode {#ifdef CONFIG_SECURITY void *i_security;#endif +#ifdef CONFIG_INTEGRITY +void *i_integrity; +#endif void *i_private;/* fs or device private pointer */ };
include/linux/audit.h +8 -0
@@ -123,6 +123,11 @@#define AUDIT_LAST_KERN_ANOM_MSG 1799#define AUDIT_ANOM_PROMISCUOUS 1700/* Device changed promiscuous mode */ #define AUDIT_ANOM_ABEND 1701/* Process ended abnormally */ +#define AUDIT_INTEGRITY_DATA 1800/* Data integrity verification */ +#define AUDIT_INTEGRITY_METADATA 1801/* Metadata integrity verification */ +#define AUDIT_INTEGRITY_STATUS 1802/* Integrity enable status */ +#define AUDIT_INTEGRITY_HASH 1803/* Integrity HASH type */ +#define AUDIT_INTEGRITY_PCR 1804/* PCR invalidation msgs */ #define AUDIT_KERNEL 2000/* Asynchronous audit record. NOT A REQUEST. */
@@ -441,6 +446,8 @@ extern int audit_set_loginuid(struct ta#define audit_get_loginuid (t) ((t)->loginuid)#define audit_get_sessionid (t) ((t)->sessionid)extern void audit_log_task_context (struct audit_buffer *ab); +extern void audit_log_inode_context (struct audit_buffer *ab, +struct inode *inode);extern int __audit_ipc_obj (struct kern_ipc_perm *ipcp);extern int __audit_ipc_set_perm (unsigned long qbytes,uid_t uid,gid_t gid,mode_t mode);extern int audit_bprm (struct linux_binprm *bprm);
@@ -521,6 +528,7 @@ extern int audit_signals;#define audit_get_loginuid (t) (-1)#define audit_get_sessionid (t) (-1)#define audit_log_task_context (b) do { ; } while (0) +#define audit_log_inode_context (b, a) do { ; } while (0)#define audit_ipc_obj (i) ({ 0; })#define audit_ipc_set_perm (q,u,g,m) ({ 0; })#define audit_bprm (p) ({ 0; })
security/integrity/integrity_audit.c new file +73 -0
73 lines not on this page · raw message
Documentation/kernel-parameters.txt +5 -0
@@ -821,6 +821,11 @@ and is between 256 and 4096 characters. inport.irq= [HW] Inport (ATI XL and Microsoft) busmouse driver Format: <irq> + integrity_audit= [INTEGRITY] + Format: { "0" | "1" } + 0 -- disable integrity auditing messages. + 1 -- enable integrity auditing messages. (Default) + inttest= [IA64] iommu= [x86]
security/integrity/Makefile new file +7 -0
@@ -0,0 +1,7 @@ +# +# Makefile for the kernel integrity code +# + +# Object file lists +obj-$(CONFIG_INTEGRITY) += integrity.o integrity_dummy.o \ + integrity_audit.o integrity_policy.o
security/integrity/Kconfig new file +24 -0
@@ -0,0 +1,24 @@ +# +# Integrity configuration +# + +menu "Integrity options" + +config INTEGRITY + bool "Enable different integrity models" + help + This allows you to choose different integrity modules to be + configured into your kernel. + + If you are unsure how to answer this question, answer N. + +config INTEGRITY_AUDIT + bool "Integrity audit boot parameter" + depends on INTEGRITY + default y + help + This option adds a kernel parameter 'integrity_audit', which + allows integrity auditing to be disabled at boot. If this + option is selected, integrity auditing can be disabled with + 'integrity_audit=0' on the kernel command line. +endmenu
security/Kconfig +2 -0
@@ -4,6 +4,8 @@ menu "Security options" +source security/integrity/Kconfig + config KEYS bool "Enable access key retention support" help
fs/exec.c +4 -0
@@ -47,6 +47,7 @@#include <linux/ptrace.h> #include <linux/mount.h> #include <linux/security.h> +#include <linux/integrity.h> #include <linux/syscalls.h> #include <linux/rmap.h> #include <linux/tsacct_kern.h>
@@ -1192,6 +1193,9 @@ int search_binary_handler(struct linux_b retval =security_bprm_check (bprm);if (retval)return retval; + retval =integrity_bprm_check (bprm); +if (retval) +return retval;/* kernel module loader fixup */ /* so we don't try to load run modprobe in kernel space. */
fs/namei.c +10 -2
@@ -24,6 +24,7 @@#include <linux/fsnotify.h> #include <linux/personality.h> #include <linux/security.h> +#include <linux/integrity.h> #include <linux/syscalls.h> #include <linux/mount.h> #include <linux/audit.h>
@@ -286,7 +287,10 @@ int permission(struct inode *inode, intif (retval)return retval; -return security_inode_permission (inode, mask, nd); + retval =security_inode_permission (inode, mask, nd); +if (retval) +return retval; +return integrity_inode_permission (inode, mask, nd); }/**
@@ -462,6 +466,7 @@ static struct dentry * cached_lookup(strstatic int exec_permission_lite (struct inode *inode,struct nameidata *nd) { +int retval;umode_t mode = inode->i_mode;if (inode->i_op && inode->i_op->permission)
@@ -486,7 +491,10 @@ static int exec_permission_lite(struct ireturn -EACCES ; ok: -return security_inode_permission (inode,MAY_EXEC , nd); + retval =security_inode_permission (inode,MAY_EXEC , nd); +if (retval) +return retval; +return integrity_inode_permission (inode,MAY_EXEC , nd); }/*
mm/mmap.c +4 -0
@@ -20,6 +20,7 @@#include <linux/fs.h> #include <linux/personality.h> #include <linux/security.h> +#include <linux/integrity.h> #include <linux/hugetlb.h> #include <linux/profile.h> #include <linux/module.h>
@@ -1036,6 +1037,9 @@ unsigned long do_mmap_pgoff(struct file error =security_file_mmap (file, reqprot, prot, flags, addr,0 );if (error)return error; + error =integrity_file_mmap (file, reqprot, prot, flags, addr,0 ); +if (error) +return error;return mmap_region (file, addr, len, flags, vm_flags, pgoff, accountable);
security/integrity/integrity_policy.c new file +197 -0
197 lines not on this page · raw message
security/Makefile +4 -0
@@ -19,3 +19,7 @@ obj-$(CONFIG_SECURITY_SMACK) += commonc obj-$(CONFIG_SECURITY_CAPABILITIES) += commoncap.o capability.o obj-$(CONFIG_SECURITY_ROOTPLUG) += commoncap.o root_plug.o obj-$(CONFIG_CGROUP_DEVICE) += device_cgroup.o + +# Object integrity file lists +subdir-$(CONFIG_INTEGRITY) += integrity +obj-$(CONFIG_INTEGRITY) += integrity/built-in.o
James Morris
maintainerQuoted 13 lines · Mimi Zohar
security/integrity/integrity.c new file +13
-0+int register_template (char *template_name, +struct template_operations *template_ops) +{ +int template_len; +struct template_list_entry *entry; + +if (!template_initialized++) +INIT_LIST_HEAD (&integrity_templates); + + entry =kmalloc (sizeof (*entry),GFP_ATOMIC ); +INIT_LIST_HEAD (&entry->template); + + template_len =strlen (template_name);
security/integrity/integrity.c line 92
Quoted 10 lines
security/integrity/integrity.c new file +10
-0+if (template_len >TEMPLATE_NAME_LEN_MAX ) + template_len =TEMPLATE_NAME_LEN_MAX ; +memcpy (entry->template_name, template_name, template_len); + entry->template_name[template_len] ='\0' ; + entry->template_ops = template_ops; +list_add (&entry->template, &integrity_templates); + +return 0 ; +} +EXPORT_SYMBOL_GPL (register_template);
There's no locking around the mainpulation of integrity_templates list. It seems that this could lead to list corruption.
- James
Signature · 2 lines
James Morris <[email protected]>