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.johan...@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.johan...@canonical.com <mailto:john.johan...@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.arn...@canonical.com <mailto:seth.arn...@canonical.com> <mailto: > seth.arn...@canonical.com <mailto:seth.arn...@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 > > > > > > > > > >
-- AppArmor mailing list AppArmor@lists.ubuntu.com Modify settings or unsubscribe at: https://lists.ubuntu.com/mailman/listinfo/apparmor