[apparmor] Apparmor: Query
Murali Selvaraj
murali.selvaraj2003 at gmail.com
Sun Aug 9 23:20:52 UTC 2020
Hi John, Seth,
Thanks again for the details. I would like to get your inputs and clarify
my understanding.
Please go through the trailing email and correct me if I am wrong.
*Goal:* Reducing root permission of the process and enabling required
capabilities for the process.
*Design and approach:*
- To identify the required CAPs for the process, we are planning to enable
all CAPs while running in "non-root"
mode and from apparmor logs, hopefully we would be able to find the
required capability list for the process
specific.
- Please note that our user "non-root" (UID) is fixed. we won't change the
user UID and GID for non-root.
*Implementation:*
- Process would be starting as "root" and dropping to non-root then
applying required CAPs based on above apparmor logs
using libcap APIs.
- Most of the process needs CAP_DAC_OVERRIDE, CAP_DAC_READ_SEARCH to
read/write root privilege files/directories.
*Query specific to above non-root approach: *
- We are planning to enable CAP_DAC_OVERRIDE, CAP_DAC_READ_SEARCH CAPs when
the process switches to non-root.
- Then based on a process for example network specific process, we will
enable CAP_NET_ADMIN.
- In case of system specific processes to access hardware details, we will
enable CAP_SYS_ADMIN.
- Please note, we will require CAPs based on apparmor logs as indicated
above.
Here, the doubt is that if we enable CAP_DAC_OVERRIDE, CAP_DAC_READ_SEARCH,
CAP_NET_ADMIN, CAP_SYS_ADMIN to run
the process in non-root to ensure it works in the same way when it was
running in "root".
Do you think enabling CAP_DAC_OVERRIDE, CAP_DAC_READ_SEARCH, CAP_NET_ADMIN,
CAP_SYS_ADMIN in the process
are we missing any security or this is expected while using Linux
capabilities for non-root (dropping root privilege).
Please share your valuable suggestions on security specific views.
*General query:*
- Is Linux capabilities belong to DAC or LSM/MAC?
As per my understanding, Linux capabilities are part of LSM. But I still
think that few CAPs are used in DAC.
Please share the details with example.
- Is LSM mandatory to enable in Linux Kernel?
- Which LSM is enabled in linux by default?
- Why do we need MAC as we have a security check by discretionary access
controls (DAC) ?
Is MAC mandatory to enable or optional?
- Is MAC really mandatory for Linux? AS per my understanding, for embedded
linux devices no need to enable MAC on production devices.
Thanks
Murali.S
On Wed, Aug 5, 2020 at 3:25 AM John Johansen <john.johansen at canonical.com>
wrote:
> On 8/4/20 7:46 PM, Murali Selvaraj wrote:
> > Thanks for the explanation.
> >
> > Goal: Converting root process to non-root process by enabling required
> capabilities for the process.
> >
> > Scope: Am trying to find out required capabilities for the process which
> is going to run as "non-root"
> >
> > How to use Apparmor to find the capabilities specific to process:
> >
> > -> As per above discussion, Apparmor does not grant the required
> capabilities.
> >
> > -> We had thought that, from apparmor logs, we would be able to find the
> required capabilities.
> >
> > -> To find this, we would be following the steps to find the
> capabilities.
> >
> > Process (A) will be running in "non-root" but with all enabled
> capabilities and check the apparmor logs.
> > Apparmor logs will show the required capabilities.
> > Capture these CAPS and use this CAPS in the process code to convert that
> process root to non-root by only enabling this CAPs observed in apparmor
> logs.
> >
> > Is above understanding correct? please confirm the steps if anything is
> missing.
> >
>
> Yes AppArmor with the caveat that the "non-root" user is the one you plan
> to use in the future. Any "non-root" user will likely work but I can't
> guarantee it unless you use the same uid.
>
>
>
>
>
> > *General Query:*
> >
> > In any event, AppArmor will usually see capability requests after the
> usual DAC permissions are handled.
> >
> > Can you please explain this above statement with simple example?
> >
>
> The kernel applies multiple checks (eg. input validation) and the kernel
> bails on the first failed check. A pseudo code of this idea is
>
> fn () {
>
> if (input bad)
> return fail;
>
> if ( task uid != object uid) {
> if ( not capable (CAP))
> return fail; }
> if ( not APPARMOR_CAP(CAP)) <---- AppArmor will log if we
> get here
> return fail;
> }
>
>
> The kernel generally does multiple checks like explained in the pseudo
> code above. The general pattern is the same as in the pseudo code too. That
> is input validation comes first, then object lookup, then DAC based
> permission check (regular unix capability and uid checks), and then the LSM
> (apparmor) based checks. But code gets grouped into reusable fns and some
> time fn order can result in a MAC (apparmor) happening before the DAC check.
>
> The overlarching pattern is DAC comes first but there are a few cases
> where AppArmor is checked first, however you can be assured all required
> checks will happen.
>
>
> > For example, Process (x) tries to open a file (/etc/security) which is
> root permission but the process (x) runs in "non-root mode.
> > Pls note, process (x) does not have permission to open this file
> ((/etc/security) )
> >
> > open => sys_open() => kernel further code for handing the code.
> >
> > sys_open() => will return permission denied error due to permission
> issue.
> >
> > Here, capable() check won't happen. Does DAC take care of this check
> without using capability (CAP_DAC_READ_SEARCH)?
> >
>
> yes DAC includes uid and guid checks. The capability call for
> CAP_DAC_READ_SEARCH only happens if the uid/guid checks fail.
>
> > In such a case, trying to understand when Kernel uses capable() to check
> CAP_DAC_READ_SEARCH/CAP_DAC_OVERRIDE before/after DAC.
>
> these capabilities are only checked if the uid/guid check fail, in which
> case the task will need these capabilities to access the file
>
> ie. if you own the file you don't need CAP_DAC_OVERRIDE
> if you are in a group that allows access to the file you don't need
> CAP_DAC_OVERRIDE
>
> > Can you please explain the relation between DAC, apparmor and linux
> capability with this context?
> >
>
> Its generally follows the pattern outlined in the pseudo code above, but
> the pattern does vary with the hook and object. The reality is more
> complicated than the pseudo code.
>
> There are hooks where you get multiple DAC checks (uid and cap) an
> multiple LSM checks. Eg. some file operations will be closer to the pattern
>
> input validation
>
> object lookup
> loop on path elements
> DAC uid check
> DAC capability check
> MAC capability check
> MAC inode check
>
> MAC path check
>
> MAC inode check
>
>
> so there are potentially checks on every element of the path walk, and
> also checks at the operation type (eg. mmap, chown, ...)
>
>
>
> > Thanks
> > Murali.S
> >
> > On Tue, Aug 4, 2020 at 6:08 AM John Johansen <
> john.johansen at canonical.com <mailto:john.johansen at canonical.com>> wrote:
> >
> > On 8/3/20 8:02 PM, Murali Selvaraj wrote:
> > >
> > > Hi Seth,
> > >
> > > Thanks for the detailed explanation. Please go through below
> details and clarify further queries.
> > >
> > > I do not see a capability difference when this script runs in root
> (UID:0) and nobody (UID>0).
> > > If we are observing the required capabilities when the script runs
> in root, that would be easy for us to find
> > > the needed capabilities for this script. Then we will apply this
> capability when it runs in nobody user.
> > >
> > > #!/bin/sh
> > > echo "Testing"
> > > while [ 1 ]
> > > do
> > > cat /etc/foo =================> Ensure this file belongs to root
> permission
> > > echo "TESTING" > /nvram/foo
> > > killall <root_process_name>
> > > sleep 5
> > > done
> > >
> > > ls -ltr /etc/foo
> > > -rw-r--r-- 1 root root 8 Aug 3 20:31 /etc/foo
> > >
> >
> > can you please add
> >
> > echo -n "Confinement:"
> > cat /proc/self/attr/current || echo "Failed to obtain confinement" ;
> exit 1
> >
> > to your script after the killall or something similar, this will
> dump the confinement of the "cat" command but unless you have a transition
> for "cat" it should have the confinement of it parent or be denied.
> >
> > I should note that apparmor does have a dedup cache around logging
> capabilities. It is a single entry per processor (or virtual processor),
> and will prevent a previously seen cap from being logged IFF no other
> PROFILE has mediated a cap on that processor since the last time that
> profile previously logged the CAP in question.
> >
> > There is no manual switch to clear the cache, but it can be
> effectively cleared by replacing the profile but you need to actually make
> a change to the profile so that profile load dedup doesn't drop the
> replacement.
> >
> >
> > >
> > > Can you please check this script in your environment and share
> your observation. Please do the needful.
> > > Please execute in root and non-root mode and find the capability
> list from apparmor log events.
> > >
> >
> > not exactly your script but roughly equivalent
> >
> > unconfined non-root user killing root process
> >
> > $ kill 23579
> > bash: kill: (23579) - Operation not permitted
> >
> > no apparmor log message.
> >
> > ----
> >
> > unconfined root user killing root process
> >
> > $ sudo kill 23579
> >
> > success, no apparmor log message
> >
> > ----
> >
> > confined non-root user without signal or CAP permissions killing
> root process
> >
> > $ aa-exec -p demo -- kill 23965
> > kill: (23965): Operation not permitted
> >
> > no apparmor log message
> >
> > ----
> >
> > confined root user without signal or CAP permissions killing root
> process
> >
> > $ sudo aa-exec -p demo -- kill 23965
> > kill: (23965): Permission denied
> >
> > apparmor log messages
> >
> > [987021.379719] audit: type=1400 audit(1596533293.878:234):
> apparmor="DENIED" operation="signal" profile="demo" pid=24036 comm="kill"
> requested_mask="send" denied_mask="send" signal=term peer="/usr/bin/man"
> > [987021.379727] audit: type=1400 audit(1596533293.878:235):
> apparmor="DENIED" operation="signal" profile="/usr/bin/man" pid=24036
> comm="kill" requested_mask="receive" denied_mask="receive" signal=term
> peer="demo"
> >
> > notice no capabilities are needed to send the signal because its
> being sent from root to a root process
> >
> > ----
> >
> > confined root user without signal or CAP permission kill a non-root
> process (different uids)
> >
> > $ sudo aa-exec -p demo -- kill 24690
> > kill: (24690): Operation not permitted
> >
> > apparmor log message
> >
> > [989073.431936] audit: type=1400 audit(1596535345.981:238):
> apparmor="DENIED" operation="capable" profile="demo" pid=24717 comm="kill"
> capability=5 capname="kill"
> >
> > finally we get a CAP request for kill
> >
> >
> > The reason for this is that the kernel applies DAC mediation before
> LSM (apparmor) mediation. AppArmor never sees the permission request unless
> DAC allow the operation.
> >
> > > *Need further clarifications:*
> > >
> > > My aim is to identify the required capabilities for the process
> when it runs in "non-root" user.
> > > Currently, this process runs in root mode, so by default all CAPs
> are enabled in Effective/Permitted CAPs.
> > >
> > > Analysis:
> > >
> > > -> While the process runs in non-root mode, we are planning to
> apply the capabilities before switching to non-root from root.
> > > So, we need to set appropriate capabilities in order to run the
> application successfully in "non-root".
> > >
> > yes
> >
> > > -> As per my assumption, we will find the required capabilities
> when the process runs in root-mode. To find the required CAPs list
> > > we thought to use "apparmor" logs while the process runs in
> compliant mode.
> >
> > this doesn't quite work but you will be able to collect capabilities
> that don't rely on a uid check. This is because of how the kernel doesn't
> always apply a capability check, Eg. for kill CAPS are not always checked
> in the same way when subject uid == object uid vs. subject uid != object
> uid. The same can be said for DAC_OVERRIDE, DAC_READSEARCH, ...
> >
> > Some capabilities however aren't guarded by uid checks and you
> should be able to collect these caps when run as root. What you need to do
> to collect the full list of capabilities is give the non-root process all
> capabilities and run it. This should collect the full set of CAPs with how
> you are using uids.
> >
> >
> > > Once we get the CAPs list from Apparmor logs, then we shall use
> the same required CAPS only ( NOT all the CAPs) for the
> > > process when it runs in non-root mode.
> > >
> > > -> The idea is that we are trying to drop root privilege using
> this method.
> > >
> > > Can you please confirm , the above method is possible in apparmor
> event logs to find the required CAPs at least when run
> > > in "root" mode.
> > >
> >
> > close but see above, also you need to make sure exercise the
> application to get proper coverage
> >
> > > Thanks
> > > Murali.S
> > >
> > > On Mon, Aug 3, 2020 at 8:21 PM Seth Arnold <
> seth.arnold at canonical.com <mailto:seth.arnold at canonical.com> <mailto:
> seth.arnold at canonical.com <mailto:seth.arnold at canonical.com>>> wrote:
> > >
> > > Hello Murali,
> > >
> > > On Mon, Aug 03, 2020 at 02:03:38PM -0400, Murali Selvaraj
> wrote:
> > > > Query 1:
> > > >
> > > > - But I do not see CAP_DAC_OVERRIDE and CAP_KILL in apparmor
> event logs.
> > >
> > > AppArmor does not have a mechanism to grant capabilities that
> a process
> > > does not already have. The kernel will query LSMs to see if a
> capability
> > > is allowed to be used if the process already has the
> capability in
> > > question. (There may be exceptions to this, there's hundreds
> of these
> > > checks scattered throughout the kernel.)
> > >
> > > You'll only see these requests in AppArmor logs if the process
> had these
> > > capabilities. By using su to switch to the 'nobody' account,
> you only have
> > > access to whatever privileges the nobody account already has:
> additional
> > > access to root_squashed files on NFS, any other processes
> mistakenly
> > > running as user nobody, etc.
> > >
> > > Because this doesn't include any capabilities in the process's
> > > capabilities sets, AppArmor won't even see the requests.
> > >
> > > > Query 2:
> > > >
> > > > - How apparmor identities how many capabilities are needed
> for the process?
> > >
> > > The kernel will call capable() in the codepaths as necessary;
> the security
> > > module interface will get the calls, without context, after
> the rest of
> > > the kernel's capabilities handling. It's difficult to follow
> because it's
> > > been heavily optimized for performance.
> > >
> > > In any event, AppArmor will usually see capability requests
> after the
> > > usual DAC permissions are handled.
> > >
> > >
> > > > Query 3:
> > > >
> > > > - Does all system calls need capability when it runs in a
> non-root process,
> > > > how does apparmor mapping the linux capabilities?
> > >
> > > "root processes" means both uid 0 as well as having
> capabilities in the
> > > effective capability set. (Perhaps it'd also make sense to
> consider the
> > > other capability sets in the process?) A uid 0 process with no
> > > capabilities still has considerable power, since many
> important files like
> > > /etc/sudoers are owned by uid 0, and modifying these files
> through DAC
> > > permissions alone could be used to then gain capabilities.
> However, a uid
> > > 0 process with no capabilities couldn't itself initiate a
> reboot in the
> > > kernel, or override DAC restrictions on files, etc.
> > >
> > > A process with capabilities need not be uid 0 though I can't
> immediately
> > > point any common examples.
> > >
> > > Linux's uid namespaces makes things a bit more complicated: a
> process can
> > > have namespace-level capabilities that do not extend to
> capabilities in
> > > the init namespace. (Consider something like an LXD guest:
> there may be
> > > different users within the guest, and the 'root' user with the
> LXD guest
> > > can do privileged operations over the namespace, eg manage the
> routing
> > > table used for that network namespace, but not be able to
> manage the
> > > routing table used by the network namespace for the init
> process.)
> > >
> > > See the user_namespaces(7) and unshare(2) manpages for some
> more information.
> > >
> > > > Can someone please clarify these queries?
> > >
> > > I'm afraid my description probably made things worse.
> > >
> > > Let me try one quick simple thing:
> > >
> > > Run your example with and without root privileges. You'll see
> the
> > > difference in AppArmor log output. Hopefully that helps. :)
> > >
> > > Thanks
> > >
> > >
> >
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.ubuntu.com/archives/apparmor/attachments/20200809/2a8ab87b/attachment-0001.html>
More information about the AppArmor
mailing list