Bug 1392573

Summary: semodule -l no longer returns version information
Product: Red Hat Enterprise Linux 7 Reporter: Marc St-Laurent <marc.st-laurent>
Component: policycoreutilsAssignee: Petr Lautrbach <plautrba>
Status: CLOSED ERRATA QA Contact: Dalibor Pospíšil <dapospis>
Severity: high Docs Contact: Mirek Jahoda <mjahoda>
Priority: urgent    
Version: 7.2CC: a.dekker, andrea.veri, aperotti, arusso, asadawar, christian.kaenzig, dapospis, dexter, dgross, dwalsh, egolov, erinn.looneytriggs, fabian.arrotin, fkrska, jbubeck, lvrabec, maurizio.antillon, mgrepl, mhjacks, mjahoda, mkolaja, mmalik, mueller, pdwyer, peter.vreman, plautrba, renato.ramonda, rik.theys, sajner.2, sreber, ssekidde, trevor.hemsley, yann.lopez
Target Milestone: rcKeywords: Regression, ZStream
Target Release: ---   
Hardware: x86_64   
OS: Linux   
Whiteboard:
Fixed In Version: policycoreutils-2.5-12.el7 Doc Type: If docs needed, set a value
Doc Text:
In Red Hat Enterprise Linux 7.3, the semodule tool did not show module versions. Consequently, tools such as Puppet, which expect module version in the output of the "semodule -l" command, stopped working or worked incorrectly. The libsemanage and semodule tools have been fixed to return a module version. If there is no module version available, "(null)" is printed.
Story Points: ---
Clone Of:
: 1395222 1395733 (view as bug list) Environment:
Last Closed: 2017-08-01 16:16:12 UTC Type: Bug
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: ---
Bug Depends On:    
Bug Blocks: 1391886, 1395222, 1395733    

Description Marc St-Laurent 2016-11-07 19:36:29 UTC
Description of problem: semodule -l used to return the list of installed policy modules *and* version information.  As of policycoreutils-2.5-8.el7.x86_64, the output only list the names.


Version-Release number of selected component (if applicable):

Name        : policycoreutils
Version     : 2.5
Release     : 8.el7
Architecture: x86_64
Install Date: Thu Nov  3 02:55:09 2016


How reproducible:
This is only occurring on one host so far.

Steps to Reproduce:
1. upgrade policycoreutils
2. run semodule -l

Actual results:
get list of installed policy module names only:
abrt
accountsd
acct
afs
aiccu
...


Expected results:
2 columns: names of installed policy modules:
abrt    1.4.1
accountsd       1.1.0
acct    1.6.0
afs     1.9.0
aiccu   1.1.0


Additional info:

Comment 1 Marc St-Laurent 2016-11-07 19:38:40 UTC
Under "How reproducible" I meant to say that we only have one rhel7 machine with this version of policycoreutils recently upgraded.

Comment 2 Aaron Russo 2016-11-07 22:01:57 UTC
I am seeing this issue as well. Since downgrading policycoreutils alone did not fix my issue, I was only able to narrow the issue down to the following packages via yum history. undoing this transaction fixed the issue, and redoing it recreated the issue.

...
Packages Altered:
    Updated libsemanage-2.1.10-18.el7.x86_64                  @ucb-patchmgmt-rhel-x86_64-server-7-weekly-current
    Update              2.5-4.el7.x86_64                      @ucb-patchmgmt-rhel-x86_64-server-7-weekly-current
    Updated libsemanage-python-2.1.10-18.el7.x86_64           @ucb-patchmgmt-rhel-x86_64-server-7-weekly-current
    Update                     2.5-4.el7.x86_64               @ucb-patchmgmt-rhel-x86_64-server-7-weekly-current
    Updated policycoreutils-2.2.5-20.el7.x86_64               @ucb-patchmgmt-rhel-x86_64-server-7-weekly-current
    Update                  2.5-8.el7.x86_64                  @ucb-patchmgmt-rhel-x86_64-server-7-weekly-current
    Updated policycoreutils-python-2.2.5-20.el7.x86_64        @ucb-patchmgmt-rhel-x86_64-server-7-weekly-current
    Update                         2.5-8.el7.x86_64           @ucb-patchmgmt-rhel-x86_64-server-7-weekly-current
    Updated selinux-policy-3.13.1-60.el7_2.9.noarch           @ucb-patchmgmt-rhel-x86_64-server-7-weekly-current
    Update                 3.13.1-102.el7_3.4.noarch          @ucb-patchmgmt-rhel-x86_64-server-7-weekly-current
    Updated selinux-policy-targeted-3.13.1-60.el7_2.9.noarch  @ucb-patchmgmt-rhel-x86_64-server-7-weekly-current
    Update                          3.13.1-102.el7_3.4.noarch @ucb-patchmgmt-rhel-x86_64-server-7-weekly-current
    Updated setools-libs-3.3.7-46.el7.x86_64                  @ucb-patchmgmt-rhel-x86_64-server-7-weekly-current
    Update               3.3.8-1.1.el7.x86_64                 @ucb-patchmgmt-rhel-x86_64-server-7-weekly-current
<snip>

Comment 5 Petr Lautrbach 2016-11-10 22:37:26 UTC
Since SELinux userspace 2.4 modules uses CIL and CIL doesn't have any component which would represent a module name or version. Therefore a module name is derived from a filename and a version completely dropped from semodule output.

However, original .pp files are stored together with cil files as hll files. It means that a version could be extracted from that file.

I prepared a patch and srpms [1] with libsemanage patched to look to try to extract a version from hll files if an original module was installed from .pp file. And semodule patched to accept another list option - legacy - which tries to provide same output as pre-2.4 releases, e.g.:

# semodule -l | tail -n 3    
zarafa
zebra
zoneminder

# semodule -lfull | tail -n 3
100 zebra             pp         
100 zoneminder        cil         
100 zosremote         pp disabled

# semodule -llegacy | tail -n 3
zebra   1.13.0
zoneminder      (null)
zosremote       1.2.0   Disabled



(null) at zoneminder means that the module was not installed from .pp file and there's no version available.


[1] https://plautrba.fedorapeople.org/copr/selinux-semodule-llegacy/

Comment 7 Martin Jackson 2016-11-10 23:26:05 UTC
Thanks for the reply, and the patch!

We typically install from .pp files.  Systems like puppet would need to "know" to use "-llegacy".  Is it reasonable to make the default "-l" behavior use the output format described by "-llegacy"?  (It would fix at least one major tool, and I would think the risk of reverting to the previous behavior would be quite low.)

For example, the relevant code in Puppet looks like this:

  def exists?
    self.debug "Checking for module #{@resource[:name]}"
    execpipe("#{command(:semodule)} --list") do |out|
      out.each_line do |line|
        if line =~ /#{@resource[:name]}\b/
          return :true
        end
      end
    end
    nil
  end

  def selmodversion_loaded
    lines = ()
    begin
      execpipe("#{command(:semodule)} --list") do |output|
        output.each_line do |line|
          line.chomp!
          bits = line.split
          if bits[0] == @resource[:name]
            self.debug "load version #{bits[1]}"
            return bits[1]
          end
        end
      end
    rescue Puppet::ExecutionFailure
      raise Puppet::ExecutionFailure, "Could not list policy modules: #{lines.join(' ').chomp!}", $!.backtrace
    end
    nil
  end

https://github.com/puppetlabs/puppet/blob/ebd96213cab43bb2a8071b7ac0206c3ed0be8e58/lib/puppet/provider/selmodule/semodule.rb

Comment 8 Martin Jackson 2016-11-10 23:32:34 UTC
There's also this:  I don't know enough about hte binary formats of .pp files to say if this would still work, but if that hasn't changed, I would think it should:

  def selmodversion_file
    magic = 0xF97CFF8F

    filename = selmod_name_to_filename
    mod = File.new(filename, "r")

    (hdr, ver, numsec) = mod.read(12).unpack('VVV')

    raise Puppet::Error, "Found #{hdr} instead of magic #{magic} in #{filename}" if hdr != magic

    raise Puppet::Error, "Unknown policy file version #{ver} in #{filename}" if ver != 1

    # Read through (and throw away) the file section offsets, and also
    # the magic header for the first section.

    mod.read((numsec + 1) * 4)

    ## Section 1 should be "SE Linux Module"

    selmod_readnext(mod)
    selmod_readnext(mod)

    # Skip past the section headers
    mod.read(14)

    # Module name
    selmod_readnext(mod)

    # At last!  the version

    v = selmod_readnext(mod)

    self.debug "file version #{v}"
    v
  end

(reference same URL as above for context)

Comment 9 Petr Lautrbach 2016-11-11 09:38:13 UTC
(In reply to Martin Jackson from comment #7)
> Thanks for the reply, and the patch!
> 
> We typically install from .pp files.  Systems like puppet would need to
> "know" to use "-llegacy".  Is it reasonable to make the default "-l"
> behavior use the output format described by "-llegacy"?  (It would fix at
> least one major tool, and I would think the risk of reverting to the
> previous behavior would be quite low.)

The downside of making this default is that it would diverge the default behavior from upstream, Fedora and other distributions which use recent (newer than 2015-02-02 release) SELinux userspace. I have to admit that -llegacy doesn't make it much better in sense of general compatibility.

Upstream removed versions the output list and a there's no version element in CIL because there were feelings that versions are not really used and they were even not enforced at all. 'semodule -i' and 'semodule -u' do the same thing and both don't check versions. E.g. ssh.pp in selinux-policy is being changed all the time while the module version is still same as it was in 2013.


> For example, the relevant code in Puppet looks like this:
> 
>   def exists?
>     self.debug "Checking for module #{@resource[:name]}"
>     execpipe("#{command(:semodule)} --list") do |out|
>       out.each_line do |line|
>         if line =~ /#{@resource[:name]}\b/
>           return :true
>         end
>       end
>     end
>     nil
>   end
> 
>   def selmodversion_loaded
>     lines = ()
>     begin
>       execpipe("#{command(:semodule)} --list") do |output|
>         output.each_line do |line|
>           line.chomp!
>           bits = line.split
>           if bits[0] == @resource[:name]
>             self.debug "load version #{bits[1]}"
>             return bits[1]
>           end
>         end
>       end
>     rescue Puppet::ExecutionFailure
>       raise Puppet::ExecutionFailure, "Could not list policy modules:
> #{lines.join(' ').chomp!}", $!.backtrace
>     end
>     nil
>   end
> 
> https://github.com/puppetlabs/puppet/blob/
> ebd96213cab43bb2a8071b7ac0206c3ed0be8e58/lib/puppet/provider/selmodule/
> semodule.rb

Comment 10 Petr Lautrbach 2016-11-11 09:39:35 UTC
*** Bug 1392154 has been marked as a duplicate of this bug. ***

Comment 21 Petr Lautrbach 2016-11-16 13:32:49 UTC
So we're adding module versions back to 'semodule -l' output what is basically the behaviour from rhel-7.2. 

# semodule -l
...
pegasus 1.9.0
permissivedomains       (null)
pesign  1.0.0
...

Note: disabled module are not shown in this list. In order to list them, you still need to use 'semodule -lfull'

Comment 23 Renato Ramonda 2016-11-24 13:11:30 UTC
Hello, 
this bug is impacting us too: we use ansible for automated policy deployment, including several custom policy packets. 

Obviously our playbooks use the current version to choose an update is needed (the update option is VERY useful: we have several self maintained policies with custom versioning for example).

So now every time the configuration management runs we reinstall all modules, which is inefficient, wrong, and adds seconds to the length of the run.

Are there any news about when an updated package will be available?

Comment 24 Erinn Looney-Triggs 2017-01-07 06:37:39 UTC
Ok, it is clear the RH folks had a long discussion here that we can't see. So what I would like to know is the versions are being added back, but is that being pushed upstream? Or is this a divergence for RH? 

Just trying to plan out tooling, serverspec is currently breaking because of this change.

-Erinn

Comment 25 Trevor Hemsley 2017-01-17 13:22:09 UTC
semodule -llegacy doesn't appear to work on 7.3 yet - is there an ETA for this regression to be fixed?

Comment 26 Petr Lautrbach 2017-01-17 13:26:45 UTC
The updated semodule will add module versions to 'semodule -l' output what is basically the behaviour from rhel-7.2. 

# semodule -l
...
pegasus 1.9.0
permissivedomains       (null)
pesign  1.0.0
...

Note: disabled module are not shown in this list. In order to list them, you still need to use 'semodule -lfull'

It will be part of the next minor updates - https://bugzilla.redhat.com/show_bug.cgi?id=1395733 - is already RELEASE_PENDING

Comment 29 errata-xmlrpc 2017-08-01 16:16:12 UTC
Since the problem described in this bug report should be
resolved in a recent advisory, it has been closed with a
resolution of ERRATA.

For information on the advisory, and where to find the updated
files, follow the link below.

If the solution does not work for you, open a new bug report.

https://access.redhat.com/errata/RHBA-2017:1883

Comment 30 Filip Krska 2019-07-19 12:59:05 UTC
(In reply to Erinn Looney-Triggs from comment #24)
> Ok, it is clear the RH folks had a long discussion here that we can't see.
> So what I would like to know is the versions are being added back, but is
> that being pushed upstream? Or is this a divergence for RH? 
> 
> Just trying to plan out tooling, serverspec is currently breaking because of
> this change.
> 
> -Erinn

There are no plans to revert to old behaviour neither upstream nor in RHEL 8, Fedora...

The background is summarized in attached public article:

https://access.redhat.com/solutions/2760071

Best Regards

Filip