Page MenuHomeFreeBSD

Verified execution (veriexec) fingerprint loader
ClosedPublic

Authored by stevek on Nov 18 2016, 4:50 PM.
Tags
None
Referenced Files
Unknown Object (File)
Thu, Apr 18, 12:10 PM
Unknown Object (File)
Mar 22 2024, 11:17 PM
Unknown Object (File)
Mar 18 2024, 5:28 PM
Unknown Object (File)
Mar 3 2024, 7:33 AM
Unknown Object (File)
Mar 3 2024, 7:06 AM
Unknown Object (File)
Jan 7 2024, 6:12 AM
Unknown Object (File)
Dec 22 2023, 9:41 PM
Unknown Object (File)
Nov 23 2023, 5:09 PM

Details

Summary

This application (veriexecctl) handles reading a fingerprints file containing paths, fingerprints, and optional option flags which in turn get pushed into the MAC/veriexec meta-data store via the veriexec device.

The format of the fingerprints file is as follows:
path type fingerprint options

The type of fingerprint supported depends on what MAC/veriexec fingerprint modules have been loaded into the system. The veriexecctl application is able to determine which ones are available by consulting the security.mac.veriexec.algorithms sysctl.

The following options are currently supported in MAC/veriexec and by the veriexecctl application:

  • indirect
    • If this option is set then the executable cannot be invoked directly, it can only be used as an interpreter in shell scripts.
  • file
    • Indicates that the fingerprint is associated with a file, not an executable. Files have their fingerprints verified during open(2) and are automatically made read only. This option may be used to verify shared libraries have not been tampered with.
  • no_ptrace
    • If this option is set then the executable cannot be traced with the ptrace(2) process tracing and debugging call.
  • trusted
    • If this option is set then the executable is allowed to write to the mem(4) devices. By default, when verified execution is enforced, no process is allowed to write to the mem(4) devices.

The options are not case sensitive.

Depends on D8561.

Test Plan

Various versions of this code (with some differences) has been in use for a few years and has gone through in-house testing.

Diff Detail

Repository
rS FreeBSD src repository - subversion
Lint
Lint Not Applicable
Unit
Tests Not Applicable

Event Timeline

stevek retitled this revision from to Verified execution (veriexec) fingerprint loader.
stevek updated this object.
stevek edited the test plan for this revision. (Show Details)
stevek added a reviewer: rwatson.
stevek added a subscriber: sjg.

Other than the question about the meaning of "executed", I edited and modified the markup, and so will just provide this file:

sbin/veriexecctl/veriexecctl.8
50 ↗(On Diff #22333)

There should be a comma after "Once loaded", but it looks like it can be removed entirely so the sentence just starts with "The kernel can then..."

Then meaning of "executed" here is not clear. Does it mean "executable", or does it mean "on execution"? Can it be removed?

sbin/veriexecctl/veriexecctl.8
50 ↗(On Diff #22333)

This is the exact wording that came from NetBSD (See http://cvsweb.netbsd.org/bsdweb.cgi/src/sbin/veriexecctl/veriexecctl.8?rev=1.2)

I agree that the sentence is a bit awkward.

It's referring to the fingerprint prints being loaded into the kernel. Once they are in the in-kernel meta-data store, the kernel can calculate the fingerprint of programs at the time of execution or files that are opened with O_VERIFY and report whether or not the fingerprint matches the one in the meta-data store.

Given the terminology that we utilize is the meta-data store instead of fingerprint table, it would be ideal to change the wording of this sentence accordingly.

Updated. The sentence in question now reads (without markup):

The veriexecctl command loads an in-kernel metadata store of the
fingerprints given in the fingerprints file.  The kernel can then
calculate the fingerprint of programs at time of execution or files that
are opened with O_VERIFY and verify whether the fingerprints match.

If I understand this correctly, this is a system based on symmetric-key message authentication codes which allows specific files to be assigned specific a specific MAC, which is then checked when those files are loaded.

It is worth noting that I have a draft of a public-key based trust system which has similar goals, but different methods. That said, I don't see any reason why these two systems can't coexist, and perhaps they can be designed to interoperate in some way.

No there's no symmetric key stuff here - just known good hashes of files, plus the ability to associate other "labels" with them.
Those hashes (in our implementation) are delivered to the kernel after verifying a digital signature.

jtl added inline comments.
sbin/veriexecctl/veriexecctl.c
112 ↗(On Diff #22333)

Check errno in case the argument is invalid?

sbin/veriexecctl/veriexecctl_parse.y
6 ↗(On Diff #22333)

Does this need to maintain any of the original copyrights from that file? (Actually, I guess that same question may apply to other things in these related reviews.)

178 ↗(On Diff #22333)

I notice this only supports unsigned loading. Do you have plans to upstream signed loading?

sbin/veriexecctl/veriexecctl.c
93 ↗(On Diff #22333)

I feel like "signature file" may not be the best way to describe this. The file is really a list of files with associated data and doesn't really contain any "signatures". So, "manifest" is probably a better name.

(Further, in another implementation, there might actually be a "signature file" that contains a detached signature to validate the manifest.)

sbin/veriexecctl/veriexecctl_parse.y
6 ↗(On Diff #22333)
178 ↗(On Diff #22333)

Not in the way that we use it in Juniper. As mentioned in D8554, we have had discussions with Robert about possibilities, but nothing has been made concrete yet.

sbin/veriexecctl/veriexecctl.c
112 ↗(On Diff #22333)

Per atoi(3): The function atoi() need not affect the value of errno on an error.

What happens in practice is, if there's no valid characters, you just end up with 0 as the return value.

sbin/veriexecctl/veriexecctl.c
93 ↗(On Diff #22333)

manifest would probably be better, yes. The "signature_file" part came from the original sources. See the following for reference: http://cvsweb.netbsd.org/bsdweb.cgi/src/sbin/veriexecctl/veriexecctl.c?rev=1.5&content-type=text/x-cvsweb-markup&only_with_tag=MAIN

I think this should be committed basically "as is" (perhaps with the few tweaks suggested in the review), unless someone raises serious objections in the next week or so.

This has years of "soak time". I've also personally stared at this code for many hours over many years.

I do think it could use some additional infrastructure to make sure this is easy to implement in the base system. In particular, we'll need to figure out how to distribute secure manifests with packages for people that like to get their ports that way. However, IMO, that's not a reason to keep this out of the tree. Rather, having this code in the tree will let us develop the extra needed infrastructure on top of this.

sbin/veriexecctl/veriexecctl.c
112 ↗(On Diff #22333)

I think that statement in the manpage may be out of date.

Looking at the code in lib/libc/stdlib/atoi.c, I see that atoi() just calls strtol(). strtol() does set errno when there is a problem.

sbin/veriexecctl/veriexecctl_parse.y
178 ↗(On Diff #22333)

FWIW, I think that the code Juniper uses to load signed manifests could probably be adapted fairly well. You would just need to redefine the trusted certs to something appropriate for the local environment.

I admit that some of the other infrastructure would not be quite so easily adapted.

I'll try to start an email thread with @rwatson, @sjg, and you with my idea of what might be appropriate for base.

This revision is now accepted and ready to land.Jan 10 2018, 12:20 AM

Just as a note, I'm going to be editing a paper on a larger FreeBSD trust system for submission to BSDCan. I plan on incorporating this work into the overall design.

I'd like to get an author list for this work (and any related coming patches), as well as for the NetBSD system if possible for the bibliography.

jilles added inline comments.
sbin/veriexecctl/veriexecctl.c
112 ↗(On Diff #22333)

If you care about errors, you should not use atoi() at all since the standards do not require it to set errno (even though FreeBSD's implementation sets it) and allow undefined behaviour if the conversion overflows.

Undefined behaviour can be avoided by using the standard strtol() correctly or by using OpenBSD's strtonum().

I'd like to get an author list for this work (and any related coming patches), as well as for the NetBSD system if possible for the bibliography.

Brett Lymn <blymn at netbsd.org> is the original author of verified exec in NetBSD.

I ported the early version of that to Junos about a dozen years ago.

This rework is mostly by stevek with bugs etc contributed by me ;-)

BTW the same manifests used here fit into the loader verification that I plan to speak about at BSDCan.

This revision was automatically updated to reflect the committed changes.