nfsd4: preallocate nfs4_rpc_args
[safe/jmp/linux-2.6] / security / security.c
index 2797573..687c6fd 100644 (file)
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/security.h>
+#include <linux/ima.h>
 
 /* Boot-time LSM user choice */
-static __initdata char chosen_lsm[SECURITY_NAME_MAX + 1];
+static __initdata char chosen_lsm[SECURITY_NAME_MAX + 1] =
+       CONFIG_DEFAULT_SECURITY;
 
 /* things that live in capability.c */
-extern struct security_operations default_security_ops;
 extern void security_fixup_ops(struct security_operations *ops);
 
-struct security_operations *security_ops;      /* Initialized to NULL */
+static struct security_operations *security_ops;
+static struct security_operations default_security_ops = {
+       .name   = "default",
+};
 
 static inline int verify(struct security_operations *ops)
 {
@@ -61,6 +65,11 @@ int __init security_init(void)
        return 0;
 }
 
+void reset_security_ops(void)
+{
+       security_ops = &default_security_ops;
+}
+
 /* Save user chosen LSM */
 static int __init choose_lsm(char *str)
 {
@@ -79,8 +88,10 @@ __setup("security=", choose_lsm);
  *
  * Return true if:
  *     -The passed LSM is the one chosen by user at boot time,
- *     -or user didn't specify a specific LSM and we're the first to ask
- *      for registration permission,
+ *     -or the passed LSM is configured as the default and the user did not
+ *      choose an alternate LSM at boot time,
+ *     -or there is no default LSM set and the user didn't specify a
+ *      specific LSM and we're the first to ask for registration permission,
  *     -or the passed LSM is currently loaded.
  * Otherwise, return false.
  */
@@ -199,9 +210,9 @@ int security_quota_on(struct dentry *dentry)
        return security_ops->quota_on(dentry);
 }
 
-int security_syslog(int type)
+int security_syslog(int type, bool from_file)
 {
-       return security_ops->syslog(type);
+       return security_ops->syslog(type, from_file);
 }
 
 int security_settime(struct timespec *ts, struct timezone *tz)
@@ -235,7 +246,12 @@ int security_bprm_set_creds(struct linux_binprm *bprm)
 
 int security_bprm_check(struct linux_binprm *bprm)
 {
-       return security_ops->bprm_check_security(bprm);
+       int ret;
+
+       ret = security_ops->bprm_check_security(bprm);
+       if (ret)
+               return ret;
+       return ima_bprm_check(bprm);
 }
 
 void security_bprm_committing_creds(struct linux_binprm *bprm)
@@ -352,12 +368,21 @@ EXPORT_SYMBOL(security_sb_parse_opts_str);
 
 int security_inode_alloc(struct inode *inode)
 {
+       int ret;
+
        inode->i_security = NULL;
-       return security_ops->inode_alloc_security(inode);
+       ret =  security_ops->inode_alloc_security(inode);
+       if (ret)
+               return ret;
+       ret = ima_inode_alloc(inode);
+       if (ret)
+               security_inode_free(inode);
+       return ret;
 }
 
 void security_inode_free(struct inode *inode)
 {
+       ima_inode_free(inode);
        security_ops->inode_free_security(inode);
 }
 
@@ -371,42 +396,42 @@ int security_inode_init_security(struct inode *inode, struct inode *dir,
 EXPORT_SYMBOL(security_inode_init_security);
 
 #ifdef CONFIG_SECURITY_PATH
-int security_path_mknod(struct path *path, struct dentry *dentry, int mode,
+int security_path_mknod(struct path *dir, struct dentry *dentry, int mode,
                        unsigned int dev)
 {
-       if (unlikely(IS_PRIVATE(path->dentry->d_inode)))
+       if (unlikely(IS_PRIVATE(dir->dentry->d_inode)))
                return 0;
-       return security_ops->path_mknod(path, dentry, mode, dev);
+       return security_ops->path_mknod(dir, dentry, mode, dev);
 }
 EXPORT_SYMBOL(security_path_mknod);
 
-int security_path_mkdir(struct path *path, struct dentry *dentry, int mode)
+int security_path_mkdir(struct path *dir, struct dentry *dentry, int mode)
 {
-       if (unlikely(IS_PRIVATE(path->dentry->d_inode)))
+       if (unlikely(IS_PRIVATE(dir->dentry->d_inode)))
                return 0;
-       return security_ops->path_mkdir(path, dentry, mode);
+       return security_ops->path_mkdir(dir, dentry, mode);
 }
 
-int security_path_rmdir(struct path *path, struct dentry *dentry)
+int security_path_rmdir(struct path *dir, struct dentry *dentry)
 {
-       if (unlikely(IS_PRIVATE(path->dentry->d_inode)))
+       if (unlikely(IS_PRIVATE(dir->dentry->d_inode)))
                return 0;
-       return security_ops->path_rmdir(path, dentry);
+       return security_ops->path_rmdir(dir, dentry);
 }
 
-int security_path_unlink(struct path *path, struct dentry *dentry)
+int security_path_unlink(struct path *dir, struct dentry *dentry)
 {
-       if (unlikely(IS_PRIVATE(path->dentry->d_inode)))
+       if (unlikely(IS_PRIVATE(dir->dentry->d_inode)))
                return 0;
-       return security_ops->path_unlink(path, dentry);
+       return security_ops->path_unlink(dir, dentry);
 }
 
-int security_path_symlink(struct path *path, struct dentry *dentry,
+int security_path_symlink(struct path *dir, struct dentry *dentry,
                          const char *old_name)
 {
-       if (unlikely(IS_PRIVATE(path->dentry->d_inode)))
+       if (unlikely(IS_PRIVATE(dir->dentry->d_inode)))
                return 0;
-       return security_ops->path_symlink(path, dentry, old_name);
+       return security_ops->path_symlink(dir, dentry, old_name);
 }
 
 int security_path_link(struct dentry *old_dentry, struct path *new_dir,
@@ -612,14 +637,14 @@ int security_inode_killpriv(struct dentry *dentry)
 int security_inode_getsecurity(const struct inode *inode, const char *name, void **buffer, bool alloc)
 {
        if (unlikely(IS_PRIVATE(inode)))
-               return 0;
+               return -EOPNOTSUPP;
        return security_ops->inode_getsecurity(inode, name, buffer, alloc);
 }
 
 int security_inode_setsecurity(struct inode *inode, const char *name, const void *value, size_t size, int flags)
 {
        if (unlikely(IS_PRIVATE(inode)))
-               return 0;
+               return -EOPNOTSUPP;
        return security_ops->inode_setsecurity(inode, name, value, size, flags);
 }
 
@@ -659,7 +684,12 @@ int security_file_mmap(struct file *file, unsigned long reqprot,
                        unsigned long prot, unsigned long flags,
                        unsigned long addr, unsigned long addr_only)
 {
-       return security_ops->file_mmap(file, reqprot, prot, flags, addr, addr_only);
+       int ret;
+
+       ret = security_ops->file_mmap(file, reqprot, prot, flags, addr, addr_only);
+       if (ret)
+               return ret;
+       return ima_file_mmap(file, prot);
 }
 
 int security_file_mprotect(struct vm_area_struct *vma, unsigned long reqprot,
@@ -739,9 +769,9 @@ int security_kernel_create_files_as(struct cred *new, struct inode *inode)
        return security_ops->kernel_create_files_as(new, inode);
 }
 
-int security_kernel_module_request(void)
+int security_kernel_module_request(char *kmod_name)
 {
-       return security_ops->kernel_module_request();
+       return security_ops->kernel_module_request(kmod_name);
 }
 
 int security_task_setuid(uid_t id0, uid_t id1, uid_t id2, int flags)