@@ -1104,11 +1104,24 @@ int security_inode_init_security(struct inode *inode, struct inode *dir,
if (unlikely(IS_PRIVATE(inode)))
return 0;
- if (!initxattrs)
- return call_int_hook(inode_init_security, -EOPNOTSUPP, inode,
- dir, qstr, NULL, NULL, NULL);
+ if (!initxattrs) {
+ rc = -EOPNOTSUPP;
+ hlist_for_each_entry(p,
+ &security_hook_heads.inode_init_security,
+ list) {
+ rc = p->hook.inode_init_security(inode, dir, qstr,
+ NULL, NULL, NULL);
+ if (rc == -EOPNOTSUPP) {
+ rc = 0;
+ continue;
+ }
+ if (rc)
+ break;
+ }
+ return rc;
+ }
- repo = kzalloc((LSM_COUNT * 2) * sizeof(*repo), GFP_NOFS);
+ repo = kzalloc((LSM_COUNT + 1) * sizeof(*repo), GFP_NOFS);
if (repo == NULL)
return -ENOMEM;
@@ -1119,18 +1132,20 @@ int security_inode_init_security(struct inode *inode, struct inode *dir,
rc = p->hook.inode_init_security(inode, dir, qstr,
&repo[i].name, &repo[i].value,
&repo[i].value_len);
+ if (rc == -EOPNOTSUPP)
+ continue;
if (rc)
goto out;
- rc = evm_inode_init_security(inode, &repo[i], &repo[i + 1]);
- if (rc)
- goto out;
-
- i += 2;
+ i++;
}
+ rc = evm_inode_init_security(inode, &repo[i], &repo[i + 1]);
+ if (rc)
+ goto out;
+
rc = initxattrs(inode, repo, fs_data);
out:
- for (i-- ; i >= 0; i--)
+ for (i++ ; i >= 0; i--)
kfree(repo[i].value);
kfree(repo);
return (rc == -EOPNOTSUPP) ? 0 : rc;
The code assumes you can call evm_init_inode_security more than once for an inode, but that won't work because security.evm is a single value attribute. This does not make EVM work properly, but does allow the security modules to initialize their attribures. Signed-off-by: Casey Schaufler <casey@schaufler-ca.com> --- security/security.c | 35 +++++++++++++++++++++++++---------- 1 file changed, 25 insertions(+), 10 deletions(-)