All of lore.kernel.org
 help / color / mirror / Atom feed
* Is it possible to prevent a binary executable file from being read via SELinux?
@ 2016-11-01 15:57 Patrick Doyle
  2016-11-01 19:45 ` Stephen Smalley
  0 siblings, 1 reply; 9+ messages in thread
From: Patrick Doyle @ 2016-11-01 15:57 UTC (permalink / raw)
  To: selinux

Background:
I have an embedded processor running a custom application on top of
Linux.  I control the kernel, the rootfs, and the application.  I
would like to deploy this application such that, if somebody were to
gain access to my device, even root access, (s)he would not be able to
read or copy the application from the device.

I don't know how or if the kernel would even support such a situation
-- if the executable is not readable, it should not be mappable, and
therefore the kernel would have a hard time swapping in pages from it.
So, I recognize that this may be an impossible request.

But it feels like the sort of thing somebody else should have wondered
about, and it feels like the sort of thing that SELinux might be able
to handle.

Any thoughts or recommendations?

I asked on IRC, and one person (grist) suggested that perhaps I should
encrypt the file.  I could do that, but then I find myself in the
situation of figuring out how to protect the encryption key on the
device.

I could implement a TEE (Trusted Execution Environment) on the device
or attach a TPM (Trusted Platform Module) to protect the key, but
those approaches add their own complexities.

Any thoughts or pointers would be gratefully accepted.

--wpd

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: Is it possible to prevent a binary executable file from being read via SELinux?
  2016-11-01 15:57 Is it possible to prevent a binary executable file from being read via SELinux? Patrick Doyle
@ 2016-11-01 19:45 ` Stephen Smalley
  2016-11-01 22:41   ` Patrick Doyle
  0 siblings, 1 reply; 9+ messages in thread
From: Stephen Smalley @ 2016-11-01 19:45 UTC (permalink / raw)
  To: Patrick Doyle, selinux

On 11/01/2016 11:57 AM, Patrick Doyle wrote:
> Background:
> I have an embedded processor running a custom application on top of
> Linux.  I control the kernel, the rootfs, and the application.  I
> would like to deploy this application such that, if somebody were to
> gain access to my device, even root access, (s)he would not be able to
> read or copy the application from the device.
> 
> I don't know how or if the kernel would even support such a situation
> -- if the executable is not readable, it should not be mappable, and
> therefore the kernel would have a hard time swapping in pages from it.
> So, I recognize that this may be an impossible request.
> 
> But it feels like the sort of thing somebody else should have wondered
> about, and it feels like the sort of thing that SELinux might be able
> to handle.
> 
> Any thoughts or recommendations?
> 
> I asked on IRC, and one person (grist) suggested that perhaps I should
> encrypt the file.  I could do that, but then I find myself in the
> situation of figuring out how to protect the encryption key on the
> device.
> 
> I could implement a TEE (Trusted Execution Environment) on the device
> or attach a TPM (Trusted Platform Module) to protect the key, but
> those approaches add their own complexities.
> 
> Any thoughts or pointers would be gratefully accepted.

Is anything besides your application even running on the device?  Are
there other services/applications that run on the device too?  If not,
then I doubt SELinux or any other access control mechanism is going to
be particularly helpful to you.

When you say "gain access to my device", what kind of access did you
have in mind?  Physical access (if so, then SELinux won't help with
that)?  Remote exploitation of your own application (if so, then
assuming they can do that, they obviously can read out your
application's own memory and SELinux can't prevent that)?  Remote
exploitation of a service or application other than your application
that is running on the device (if so, then yes, Linux DAC and SELinux
can help here)?

You could achieve a degree of protection via Linux DAC by setting the
ownership and mode of the application executable file as restrictively
as possible (it doesn't need to be readable at all, and can be limited
to only being executed by root), by running all other
services/applications in non-root UIDs that differ from the UID in which
your application runs, and by eliminating/minimizing all setuid-root
executables and mounting nosuid where appropriate.

If you can't get rid of root services entirely, then SELinux can extend
this protection to even root processes.  You'd probably want a custom
policy from scratch for that kind of scenario; see the Android policy
for an example.

Obviously this wouldn't help mitigate kernel vulnerabilities or someone
with physical access to the device.

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: Is it possible to prevent a binary executable file from being read via SELinux?
  2016-11-01 19:45 ` Stephen Smalley
@ 2016-11-01 22:41   ` Patrick Doyle
  2016-11-02 13:25     ` Stephen Smalley
  0 siblings, 1 reply; 9+ messages in thread
From: Patrick Doyle @ 2016-11-01 22:41 UTC (permalink / raw)
  To: Stephen Smalley; +Cc: selinux

Thank you for your reply.

On Tue, Nov 1, 2016 at 3:45 PM, Stephen Smalley <sds@tycho.nsa.gov> wrote:
>
> If you can't get rid of root services entirely, then SELinux can extend
> this protection to even root processes.  You'd probably want a custom
> policy from scratch for that kind of scenario; see the Android policy
> for an example.
A custom policy is most likely what I want... my question is... can I
set up such a policy that disallows reading (and, by extension,
copying) of an executable binary, and yet still be able to execute it?
 A related question would be: can I bake that policy immutably into
the kernel so that it cannot be disabled?  While I can't prevent
physical access to the device, I can encrypt the kernel & rootfs
(embedded as a cramfs) as a single binary blob, so I think (hope) that
is as secure as my encryption key.  I would also do all of the normal
hardening stuff of disabling loadable modules, shutting down network
services, etc...

--wpd

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: Is it possible to prevent a binary executable file from being read via SELinux?
  2016-11-01 22:41   ` Patrick Doyle
@ 2016-11-02 13:25     ` Stephen Smalley
  2016-11-02 13:52       ` Patrick Doyle
  0 siblings, 1 reply; 9+ messages in thread
From: Stephen Smalley @ 2016-11-02 13:25 UTC (permalink / raw)
  To: Patrick Doyle; +Cc: selinux

On 11/01/2016 06:41 PM, Patrick Doyle wrote:
> Thank you for your reply.
> 
> On Tue, Nov 1, 2016 at 3:45 PM, Stephen Smalley <sds@tycho.nsa.gov> wrote:
>>
>> If you can't get rid of root services entirely, then SELinux can extend
>> this protection to even root processes.  You'd probably want a custom
>> policy from scratch for that kind of scenario; see the Android policy
>> for an example.
> A custom policy is most likely what I want... my question is... can I
> set up such a policy that disallows reading (and, by extension,
> copying) of an executable binary, and yet still be able to execute it?

As I said, you can prevent reading of the binary by all other processes
on the system, but not by the application itself.  The domain in which
the application runs must be able to read the binary in order to execute
it as far as SELinux is concerned.  And fundamentally, the running
application process always has read access to its executable (this may
change in the future with Intel Memory Protection Keys and execute-only
memory but that's not reality today).

>  A related question would be: can I bake that policy immutably into
> the kernel so that it cannot be disabled?  While I can't prevent
> physical access to the device, I can encrypt the kernel & rootfs
> (embedded as a cramfs) as a single binary blob, so I think (hope) that
> is as secure as my encryption key.  I would also do all of the normal
> hardening stuff of disabling loadable modules, shutting down network
> services, etc...

The Android model is to put the init program (which loads the policy)
and the policy file into the initramfs, and the bootloader verifies the
signature of the boot image that contains the kernel and the initramfs.
That's as close we get to baking the policy into the kernel presently.

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: Is it possible to prevent a binary executable file from being read via SELinux?
  2016-11-02 13:25     ` Stephen Smalley
@ 2016-11-02 13:52       ` Patrick Doyle
  2016-11-02 14:08         ` Stephen Smalley
  0 siblings, 1 reply; 9+ messages in thread
From: Patrick Doyle @ 2016-11-02 13:52 UTC (permalink / raw)
  To: Stephen Smalley; +Cc: selinux

Thank you again.

On Wed, Nov 2, 2016 at 9:25 AM, Stephen Smalley <sds@tycho.nsa.gov> wrote:
> As I said, you can prevent reading of the binary by all other processes
> on the system, but not by the application itself.  The domain in which
> the application runs must be able to read the binary in order to execute
> it as far as SELinux is concerned.  And fundamentally, the running
> application process always has read access to its executable (this may
> change in the future with Intel Memory Protection Keys and execute-only
> memory but that's not reality today).
That makes sense.  I will be running on an ARM architecture, so Intel
Memory Protection Keys won't help :-)

I haven't finished reading the documentation yet, so I don't know the
correct syntax for specifying a policy.  I do know that the SELinux
approach is to disallow everything, except what is explicitly listed
in the policy.  Given that I am interested in starting small, and
achieving this one goal of preventing read access to my application,
would a reasonable custom policy look something like:

Allow all file access to /bin to everybody
Allow all file access to /usr to everybody
Allow all device access to /dev to everybody
etc... (for all of my directories in /... except /opt)
Allow execute file access to /opt/local/myapp to everybody
for /opt/local/myapp allow read access to /opt/local/myapp

Yes, I know this exactly counter to the "dissallow everything, only
allow what you need" mindset.  My hope would be to achieve that
mindset in the end, but as a starting point, and as an exercise in
learning how to speak the policy language, would this be reasonable?

>
> The Android model is to put the init program (which loads the policy)
> and the policy file into the initramfs, and the bootloader verifies the
> signature of the boot image that contains the kernel and the initramfs.
> That's as close we get to baking the policy into the kernel presently.
>
My approach was similar -- except that my whole (tiny) rootfs would be
in the initramfs.  And I guess I would need to ensure that my policy
did not explicitly allow the policy to be changed.

Thanks again for your help.  This is starting to make sense.

--wpd

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: Is it possible to prevent a binary executable file from being read via SELinux?
  2016-11-02 13:52       ` Patrick Doyle
@ 2016-11-02 14:08         ` Stephen Smalley
  2016-11-02 15:10           ` Patrick Doyle
  0 siblings, 1 reply; 9+ messages in thread
From: Stephen Smalley @ 2016-11-02 14:08 UTC (permalink / raw)
  To: Patrick Doyle; +Cc: selinux

On 11/02/2016 09:52 AM, Patrick Doyle wrote:
> I haven't finished reading the documentation yet, so I don't know the
> correct syntax for specifying a policy.  I do know that the SELinux
> approach is to disallow everything, except what is explicitly listed
> in the policy.  Given that I am interested in starting small, and
> achieving this one goal of preventing read access to my application,
> would a reasonable custom policy look something like:
> 
> Allow all file access to /bin to everybody
> Allow all file access to /usr to everybody
> Allow all device access to /dev to everybody
> etc... (for all of my directories in /... except /opt)
> Allow execute file access to /opt/local/myapp to everybody
> for /opt/local/myapp allow read access to /opt/local/myapp
> 
> Yes, I know this exactly counter to the "dissallow everything, only
> allow what you need" mindset.  My hope would be to achieve that
> mindset in the end, but as a starting point, and as an exercise in
> learning how to speak the policy language, would this be reasonable?

No.  For example, if all processes can access all /dev nodes, then they
can perform raw reads/writes to the block devices and thereby circumvent
any file-based access controls entirely.  If all processes can write to
e.g. /lib, then they can replace the dynamic linker and any shared
libraries used by your application and get it to execute their code in
order to dump its memory.  If they can all execute your application,
then they can run its binary in their own memory and then dump its
contents.  Please, see my original email and answer the questions there
(which you mostly ignored) to see whether this is even a worthwhile
exercise, and then, if so, follow the guidance for using sound DAC
ownership and modes first, then investigate SELinux to address residual
gaps.

If you want a simple, small SELinux policy to start from, I would again
recommend the Android SELinux policy.

>> The Android model is to put the init program (which loads the policy)
>> and the policy file into the initramfs, and the bootloader verifies the
>> signature of the boot image that contains the kernel and the initramfs.
>> That's as close we get to baking the policy into the kernel presently.
>>
> My approach was similar -- except that my whole (tiny) rootfs would be
> in the initramfs.  And I guess I would need to ensure that my policy
> did not explicitly allow the policy to be changed.

Yes, that's what Android does too - its rootfs is the initramfs and its
default policy does not allow policy to be reloaded again after the
first load by init.  See its policy for an example.

> Thanks again for your help.  This is starting to make sense.

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: Is it possible to prevent a binary executable file from being read via SELinux?
  2016-11-02 14:08         ` Stephen Smalley
@ 2016-11-02 15:10           ` Patrick Doyle
  2016-11-02 16:31             ` Stephen Smalley
  0 siblings, 1 reply; 9+ messages in thread
From: Patrick Doyle @ 2016-11-02 15:10 UTC (permalink / raw)
  To: Stephen Smalley; +Cc: selinux

On Wed, Nov 2, 2016 at 10:08 AM, Stephen Smalley <sds@tycho.nsa.gov> wrote:
> No.  For example, if all processes can access all /dev nodes, then they
> can perform raw reads/writes to the block devices and thereby circumvent
> any file-based access controls entirely.  If all processes can write to
> e.g. /lib, then they can replace the dynamic linker and any shared
> libraries used by your application and get it to execute their code in
> order to dump its memory.  If they can all execute your application,
> then they can run its binary in their own memory and then dump its
> contents.
I didn't realize that saying "Allow all access" would circumvent the
normal Linux based file permissions.  I assumed that SELinux was
layered on top of those permissions.  I guess I have more to learn.


>  Please, see my original email and answer the questions there
> (which you mostly ignored) to see whether this is even a worthwhile
> exercise, and then, if so, follow the guidance for using sound DAC
> ownership and modes first, then investigate SELinux to address residual
> gaps.
ok.  That is what I have been attempting to do... one residual gap I
see with that is that a root user can make a copy of my application.
I would like to prevent that.

>> Is anything besides your application even running on the device?
yes

>> Are there other services/applications that run on the device too?
yes

>> When you say "gain access to my device", what kind of access did you have in mind?

I am assuming that somebody has managed to gain root access to my
device, possibly via a serial port, or possibly via a remote exploit
of one of the other services running on the device.  (S)He will
certainly have physical access to the device, and therefore my kernel
& rootfs will be encrypted, (and the key would be protected by the
secure boot facilities of the SoC).  But if (s)he gains root access to
the file system, I don't want him/her to be able to be able to copy my
application code off the device.

>
> If you want a simple, small SELinux policy to start from, I would again
> recommend the Android SELinux policy.
>
Very well.  I will start there and save the rest of my questions until
after I have learned more.

Thanks again for your tips and advice.

--wpd

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: Is it possible to prevent a binary executable file from being read via SELinux?
  2016-11-02 15:10           ` Patrick Doyle
@ 2016-11-02 16:31             ` Stephen Smalley
  2016-11-02 18:42               ` Patrick Doyle
  0 siblings, 1 reply; 9+ messages in thread
From: Stephen Smalley @ 2016-11-02 16:31 UTC (permalink / raw)
  To: Patrick Doyle; +Cc: selinux

On 11/02/2016 11:10 AM, Patrick Doyle wrote:
> On Wed, Nov 2, 2016 at 10:08 AM, Stephen Smalley <sds@tycho.nsa.gov> wrote:
>> No.  For example, if all processes can access all /dev nodes, then they
>> can perform raw reads/writes to the block devices and thereby circumvent
>> any file-based access controls entirely.  If all processes can write to
>> e.g. /lib, then they can replace the dynamic linker and any shared
>> libraries used by your application and get it to execute their code in
>> order to dump its memory.  If they can all execute your application,
>> then they can run its binary in their own memory and then dump its
>> contents.
> I didn't realize that saying "Allow all access" would circumvent the
> normal Linux based file permissions.  I assumed that SELinux was
> layered on top of those permissions.  I guess I have more to learn.

No, my comments were with respect to SELinux, not DAC.  DAC is still in
effect and SELinux does not override DAC denials.  But the point
remains: if you are trying to protect against an errant root process,
then the policy you described won't provide any real protection.

> 
> 
>>  Please, see my original email and answer the questions there
>> (which you mostly ignored) to see whether this is even a worthwhile
>> exercise, and then, if so, follow the guidance for using sound DAC
>> ownership and modes first, then investigate SELinux to address residual
>> gaps.
> ok.  That is what I have been attempting to do... one residual gap I
> see with that is that a root user can make a copy of my application.
> I would like to prevent that.
> 
>>> Is anything besides your application even running on the device?
> yes
> 
>>> Are there other services/applications that run on the device too?
> yes
> 
>>> When you say "gain access to my device", what kind of access did you have in mind?
> 
> I am assuming that somebody has managed to gain root access to my
> device, possibly via a serial port, or possibly via a remote exploit
> of one of the other services running on the device.  (S)He will
> certainly have physical access to the device, and therefore my kernel
> & rootfs will be encrypted, (and the key would be protected by the
> secure boot facilities of the SoC).  But if (s)he gains root access to
> the file system, I don't want him/her to be able to be able to copy my
> application code off the device.
> 
>>
>> If you want a simple, small SELinux policy to start from, I would again
>> recommend the Android SELinux policy.
>>
> Very well.  I will start there and save the rest of my questions until
> after I have learned more.
> 
> Thanks again for your tips and advice.
> 
> --wpd
> 

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: Is it possible to prevent a binary executable file from being read via SELinux?
  2016-11-02 16:31             ` Stephen Smalley
@ 2016-11-02 18:42               ` Patrick Doyle
  0 siblings, 0 replies; 9+ messages in thread
From: Patrick Doyle @ 2016-11-02 18:42 UTC (permalink / raw)
  To: Stephen Smalley; +Cc: selinux

On Wed, Nov 2, 2016 at 12:31 PM, Stephen Smalley <sds@tycho.nsa.gov> wrote:
> On 11/02/2016 11:10 AM, Patrick Doyle wrote:
>> I didn't realize that saying "Allow all access" would circumvent the
>> normal Linux based file permissions.  I assumed that SELinux was
>> layered on top of those permissions.  I guess I have more to learn.
>
> No, my comments were with respect to SELinux, not DAC.  DAC is still in
> effect and SELinux does not override DAC denials.  But the point
> remains: if you are trying to protect against an errant root process,
> then the policy you described won't provide any real protection.
>
OK, thanks.  That's good to know.  I was (perhaps foolishly) trying to
describe a policy that protected the one thing I knew I wanted
protected, and left everything else as (un)protected as it would be
without SELinux.  But I'm going to stop asking questions now until I
spend more time reading the documentation, trying things, and
understanding more things.

I appreciate your time (and the patience) you have given me thus far.
Now that I know my quest (executable, but not readable, even by root)
is not impossible, it's time for me to go do some more legwork (and
brainwork).  And at the end of this process, I expect I'll have a
solution that is even more secure than my original quest.

Thanks again.

--wpd

^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2016-11-02 18:42 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-11-01 15:57 Is it possible to prevent a binary executable file from being read via SELinux? Patrick Doyle
2016-11-01 19:45 ` Stephen Smalley
2016-11-01 22:41   ` Patrick Doyle
2016-11-02 13:25     ` Stephen Smalley
2016-11-02 13:52       ` Patrick Doyle
2016-11-02 14:08         ` Stephen Smalley
2016-11-02 15:10           ` Patrick Doyle
2016-11-02 16:31             ` Stephen Smalley
2016-11-02 18:42               ` Patrick Doyle

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.