On Thu, 2015-05-07 at 10:14 +0200, Patrick Ohly wrote:
> On Wed, 2015-05-06 at 17:36 +0200, Zbigniew Jasiński wrote:
> > > According to the Wiki, one creates privkey_ima.pem but does not copy it to
> > > the image (at least in that use case - there's another one about 
> > > converting a
> > > live image where the key gets copied temporarily).
> > > 
> > > http://sourceforge.net/p/linux-ima/wiki/Home/ talks about "Creating
> > > trusted and EVM encrypted keys". Is that what's missing in the Tizen Wiki 
> > > for
> > > "evm=fix" to work? If so, will signing files with evmctl use 
> > > privkey_ima.pem
> > > for EVM while "evm=fix" uses some other key?
> >  
> > You're right. It's missing from Tizen's Wiki. I will make changes.
> 
> Good to hear that I understood something right ;-} Please ping me when
> you are done.
> 
> > > That problem aside, should IMA/EVM do any checking on /etc at all 
> > > according
> > > to the policy in the Wiki? The instructions only mention the creation of
> > > checksums for /usr /bin /sbin and /lib, but not /etc. Is the policy in
> > > /etc/ima/ima_policy perhaps extending the policies activated by
> > > "ima_appraise_tcb ima_tcb" instead of replacing it?
> > > 
> >  
> > Are you sure that this example policy is loaded? You can check it by 
> > cat'ing policy file.
> 
> Good point. It turns out that /sys/kernel/security/ima/policy is empty
> unless I boot with ima_tcb or ima_appraise_tcb. So my /etc/ima/policy
> does not get loaded - need to check whether it's set up correctly.

http://sourceforge.net/p/linux-ima/wiki/Home/#defining-an-lsm-specific-policy 
mentions a "systemd commit c8161158". Took me a while to figure out that the 
leading c in c8161158 is for "commit" and that the actual commit hash is 
8161158 - you might want to fix that page.

But the Tizen Wiki instructions do not rely on that. They place the
policy file into /etc/ima/ima_policy (to be loaded by the kernel)
whereas systemd uses /etc/ima/ima-policy (hyphen instead of underscore).
What's the advantage of having the kernel load the policy? More secure
because it also checks /etc/ima/ima_policy.sig?

BTW, where in the source code is that signature check? Is it part of the
ima_policy_check() call in integrity_read_file()?

Both methods of loading the policy suggested by the Tizen Wiki failed
for me: systemd did not find the file (wrong name) and the kernel did
not load it because I forgot to create the .sig file (?).

But even if I had done that, it wouldn't have worked, because something
is missing in the Tizen Wiki: one has to add "ima_load" to the boot
options to activate policy loading from inside the kernel. I found that
when looking at the commit adding the feature.

Note that there is no kernel output at all when loading the policy
(neither on success nor when it fails the signature check). Some more
verbosity would have been useful. At least I couldn't figure out whether
the kernel even tried to load the policy. Even with the .sig file in
place and ima_load as boot parameter, the policy still doesn't get
loaded.

Anything else that I should check?

The systemd method does not work either: as seen in
https://review.tizen.org/git/?p=platform/upstream/systemd.git;a=blob;f=src/ima-setup.c;h=03e43dcf16b7e37d5b9d26e6522090848631d518;hb=8161158
 the systemd code copies the file *content* of /etc/ima/ima-policy into 
/sys/kernel/security/ima/policy, not the file *name*. That's okay, 
ima_write_policy() checks the first character and treats the data as rule data 
when they don't start with a slash (but see below about the difference between 
one rule and many).

It expects the entire chunk to be a valid rule because it calls
ima_parse_add_rule() directly without concatenating with further write
calls. The original systemd code in 8161158 got that right via mmap
+write, but that was later replaced with streaming data via
copy_bytes(), an internal helper. That has several problems:
     1. sendfile() is tried first, and is expected to return either
        EINVAL or ENOSYS.
     2. Data is copied in chunks of 16KB.

The second problem prevents installing policies of more than 16KB.
Granted, this is unlikely to be a problem in practice, but still.

But it does not even get that far. The code [1] fails in the second loop
iteration. Here's some manually added debug output:
systemd[1]: Loading the IMA custom policy /etc/ima/ima-policy.
systemd[1]: sendfile(): n = 28, errno = 17
systemd[1]: sendfile(): n = -1, errno = 22
systemd[1]: read(): n = 836, errno = 22
systemd[1]: loop_write(): r = -22
systemd[1]: Failed to load the IMA custom policy file /etc/ima/ima-policy: 
Invalid argument
IMA: policy update failed
[!!!!!!] Failed to load IMA policy, freezing.

[1] 
https://review.tizen.org/git/?p=platform/upstream/systemd.git;a=blob;f=src/shared/copy.c;h=0239a58066ec3314dc004fde3a3a49cf84846e2b;hb=refs/heads/sandbox/mwereski/systemd_v219#l31

n = 28 happens to be the length of the first line in the policy that I
am trying to load. It looks like ima_write_policy() needs to handle
multiple rules per write and doesn't. Or is systemd's IMA support broken
(and always has been) because it uses the kernel interface incorrectly?

Anyway, the second sendfile() then fails because there is no new data to
be written and ima_write_policy() treats that as an error instead EOF.
Falling back to read/write of course also doesn't help anymore at that
point.

-- 
Best Regards, Patrick Ohly

The content of this message is my personal opinion only and although
I am an employee of Intel, the statements I make here in no way
represent Intel's position on the issue, nor am I authorized to speak
on behalf of Intel on this matter.



_______________________________________________
Dev mailing list
[email protected]
https://lists.tizen.org/listinfo/dev

Reply via email to