diff mbox series

[RFC] selinux-notebook: mls_mcs.md convert and update text

Message ID 20200807144025.11668-1-richard_c_haines@btinternet.com (mailing list archive)
State Changes Requested
Headers show
Series [RFC] selinux-notebook: mls_mcs.md convert and update text | expand

Commit Message

Richard Haines Aug. 7, 2020, 2:40 p.m. UTC
This is an RFC patch to get some feedback as:
1) Table 1 is now a pipe table, however it still has <br> codes to
   break up the text. Also updated styles.html.css to match the pdf version
   to allow correct HTML rendering.
2) Table 2 is now a pipe table with updated text.

Add a TOC to aid navigation
Add text to clarify MCS/MLS

Signed-off-by: Richard Haines <richard_c_haines@btinternet.com>
---
 src/mls_mcs.md      | 236 ++++++++++++++++----------------------------
 src/styles_html.css |   5 +-
 2 files changed, 86 insertions(+), 155 deletions(-)

Comments

Stephen Smalley Aug. 7, 2020, 3:27 p.m. UTC | #1
On 8/7/20 10:40 AM, Richard Haines wrote:

> This is an RFC patch to get some feedback as:
> 1) Table 1 is now a pipe table, however it still has <br> codes to
>     break up the text. Also updated styles.html.css to match the pdf version
>     to allow correct HTML rendering.
> 2) Table 2 is now a pipe table with updated text.
>
> Add a TOC to aid navigation
> Add text to clarify MCS/MLS
>
> Signed-off-by: Richard Haines <richard_c_haines@btinternet.com>
> ---
>
> @@ -48,6 +56,18 @@ The sections that follow discuss the format of a security level and
>   range, and how these are managed by the constraints mechanism within
>   SELinux using dominance rules.
>   
> +### MLS or MCS Policy
> +
> +From an SELinux perspective:
> +
> +-   An MLS policy has more than one security level with zero or more categories.
> +    It is generally used in systems that require the 'Read Down' and 'Write Up'
> +    services, whether it be for files, network services etc..
> +-   An MCS policy has a single security level with zero or more categories.
> +    Example uses are virtualization (see the
> +    [**Virtual Machine Support**](vm_support.md#selinux-virtual-machine-support)
> +    section) and container security.
> +

To be clear, SELinux (i.e. the code/mechanism) only knows of MLS, i.e. 
it has a MLS engine in the security server and a MLS portion of the 
policy configuration that drives that engine.  That MLS engine has been 
leveraged by two different types of policies, the original MLS 
configuration modeled after Bell-LaPadula and the later-introduced MCS 
configuration (which underwent a fundamental transformation from being 
user-facing and somewhat discretionary to being a transparent isolation 
mechanism for sandbox, container, and virtualization runtimes). The 
number of sensitivities, number of categories, and the set of MLS 
constraints used to determine whether a permission is allowed are 
entirely up to the policy author. A level in SELinux is a combination of 
a hierarchical sensitivity and a non-hierarchical (potentially empty) 
category set. In practice MCS is used for simple isolation and therefore 
doesn't employ sensitivities since there is no hierarchical relationship 
to be enforced.
Richard Haines Aug. 7, 2020, 3:36 p.m. UTC | #2
On Fri, 2020-08-07 at 11:27 -0400, Stephen Smalley wrote:
> On 8/7/20 10:40 AM, Richard Haines wrote:
> 
> > This is an RFC patch to get some feedback as:
> > 1) Table 1 is now a pipe table, however it still has <br> codes to
> >     break up the text. Also updated styles.html.css to match the
> > pdf version
> >     to allow correct HTML rendering.
> > 2) Table 2 is now a pipe table with updated text.
> > 
> > Add a TOC to aid navigation
> > Add text to clarify MCS/MLS
> > 
> > Signed-off-by: Richard Haines <richard_c_haines@btinternet.com>
> > ---
> > 
> > @@ -48,6 +56,18 @@ The sections that follow discuss the format of a
> > security level and
> >   range, and how these are managed by the constraints mechanism
> > within
> >   SELinux using dominance rules.
> >   
> > +### MLS or MCS Policy
> > +
> > +From an SELinux perspective:
> > +
> > +-   An MLS policy has more than one security level with zero or
> > more categories.
> > +    It is generally used in systems that require the 'Read Down'
> > and 'Write Up'
> > +    services, whether it be for files, network services etc..
> > +-   An MCS policy has a single security level with zero or more
> > categories.
> > +    Example uses are virtualization (see the
> > +    [**Virtual Machine Support**](vm_support.md#selinux-virtual-
> > machine-support)
> > +    section) and container security.
> > +
> 
> To be clear, SELinux (i.e. the code/mechanism) only knows of MLS,
> i.e. 
> it has a MLS engine in the security server and a MLS portion of the 
> policy configuration that drives that engine.  That MLS engine has
> been 
> leveraged by two different types of policies, the original MLS 
> configuration modeled after Bell-LaPadula and the later-introduced
> MCS 
> configuration (which underwent a fundamental transformation from
> being 
> user-facing and somewhat discretionary to being a transparent
> isolation 
> mechanism for sandbox, container, and virtualization runtimes). The 
> number of sensitivities, number of categories, and the set of MLS 
> constraints used to determine whether a permission is allowed are 
> entirely up to the policy author. A level in SELinux is a combination
> of 
> a hierarchical sensitivity and a non-hierarchical (potentially
> empty) 
> category set. In practice MCS is used for simple isolation and
> therefore 
> doesn't employ sensitivities since there is no hierarchical
> relationship 
> to be enforced.
> 
Thanks for the clarification. I'll update the text in the next version

>
Dominick Grift Aug. 7, 2020, 4:04 p.m. UTC | #3
Stephen Smalley <stephen.smalley.work@gmail.com> writes:

> On 8/7/20 10:40 AM, Richard Haines wrote:
>
>> This is an RFC patch to get some feedback as:
>> 1) Table 1 is now a pipe table, however it still has <br> codes to
>>     break up the text. Also updated styles.html.css to match the pdf version
>>     to allow correct HTML rendering.
>> 2) Table 2 is now a pipe table with updated text.
>>
>> Add a TOC to aid navigation
>> Add text to clarify MCS/MLS
>>
>> Signed-off-by: Richard Haines <richard_c_haines@btinternet.com>
>> ---
>>
>> @@ -48,6 +56,18 @@ The sections that follow discuss the format of a security level and
>>   range, and how these are managed by the constraints mechanism within
>>   SELinux using dominance rules.
>>   +### MLS or MCS Policy
>> +
>> +From an SELinux perspective:
>> +
>> +-   An MLS policy has more than one security level with zero or more categories.
>> +    It is generally used in systems that require the 'Read Down' and 'Write Up'
>> +    services, whether it be for files, network services etc..
>> +-   An MCS policy has a single security level with zero or more categories.
>> +    Example uses are virtualization (see the
>> +    [**Virtual Machine Support**](vm_support.md#selinux-virtual-machine-support)
>> +    section) and container security.
>> +
>
> To be clear, SELinux (i.e. the code/mechanism) only knows of MLS,
> i.e. it has a MLS engine in the security server and a MLS portion of
> the policy configuration that drives that engine.  That MLS engine has
> been leveraged by two different types of policies, the original MLS
> configuration modeled after Bell-LaPadula and the later-introduced MCS
> configuration (which underwent a fundamental transformation from being
> user-facing and somewhat discretionary to being a transparent
> isolation mechanism for sandbox, container, and virtualization
> runtimes). The number of sensitivities, number of categories, and the
> set of MLS constraints used to determine whether a permission is
> allowed are entirely up to the policy author. A level in SELinux is a
> combination of a hierarchical sensitivity and a non-hierarchical
> (potentially empty) category set. In practice MCS is used for simple
> isolation and therefore doesn't employ sensitivities since there is no
> hierarchical relationship to be enforced.
>
>

Compartments might not be hierarcical in the sense of dominance but if
there was no hierarchy then I would argue the there would not be a need
for categoryorder.
Stephen Smalley Aug. 7, 2020, 4:39 p.m. UTC | #4
On Fri, Aug 7, 2020 at 12:04 PM Dominick Grift
<dominick.grift@defensec.nl> wrote:
>
> Stephen Smalley <stephen.smalley.work@gmail.com> writes:
>
> > On 8/7/20 10:40 AM, Richard Haines wrote:
> >
> >> This is an RFC patch to get some feedback as:
> >> 1) Table 1 is now a pipe table, however it still has <br> codes to
> >>     break up the text. Also updated styles.html.css to match the pdf version
> >>     to allow correct HTML rendering.
> >> 2) Table 2 is now a pipe table with updated text.
> >>
> >> Add a TOC to aid navigation
> >> Add text to clarify MCS/MLS
> >>
> >> Signed-off-by: Richard Haines <richard_c_haines@btinternet.com>
> >> ---
> >>
> >> @@ -48,6 +56,18 @@ The sections that follow discuss the format of a security level and
> >>   range, and how these are managed by the constraints mechanism within
> >>   SELinux using dominance rules.
> >>   +### MLS or MCS Policy
> >> +
> >> +From an SELinux perspective:
> >> +
> >> +-   An MLS policy has more than one security level with zero or more categories.
> >> +    It is generally used in systems that require the 'Read Down' and 'Write Up'
> >> +    services, whether it be for files, network services etc..
> >> +-   An MCS policy has a single security level with zero or more categories.
> >> +    Example uses are virtualization (see the
> >> +    [**Virtual Machine Support**](vm_support.md#selinux-virtual-machine-support)
> >> +    section) and container security.
> >> +
> >
> > To be clear, SELinux (i.e. the code/mechanism) only knows of MLS,
> > i.e. it has a MLS engine in the security server and a MLS portion of
> > the policy configuration that drives that engine.  That MLS engine has
> > been leveraged by two different types of policies, the original MLS
> > configuration modeled after Bell-LaPadula and the later-introduced MCS
> > configuration (which underwent a fundamental transformation from being
> > user-facing and somewhat discretionary to being a transparent
> > isolation mechanism for sandbox, container, and virtualization
> > runtimes). The number of sensitivities, number of categories, and the
> > set of MLS constraints used to determine whether a permission is
> > allowed are entirely up to the policy author. A level in SELinux is a
> > combination of a hierarchical sensitivity and a non-hierarchical
> > (potentially empty) category set. In practice MCS is used for simple
> > isolation and therefore doesn't employ sensitivities since there is no
> > hierarchical relationship to be enforced.
> >
> >
>
> Compartments might not be hierarcical in the sense of dominance but if
> there was no hierarchy then I would argue the there would not be a need
> for categoryorder.

In the policy.conf language, there is a dominance statement that
specifies the hierarchical ordering of sensitivities.  There is no
equivalent for categories, and the kernel never compares category
pairs for any kind of >, =, or < relationship; it only compares subset
comparisons between two category sets.  So there is no hierarchy.  If
CIL defines a categoryorder, then that's unnecessary.
James Carter Aug. 7, 2020, 4:42 p.m. UTC | #5
On Fri, Aug 7, 2020 at 12:39 PM Stephen Smalley
<stephen.smalley.work@gmail.com> wrote:
>
> On Fri, Aug 7, 2020 at 12:04 PM Dominick Grift
> <dominick.grift@defensec.nl> wrote:
> >
> > Stephen Smalley <stephen.smalley.work@gmail.com> writes:
> >
> > > On 8/7/20 10:40 AM, Richard Haines wrote:
> > >
> > >> This is an RFC patch to get some feedback as:
> > >> 1) Table 1 is now a pipe table, however it still has <br> codes to
> > >>     break up the text. Also updated styles.html.css to match the pdf version
> > >>     to allow correct HTML rendering.
> > >> 2) Table 2 is now a pipe table with updated text.
> > >>
> > >> Add a TOC to aid navigation
> > >> Add text to clarify MCS/MLS
> > >>
> > >> Signed-off-by: Richard Haines <richard_c_haines@btinternet.com>
> > >> ---
> > >>
> > >> @@ -48,6 +56,18 @@ The sections that follow discuss the format of a security level and
> > >>   range, and how these are managed by the constraints mechanism within
> > >>   SELinux using dominance rules.
> > >>   +### MLS or MCS Policy
> > >> +
> > >> +From an SELinux perspective:
> > >> +
> > >> +-   An MLS policy has more than one security level with zero or more categories.
> > >> +    It is generally used in systems that require the 'Read Down' and 'Write Up'
> > >> +    services, whether it be for files, network services etc..
> > >> +-   An MCS policy has a single security level with zero or more categories.
> > >> +    Example uses are virtualization (see the
> > >> +    [**Virtual Machine Support**](vm_support.md#selinux-virtual-machine-support)
> > >> +    section) and container security.
> > >> +
> > >
> > > To be clear, SELinux (i.e. the code/mechanism) only knows of MLS,
> > > i.e. it has a MLS engine in the security server and a MLS portion of
> > > the policy configuration that drives that engine.  That MLS engine has
> > > been leveraged by two different types of policies, the original MLS
> > > configuration modeled after Bell-LaPadula and the later-introduced MCS
> > > configuration (which underwent a fundamental transformation from being
> > > user-facing and somewhat discretionary to being a transparent
> > > isolation mechanism for sandbox, container, and virtualization
> > > runtimes). The number of sensitivities, number of categories, and the
> > > set of MLS constraints used to determine whether a permission is
> > > allowed are entirely up to the policy author. A level in SELinux is a
> > > combination of a hierarchical sensitivity and a non-hierarchical
> > > (potentially empty) category set. In practice MCS is used for simple
> > > isolation and therefore doesn't employ sensitivities since there is no
> > > hierarchical relationship to be enforced.
> > >
> > >
> >
> > Compartments might not be hierarcical in the sense of dominance but if
> > there was no hierarchy then I would argue the there would not be a need
> > for categoryorder.
>
> In the policy.conf language, there is a dominance statement that
> specifies the hierarchical ordering of sensitivities.  There is no
> equivalent for categories, and the kernel never compares category
> pairs for any kind of >, =, or < relationship; it only compares subset
> comparisons between two category sets.  So there is no hierarchy.  If
> CIL defines a categoryorder, then that's unnecessary.

CIL has a category order statement only so that it can handle category
ranges. It is not a hierarchy.

Jim
Stephen Smalley Aug. 7, 2020, 4:43 p.m. UTC | #6
On Fri, Aug 7, 2020 at 12:39 PM Stephen Smalley
<stephen.smalley.work@gmail.com> wrote:
>
> On Fri, Aug 7, 2020 at 12:04 PM Dominick Grift
> <dominick.grift@defensec.nl> wrote:
> >
> > Stephen Smalley <stephen.smalley.work@gmail.com> writes:
> >
> > > On 8/7/20 10:40 AM, Richard Haines wrote:
> > >
> > >> This is an RFC patch to get some feedback as:
> > >> 1) Table 1 is now a pipe table, however it still has <br> codes to
> > >>     break up the text. Also updated styles.html.css to match the pdf version
> > >>     to allow correct HTML rendering.
> > >> 2) Table 2 is now a pipe table with updated text.
> > >>
> > >> Add a TOC to aid navigation
> > >> Add text to clarify MCS/MLS
> > >>
> > >> Signed-off-by: Richard Haines <richard_c_haines@btinternet.com>
> > >> ---
> > >>
> > >> @@ -48,6 +56,18 @@ The sections that follow discuss the format of a security level and
> > >>   range, and how these are managed by the constraints mechanism within
> > >>   SELinux using dominance rules.
> > >>   +### MLS or MCS Policy
> > >> +
> > >> +From an SELinux perspective:
> > >> +
> > >> +-   An MLS policy has more than one security level with zero or more categories.
> > >> +    It is generally used in systems that require the 'Read Down' and 'Write Up'
> > >> +    services, whether it be for files, network services etc..
> > >> +-   An MCS policy has a single security level with zero or more categories.
> > >> +    Example uses are virtualization (see the
> > >> +    [**Virtual Machine Support**](vm_support.md#selinux-virtual-machine-support)
> > >> +    section) and container security.
> > >> +
> > >
> > > To be clear, SELinux (i.e. the code/mechanism) only knows of MLS,
> > > i.e. it has a MLS engine in the security server and a MLS portion of
> > > the policy configuration that drives that engine.  That MLS engine has
> > > been leveraged by two different types of policies, the original MLS
> > > configuration modeled after Bell-LaPadula and the later-introduced MCS
> > > configuration (which underwent a fundamental transformation from being
> > > user-facing and somewhat discretionary to being a transparent
> > > isolation mechanism for sandbox, container, and virtualization
> > > runtimes). The number of sensitivities, number of categories, and the
> > > set of MLS constraints used to determine whether a permission is
> > > allowed are entirely up to the policy author. A level in SELinux is a
> > > combination of a hierarchical sensitivity and a non-hierarchical
> > > (potentially empty) category set. In practice MCS is used for simple
> > > isolation and therefore doesn't employ sensitivities since there is no
> > > hierarchical relationship to be enforced.
> > >
> > >
> >
> > Compartments might not be hierarcical in the sense of dominance but if
> > there was no hierarchy then I would argue the there would not be a need
> > for categoryorder.
>
> In the policy.conf language, there is a dominance statement that
> specifies the hierarchical ordering of sensitivities.  There is no
> equivalent for categories, and the kernel never compares category
> pairs for any kind of >, =, or < relationship; it only compares subset
> comparisons between two category sets.  So there is no hierarchy.  If
> CIL defines a categoryorder, then that's unnecessary.

Oh, I see; it is to allow validation of e.g. cN.cM notation.
So that's a comparison within a context, not between two different contexts.
diff mbox series

Patch

diff --git a/src/mls_mcs.md b/src/mls_mcs.md
index 4b4c15c..deb8c64 100644
--- a/src/mls_mcs.md
+++ b/src/mls_mcs.md
@@ -1,5 +1,13 @@ 
 # Multi-Level and Multi-Category Security
 
+-   [Security Levels](#security-levels)
+    -   [MLS or MCS Policy](#mls-or-mcs-policy)
+    -   [MLS / MCS Range Format](#mls-mcs-range-format)
+    -   [Translating Levels](#translating-levels)
+    -   [Managing Security Levels via Dominance Rules](#managing-security-levels-via-dominance-rules)
+-   [MLS Labeled Network and Database Support](#mls-labeled-network-and-database-support)
+-   [Common Criteria Certification](#common-criteria-certification)
+
 As stated in the
 [**Mandatory Access Control (MAC)**](mac.md#mandatory-access-control)
 section as well as supporting Type Enforcement (TE), SELinux also supports
@@ -48,6 +56,18 @@  The sections that follow discuss the format of a security level and
 range, and how these are managed by the constraints mechanism within
 SELinux using dominance rules.
 
+### MLS or MCS Policy
+
+From an SELinux perspective:
+
+-   An MLS policy has more than one security level with zero or more categories.
+    It is generally used in systems that require the 'Read Down' and 'Write Up'
+    services, whether it be for files, network services etc..
+-   An MCS policy has a single security level with zero or more categories.
+    Example uses are virtualization (see the
+    [**Virtual Machine Support**](vm_support.md#selinux-virtual-machine-support)
+    section) and container security.
+
 ## Security Levels
 
 **Table 1: Level, Label, Category or Compartment** shows the components that
@@ -59,50 +79,16 @@  within an MLS / MCS environment.
 The table also adds terminology in general use as other terms can be
 used that have the same meanings.
 
-<table>
-<tbody>
-<tr>
-<td><center><p><strong>Security Level (or Level)</strong></p></center>
-<p><center>Consisting of a sensitivity and zero or more category entries:</center></p></td>
-<td colspan="2"; rowspan="2";><center>Note that SELinux uses <code>level</code>, <code>sensitivity</code> and <code>category</code><br>in the language statements (see the <a href="mls_statements.md#mls-statements"> MLS Language Statements</a> section),<br>however when discussing these the following terms can also be used:<br> labels, classifications, and compartments.</center></td>
-</tr>
-<tr>
-<td><center><p><code>sensitivity [: category, ... ]</code><br>also known as:</p>
-<p><strong>Sensitivity Label</strong></p>
-<p>Consisting of a classification and compartment.</p></center></td>
-</tr>
-<tr>
-<td colspan="3"><center><strong>&lt;-------------- Range --------------&gt;</strong></center></td>
-</tr>
-<tr>
-<td><center><strong>Low</strong></center></td>
-<td rowspan="6"><center><strong>-</strong></center></td>
-<td><center><strong>High</strong></center></td>
-</tr>
-<tr>
-<td><center><code>sensitivity [: category, ... ]</code></center></td>
-<td><center><code>sensitivity [: category, ... ]</code></center></td>
-</tr>
-<tr>
-<td><center>For a process or subject this is the current level or sensitivity</center></td>
-<td><center>For a process or subject this is the Clearance</center></td>
-</tr>
-<tr>
-<td><center>For an object this is the current level or sensitivity</center></td>
-<td><center>For an object this is the maximum range</center></td>
-</tr>
-<tr>
-<td><center><strong>SystemLow</strong></center></td>
-
-<td><center><strong>SystemHigh</strong></center></td>
-</tr>
-<tr>
-<td><center>This is the lowest level or classification for the system<br>(for SELinux this is generally 's0', note that there are no categories).</center></td>
-
-<td><center>This is the highest level or classification for the system<br>(for SELinux this is generally 's15:c0,c255',<br>although note that they will be the highest set by the policy).</center></td>
-</tr>
-</tbody>
-</table>
+|                                 |                                 |
+| :-----------------------------: | :-----------------------------: |
+| **Security Level (or Level)**<br>Consisting of a sensitivity and zero or more category entries: *sensitivity [: category, ... ]* also known as **Sensitivity Label** consisting of a classification and compartment. | Note that SELinux uses *level*, *sensitivity* and *category* in the language statements (see the [**MLS Language Statements**](mls_statements.md#mls-statements) section), however when discussing these the following terms can also be used: labels, classifications, and compartments. |
+
+| <---------------------------- Range ----------------------------> |
+| :---------------------------------------------------------------: |
+
+|                                 |                                 |
+| :-----------------------------: | :-----------------------------: |
+| **Low**<br>*sensitivity [: category, ... ]* For a process or subject this is the current level or sensitivity. For an object this is the current level or sensitivity.<br>**SystemLow**<br>This is the lowest level or classification for the system (for SELinux this is generally 's0', note that there are no categories). | **High**<br>*sensitivity [: category, ... ]* For a process or subject this is the Clearance. For an object this is the maximum range.<br>**SystemHigh**<br>This is the highest level or classification for the system (for SELinux this is generally 's15:c0,c255', although note that they will be the highest set by policy). |
 
 **Table 1: Level, Label, Category or Compartment** - *this table shows the meanings depending on the context
 being discussed.*
@@ -111,7 +97,7 @@  The format used in the policy language statements is fully described in
 the [MLS Statements](mls_statements.md#mls-statements) section, however
 a brief overview follows.
 
-#### MLS / MCS Range Format
+### MLS / MCS Range Format
 
 The following components (shown in bold) are used to define the MLS /
 MCS security levels within the security context:
@@ -125,26 +111,34 @@  user:role:type:sensitivity[:category,...]  -  sensitivity [:category,...]
 
 **Where:**
 
-<table>
-<tbody>
-<tr>
-<td>sensitivity</td>
-<td><p>Sensitivity levels are hierarchical with (traditionally) <code>s0</code> being the lowest. These values are defined using the <em><em>sensitivity</em></em> statement. To define their hierarchy, the <em>dominance</em> statement is used.</p>
-<p>For MLS systems the highest sensitivity is the last one defined in the dominance statement (low to high). Traditionally the maximum for MLS systems is <code>s15</code> (although the maximum value for the <em><em>Reference Policy</em></em> is a build time option). </p>
-<p>For MCS systems there is only one sensitivity defined, and that is <code>s0</code>.</p></td>
-</tr>
-<tr>
-<td>category</td>
-<td>Categories are optional (i.e. there can be zero or more categories) and they form unordered and unrelated lists of 'compartments'. These values are defined using the <code>category</code> statement, where for example <code>c0.c3</code> represents a <code>range (c0 c1 c3)</code> and <code>c0, c3, c7</code> represent an unordered list. Traditionally the values are between <code>c0</code> and <code>c255</code> (although the maximum value for the Reference Policy is a build time option).</td>
-</tr>
-<tr>
-<td>level</td>
-<td>The level is a combination of the <code>sensitivity</code> and <code>category</code> values that form the actual security level. These values are defined using the <code>level</code> statement.</td>
-</tr>
-</tbody>
-</table>
-
-#### Translating Levels
+*sensitivity*
+
+-   Sensitivity levels are hierarchical with (traditionally) *s0* being the
+    lowest. These values are defined using the *sensitivity* statement.
+    To define their hierarchy, the *dominance* statement is used.
+-   For MLS systems the highest sensitivity is the last one defined in the
+    dominance statement (low to high). Traditionally the maximum for MLS systems
+    is *s15* (although the maximum value for the *Reference Policy* is a build
+    time option).
+-   For MCS systems there is only one sensitivity defined, and that is *s0*.
+
+*category*
+
+-   Categories are optional (i.e. there can be zero or more categories) and they
+    form unordered and unrelated lists of 'compartments'. These values are
+    defined using the *category* statement, where for example *c0.c3*
+    represents the range that consists of *c0 c1 c2 c3* and *c0, c3, c7* that
+    represents an unordered list. Traditionally the values are between*c0* and
+    *c255* (although the maximum value for the Reference Policy is a build time
+    option).
+
+*level*
+
+-   The level is a combination of the *sensitivity* and *category* values that
+    form the actual security level. These values are defined using the *level*
+    statement.
+
+### Translating Levels
 
 When writing policy for MLS / MCS security level components it is usual
 to use an abbreviated form such as *s0*, *s1* etc. to represent
@@ -199,112 +193,48 @@  and within the dominance rules, the process will be constrained by using
 the *mlsconstrain* statement as illustrated in
 **Figure 9: *mlsconstrain* Statements controlling Read Down & Write Up**.
 
-<table>
-<tbody>
-<tr>
-<td></td>
-<td><center><strong>Category -&gt;</strong></center></td>
-<td>c0</td>
-<td>c1</td>
-<td>c2</td>
-<td>c3</td>
-<td>c4</td>
-<td>c5</td>
-<td>c6</td>
-<td>c7</td>
-</tr>
-<tr>
-<td>s3</td>
-<td>Secret</td>
-<td>s3:c0</td>
-<td style="background-color:#D3D3D3;"></td>
-<td style="background-color:#D3D3D3;"></td>
-<td style="background-color:#D3D3D3;"></td>
-<td style="background-color:#D3D3D3;"></td>
-<td style="background-color:#D3D3D3;">s3:c5</td>
-<td>s3:c6</td>
-<td></td>
-</tr>
-<tr>
-<td>s2</td>
-<td>Confidential</td>
-<td></td>
-<td style="background-color:#D3D3D3;">s2:c1</td>
-<td style="background-color:#D3D3D3;">s2:c2</td>
-<td style="background-color:#D3D3D3;">s2:c3</td>
-<td style="background-color:#D3D3D3;">s2:c4</td>
-<td style="background-color:#D3D3D3;"></td>
-<td></td>
-<td>s2:c7</td>
-</tr>
-<tr>
-<td>s1</td>
-<td>Restricted</td>
-<td>s1:c0</td>
-<td style="background-color:#D3D3D3;">s1:c1</td>
-<td style="background-color:#D3D3D3;"></td>
-<td style="background-color:#D3D3D3;"></td>
-<td style="background-color:#D3D3D3;"></td>
-<td style="background-color:#D3D3D3;"></td>
-<td></td>
-<td>s1:c7</td>
-</tr>
-<tr>
-<td>s0</td>
-<td>Unclassified</td>
-<td>s0:c0</td>
-<td style="background-color:#D3D3D3;"></td>
-<td style="background-color:#D3D3D3;"></td>
-<td style="background-color:#D3D3D3;">s0:c3</td>
-<td style="background-color:#D3D3D3;"></td>
-<td style="background-color:#D3D3D3;"></td>
-<td></td>
-<td>s0:c7</td>
-</tr>
-<tr>
-<td><p><center><strong>^<br><br>Sensitivity</strong></center></p>
-</td>
-<td><p><center><strong>^<br>Security Level</strong></p>
-<p>(sensitivity:category)<br>aka: classification</center></p>
-</td>
-<td colspan="8"><p><center><strong>^-------- File Labels --------^</strong></center></p>
-<p><center>A process running with a range of <code>s0 - s3:c1.c5</code> has access to the files within the grey boxed area.</center></p></td>
-</tr>
-</tbody>
-</table>
-
-**Table 2: MLS Security Levels** - *Showing the scope of a process running
-at a security range of *s0 - s3:c1.c5*.*
+|Security Level| Sensitivity    |       |           |           |           |           |           |       |     |
+| :----------- | :------------: | :---: | :-------: | :-------: | :-------: | :-------: | :-------: | :---: | :-: |
+|              |**Category -\>**| *c0*  |    *c1*   |    *c2*   |    *c3*   |    *c4*   |    *c5*   | *c6*  |*c7* |
+| Secret       |*s3*            |*s3:c0*|           |           |           |           |***s3:c5***|*s3:c6*|     |
+| Confidential |*s2*            |       |***s2:c1***|***s2:c2***|***s2:c3***|***s2:c4***|           |       |s2:c7|
+| Restricted   |*s1*            |*s1:c0*|***s1:c1***|           |           |           |           |       |s1:c7|
+| Unclassified |*s0*            |*s0:c0*|           |           |***s0:c3***|           |           |       |s0:c7|
+
+**Table 2: MLS Security Levels** - *Showing that a process running at
+s0 - s3:c1.c5 has access to the highlighted **sensitivity:category** files*.
 
 ![](./images/9-mls-constrain.png)
 
-**Figure 9: Showing the mlsconstrain Statements controlling Read Down & Write Up** - *This ties in with* **Table 2: MLS Security Levels** *that shows a process running with a security range of s0 - s3:c1.c5.*
+**Figure 9: Showing mlsconstrain Statements controlling Read Down & Write Up** -
+*This ties in with* **Table 2: MLS Security Levels** *that shows a process
+running with a security range of s0 - s3:c1.c5.*
 
 Using **Figure 9: *mlsconstrain* Statements controlling Read Down & Write Up**:
 
-1.  To allow write-up, the source level (l1) must be **dominated by**
-    the target level (l2):
--   Source level = s0:c3 or s1:c1
--   Target level = s2:c1.c4
+-   To allow write-up, the source level (*l1*) must be **dominated by**
+    the target level (*l2*):
+    -  Source level = *s0:c3* or *s1:c1*
+    -  Target level = *s2:c1.c4*
 
 As can be seen, either of the source levels are **dominated by** the
 target level.
 
-2.  To allow read-down, the source level (l1) must **dominate** the
-    target level (l2):
--   Source level = s2:c1.c4
--   Target level = s0:c3
+-   To allow read-down, the source level (*l1*) must **dominate** the
+    target level (*l2*):
+    -  Source level = *s2:c1.c4*
+    -  Target level = *s0:c3*
 
 As can be seen, the source level does **dominate** the target level.
 
 However in the real world the SELinux MLS Reference Policy does not
 allow the write-up unless the process has a special privilege (by having
 the domain type added to an attribute), although it does allow the
-read-down. The default is to use l1 eq l2 (i.e. the levels are equal).
+read-down. The default is to use *l1 eq l2* (i.e. the levels are equal).
 The reference policy MLS source file (policy/mls) shows these
 *mlsconstrain* statements.
 
-### MLS Labeled Network and Database Support
+## MLS Labeled Network and Database Support
 
 Networking for MLS is supported via the NetLabel CIPSO (commercial IP
 security option) and CALIPSO (Common Architecture Label
@@ -316,7 +246,7 @@  PostgreSQL supports labeling for MLS database services as discussed in
 the [**SE-PostgreSQL Support**](postgresql.md#postgresql-selinux-support)
 section.
 
-### Common Criteria Certification
+## Common Criteria Certification
 
 While the [*Common Criteria*](http://www.commoncriteriaportal.org/)
 certification process is beyond the scope of this Notebook, it is worth
diff --git a/src/styles_html.css b/src/styles_html.css
index fef851e..a5fa457 100644
--- a/src/styles_html.css
+++ b/src/styles_html.css
@@ -15,8 +15,9 @@  a {
 
 table {
 	/* limit to 95% page width */
-	min-width: 50%;
-	max-width: 95%;
+	margin-left: auto;
+	margin-right: auto;
+	width: 95%;
 	/* combine table borders when they are adjacent */
 	border-collapse: collapse;
 }