Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Setting booleans causes duplicate ports in semanage listings #50

Closed
carlosefr opened this issue Mar 27, 2017 · 7 comments
Closed

Setting booleans causes duplicate ports in semanage listings #50

carlosefr opened this issue Mar 27, 2017 · 7 comments

Comments

@carlosefr
Copy link

I've noticed a strange interaction with custom ports and booleans. After setting a boolean, the list of ports for a particular type (which has been customized) shows duplicate entries.

Example:

$ semanage port -a -t http_port_t -p tcp 12345
$ semanage port -l | grep http_port_t
http_port_t                    tcp      12345, 80, 81, 443, 488, 8008, 8009, 8443, 9000
$ setsebool -P zebra_write_config false
$ semanage port -l | grep http_port_t
http_port_t                    tcp      12345, 12345, 80, 81, 443, 488, 8008, 8009, 8443, 9000
$ setsebool -P zebra_write_config false
$ semanage port -l | grep http_port_t
http_port_t                    tcp      12345, 12345, 12345, 80, 81, 443, 488, 8008, 8009, 8443, 9000

As can be seen, each time a boolean is set persistently (it doesn't matter which boolean or which state), the custom port 12345 is duplicated. Running semodule -B clears the duplicates.

However, if only the local customizations are listed, the port is always listed only once:

$ semanage port -l -C
SELinux Port Type              Proto    Port Number

http_port_t                    tcp      12345

I'm using CentOS:

$ cat /etc/centos-release
CentOS Linux release 7.3.1611 (Core)
$ rpm -qf /usr/sbin/semanage 
policycoreutils-python-2.5-11.el7_3.x86_64
@stephensmalley
Copy link
Member

Thanks for the bug report. Did you open a bug on Red Hat's bugzilla too? If not, would recommend it.
We generally prefer that people raise issues on the mailing list as not everyone follows github; subscribe via selinux-join AT tycho.nsa.gov; you can always open an issue here and then post a summary to the list. I can reproduce with the upstream, but the most obvious fix would impose a non-trivial performance cost on setsebool, so will have to investigate further.

@carlosefr
Copy link
Author

I din't open a bug in Red Hat's bugzilla because I'm using CentOS and don't known their policy on this.

I'll repost to that list with a link to this issue.

@stephensmalley
Copy link
Member

Well, it is reproducible on Fedora, and they take bugs against Fedora certainly.

@carlosefr
Copy link
Author

Ok, I guess I can spin up a Fedora VM quickly enough. :)

@stephensmalley
Copy link
Member

BTW, the root cause seems to be commit e5aaa01 (mea culpa), which was an attempt to optimize setting booleans by not re-linking modules in that case. The problem though is that it seems the existing linked policy already includes the local customizations (e.g. your port addition) and then we end up adding it again to the final policy. Not sure yet if that was always a problem since that commit or if it got brought it when CIL was merged.

@carlosefr
Copy link
Author

Red Hat Bugzilla issue here: https://bugzilla.redhat.com/show_bug.cgi?id=1439875

fishilico pushed a commit to fishilico/selinux-notforked that referenced this issue Apr 10, 2017
…leans."

commit e5aaa01 ("Skip policy module
re-link when only setting booleans.") can lead to duplicate entries
(e.g. portcon entries) being added into the kernel policy because the
existing linked policy already includes the local customizations.
Revert this commit until we can come up with an approach that handles
this properly.  This means that setsebool -P triggers a full policy
rebuild.

From the original bug report:
I've noticed a strange interaction with custom ports and booleans.
After setting a boolean, the list of ports for a particular type
(which has been customized) shows duplicate entries.

Example:

    $ semanage port -a -t http_port_t -p tcp 12345
    $ semanage port -l | grep http_port_t
    http_port_t                    tcp      12345, 80, 81, ...
    $ setsebool -P zebra_write_config false
    $ semanage port -l | grep http_port_t
    http_port_t                    tcp      12345, 12345, 80, 81, ...
    $ setsebool -P zebra_write_config false
    $ semanage port -l | grep http_port_t
    http_port_t                    tcp      12345, 12345, 12345, 80, 81, ...

As can be seen, each time a boolean is set persistently (it doesn't
matter which boolean or which state), the custom port 12345 is
duplicated. Running "semodule -B" clears the duplicates.

However, if only the local customizations are listed, the port is
always listed only once:

    $ semanage port -l -C
    SELinux Port Type              Proto    Port Number
    http_port_t                    tcp      12345

Resolves: SELinuxProject/selinux#50
Reported-by: Carlos Rodrigues <cefrodrigues@gmail.com>
Signed-off-by: Stephen Smalley <sds@tycho.nsa.gov>
fishilico pushed a commit to fishilico/selinux-notforked that referenced this issue Apr 10, 2017
…leans."

commit e5aaa01 ("Skip policy module
re-link when only setting booleans.") can lead to duplicate entries
(e.g. portcon entries) being added into the kernel policy because the
existing linked policy already includes the local customizations.
Revert this commit until we can come up with an approach that handles
this properly.  This means that setsebool -P triggers a full policy
rebuild.

From the original bug report:
I've noticed a strange interaction with custom ports and booleans.
After setting a boolean, the list of ports for a particular type
(which has been customized) shows duplicate entries.

Example:

    $ semanage port -a -t http_port_t -p tcp 12345
    $ semanage port -l | grep http_port_t
    http_port_t                    tcp      12345, 80, 81, ...
    $ setsebool -P zebra_write_config false
    $ semanage port -l | grep http_port_t
    http_port_t                    tcp      12345, 12345, 80, 81, ...
    $ setsebool -P zebra_write_config false
    $ semanage port -l | grep http_port_t
    http_port_t                    tcp      12345, 12345, 12345, 80, 81, ...

As can be seen, each time a boolean is set persistently (it doesn't
matter which boolean or which state), the custom port 12345 is
duplicated. Running "semodule -B" clears the duplicates.

However, if only the local customizations are listed, the port is
always listed only once:

    $ semanage port -l -C
    SELinux Port Type              Proto    Port Number
    http_port_t                    tcp      12345

Resolves: SELinuxProject/selinux#50
Reported-by: Carlos Rodrigues <cefrodrigues@gmail.com>
Signed-off-by: Stephen Smalley <sds@tycho.nsa.gov>
@stephensmalley
Copy link
Member

Commit b61922f resolves this in the simplest way possible, i.e. reverting the breaking change, but results in a significant slowdown and memory overhead for setsebool -P. A follow-on patch has been posted to the list that should restore the optimization without yielding this incorrect behavior.

fishilico pushed a commit to fishilico/selinux-notforked that referenced this issue Apr 11, 2017
In commit b61922f ("libsemanage: revert
"Skip policy module re-link when only setting booleans"), we reverted
an optimization for setting booleans since it produced incorrect behavior.
This incorrect behavior was due to operating on the policy with local
changes already merged. However, reverting this change leaves us with
undesirable overhead for setsebool -P.  We also have long wanted
to support the same optimization for making other changes that do
not truly require module re-compilation/re-linking.

If we save the linked policy prior to merging local changes, we
can skip re-linking the policy modules in most cases, thereby
significantly improvement the performance and memory overhead of
semanage and setsebool -P commands.  Save the linked policy in the
policy sandbox and use it when we are not making a change that requires
recompilation of the CIL modules.  With this change, a re-link
is not performed when setting booleans or when adding, deleting, or
modifying port, node, interface, user, login (seusers) or fcontext
mappings.  We save linked versions of the kernel policy, seusers,
and users_extra produced from the CIL modules before any local
changes are merged.  This has an associated storage cost, primarily
storing an extra copy of the kernel policy file.

Before:
$ time setsebool -P zebra_write_config=1
real	0m8.714s
user	0m7.937s
sys	0m0.748s

After:
$ time setsebool -P zebra_write_config=1
real	0m1.070s
user	0m0.343s
sys	0m0.703s

Resolves: SELinuxProject/selinux#50
Reported-by: Carlos Rodrigues <cefrodrigues@gmail.com>
Signed-off-by: Stephen Smalley <sds@tycho.nsa.gov>
fishilico pushed a commit to fishilico/selinux-notforked that referenced this issue Apr 11, 2017
In commit b61922f ("libsemanage: revert
"Skip policy module re-link when only setting booleans"), we reverted
an optimization for setting booleans since it produced incorrect behavior.
This incorrect behavior was due to operating on the policy with local
changes already merged. However, reverting this change leaves us with
undesirable overhead for setsebool -P.  We also have long wanted
to support the same optimization for making other changes that do
not truly require module re-compilation/re-linking.

If we save the linked policy prior to merging local changes, we
can skip re-linking the policy modules in most cases, thereby
significantly improvement the performance and memory overhead of
semanage and setsebool -P commands.  Save the linked policy in the
policy sandbox and use it when we are not making a change that requires
recompilation of the CIL modules.  With this change, a re-link
is not performed when setting booleans or when adding, deleting, or
modifying port, node, interface, user, login (seusers) or fcontext
mappings.  We save linked versions of the kernel policy, seusers,
and users_extra produced from the CIL modules before any local
changes are merged.  This has an associated storage cost, primarily
storing an extra copy of the kernel policy file.

Before:
$ time setsebool -P zebra_write_config=1
real	0m8.714s
user	0m7.937s
sys	0m0.748s

After:
$ time setsebool -P zebra_write_config=1
real	0m1.070s
user	0m0.343s
sys	0m0.703s

Resolves: SELinuxProject/selinux#50
Reported-by: Carlos Rodrigues <cefrodrigues@gmail.com>
Signed-off-by: Stephen Smalley <sds@tycho.nsa.gov>
fishilico pushed a commit to fishilico/selinux-notforked that referenced this issue Apr 12, 2017
In commit b61922f ("libsemanage: revert
"Skip policy module re-link when only setting booleans"), we reverted
an optimization for setting booleans since it produced incorrect behavior.
This incorrect behavior was due to operating on the policy with local
changes already merged. However, reverting this change leaves us with
undesirable overhead for setsebool -P.  We also have long wanted
to support the same optimization for making other changes that do
not truly require module re-compilation/re-linking.

If we save the linked policy prior to merging local changes, we
can skip re-linking the policy modules in most cases, thereby
significantly improvement the performance and memory overhead of
semanage and setsebool -P commands.  Save the linked policy in the
policy sandbox and use it when we are not making a change that requires
recompilation of the CIL modules.  With this change, a re-link
is not performed when setting booleans or when adding, deleting, or
modifying port, node, interface, user, login (seusers) or fcontext
mappings.  We save linked versions of the kernel policy, seusers,
and users_extra produced from the CIL modules before any local
changes are merged.  This has an associated storage cost, primarily
storing an extra copy of the kernel policy file.

Before:
$ time setsebool -P zebra_write_config=1
real	0m8.714s
user	0m7.937s
sys	0m0.748s

After:
$ time setsebool -P zebra_write_config=1
real	0m1.070s
user	0m0.343s
sys	0m0.703s

Resolves: SELinuxProject/selinux#50
Reported-by: Carlos Rodrigues <cefrodrigues@gmail.com>
Signed-off-by: Stephen Smalley <sds@tycho.nsa.gov>
bachradsusi pushed a commit to fedora-selinux/selinux that referenced this issue Apr 18, 2017
…leans."

commit e5aaa01 ("Skip policy module
re-link when only setting booleans.") can lead to duplicate entries
(e.g. portcon entries) being added into the kernel policy because the
existing linked policy already includes the local customizations.
Revert this commit until we can come up with an approach that handles
this properly.  This means that setsebool -P triggers a full policy
rebuild.

From the original bug report:
I've noticed a strange interaction with custom ports and booleans.
After setting a boolean, the list of ports for a particular type
(which has been customized) shows duplicate entries.

Example:

    $ semanage port -a -t http_port_t -p tcp 12345
    $ semanage port -l | grep http_port_t
    http_port_t                    tcp      12345, 80, 81, ...
    $ setsebool -P zebra_write_config false
    $ semanage port -l | grep http_port_t
    http_port_t                    tcp      12345, 12345, 80, 81, ...
    $ setsebool -P zebra_write_config false
    $ semanage port -l | grep http_port_t
    http_port_t                    tcp      12345, 12345, 12345, 80, 81, ...

As can be seen, each time a boolean is set persistently (it doesn't
matter which boolean or which state), the custom port 12345 is
duplicated. Running "semodule -B" clears the duplicates.

However, if only the local customizations are listed, the port is
always listed only once:

    $ semanage port -l -C
    SELinux Port Type              Proto    Port Number
    http_port_t                    tcp      12345

Resolves: SELinuxProject/selinux#50
Reported-by: Carlos Rodrigues <cefrodrigues@gmail.com>
Signed-off-by: Stephen Smalley <sds@tycho.nsa.gov>
(cherry picked from SELinuxProject commit b61922f)
bachradsusi pushed a commit to fedora-selinux/selinux that referenced this issue Apr 18, 2017
In commit b61922f ("libsemanage: revert
"Skip policy module re-link when only setting booleans"), we reverted
an optimization for setting booleans since it produced incorrect behavior.
This incorrect behavior was due to operating on the policy with local
changes already merged. However, reverting this change leaves us with
undesirable overhead for setsebool -P.  We also have long wanted
to support the same optimization for making other changes that do
not truly require module re-compilation/re-linking.

If we save the linked policy prior to merging local changes, we
can skip re-linking the policy modules in most cases, thereby
significantly improvement the performance and memory overhead of
semanage and setsebool -P commands.  Save the linked policy in the
policy sandbox and use it when we are not making a change that requires
recompilation of the CIL modules.  With this change, a re-link
is not performed when setting booleans or when adding, deleting, or
modifying port, node, interface, user, login (seusers) or fcontext
mappings.  We save linked versions of the kernel policy, seusers,
and users_extra produced from the CIL modules before any local
changes are merged.  This has an associated storage cost, primarily
storing an extra copy of the kernel policy file.

Before:
$ time setsebool -P zebra_write_config=1
real	0m8.714s
user	0m7.937s
sys	0m0.748s

After:
$ time setsebool -P zebra_write_config=1
real	0m1.070s
user	0m0.343s
sys	0m0.703s

Resolves: SELinuxProject/selinux#50
Reported-by: Carlos Rodrigues <cefrodrigues@gmail.com>
Signed-off-by: Stephen Smalley <sds@tycho.nsa.gov>
(cherry picked from SELinuxProject commit 8702a86)
bachradsusi pushed a commit to fedora-selinux/selinux that referenced this issue Apr 18, 2017
…leans."

commit e5aaa01 ("Skip policy module
re-link when only setting booleans.") can lead to duplicate entries
(e.g. portcon entries) being added into the kernel policy because the
existing linked policy already includes the local customizations.
Revert this commit until we can come up with an approach that handles
this properly.  This means that setsebool -P triggers a full policy
rebuild.

From the original bug report:
I've noticed a strange interaction with custom ports and booleans.
After setting a boolean, the list of ports for a particular type
(which has been customized) shows duplicate entries.

Example:

    $ semanage port -a -t http_port_t -p tcp 12345
    $ semanage port -l | grep http_port_t
    http_port_t                    tcp      12345, 80, 81, ...
    $ setsebool -P zebra_write_config false
    $ semanage port -l | grep http_port_t
    http_port_t                    tcp      12345, 12345, 80, 81, ...
    $ setsebool -P zebra_write_config false
    $ semanage port -l | grep http_port_t
    http_port_t                    tcp      12345, 12345, 12345, 80, 81, ...

As can be seen, each time a boolean is set persistently (it doesn't
matter which boolean or which state), the custom port 12345 is
duplicated. Running "semodule -B" clears the duplicates.

However, if only the local customizations are listed, the port is
always listed only once:

    $ semanage port -l -C
    SELinux Port Type              Proto    Port Number
    http_port_t                    tcp      12345

Resolves: SELinuxProject/selinux#50
Reported-by: Carlos Rodrigues <cefrodrigues@gmail.com>
Signed-off-by: Stephen Smalley <sds@tycho.nsa.gov>
(cherry picked from SELinuxProject commit b61922f)
bachradsusi pushed a commit to fedora-selinux/selinux that referenced this issue Apr 18, 2017
In commit b61922f ("libsemanage: revert
"Skip policy module re-link when only setting booleans"), we reverted
an optimization for setting booleans since it produced incorrect behavior.
This incorrect behavior was due to operating on the policy with local
changes already merged. However, reverting this change leaves us with
undesirable overhead for setsebool -P.  We also have long wanted
to support the same optimization for making other changes that do
not truly require module re-compilation/re-linking.

If we save the linked policy prior to merging local changes, we
can skip re-linking the policy modules in most cases, thereby
significantly improvement the performance and memory overhead of
semanage and setsebool -P commands.  Save the linked policy in the
policy sandbox and use it when we are not making a change that requires
recompilation of the CIL modules.  With this change, a re-link
is not performed when setting booleans or when adding, deleting, or
modifying port, node, interface, user, login (seusers) or fcontext
mappings.  We save linked versions of the kernel policy, seusers,
and users_extra produced from the CIL modules before any local
changes are merged.  This has an associated storage cost, primarily
storing an extra copy of the kernel policy file.

Before:
$ time setsebool -P zebra_write_config=1
real	0m8.714s
user	0m7.937s
sys	0m0.748s

After:
$ time setsebool -P zebra_write_config=1
real	0m1.070s
user	0m0.343s
sys	0m0.703s

Resolves: SELinuxProject/selinux#50
Reported-by: Carlos Rodrigues <cefrodrigues@gmail.com>
Signed-off-by: Stephen Smalley <sds@tycho.nsa.gov>
(cherry picked from SELinuxProject commit 8702a86)
bachradsusi pushed a commit to fedora-selinux/selinux that referenced this issue Jul 28, 2017
…leans."

commit e5aaa01 ("Skip policy module
re-link when only setting booleans.") can lead to duplicate entries
(e.g. portcon entries) being added into the kernel policy because the
existing linked policy already includes the local customizations.
Revert this commit until we can come up with an approach that handles
this properly.  This means that setsebool -P triggers a full policy
rebuild.

From the original bug report:
I've noticed a strange interaction with custom ports and booleans.
After setting a boolean, the list of ports for a particular type
(which has been customized) shows duplicate entries.

Example:

    $ semanage port -a -t http_port_t -p tcp 12345
    $ semanage port -l | grep http_port_t
    http_port_t                    tcp      12345, 80, 81, ...
    $ setsebool -P zebra_write_config false
    $ semanage port -l | grep http_port_t
    http_port_t                    tcp      12345, 12345, 80, 81, ...
    $ setsebool -P zebra_write_config false
    $ semanage port -l | grep http_port_t
    http_port_t                    tcp      12345, 12345, 12345, 80, 81, ...

As can be seen, each time a boolean is set persistently (it doesn't
matter which boolean or which state), the custom port 12345 is
duplicated. Running "semodule -B" clears the duplicates.

However, if only the local customizations are listed, the port is
always listed only once:

    $ semanage port -l -C
    SELinux Port Type              Proto    Port Number
    http_port_t                    tcp      12345

Resolves: SELinuxProject/selinux#50
Reported-by: Carlos Rodrigues <cefrodrigues@gmail.com>
Signed-off-by: Stephen Smalley <sds@tycho.nsa.gov>
(cherry picked from SELinuxProject commit b61922f)
bachradsusi pushed a commit to fedora-selinux/selinux that referenced this issue Jul 28, 2017
In commit b61922f ("libsemanage: revert
"Skip policy module re-link when only setting booleans"), we reverted
an optimization for setting booleans since it produced incorrect behavior.
This incorrect behavior was due to operating on the policy with local
changes already merged. However, reverting this change leaves us with
undesirable overhead for setsebool -P.  We also have long wanted
to support the same optimization for making other changes that do
not truly require module re-compilation/re-linking.

If we save the linked policy prior to merging local changes, we
can skip re-linking the policy modules in most cases, thereby
significantly improvement the performance and memory overhead of
semanage and setsebool -P commands.  Save the linked policy in the
policy sandbox and use it when we are not making a change that requires
recompilation of the CIL modules.  With this change, a re-link
is not performed when setting booleans or when adding, deleting, or
modifying port, node, interface, user, login (seusers) or fcontext
mappings.  We save linked versions of the kernel policy, seusers,
and users_extra produced from the CIL modules before any local
changes are merged.  This has an associated storage cost, primarily
storing an extra copy of the kernel policy file.

Before:
$ time setsebool -P zebra_write_config=1
real	0m8.714s
user	0m7.937s
sys	0m0.748s

After:
$ time setsebool -P zebra_write_config=1
real	0m1.070s
user	0m0.343s
sys	0m0.703s

Resolves: SELinuxProject/selinux#50
Reported-by: Carlos Rodrigues <cefrodrigues@gmail.com>
Signed-off-by: Stephen Smalley <sds@tycho.nsa.gov>
(cherry picked from SELinuxProject commit 8702a86)
chenyt9 pushed a commit to MotorolaMobilityLLC/external-selinux that referenced this issue Jul 6, 2018
…leans."

commit e5aaa01 ("Skip policy module
re-link when only setting booleans.") can lead to duplicate entries
(e.g. portcon entries) being added into the kernel policy because the
existing linked policy already includes the local customizations.
Revert this commit until we can come up with an approach that handles
this properly.  This means that setsebool -P triggers a full policy
rebuild.

From the original bug report:
I've noticed a strange interaction with custom ports and booleans.
After setting a boolean, the list of ports for a particular type
(which has been customized) shows duplicate entries.

Example:

    $ semanage port -a -t http_port_t -p tcp 12345
    $ semanage port -l | grep http_port_t
    http_port_t                    tcp      12345, 80, 81, ...
    $ setsebool -P zebra_write_config false
    $ semanage port -l | grep http_port_t
    http_port_t                    tcp      12345, 12345, 80, 81, ...
    $ setsebool -P zebra_write_config false
    $ semanage port -l | grep http_port_t
    http_port_t                    tcp      12345, 12345, 12345, 80, 81, ...

As can be seen, each time a boolean is set persistently (it doesn't
matter which boolean or which state), the custom port 12345 is
duplicated. Running "semodule -B" clears the duplicates.

However, if only the local customizations are listed, the port is
always listed only once:

    $ semanage port -l -C
    SELinux Port Type              Proto    Port Number
    http_port_t                    tcp      12345

Resolves: SELinuxProject/selinux#50
Reported-by: Carlos Rodrigues <cefrodrigues@gmail.com>
Signed-off-by: Stephen Smalley <sds@tycho.nsa.gov>
chenyt9 pushed a commit to MotorolaMobilityLLC/external-selinux that referenced this issue Jul 6, 2018
In commit b61922f ("libsemanage: revert
"Skip policy module re-link when only setting booleans"), we reverted
an optimization for setting booleans since it produced incorrect behavior.
This incorrect behavior was due to operating on the policy with local
changes already merged. However, reverting this change leaves us with
undesirable overhead for setsebool -P.  We also have long wanted
to support the same optimization for making other changes that do
not truly require module re-compilation/re-linking.

If we save the linked policy prior to merging local changes, we
can skip re-linking the policy modules in most cases, thereby
significantly improvement the performance and memory overhead of
semanage and setsebool -P commands.  Save the linked policy in the
policy sandbox and use it when we are not making a change that requires
recompilation of the CIL modules.  With this change, a re-link
is not performed when setting booleans or when adding, deleting, or
modifying port, node, interface, user, login (seusers) or fcontext
mappings.  We save linked versions of the kernel policy, seusers,
and users_extra produced from the CIL modules before any local
changes are merged.  This has an associated storage cost, primarily
storing an extra copy of the kernel policy file.

Before:
$ time setsebool -P zebra_write_config=1
real	0m8.714s
user	0m7.937s
sys	0m0.748s

After:
$ time setsebool -P zebra_write_config=1
real	0m1.070s
user	0m0.343s
sys	0m0.703s

Resolves: SELinuxProject/selinux#50
Reported-by: Carlos Rodrigues <cefrodrigues@gmail.com>
Signed-off-by: Stephen Smalley <sds@tycho.nsa.gov>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants