media: tegra_v4l2_camera: add CSI caliabration
[linux-3.10.git] / fs / attr.c
index 91dbe2a..8dd5825 100644 (file)
--- a/fs/attr.c
+++ b/fs/attr.c
@@ -5,7 +5,7 @@
  *  changes by Thomas Schoebel-Theuer
  */
 
-#include <linux/module.h>
+#include <linux/export.h>
 #include <linux/time.h>
 #include <linux/mm.h>
 #include <linux/string.h>
@@ -13,6 +13,8 @@
 #include <linux/fsnotify.h>
 #include <linux/fcntl.h>
 #include <linux/security.h>
+#include <linux/evm.h>
+#include <linux/ima.h>
 
 /**
  * inode_change_ok - check if attribute changes to an inode are allowed
@@ -46,15 +48,16 @@ int inode_change_ok(const struct inode *inode, struct iattr *attr)
 
        /* Make sure a caller can chown. */
        if ((ia_valid & ATTR_UID) &&
-           (current_fsuid() != inode->i_uid ||
-            attr->ia_uid != inode->i_uid) && !capable(CAP_CHOWN))
+           (!uid_eq(current_fsuid(), inode->i_uid) ||
+            !uid_eq(attr->ia_uid, inode->i_uid)) &&
+           !inode_capable(inode, CAP_CHOWN))
                return -EPERM;
 
        /* Make sure caller can chgrp. */
        if ((ia_valid & ATTR_GID) &&
-           (current_fsuid() != inode->i_uid ||
-           (!in_group_p(attr->ia_gid) && attr->ia_gid != inode->i_gid)) &&
-           !capable(CAP_CHOWN))
+           (!uid_eq(current_fsuid(), inode->i_uid) ||
+           (!in_group_p(attr->ia_gid) && !gid_eq(attr->ia_gid, inode->i_gid))) &&
+           !inode_capable(inode, CAP_CHOWN))
                return -EPERM;
 
        /* Make sure a caller can chmod. */
@@ -63,7 +66,8 @@ int inode_change_ok(const struct inode *inode, struct iattr *attr)
                        return -EPERM;
                /* Also check the setgid bit! */
                if (!in_group_p((ia_valid & ATTR_GID) ? attr->ia_gid :
-                               inode->i_gid) && !capable(CAP_FSETID))
+                               inode->i_gid) &&
+                   !inode_capable(inode, CAP_FSETID))
                        attr->ia_mode &= ~S_ISGID;
        }
 
@@ -155,7 +159,8 @@ void setattr_copy(struct inode *inode, const struct iattr *attr)
        if (ia_valid & ATTR_MODE) {
                umode_t mode = attr->ia_mode;
 
-               if (!in_group_p(inode->i_gid) && !capable(CAP_FSETID))
+               if (!in_group_p(inode->i_gid) &&
+                   !inode_capable(inode, CAP_FSETID))
                        mode &= ~S_ISGID;
                inode->i_mode = mode;
        }
@@ -165,16 +170,25 @@ EXPORT_SYMBOL(setattr_copy);
 int notify_change(struct dentry * dentry, struct iattr * attr)
 {
        struct inode *inode = dentry->d_inode;
-       mode_t mode = inode->i_mode;
+       umode_t mode = inode->i_mode;
        int error;
        struct timespec now;
        unsigned int ia_valid = attr->ia_valid;
 
+       WARN_ON_ONCE(!mutex_is_locked(&inode->i_mutex));
+
        if (ia_valid & (ATTR_MODE | ATTR_UID | ATTR_GID | ATTR_TIMES_SET)) {
                if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
                        return -EPERM;
        }
 
+       if ((ia_valid & ATTR_MODE)) {
+               umode_t amode = attr->ia_mode;
+               /* Flag setting protected by i_mutex */
+               if (is_sxid(amode))
+                       inode->i_flags &= ~S_NOSEC;
+       }
+
        now = current_fs_time(inode->i_sb);
 
        attr->ia_ctime = now;
@@ -225,21 +239,17 @@ int notify_change(struct dentry * dentry, struct iattr * attr)
        if (error)
                return error;
 
-       if (ia_valid & ATTR_SIZE)
-               down_write(&dentry->d_inode->i_alloc_sem);
-
        if (inode->i_op->setattr)
                error = inode->i_op->setattr(dentry, attr);
        else
                error = simple_setattr(dentry, attr);
 
-       if (ia_valid & ATTR_SIZE)
-               up_write(&dentry->d_inode->i_alloc_sem);
-
-       if (!error)
+       if (!error) {
                fsnotify_change(dentry, ia_valid);
+               ima_inode_post_setattr(dentry);
+               evm_inode_post_setattr(dentry, ia_valid);
+       }
 
        return error;
 }
-
 EXPORT_SYMBOL(notify_change);