diff mbox series

[SELinux-notebook,v8] objects.md: some clarifications

Message ID 20200721200230.1976501-1-dominick.grift@defensec.nl (mailing list archive)
State Superseded
Headers show
Series [SELinux-notebook,v8] objects.md: some clarifications | expand

Commit Message

Dominick Grift July 21, 2020, 8:02 p.m. UTC
Elaborate on labeling. Touch on the significance of the default statement, on various av permissions related to labeling using the libselinux API, and on how the kernel and unlabeled initial security identifiers are used to address labeling challenges in special cases such as initialization and failover respectively.

Signed-off-by: Dominick Grift <dominick.grift@defensec.nl>
---

v2: fixes patch description
v3: adding patch description, s/policies/policy's/, split unlabeled and kernel descriptions for clarity
v4: fixes another typo in description and emphasize system initialization a bit
v5: emphasize kernel threads with kernel isid description
v6: forgot to mention defaultuser, can only associate one label with isids
v7: copied and pasted feedback from Stephen Smalley
v8: missed a s/access vectors/permissions/ instance

 src/objects.md | 47 +++++++++++++++++++++++++++++++++++++++++++----
 1 file changed, 43 insertions(+), 4 deletions(-)

Comments

Dominick Grift July 21, 2020, 8:14 p.m. UTC | #1
Dominick Grift <dominick.grift@defensec.nl> writes:

> Elaborate on labeling. Touch on the significance of the default statement, on various av permissions related to labeling using the libselinux API, and on how the kernel and unlabeled initial security identifiers are used to address labeling challenges in special cases such as initialization and failover respectively.
>
> Signed-off-by: Dominick Grift <dominick.grift@defensec.nl>
> ---
>
> v2: fixes patch description
> v3: adding patch description, s/policies/policy's/, split unlabeled and kernel descriptions for clarity
> v4: fixes another typo in description and emphasize system initialization a bit
> v5: emphasize kernel threads with kernel isid description
> v6: forgot to mention defaultuser, can only associate one label with isids
> v7: copied and pasted feedback from Stephen Smalley
> v8: missed a s/access vectors/permissions/ instance
>
>  src/objects.md | 47 +++++++++++++++++++++++++++++++++++++++++++----
>  1 file changed, 43 insertions(+), 4 deletions(-)
>
> diff --git a/src/objects.md b/src/objects.md
> index 58664ef..1907316 100644
> --- a/src/objects.md
> +++ b/src/objects.md
> @@ -110,14 +110,20 @@ objects is managed by the system and generally unseen by the users
>  (until labeling goes wrong !!). As processes and objects are created and
>  destroyed, they either:
>  
> -1.  Inherit their labels from the parent process or object.
> +1.  Inherit their labels from the parent process or object. The policy
> +    default user, type, role and range statements can be used to
> +	change the behavior as discussed in the [**Default Rules**](default_rules.md#default-object-rules)
> +    section.
>  2.  The policy type, role and range transition statements allow a
>      different label to be assigned as discussed in the
>      [**Domain and Object Transitions**](domain_object_transitions.md#domain-and-object-transitions)
>      section.
> -3.  SELinux-aware applications can enforce a new label (with the
> -    policies approval of course) using the **libselinux** API
> -    functions.
> +3.  SELinux-aware applications can assign a new label (with the
> +    policy's approval of course) using the **libselinux** API
> +    functions. The `process setfscreate` permission can be used to
> +    allow subjects to create files with a new label programmatically
> +    using the ***setfscreatecon**(3)* function, overriding default
> +    rules and transition statements.
>  4.  An object manager (OM) can enforce a default label that can either
>      be built into the OM or obtained via a configuration file (such as
>      those used by
> @@ -269,6 +275,39 @@ and manage their transition:
>  
>  `type_transition`, `role_transition` and `range_transition`
>  
> +SELinux-aware applications can assign a new label (with the policy's
> +approval of course) using the **libselinux** API functions. The
> +`process setexec`, `process setkeycreate` and `process setsockcreate`
> +permissions can be used to allow subjects to label processes,
> +kernel keyrings, and sockets programmatically using the
> +***setexec**(3)*, ***setkeycreatecon**(3)* and
> +***setsockcreatecon**(3)* functions respectively, overriding
> +transition statements.
> +
> +The `kernel` **initial security identifier** is used to associate
> +a specified label with kernel objects, including kernel threads
> +(both those that are created during initialization but also kernel
> +threads created later), kernel-private sockets, synthetic objects
> +representing kernel resources (e.g. the "system" class).
> +
> +It is true that processes created prior to initial policy load will
> +also be in the kernel SID until/unless there is a policy loaded and
> +either a policy-defined transition or an explicit setcon or
> +setexeccon+execve, but that's just the typical default inheritance
> +from creating task behavior for processes.
> +
> +The `unlabeled` **initial security identifier** is used
> +to associate a specified label with subjects that had their label
> +invalidated due to policy changes at runtime.
> +
> +It is also assigned as the initial state for various objects e.g.
> +inodes, superblocks, etc until they reach a point where a more
> +specific label can be determined e.g. from an xattr or from policy.
> +The context associated with the unlabeled SID is used as the fallback
> +context for both subjects and objects when their label is invalidated
> +by a policy reload (their SID is unchanged but the SID is
> +transparently remapped to the unlabeled context).

I will note here that I suspect there is currently something broken
with libselinux / unlabeled sids

libselinux consumers still use *invalidated* contexts associated with
inodes to compute access vectors.

for example rpm will not consistently work until the filesystems are
relabeled after a new policy is loaded that invalidates contexts
currently associated with /bin/sh (entrypoint for setfscreatecon to
"rpm_script_t")

systemd will not consistently work until the filesystems are relabeled
after a new policy loaded that invalidates contexts currently associated
with (i suspect) parent directories for socket activated sock files
(maybe setfscreatecon?)

> +
>  ### Object Reuse
>  
>  As GNU / Linux runs it creates instances of objects and manages the
Stephen Smalley July 22, 2020, 3:11 p.m. UTC | #2
On Tue, Jul 21, 2020 at 4:03 PM Dominick Grift
<dominick.grift@defensec.nl> wrote:
>
> Elaborate on labeling. Touch on the significance of the default statement, on various av permissions related to labeling using the libselinux API, and on how the kernel and unlabeled initial security identifiers are used to address labeling challenges in special cases such as initialization and failover respectively.
>
> Signed-off-by: Dominick Grift <dominick.grift@defensec.nl>
> ---

> diff --git a/src/objects.md b/src/objects.md
> index 58664ef..1907316 100644
> --- a/src/objects.md
> +++ b/src/objects.md
> @@ -269,6 +275,39 @@ and manage their transition:
> +The `kernel` **initial security identifier** is used to associate
> +a specified label with kernel objects, including kernel threads
> +(both those that are created during initialization but also kernel
> +threads created later), kernel-private sockets, synthetic objects

      ^^and^^

> +representing kernel resources (e.g. the "system" class).
> +
> +It is true that processes created prior to initial policy load will
> +also be in the kernel SID until/unless there is a policy loaded and
> +either a policy-defined transition or an explicit setcon or
> +setexeccon+execve, but that's just the typical default inheritance
> +from creating task behavior for processes.
> +
> +The `unlabeled` **initial security identifier** is used
> +to associate a specified label with subjects that had their label
> +invalidated due to policy changes at runtime.
> +
> +It is also assigned as the initial state for various objects e.g.
> +inodes, superblocks, etc until they reach a point where a more
> +specific label can be determined e.g. from an xattr or from policy.
> +The context associated with the unlabeled SID is used as the fallback
> +context for both subjects and objects when their label is invalidated
> +by a policy reload (their SID is unchanged but the SID is
> +transparently remapped to the unlabeled context).

There is some redundancy between the last sentence of the last
paragraph above and the preceding paragraph; the last sentence notes
that it is used for both subject and objects (not just subjects as in
the preceding paragraph) and that it is technically the context
associated with the unlabeled SID that is used for invalidated SIDs,
not the SID itself.  The unlabeled SID itself is used as per the 1st
sentence of the last paragraph above.
Stephen Smalley July 22, 2020, 4:48 p.m. UTC | #3
On Tue, Jul 21, 2020 at 4:14 PM Dominick Grift
<dominick.grift@defensec.nl> wrote:
> > +context for both subjects and objects when their label is invalidated
> > +by a policy reload (their SID is unchanged but the SID is
> > +transparently remapped to the unlabeled context).
>
> I will note here that I suspect there is currently something broken
> with libselinux / unlabeled sids
>
> libselinux consumers still use *invalidated* contexts associated with
> inodes to compute access vectors.
>
> for example rpm will not consistently work until the filesystems are
> relabeled after a new policy is loaded that invalidates contexts
> currently associated with /bin/sh (entrypoint for setfscreatecon to
> "rpm_script_t")
>
> systemd will not consistently work until the filesystems are relabeled
> after a new policy loaded that invalidates contexts currently associated
> with (i suspect) parent directories for socket activated sock files
> (maybe setfscreatecon?)

That's because userspace doesn't pass SIDs to the kernel (they aren't
exported by the kernel); it passes security contexts, and the kernel
refuses to accept invalid contexts. So a context previously used by
userspace that is invalidated by a policy reload and then later passed
in again to a kernel interface will produce an error.  IIRC, the
security_get_initial_context() and avc_get_initial_sid() interfaces
were added to allow userspace object managers like SEPostgreSQL to get
the context associated with an initial SID like the unlabeled SID for
their own internal use/handling, but libselinux doesn't try to remap
like that internally and it wouldn't always know whether the context
was previously valid unless it maintained state on all calls.
Dominick Grift July 22, 2020, 4:57 p.m. UTC | #4
On 7/22/20 6:48 PM, Stephen Smalley wrote:
> On Tue, Jul 21, 2020 at 4:14 PM Dominick Grift
> <dominick.grift@defensec.nl> wrote:
>>> +context for both subjects and objects when their label is invalidated
>>> +by a policy reload (their SID is unchanged but the SID is
>>> +transparently remapped to the unlabeled context).
>>
>> I will note here that I suspect there is currently something broken
>> with libselinux / unlabeled sids
>>
>> libselinux consumers still use *invalidated* contexts associated with
>> inodes to compute access vectors.
>>
>> for example rpm will not consistently work until the filesystems are
>> relabeled after a new policy is loaded that invalidates contexts
>> currently associated with /bin/sh (entrypoint for setfscreatecon to
>> "rpm_script_t")
>>
>> systemd will not consistently work until the filesystems are relabeled
>> after a new policy loaded that invalidates contexts currently associated
>> with (i suspect) parent directories for socket activated sock files
>> (maybe setfscreatecon?)
> 
> That's because userspace doesn't pass SIDs to the kernel (they aren't
> exported by the kernel); it passes security contexts, and the kernel
> refuses to accept invalid contexts. So a context previously used by
> userspace that is invalidated by a policy reload and then later passed
> in again to a kernel interface will produce an error.  IIRC, the

Can we not just assume that if that happens, that the kernel should just
treat the context as if it were the context of the unlabeled isid.

I mean that is what it boils down to anyway: everything always needs a
valid context. so might as well treat invalid contexts as unlabeled
isids? Not sure how "state" is relevant here as invalid is invalid.

Regardless, this current behavior makes things less robust. I wont
pretent that I am qualified to judge whether addressing this is
technically possible or not.

> security_get_initial_context() and avc_get_initial_sid() interfaces
> were added to allow userspace object managers like SEPostgreSQL to get
> the context associated with an initial SID like the unlabeled SID for
> their own internal use/handling, but libselinux doesn't try to remap
> like that internally and it wouldn't always know whether the context
> was previously valid unless it maintained state on all calls.
>
Dominick Grift July 22, 2020, 5:29 p.m. UTC | #5
On 7/22/20 6:48 PM, Stephen Smalley wrote:
> On Tue, Jul 21, 2020 at 4:14 PM Dominick Grift
> <dominick.grift@defensec.nl> wrote:
>>> +context for both subjects and objects when their label is invalidated
>>> +by a policy reload (their SID is unchanged but the SID is
>>> +transparently remapped to the unlabeled context).
>>
>> I will note here that I suspect there is currently something broken
>> with libselinux / unlabeled sids
>>
>> libselinux consumers still use *invalidated* contexts associated with
>> inodes to compute access vectors.
>>
>> for example rpm will not consistently work until the filesystems are
>> relabeled after a new policy is loaded that invalidates contexts
>> currently associated with /bin/sh (entrypoint for setfscreatecon to
>> "rpm_script_t")
>>
>> systemd will not consistently work until the filesystems are relabeled
>> after a new policy loaded that invalidates contexts currently associated
>> with (i suspect) parent directories for socket activated sock files
>> (maybe setfscreatecon?)
> 
> That's because userspace doesn't pass SIDs to the kernel (they aren't
> exported by the kernel); it passes security contexts, and the kernel
> refuses to accept invalid contexts. So a context previously used by
> userspace that is invalidated by a policy reload and then later passed
> in again to a kernel interface will produce an error.  IIRC, the
> security_get_initial_context() and avc_get_initial_sid() interfaces
> were added to allow userspace object managers like SEPostgreSQL to get
> the context associated with an initial SID like the unlabeled SID for
> their own internal use/handling, but libselinux doesn't try to remap
> like that internally and it wouldn't always know whether the context
> was previously valid unless it maintained state on all calls.
> 

This issue will also, in some cases, cause selinux-autorelabel to fail.


systemd can't compute the contexts for socket activated daemons, and so
these daemons fail to start. device mapper seems to be one of them, and
so partitions might not get mounted in the autorelabel target
effectively that means that autorelabel wont be able to relabel
everything (because its not mounted because device-mapper failed to
start, because systemd was unable to compute.
Stephen Smalley July 22, 2020, 5:32 p.m. UTC | #6
On Wed, Jul 22, 2020 at 12:57 PM Dominick Grift
<dominick.grift@defensec.nl> wrote:
> Can we not just assume that if that happens, that the kernel should just
> treat the context as if it were the context of the unlabeled isid.

No, because then a simple typo or other error in a context provided by
a user or application would end up being handled as the unlabeled
context instead of producing an error return that can be handled by
the application or user.

> I mean that is what it boils down to anyway: everything always needs a
> valid context. so might as well treat invalid contexts as unlabeled
> isids? Not sure how "state" is relevant here as invalid is invalid.

The state is whether the context was previously valid and used by the
application.
Dominick Grift July 23, 2020, 8:13 a.m. UTC | #7
On 7/22/20 7:32 PM, Stephen Smalley wrote:
> On Wed, Jul 22, 2020 at 12:57 PM Dominick Grift
> <dominick.grift@defensec.nl> wrote:
>> Can we not just assume that if that happens, that the kernel should just
>> treat the context as if it were the context of the unlabeled isid.
> 
> No, because then a simple typo or other error in a context provided by
> a user or application would end up being handled as the unlabeled
> context instead of producing an error return that can be handled by
> the application or user.

So are you saying that it is up to the libselinux consumers to deal with
this? what do you suggest they do in these situations?

> 
>> I mean that is what it boils down to anyway: everything always needs a
>> valid context. so might as well treat invalid contexts as unlabeled
>> isids? Not sure how "state" is relevant here as invalid is invalid.
> 
> The state is whether the context was previously valid and used by the
> application.
>
Stephen Smalley July 23, 2020, 12:22 p.m. UTC | #8
On Thu, Jul 23, 2020 at 4:13 AM Dominick Grift
<dominick.grift@defensec.nl> wrote:
>
>
>
> On 7/22/20 7:32 PM, Stephen Smalley wrote:
> > On Wed, Jul 22, 2020 at 12:57 PM Dominick Grift
> > <dominick.grift@defensec.nl> wrote:
> >> Can we not just assume that if that happens, that the kernel should just
> >> treat the context as if it were the context of the unlabeled isid.
> >
> > No, because then a simple typo or other error in a context provided by
> > a user or application would end up being handled as the unlabeled
> > context instead of producing an error return that can be handled by
> > the application or user.
>
> So are you saying that it is up to the libselinux consumers to deal with
> this? what do you suggest they do in these situations?

libselinux cannot handle it in the general case.  If using the
userspace AVC and SIDs obtained via avc_context_to_sid(), then
libselinux could transparently re-map those to the unlabeled context
if they cease to be valid.  Otherwise, it is up to the callers to deal
with and the correct handling is application-specific.  SEPostgreSQL
does this for example:
https://github.com/postgres/postgres/blob/master/contrib/sepgsql/label.c#L460

However, I don't think that would help something like systemd; even if
you re-map the context to the unlabeled context, you aren't going to
get a useful result from security_compute_create() or similar to use
in labeling sockets, processes, files, etc.
Dominick Grift July 23, 2020, 1:04 p.m. UTC | #9
On 7/23/20 2:22 PM, Stephen Smalley wrote:
> On Thu, Jul 23, 2020 at 4:13 AM Dominick Grift
> <dominick.grift@defensec.nl> wrote:
>>
>>
>>
>> On 7/22/20 7:32 PM, Stephen Smalley wrote:
>>> On Wed, Jul 22, 2020 at 12:57 PM Dominick Grift
>>> <dominick.grift@defensec.nl> wrote:
>>>> Can we not just assume that if that happens, that the kernel should just
>>>> treat the context as if it were the context of the unlabeled isid.
>>>
>>> No, because then a simple typo or other error in a context provided by
>>> a user or application would end up being handled as the unlabeled
>>> context instead of producing an error return that can be handled by
>>> the application or user.
>>
>> So are you saying that it is up to the libselinux consumers to deal with
>> this? what do you suggest they do in these situations?
> 
> libselinux cannot handle it in the general case.  If using the
> userspace AVC and SIDs obtained via avc_context_to_sid(), then
> libselinux could transparently re-map those to the unlabeled context
> if they cease to be valid.  Otherwise, it is up to the callers to deal
> with and the correct handling is application-specific.  SEPostgreSQL
> does this for example:
> https://github.com/postgres/postgres/blob/master/contrib/sepgsql/label.c#L460
> 
> However, I don't think that would help something like systemd; even if
> you re-map the context to the unlabeled context, you aren't going to
> get a useful result from security_compute_create() or similar to use
> in labeling sockets, processes, files, etc.>

I suppose systemd probably should not fail "hard" when getfilecon (or
whatever) fails and returns with "invalid argument", and it should then
just not use setfilecon rather than not create the object at all (as it
seems to be doing now)
Stephen Smalley July 23, 2020, 1:24 p.m. UTC | #10
On Thu, Jul 23, 2020 at 9:04 AM Dominick Grift
<dominick.grift@defensec.nl> wrote:
>
>
>
> On 7/23/20 2:22 PM, Stephen Smalley wrote:
> > On Thu, Jul 23, 2020 at 4:13 AM Dominick Grift
> > <dominick.grift@defensec.nl> wrote:
> >>
> >>
> >>
> >> On 7/22/20 7:32 PM, Stephen Smalley wrote:
> >>> On Wed, Jul 22, 2020 at 12:57 PM Dominick Grift
> >>> <dominick.grift@defensec.nl> wrote:
> >>>> Can we not just assume that if that happens, that the kernel should just
> >>>> treat the context as if it were the context of the unlabeled isid.
> >>>
> >>> No, because then a simple typo or other error in a context provided by
> >>> a user or application would end up being handled as the unlabeled
> >>> context instead of producing an error return that can be handled by
> >>> the application or user.
> >>
> >> So are you saying that it is up to the libselinux consumers to deal with
> >> this? what do you suggest they do in these situations?
> >
> > libselinux cannot handle it in the general case.  If using the
> > userspace AVC and SIDs obtained via avc_context_to_sid(), then
> > libselinux could transparently re-map those to the unlabeled context
> > if they cease to be valid.  Otherwise, it is up to the callers to deal
> > with and the correct handling is application-specific.  SEPostgreSQL
> > does this for example:
> > https://github.com/postgres/postgres/blob/master/contrib/sepgsql/label.c#L460
> >
> > However, I don't think that would help something like systemd; even if
> > you re-map the context to the unlabeled context, you aren't going to
> > get a useful result from security_compute_create() or similar to use
> > in labeling sockets, processes, files, etc.>
>
> I suppose systemd probably should not fail "hard" when getfilecon (or
> whatever) fails and returns with "invalid argument", and it should then
> just not use setfilecon rather than not create the object at all (as it
> seems to be doing now)

There is a tension there with fail-closed versus fail-open and the
potential for a security vulnerability to arise if it proceeds.  Would
have to look at the specifics to evaluate how it should be handled.
Of course, in practice, one really shouldn't be removing contexts
while they are still in use (or else use aliases to preserve some
degree of compatibility).
Dominick Grift July 23, 2020, 1:37 p.m. UTC | #11
On 7/23/20 3:24 PM, Stephen Smalley wrote:
> On Thu, Jul 23, 2020 at 9:04 AM Dominick Grift+
> <dominick.grift@defensec.nl> wrote:
>>
>>
>>
>> On 7/23/20 2:22 PM, Stephen Smalley wrote:
>>> On Thu, Jul 23, 2020 at 4:13 AM Dominick Grift
>>> <dominick.grift@defensec.nl> wrote:
>>>>
>>>>
>>>>
>>>> On 7/22/20 7:32 PM, Stephen Smalley wrote:
>>>>> On Wed, Jul 22, 2020 at 12:57 PM Dominick Grift
>>>>> <dominick.grift@defensec.nl> wrote:
>>>>>> Can we not just assume that if that happens, that the kernel should just
>>>>>> treat the context as if it were the context of the unlabeled isid.
>>>>>
>>>>> No, because then a simple typo or other error in a context provided by
>>>>> a user or application would end up being handled as the unlabeled
>>>>> context instead of producing an error return that can be handled by
>>>>> the application or user.
>>>>
>>>> So are you saying that it is up to the libselinux consumers to deal with
>>>> this? what do you suggest they do in these situations?
>>>
>>> libselinux cannot handle it in the general case.  If using the
>>> userspace AVC and SIDs obtained via avc_context_to_sid(), then
>>> libselinux could transparently re-map those to the unlabeled context
>>> if they cease to be valid.  Otherwise, it is up to the callers to deal
>>> with and the correct handling is application-specific.  SEPostgreSQL
>>> does this for example:
>>> https://github.com/postgres/postgres/blob/master/contrib/sepgsql/label.c#L460
>>>
>>> However, I don't think that would help something like systemd; even if
>>> you re-map the context to the unlabeled context, you aren't going to
>>> get a useful result from security_compute_create() or similar to use
>>> in labeling sockets, processes, files, etc.>
>>
>> I suppose systemd probably should not fail "hard" when getfilecon (or
>> whatever) fails and returns with "invalid argument", and it should then
>> just not use setfilecon rather than not create the object at all (as it
>> seems to be doing now)
> 
> There is a tension there with fail-closed versus fail-open and the
> potential for a security vulnerability to arise if it proceeds.  Would
> have to look at the specifics to evaluate how it should be handled.
> Of course, in practice, one really shouldn't be removing contexts
> while they are still in use (or else use aliases to preserve some
> degree of compatibility).
> 

Using aliases is not a practical solution IMHO (although I suppose it
could be useful temporary hack), and effectively "removing contexts
while they are still in use" will alway's be the case in the current
state (even autorelabel will effectively generally run when the
filesystem has invalid labels, because that is the whole purpose of the app)

Maybe we should should rethink that whole autorelabel concept. Do we
really have to re-initialize filesystems in order to enable labeling
support? Should I be able to load a different policy at runtime, then
add a fsuse xattr rule, and be able to relabel at runtime without a
reboot, or without somehow re-initializing the filesystem?
Dominick Grift July 24, 2020, 7:54 a.m. UTC | #12
On 7/23/20 3:24 PM, Stephen Smalley wrote:
> On Thu, Jul 23, 2020 at 9:04 AM Dominick Grift
> <dominick.grift@defensec.nl> wrote:
>>
>>+++
>>
>> On 7/23/20 2:22 PM, Stephen Smalley wrote:
>>> On Thu, Jul 23, 2020 at 4:13 AM Dominick Grift
>>> <dominick.grift@defensec.nl> wrote:
>>>>
>>>>
>>>>
>>>> On 7/22/20 7:32 PM, Stephen Smalley wrote:
>>>>> On Wed, Jul 22, 2020 at 12:57 PM Dominick Grift
>>>>> <dominick.grift@defensec.nl> wrote:
>>>>>> Can we not just assume that if that happens, that the kernel should just
>>>>>> treat the context as if it were the context of the unlabeled isid.
>>>>>
>>>>> No, because then a simple typo or other error in a context provided by
>>>>> a user or application would end up being handled as the unlabeled
>>>>> context instead of producing an error return that can be handled by
>>>>> the application or user.
>>>>
>>>> So are you saying that it is up to the libselinux consumers to deal with
>>>> this? what do you suggest they do in these situations?
>>>
>>> libselinux cannot handle it in the general case.  If using the
>>> userspace AVC and SIDs obtained via avc_context_to_sid(), then
>>> libselinux could transparently re-map those to the unlabeled context
>>> if they cease to be valid.  Otherwise, it is up to the callers to deal
>>> with and the correct handling is application-specific.  SEPostgreSQL
>>> does this for example:
>>> https://github.com/postgres/postgres/blob/master/contrib/sepgsql/label.c#L460
>>>
>>> However, I don't think that would help something like systemd; even if
>>> you re-map the context to the unlabeled context, you aren't going to
>>> get a useful result from security_compute_create() or similar to use
>>> in labeling sockets, processes, files, etc.>
>>
>> I suppose systemd probably should not fail "hard" when getfilecon (or
>> whatever) fails and returns with "invalid argument", and it should then
>> just not use setfilecon rather than not create the object at all (as it
>> seems to be doing now)
> 
> There is a tension there with fail-closed versus fail-open and the
> potential for a security vulnerability to arise if it proceeds.  Would
> have to look at the specifics to evaluate how it should be handled.
> Of course, in practice, one really shouldn't be removing contexts
> while they are still in use (or else use aliases to preserve some
> degree of compatibility).
> 

I guess if there is tension be between GNU/Linux use of libselinux and
SEAndroids use of libselinux, where SE for Android is implemented by the
vendor to be immutable by the device owner, and where GNU/Linux
leverages SELinux to empower device owners, then any tension can be
alleviated if Google forks libselinux. In GNU/Linux it should just be
possible to switch policies.
Stephen Smalley July 24, 2020, 12:23 p.m. UTC | #13
On Fri, Jul 24, 2020 at 3:54 AM Dominick Grift
<dominick.grift@defensec.nl> wrote:
>
>
>
> On 7/23/20 3:24 PM, Stephen Smalley wrote:
>  > There is a tension there with fail-closed versus fail-open and the
> > potential for a security vulnerability to arise if it proceeds.  Would
> > have to look at the specifics to evaluate how it should be handled.
> > Of course, in practice, one really shouldn't be removing contexts
> > while they are still in use (or else use aliases to preserve some
> > degree of compatibility).
> >
>
> I guess if there is tension be between GNU/Linux use of libselinux and
> SEAndroids use of libselinux, where SE for Android is implemented by the
> vendor to be immutable by the device owner, and where GNU/Linux
> leverages SELinux to empower device owners, then any tension can be
> alleviated if Google forks libselinux. In GNU/Linux it should just be
> possible to switch policies.

I wasn't talking about Android, just about the tension of
fail-closed/secure versus fail-open/insecure in general.
I don't have any problem with someone installing a new policy that
completely changes the set of file contexts; I just don't think they
should do that at runtime without a reboot in between and expect
things to work seamlessly.
Dominick Grift July 24, 2020, 12:29 p.m. UTC | #14
On 7/24/20 2:23 PM, Stephen Smalley wrote:
> On Fri, Jul 24, 2020 at 3:54 AM Dominick Grift
> <dominick.grift@defensec.nl> wrote:
>>
>>
>>
>> On 7/23/20 3:24 PM, Stephen Smalley wrote:
>>  > There is a tension there with fail-closed versus fail-open and the
>>> potential for a security vulnerability to arise if it proceeds.  Would
>>> have to look at the specifics to evaluate how it should be handled.
>>> Of course, in practice, one really shouldn't be removing contexts
>>> while they are still in use (or else use aliases to preserve some
>>> degree of compatibility).
>>>
>>
>> I guess if there is tension be between GNU/Linux use of libselinux and
>> SEAndroids use of libselinux, where SE for Android is implemented by the
>> vendor to be immutable by the device owner, and where GNU/Linux
>> leverages SELinux to empower device owners, then any tension can be
>> alleviated if Google forks libselinux. In GNU/Linux it should just be
>> possible to switch policies.
> 
> I wasn't talking about Android, just about the tension of
> fail-closed/secure versus fail-open/insecure in general.
> I don't have any problem with someone installing a new policy that
> completely changes the set of file contexts; I just don't think they
> should do that at runtime without a reboot in between and expect
> things to work seamlessly.
> 

Yes but that is not what I am saying. It does not work even when you
reboot. I tried to explain that:

You install a new policy and run fixfiles -F onboot && reboot (as one
should)

systemd will fail to compute create socket activated sockets. and so
these socket activated daemon fail to start.

One of the daemons is device-mapper, and so if you use LVM type stuff
you may end up with with a system that is only partially relabeled.

Not to mention that in the relabel target various other services that
are socket activated fail to start, and so  who know how else that may
affect things.

There is also this (however this might no longer be accurate):

systemd computes whether it can dynamically transition on boot. If the
systemd executable file has an invalid label and this computation fails
then systemd might just freeze in the first place.
Stephen Smalley July 24, 2020, 12:56 p.m. UTC | #15
On Fri, Jul 24, 2020 at 8:29 AM Dominick Grift
<dominick.grift@defensec.nl> wrote:
>
>
>
> On 7/24/20 2:23 PM, Stephen Smalley wrote:
> > On Fri, Jul 24, 2020 at 3:54 AM Dominick Grift
> > <dominick.grift@defensec.nl> wrote:
> >>
> >>
> >>
> >> On 7/23/20 3:24 PM, Stephen Smalley wrote:
> >>  > There is a tension there with fail-closed versus fail-open and the
> >>> potential for a security vulnerability to arise if it proceeds.  Would
> >>> have to look at the specifics to evaluate how it should be handled.
> >>> Of course, in practice, one really shouldn't be removing contexts
> >>> while they are still in use (or else use aliases to preserve some
> >>> degree of compatibility).
> >>>
> >>
> >> I guess if there is tension be between GNU/Linux use of libselinux and
> >> SEAndroids use of libselinux, where SE for Android is implemented by the
> >> vendor to be immutable by the device owner, and where GNU/Linux
> >> leverages SELinux to empower device owners, then any tension can be
> >> alleviated if Google forks libselinux. In GNU/Linux it should just be
> >> possible to switch policies.
> >
> > I wasn't talking about Android, just about the tension of
> > fail-closed/secure versus fail-open/insecure in general.
> > I don't have any problem with someone installing a new policy that
> > completely changes the set of file contexts; I just don't think they
> > should do that at runtime without a reboot in between and expect
> > things to work seamlessly.
> >
>
> Yes but that is not what I am saying. It does not work even when you
> reboot. I tried to explain that:
>
> You install a new policy and run fixfiles -F onboot && reboot (as one
> should)
>
> systemd will fail to compute create socket activated sockets. and so
> these socket activated daemon fail to start.
>
> One of the daemons is device-mapper, and so if you use LVM type stuff
> you may end up with with a system that is only partially relabeled.
>
> Not to mention that in the relabel target various other services that
> are socket activated fail to start, and so  who know how else that may
> affect things.
>
> There is also this (however this might no longer be accurate):
>
> systemd computes whether it can dynamically transition on boot. If the
> systemd executable file has an invalid label and this computation fails
> then systemd might just freeze in the first place.

I think for this kind of complete policy changeover, you need to
relabel prior to rebooting.  Obviously that carries its own set of
challenges; you'd at least have to switch to permissive mode first and
potentially run setfiles in a domain (e.g. setfiles_mac_t) that is
allowed to get/set contexts unknown to the current policy
(CAP_MAC_ADMIN + capability2 mac_admin permission) or load the new
policy prior to running setfiles.  Or boot with SELinux disabled,
label via setfiles, and then boot with the new policy.  The preferred
model of course is to install with the desired policy in the first
place. IIUC Android upgrades are a bit different in that they reboot
into recovery mode, create the new filesystem (required anyway for
dm-verity) with the correct labels for its policy, and then reboot
into normal mode.

I don't think the separate autorelabel service can work for whole
policy changeovers; it would need to be done directly by systemd
itself prior to any other actions.  I think Android's init does
something like that for the userdata partition since that doesn't get
replaced on upgrades.
Dominick Grift July 24, 2020, 1:06 p.m. UTC | #16
On 7/24/20 2:56 PM, Stephen Smalley wrote:
> On Fri, Jul 24, 2020 at 8:29 AM Dominick Grift
> <dominick.grift@defensec.nl> wrote:
>>
>>
>>
>> On 7/24/20 2:23 PM, Stephen Smalley wrote:
>>> On Fri, Jul 24, 2020 at 3:54 AM Dominick Grift
>>> <dominick.grift@defensec.nl> wrote:
>>>>
>>>>
>>>>
>>>> On 7/23/20 3:24 PM, Stephen Smalley wrote:
>>>>  > There is a tension there with fail-closed versus fail-open and the
>>>>> potential for a security vulnerability to arise if it proceeds.  Would
>>>>> have to look at the specifics to evaluate how it should be handled.
>>>>> Of course, in practice, one really shouldn't be removing contexts
>>>>> while they are still in use (or else use aliases to preserve some
>>>>> degree of compatibility).
>>>>>
>>>>
>>>> I guess if there is tension be between GNU/Linux use of libselinux and
>>>> SEAndroids use of libselinux, where SE for Android is implemented by the
>>>> vendor to be immutable by the device owner, and where GNU/Linux
>>>> leverages SELinux to empower device owners, then any tension can be
>>>> alleviated if Google forks libselinux. In GNU/Linux it should just be
>>>> possible to switch policies.
>>>
>>> I wasn't talking about Android, just about the tension of
>>> fail-closed/secure versus fail-open/insecure in general.
>>> I don't have any problem with someone installing a new policy that
>>> completely changes the set of file contexts; I just don't think they
>>> should do that at runtime without a reboot in between and expect
>>> things to work seamlessly.
>>>
>>
>> Yes but that is not what I am saying. It does not work even when you
>> reboot. I tried to explain that:
>>
>> You install a new policy and run fixfiles -F onboot && reboot (as one
>> should)
>>
>> systemd will fail to compute create socket activated sockets. and so
>> these socket activated daemon fail to start.
>>
>> One of the daemons is device-mapper, and so if you use LVM type stuff
>> you may end up with with a system that is only partially relabeled.
>>
>> Not to mention that in the relabel target various other services that
>> are socket activated fail to start, and so  who know how else that may
>> affect things.
>>
>> There is also this (however this might no longer be accurate):
>>
>> systemd computes whether it can dynamically transition on boot. If the
>> systemd executable file has an invalid label and this computation fails
>> then systemd might just freeze in the first place.
> 
> I think for this kind of complete policy changeover, you need to
> relabel prior to rebooting.

I think i tried that, but the extended attribute filesystems need to be
re-initialized AFAIK else fixfiles just returns with "Operation not
supported". Not sure if that strictly speaking requires a reboot or if
you can somehow do that with mount -o remount?

Is there a way to enable labeling support of extended attribute
filesystems without rebooting?

I think there was a patch recently by the Red Hat ContainerOS people to
enable labeling from the initramfs (ie labeling when SELinux is
disabled) How does that relate to the issue where I am seemingly not
able to relabel the filesystem after adding a fsuse trans rule without
rebooting? (ie SELinux is enabled, there is a fsuse xattr but the
filesystem hasnt been re-initialized yes and setfiles reports "operation
not supported")

  Obviously that carries its own set of
> challenges; you'd at least have to switch to permissive mode first and
> potentially run setfiles in a domain (e.g. setfiles_mac_t) that is
> allowed to get/set contexts unknown to the current policy
> (CAP_MAC_ADMIN + capability2 mac_admin permission) or load the new
> policy prior to running setfiles.  Or boot with SELinux disabled,
> label via setfiles, and then boot with the new policy.  The preferred
> model of course is to install with the desired policy in the first
> place. IIUC Android upgrades are a bit different in that they reboot
> into recovery mode, create the new filesystem (required anyway for
> dm-verity) with the correct labels for its policy, and then reboot
> into normal mode.
> 
> I don't think the separate autorelabel service can work for whole
> policy changeovers; it would need to be done directly by systemd
> itself prior to any other actions.  I think Android's init does
> something like that for the userdata partition since that doesn't get
> replaced on upgrades.
>
Stephen Smalley July 24, 2020, 1:26 p.m. UTC | #17
On Fri, Jul 24, 2020 at 9:06 AM Dominick Grift
<dominick.grift@defensec.nl> wrote:
>
>
>
> On 7/24/20 2:56 PM, Stephen Smalley wrote:
> > On Fri, Jul 24, 2020 at 8:29 AM Dominick Grift
> > <dominick.grift@defensec.nl> wrote:
> >>
> >>
> >>
> >> On 7/24/20 2:23 PM, Stephen Smalley wrote:
> >>> On Fri, Jul 24, 2020 at 3:54 AM Dominick Grift
> >>> <dominick.grift@defensec.nl> wrote:
> >>>>
> >>>>
> >>>>
> >>>> On 7/23/20 3:24 PM, Stephen Smalley wrote:
> > I think for this kind of complete policy changeover, you need to
> > relabel prior to rebooting.
>
> I think i tried that, but the extended attribute filesystems need to be
> re-initialized AFAIK else fixfiles just returns with "Operation not
> supported". Not sure if that strictly speaking requires a reboot or if
> you can somehow do that with mount -o remount?
>
> Is there a way to enable labeling support of extended attribute
> filesystems without rebooting?
>
> I think there was a patch recently by the Red Hat ContainerOS people to
> enable labeling from the initramfs (ie labeling when SELinux is
> disabled) How does that relate to the issue where I am seemingly not
> able to relabel the filesystem after adding a fsuse trans rule without
> rebooting? (ie SELinux is enabled, there is a fsuse xattr but the
> filesystem hasnt been re-initialized yes and setfiles reports "operation
> not supported")

So, first, fs_use_* rules should be relatively standard across SELinux
policies because they are more about the characteristics of the
filesystem driver and what it supports than about a particular policy.
The only thing policy-specific about them is the context to assign to
filesystem/superblock.  I updated scripts/selinux/mdp to auto-generate
appropriate fs_use* rules for many filesystem types and I'd recommend
using those rules in any new policy.  Similarly, mdp can be used as a
guide to which filesystem types should be using genfscon although
incomplete.  If there was a good general way that I could test for the
properties of a filesystem type in the SELinux module code and
automatically assign FS_USE_* and/or use of genfscon, I'd do that
instead.

Second, if your policy is changing these rules and the superblock has
already been initialized, then the only way to get your new rule
applied is if you can cause the old superblock to go away, e.g.
unmount.  And that won't work while it is in use.  So rebooting if
your only option if you cannot do that.  Rebooting with SELinux
disabled and then running setfiles will be the safest when performing
a complete policy changeover since you will then have no interference
by the old policy.
Dominick Grift July 24, 2020, 1:30 p.m. UTC | #18
On 7/24/20 3:26 PM, Stephen Smalley wrote:
<snip>

> 
> Second, if your policy is changing these rules and the superblock has
> already been initialized, then the only way to get your new rule
> applied is if you can cause the old superblock to go away, e.g.
> unmount.  And that won't work while it is in use.  So rebooting if
> your only option if you cannot do that.  Rebooting with SELinux
> disabled and then running setfiles will be the safest when performing
> a complete policy changeover since you will then have no interference
> by the old policy.
> 

Thanks, I think this is the answer I was looking for. It is not entirely
elegant to say the least but I guess it will have to do.
diff mbox series

Patch

diff --git a/src/objects.md b/src/objects.md
index 58664ef..1907316 100644
--- a/src/objects.md
+++ b/src/objects.md
@@ -110,14 +110,20 @@  objects is managed by the system and generally unseen by the users
 (until labeling goes wrong !!). As processes and objects are created and
 destroyed, they either:
 
-1.  Inherit their labels from the parent process or object.
+1.  Inherit their labels from the parent process or object. The policy
+    default user, type, role and range statements can be used to
+	change the behavior as discussed in the [**Default Rules**](default_rules.md#default-object-rules)
+    section.
 2.  The policy type, role and range transition statements allow a
     different label to be assigned as discussed in the
     [**Domain and Object Transitions**](domain_object_transitions.md#domain-and-object-transitions)
     section.
-3.  SELinux-aware applications can enforce a new label (with the
-    policies approval of course) using the **libselinux** API
-    functions.
+3.  SELinux-aware applications can assign a new label (with the
+    policy's approval of course) using the **libselinux** API
+    functions. The `process setfscreate` permission can be used to
+    allow subjects to create files with a new label programmatically
+    using the ***setfscreatecon**(3)* function, overriding default
+    rules and transition statements.
 4.  An object manager (OM) can enforce a default label that can either
     be built into the OM or obtained via a configuration file (such as
     those used by
@@ -269,6 +275,39 @@  and manage their transition:
 
 `type_transition`, `role_transition` and `range_transition`
 
+SELinux-aware applications can assign a new label (with the policy's
+approval of course) using the **libselinux** API functions. The
+`process setexec`, `process setkeycreate` and `process setsockcreate`
+permissions can be used to allow subjects to label processes,
+kernel keyrings, and sockets programmatically using the
+***setexec**(3)*, ***setkeycreatecon**(3)* and
+***setsockcreatecon**(3)* functions respectively, overriding
+transition statements.
+
+The `kernel` **initial security identifier** is used to associate
+a specified label with kernel objects, including kernel threads
+(both those that are created during initialization but also kernel
+threads created later), kernel-private sockets, synthetic objects
+representing kernel resources (e.g. the "system" class).
+
+It is true that processes created prior to initial policy load will
+also be in the kernel SID until/unless there is a policy loaded and
+either a policy-defined transition or an explicit setcon or
+setexeccon+execve, but that's just the typical default inheritance
+from creating task behavior for processes.
+
+The `unlabeled` **initial security identifier** is used
+to associate a specified label with subjects that had their label
+invalidated due to policy changes at runtime.
+
+It is also assigned as the initial state for various objects e.g.
+inodes, superblocks, etc until they reach a point where a more
+specific label can be determined e.g. from an xattr or from policy.
+The context associated with the unlabeled SID is used as the fallback
+context for both subjects and objects when their label is invalidated
+by a policy reload (their SID is unchanged but the SID is
+transparently remapped to the unlabeled context).
+
 ### Object Reuse
 
 As GNU / Linux runs it creates instances of objects and manages the