ocfs2: Switch to security_inode_init_security()
authorRoberto Sassu <roberto.sassu@huawei.com>
Tue, 14 Mar 2023 08:17:16 +0000 (09:17 +0100)
committerPaul Moore <paul@paul-moore.com>
Thu, 23 Mar 2023 23:35:33 +0000 (19:35 -0400)
In preparation for removing security_old_inode_init_security(), switch to
security_inode_init_security().

Extend the existing ocfs2_initxattrs() to take the
ocfs2_security_xattr_info structure from fs_info, and populate the
name/value/len triple with the first xattr provided by LSMs.

As fs_info was not used before, ocfs2_initxattrs() can now handle the case
of replicating the behavior of security_old_inode_init_security(), i.e.
just obtaining the xattr, in addition to setting all xattrs provided by
LSMs.

Supporting multiple xattrs is not currently supported where
security_old_inode_init_security() was called (mknod, symlink), as it
requires non-trivial changes that can be done at a later time. Like for
reiserfs, even if EVM is invoked, it will not provide an xattr (if it is
not the first to set it, its xattr will be discarded; if it is the first,
it does not have xattrs to calculate the HMAC on).

Finally, since security_inode_init_security(), unlike
security_old_inode_init_security(), returns zero instead of -EOPNOTSUPP if
no xattrs were provided by LSMs or if inodes are private, additionally
check in ocfs2_init_security_get() if the xattr name is set.

If not, act as if security_old_inode_init_security() returned -EOPNOTSUPP,
and set si->enable to zero to notify to the functions following
ocfs2_init_security_get() that no xattrs are available.

Signed-off-by: Roberto Sassu <roberto.sassu@huawei.com>
Reviewed-by: Casey Schaufler <casey@schaufler-ca.com>
Acked-by: Joseph Qi <joseph.qi@linux.alibaba.com>
Reviewed-by: Mimi Zohar <zohar@linux.ibm.com>
Signed-off-by: Paul Moore <paul@paul-moore.com>
fs/ocfs2/namei.c
fs/ocfs2/xattr.c

index 9175dbc472011ec1005863edeac6bb925fc64dee..17c52225b87d4bc4cfa1b2986120ee9ae6cc4b97 100644 (file)
@@ -242,6 +242,7 @@ static int ocfs2_mknod(struct mnt_idmap *idmap,
        int want_meta = 0;
        int xattr_credits = 0;
        struct ocfs2_security_xattr_info si = {
+               .name = NULL,
                .enable = 1,
        };
        int did_quota_inode = 0;
@@ -1805,6 +1806,7 @@ static int ocfs2_symlink(struct mnt_idmap *idmap,
        int want_clusters = 0;
        int xattr_credits = 0;
        struct ocfs2_security_xattr_info si = {
+               .name = NULL,
                .enable = 1,
        };
        int did_quota = 0, did_quota_inode = 0;
index 389308efe854f872648f2fafe08a9666e9e38c97..469ec45baee2b796c8ebbf990c6dd6b928887fbf 100644 (file)
@@ -7259,9 +7259,21 @@ static int ocfs2_xattr_security_set(const struct xattr_handler *handler,
 static int ocfs2_initxattrs(struct inode *inode, const struct xattr *xattr_array,
                     void *fs_info)
 {
+       struct ocfs2_security_xattr_info *si = fs_info;
        const struct xattr *xattr;
        int err = 0;
 
+       if (si) {
+               si->value = kmemdup(xattr_array->value, xattr_array->value_len,
+                                   GFP_KERNEL);
+               if (!si->value)
+                       return -ENOMEM;
+
+               si->name = xattr_array->name;
+               si->value_len = xattr_array->value_len;
+               return 0;
+       }
+
        for (xattr = xattr_array; xattr->name != NULL; xattr++) {
                err = ocfs2_xattr_set(inode, OCFS2_XATTR_INDEX_SECURITY,
                                      xattr->name, xattr->value,
@@ -7277,13 +7289,23 @@ int ocfs2_init_security_get(struct inode *inode,
                            const struct qstr *qstr,
                            struct ocfs2_security_xattr_info *si)
 {
+       int ret;
+
        /* check whether ocfs2 support feature xattr */
        if (!ocfs2_supports_xattr(OCFS2_SB(dir->i_sb)))
                return -EOPNOTSUPP;
-       if (si)
-               return security_old_inode_init_security(inode, dir, qstr,
-                                                       &si->name, &si->value,
-                                                       &si->value_len);
+       if (si) {
+               ret = security_inode_init_security(inode, dir, qstr,
+                                                  &ocfs2_initxattrs, si);
+               /*
+                * security_inode_init_security() does not return -EOPNOTSUPP,
+                * we have to check the xattr ourselves.
+                */
+               if (!ret && !si->name)
+                       si->enable = 0;
+
+               return ret;
+       }
 
        return security_inode_init_security(inode, dir, qstr,
                                            &ocfs2_initxattrs, NULL);