Re: [PATCH V2] Ensure correct monolithic binary policy is loaded

Chris PeBenito <[email protected]>
Newsgroups org.kernel.vger.selinux-refpolicy
Message-ID <[email protected]>
On 12/20/20 7:31 AM, Richard Haines wrote:
> On Sat, 2020-12-19 at 15:49 -0500, Chris PeBenito wrote:
>> On 12/18/20 10:03 AM, Richard Haines wrote:
>>> When building a monolithic policy with 'make load', the
>>> selinux_config(5) file 'SELINUXTYPE' entry determines what policy
>>> is loaded as load_policy(8) does not take a path value (it always
>>> loads
>>> the active system policy as defined by /etc/selinux/config).
>>>
>>> Currently it is possible to load the wrong binary policy, for
>>> example if
>>> the Reference Policy source is located at:
>>> /etc/selinux/refpolicy
>>> and the /etc/selinux/config file has the following entry:
>>> SELINUXTYPE=targeted
>>> Then the /etc/selinux/targeted/policy/policy.<ver> is loaded when
>>> 'make load' is executed.
>>>
>>> Another example is that if the Reference Policy source is located
>>> at:
>>> /tmp/custom-rootfs/etc/selinux/refpolicy
>>> and the /etc/selinux/config file has the following entry:
>>> SELINUXTYPE=refpolicy
>>> Then the /etc/selinux/refpolicy/policy/policy.<ver> is loaded when
>>> 'make DESTDIR=/tmp/custom-rootfs load' is executed (not the
>>> /tmp/custom-rootfs/etc/selinux/refpolicy/policy/policy.<ver> that
>>> the
>>> developer thought would be loaded).
>>>
>>> Resolve these issues by using selinux_path(3) to resolve the policy
>>> root,
>>> then checking the selinux_config(5) file for the appropriate
>>> SELINUXTYPE
>>> entry.
>>>
>>> Remove the '@touch $(tmpdir)/load' line as the file is never
>>> referenced.
>>>
>>> Signed-off-by: Richard Haines <[email protected]>
>>> ---
>>> V2 Changes: Use $(error .. instead of NO_LOAD logic. Use python
>>> script to
>>> find selinux path not sestatus. Reword error messages.
>>>
>>>    Makefile                |  1 +
>>>    Rules.monolithic        | 15 ++++++++++++++-
>>>    support/selinux_path.py | 13 +++++++++++++
>>>    3 files changed, 28 insertions(+), 1 deletion(-)
>>>    create mode 100644 support/selinux_path.py
>>>
>>> diff --git a/Makefile b/Makefile
>>> index 6ba215f1..e49d43d0 100644
>>> --- a/Makefile
>>> +++ b/Makefile
>>> @@ -97,6 +97,7 @@ genxml := $(PYTHON) $(support)/segenxml.py
>>>    gendoc := $(PYTHON) $(support)/sedoctool.py
>>>    genperm := $(PYTHON) $(support)/genclassperms.py
>>>    policyvers := $(PYTHON) $(support)/policyvers.py
>>> +selinux_path := $(PYTHON) $(support)/selinux_path.py
>>>    fcsort := $(PYTHON) $(support)/fc_sort.py
>>>    setbools := $(AWK) -f $(support)/set_bools_tuns.awk
>>>    get_type_attr_decl := $(SED) -r -f
>>> $(support)/get_type_attr_decl.sed
>>> diff --git a/Rules.monolithic b/Rules.monolithic
>>> index a8ae98d1..cd065362 100644
>>> --- a/Rules.monolithic
>>> +++ b/Rules.monolithic
>>> @@ -42,6 +42,12 @@ vpath %.te $(all_layers)
>>>    vpath %.if $(all_layers)
>>>    vpath %.fc $(all_layers)
>>>    
>>> +# load_policy(8) loads policy from
>>> <SELINUX_PATH>/<SELINUXTYPE>/policy/policy.<ver>
>>> +# It does this by reading the <SELINUX_PATH>/config file and using
>>> the
>>> +# SELINUX_PATH/SELINUXTYPE entries to form the initial path.
>>> +SELINUX_PATH := $(shell $(selinux_path))
>>> +SELINUXTYPE := $(strip $(shell $(AWK) -F= '/^SELINUXTYPE/{ print
>>> $$2 }' $(SELINUX_PATH)/config))
>>> +
>>>    ########################################
>>>    #
>>>    # default action: build policy locally
>>> @@ -91,9 +97,16 @@ endif
>>>    # Load the binary policy
>>>    #
>>>    reload $(tmpdir)/load: $(loadpath) $(fcpath) $(appfiles)
>>> +ifneq ($(SELINUXTYPE),$(NAME))
>>> +       $(error Cannot load policy as $(SELINUX_PATH)/config file
>>> contains SELINUXTYPE=$(SELINUXTYPE) - \
>>> +               Edit $(SELINUX_PATH)/config and set
>>> "SELINUXTYPE=$(NAME)")
>>> +endif
>>> +ifneq ($(topdir),$(SELINUX_PATH))
>>> +       $(error Cannot load policy as policy root MUST be
>>> $(SELINUX_PATH)/$(NAME) - \
>>> +               Current policy root is: $(topdir)/$(NAME))
>>> +endif
>>>          @echo "Loading $(NAME) $(loadpath)"
>>>          $(verbose) $(LOADPOLICY) -q $(loadpath)
>>> -       @touch $(tmpdir)/load
>>>    
>>>    ########################################
>>>    #
>>> diff --git a/support/selinux_path.py b/support/selinux_path.py
>>> new file mode 100644
>>> index 00000000..b663ff09
>>> --- /dev/null
>>> +++ b/support/selinux_path.py
>>> @@ -0,0 +1,13 @@
>>> +#!/usr/bin/env python3
>>> +
>>> +try:
>>> +    import warnings
>>> +    with warnings.catch_warnings():
>>> +        warnings.filterwarnings("ignore",
>>> category=PendingDeprecationWarning)
>>> +        import selinux
>>> +
>>> +    if selinux.is_selinux_enabled():
>>> +        # Strip the trailing '/'
>>> +        print(selinux.selinux_path()[:-1])
>>
>> Why not use selinux.selinux_binary_policy_path()? Then you don't need
>> to parse
>> for SELINUXTYPE above.
> 
> Because it has more information than needed. How about using
> selinux.selinux_policy_root() to give:
> 
> # load_policy(8) loads policy from <POLICY_ROOT>/policy/policy.<ver>
> # It does this by reading the <SELINUX_PATH>/config file and using the
> # SELINUX_PATH/SELINUXTYPE entry to form the <POLICY_ROOT>.
> POLICY_ROOT := $(shell $(selinux_policy_root))
> SELINUXTYPE := $(shell basename $(POLICY_ROOT))
> SELINUX_PATH := $(shell dirname $(POLICY_ROOT))

Ok, that works, though make has builtin versions of basename and dirname: 
https://www.gnu.org/software/make/manual/html_node/File-Name-Functions.html


-- 
Chris PeBenito
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.