Welcome to the Acumen Security Blog

The Email Client EP

The email client extended package (EP) hasn’t received much attention since it came out. Originally released as a stand-alone protection profile (PP) in 2014, it was rewritten as an EP for the Application Software PP in 2015. At this point it has been out for over a year without any evaluations on the Product Compliant List (PCL) or in evaluation. For vendors who are considering an evaluation against this EP but who may have only a passing familiarity with Common Criteria some of its requirements may seem unusual. A closer look at the email EP’s more unique SFRs shows that they should not be unreasonably challenging to test and vendors with compliant products and a business case for certification should not be driven away by unfamiliar terminology.

An unusual threat that the email client EP addresses is that of bad third-party utilities or tools, which in the EP is called T.FLAWED_ADDON. This sounds like it may be a challenge to address, but the requirements of the security functional requirements (SFRs) associated with this threat are quite modest. FPT_AON_EXT.1 and .2 simply verify that if the TOE can use add-ons that those add-ons are authorized and digitally signed. One possible challenge is that one of the testing assurance activities associated with these SFRs is a test where an attempt is made to load add-ons that are modified and improperly signed. These tests would be easy to perform on an email client that runs on a standard desktop operating system. On a more restricted mobile operating system it may not be as straightforward to load a modified add on and carrying out these tests may require developer access.

Another unique SFR in the email client EP is FCS_SMIME_EXT.1. This is not something that’s frequently tested in US Common Criteria evaluations but the requirements of the SFR are fairly straightforward. The testing largely involves sending signed messages between clients, but does require the ability to perform man-in-the-middle attack on messages as they are being transmitted. This is the only SFR in the EP that requires packet modification capabilities.

A number of the email client EP’s other unique SFRs have only documentation based assurance activities. Others that have testing AAs only require an evaluator to use the product’s standard functionality that should be available to any user. FDP_NOT_EXT.1 (S/MIME status notification) can be tested entirely by sending different and receiving different types of emails.

Any client looking to evaluate a product against the email client EP would be well advised to first perform a proper gap analysis, however the EP’s requirements for both the vendor and the testing lab are relatively modest compared to those of the base PP that the EP adds on to.

Revisiting W^X with OpenBSD 6.0

Overview

OpenBSD 6.0 was released today, and with it some exciting new security features.  From my perspective, the chief among them is the technical enforcement of W^X in user-land. Since moving to a technical control rather than a policy statement for enforcing executable space protection was a result of discussions caused by my last blog post on the situation, I’m very excited about this development and thought that giving a demonstration and discussion would be in order. (In the spirit of not putting the headline on Page 1 and the retraction on Page 11, hopefully BSDNow will cover this as well).

Review

Recall that my interest in the subject stems from an objective requirement in the NIAP-sponsored Operating System Protection Profile v4.x, which states that the operating system should prevent an application from being able to map a page of memory with both Write and Execute permissions (protecting mmap(2)) and that once mapped, a page of memory should not be able to have permissions escalated (protecting mprotect(2)).

There is room for interpretation of the meaning of this requirement around two competing ways to implement it.  I made my case for my personal preference in my last post, however the competing case wherein we are merely concerned with a page of memory never being simultaneously W|X and not necessarily enforcing, say W!->X, does have merit and would likely meet the letter of the requirement.

OpenBSD, which is where the branded term “W^X” originates, now enforces the strict W^X definition, and not the PaX/grsec “once write never execute” type of policy in 6.0.

Looking Deeper – A side-by-side comparison with HardenedBSD’s PaX model

In OpenBSD 6.0, when an application attempts to map a page of memory W|X, the process will be terminated with a SIGABRT (signal 6), causing the process to die and drop core. Attempting to run my test application, cc-memtest, which has 3 cases defined, does not get past the first test on OpenBSD 6.0, as the application is aborted:

obsd60-hbsd-cap6

Looking in GDB, we see right where the fault is caught:

obsd60-cap2

Handling this same case, a PaX model implementation does something a little differently.  As we see in both GDB and the procstat output, the page of memory is actually created and mapped, however it is only writable, not executable (and, properly, not readable either, which we didn’t request).

obsd60-hbsd-cap3

The implementation returns a writable page whenever write and execute permissions are asked for.

The application is actually allowed to run, and may or may not be OK.  Attempts to perform an action on that page for which you don’t have permissions will fail (ie, attempting to execute code that is placed in the buffer). However, as we see with OpenBSD’s implementation, the fault is considered to be the allocation of the memory region itself and not the unapproved access to the page.

In this regards, the behavior of the OpenBSD implementation is more readily apparent. The program author requested an R|W|X page of memory and that request causes the program to terminate, as opposed to providing the page of memory with different permissions than was explicitly requested by the program author and then exhibiting failure behavior on a write that may or may not ever happen.

Because HardenedBSD doesn’t abort the process, we can set a new break point and continue onto additional tests to show how mprotect(2) hardening works:

obsd60-hbsd-cap4

Here, we see that the application has successfully mapped a page of memory as executable and then attempts to escalate permissions to include writable. mprotect(2) returns an error code, and we see from procstat that the page of memory in question was created as executable, and then was still ONLY executable after the mprotect(2) attempt.

My quick-and-dirty test program doesn’t have a handler for SIGABRT, and rather than write one in, I pulled test three out as its own program so we can verify mprotect hardening on OpenBSD:

obsd60-7

Again, we see that the page was created properly, but the attempt to make it both executable and writable caused the program to receive SIGABRT and die.

Other differences

One of the other major differences between the PaX/grsecurity model that HardenedBSD implements and OpenBSD 6.0’s implementation is around whether a page of memory should EVER be able to be writable once it has been executable and vice versa.  Some JITs for instance, may want to use mprotect(2) to switch between write and execute permissions on a page of memory in an attempt to not have simultaneously writable and executable permissions. On HardenedBSD, that does not work. On OpenBSD, you can do that:

obsd60-hbsd-cap6

For instance, on HardenedBSD, a piece of code like this will never set write permissions on the page:

obsd60-hbsd-cap5

obsd60-hbsd

So, in order to not run afoul of page exec protections under PaX, a JIT implementer (for instance) would have to take alternative approaches, such as:

  • Maintaining a ‘shadow mapping’ in the same process space and removing one map when it is no longer needed
  • Privilege separating the JIT into two processes with their own address space, each with their own mapping to a shared memory object containing the code to be run through the JIT

Conclusions

When I looked into this issue back in the spring, OpenBSD did not have technical controls in place in user-land, merely a policy that application authors should NOT map W|X memory. HardendBSD and NetBSD, both implemented the PaX model and were able to pass my tests (NetBSD needing a sysctl tweak to enable protection, HardenedBSD by default). However, discussions after the press the previous post received lead to the new technical control implementation coming in for 6.0.

Obviously, the two approaches have some functional differences. OpenBSD’s approach is more deterministic in how one might expect a program to behave than the PaX model. Both the OpenBSD approach and the PaX approach meet the “letter of the law” from the Common Criteria standpoint now, as neither will allow an application to map a page of memory with W|X permissions – OpenBSD merely shuts the door on that activity in a more spectacular fashion.

Over all, though, we are now in a position in which three operating systems exhibit correct behavior with regards to this requirement without requiring additional patches to be applied (i.e., to bring grsecurity into Linux), and all three are BSDs. My hope would be that FreeBSD might look into adopting the HardenedBSD patches up stream so that all three mainline BSDs could meet this requirement, but in the meantime the inclusion of OpenBSD in the club makes it harder for other OS vendors to not take the requirement seriously moving forward.

(and, in related news, NetBSD has actually finally removed the last RWX page of memory in its kernel.  Announcement can be seen here)