Thread (11 messages) 11 messages, 3 authors, 2019-02-04

Re: [PATCH v3 5/5] kernfs: initialize security of newly created nodes

From: Ondrej Mosnacek <omosnace@redhat.com>
Date: 2019-02-04 09:48:49
Also in: linux-fsdevel, selinux

On Thu, Jan 31, 2019 at 5:39 PM Casey Schaufler [off-list ref] wrote:
On 1/31/2019 2:20 AM, Ondrej Mosnacek wrote:
quoted
Hi Tejun,

On Wed, Jan 30, 2019 at 6:09 PM Tejun Heo [off-list ref] wrote:
quoted
Hello,

On Wed, Jan 30, 2019 at 12:41:50PM +0100, Ondrej Mosnacek wrote:
quoted
@@ -673,6 +698,12 @@ static struct kernfs_node *__kernfs_new_node(struct kernfs_root *root,
                      goto err_out3;
      }

+     if (parent) {
+             ret = kernfs_node_init_security(parent, kn);
+             if (ret)
+                     goto err_out3;
+     }
So, doing this unconditionally isn't a good idea.  kernfs doesn't use
the usual dentry/inode because there are machines with 6, even 7 digit
number of kernfs nodes and some of them even failed to boot due to
memory shortage.  Please don't blow it up by default.
Hm, I see... basically the only thing that gets allocated in
kernfs_node_init_security() by default (at least under SELinux/ no
LSM) is the kernfs_iattrs structures, so I assume you are pointing at
that. I think this can be easily fixed, if we again use the assumption
that whenever the parent node has only default attributes
(parent->iattrs == NULL), then the child node should also have just
default attributes (and so we don't need to call kernfs_iattrs() on it
nor call the security hook). Something along these lines:

[...]
+static int kernfs_node_init_security(struct kernfs_node *parent,
+                                    struct kernfs_node *kn)
+{
+       struct kernfs_iattrs *attrs, *pattrs;
+       struct qstr q;
+
+       pattrs = parent->iattrs;
+       if (!pattrs)
+               return 0;
+
+       attrs = kernfs_iattrs(kn);
+       if (!attrs)
+               return -ENOMEM;
+
+       q.name = kn->name;
+       q.hash_len = hashlen_string(parent, kn->name);
[...]

Technically this might make some LSMs unhappy, if they want to set
some non-default context even if parent is all default,
The only possibility I see as a potential problem is a kernfs
mounted with the smackfstransmute=Something option. This sets
the security.SMACK64 to "Something" and the security.SMACK64TRANSMUTE
to true on the root node. But that doesn't seem like a rational
thing to do for a kernfs based filesystem.
Actually... I am now experimenting with a slightly different
kernfs_node_init_security() implementation that should allow for
calling the hook every time and only allocating kernfs_iattrs when it
detects that the hook actually did add some security xattrs. It is
somewhat more hacky and complex, but it should provide the best
possible compromise. I will post it for review soon.
quoted
but this is
already impossible now and in this case I think we have no better
choice than sacrificing a bit of flexibility for memory efficiency,
which is apparently critical here.

Tejun, Casey, would the above modification be fine with you?
I *think so*, but I can't say 100% that I really understand the
entire issue.
quoted
--
Ondrej Mosnacek <omosnace at redhat dot com>
Associate Software Engineer, Security Technologies
Red Hat, Inc.
-- 
Ondrej Mosnacek <omosnace at redhat dot com>
Associate Software Engineer, Security Technologies
Red Hat, Inc.
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help