Skip to content

Commit 32e8514

Browse files
authored
Merge pull request #9403 from AriaXLi/rerevert_selinux
Revert "Merge pull request #9390 from AriaXLi/revert_selinux_matchpathcon"
2 parents d9265ab + 976f0ab commit 32e8514

File tree

6 files changed

+82
-20
lines changed

6 files changed

+82
-20
lines changed

Diff for: lib/puppet/provider/file/posix.rb

+16-2
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,22 @@
1212
require 'etc'
1313
require_relative '../../../puppet/util/selinux'
1414

15-
def self.post_resource_eval
16-
Selinux.matchpathcon_fini if Puppet::Util::SELinux.selinux_support?
15+
class << self
16+
def selinux_handle
17+
return nil unless Puppet::Util::SELinux.selinux_support?
18+
19+
# selabel_open takes 3 args: backend, options, and nopt. The backend param
20+
# is a constant, SELABEL_CTX_FILE, which happens to be 0. Since options is
21+
# nil, nopt can be 0 since nopt represents the # of options specified.
22+
@selinux_handle ||= Selinux.selabel_open(Selinux::SELABEL_CTX_FILE, nil, 0)
23+
end
24+
25+
def post_resource_eval
26+
if @selinux_handle
27+
Selinux.selabel_close(@selinux_handle)
28+
@selinux_handle = nil
29+
end
30+
end
1731
end
1832

1933
def uid2name(id)

Diff for: lib/puppet/type/file/selcontext.rb

+7-6
Original file line numberDiff line numberDiff line change
@@ -40,11 +40,12 @@ def retrieve
4040
end
4141

4242
def retrieve_default_context(property)
43+
return nil if Puppet::Util::Platform.windows?
4344
if @resource[:selinux_ignore_defaults] == :true
4445
return nil
4546
end
4647

47-
context = get_selinux_default_context(@resource[:path], @resource[:ensure])
48+
context = get_selinux_default_context_with_handle(@resource[:path], provider.class.selinux_handle)
4849
unless context
4950
return nil
5051
end
@@ -85,7 +86,7 @@ def sync
8586
end
8687

8788
Puppet::Type.type(:file).newparam(:selinux_ignore_defaults) do
88-
desc "If this is set then Puppet will not ask SELinux (via matchpathcon) to
89+
desc "If this is set then Puppet will not ask SELinux (via selabel_lookup) to
8990
supply defaults for the SELinux attributes (seluser, selrole,
9091
seltype, and selrange). In general, you should leave this set at its
9192
default and only set it to true when you need Puppet to not try to fix
@@ -98,7 +99,7 @@ def sync
9899
Puppet::Type.type(:file).newproperty(:seluser, :parent => Puppet::SELFileContext) do
99100
desc "What the SELinux user component of the context of the file should be.
100101
Any valid SELinux user component is accepted. For example `user_u`.
101-
If not specified it defaults to the value returned by matchpathcon for
102+
If not specified it defaults to the value returned by selabel_lookup for
102103
the file, if any exists. Only valid on systems with SELinux support
103104
enabled."
104105

@@ -109,7 +110,7 @@ def sync
109110
Puppet::Type.type(:file).newproperty(:selrole, :parent => Puppet::SELFileContext) do
110111
desc "What the SELinux role component of the context of the file should be.
111112
Any valid SELinux role component is accepted. For example `role_r`.
112-
If not specified it defaults to the value returned by matchpathcon for
113+
If not specified it defaults to the value returned by selabel_lookup for
113114
the file, if any exists. Only valid on systems with SELinux support
114115
enabled."
115116

@@ -120,7 +121,7 @@ def sync
120121
Puppet::Type.type(:file).newproperty(:seltype, :parent => Puppet::SELFileContext) do
121122
desc "What the SELinux type component of the context of the file should be.
122123
Any valid SELinux type component is accepted. For example `tmp_t`.
123-
If not specified it defaults to the value returned by matchpathcon for
124+
If not specified it defaults to the value returned by selabel_lookup for
124125
the file, if any exists. Only valid on systems with SELinux support
125126
enabled."
126127

@@ -132,7 +133,7 @@ def sync
132133
desc "What the SELinux range component of the context of the file should be.
133134
Any valid SELinux range component is accepted. For example `s0` or
134135
`SystemHigh`. If not specified it defaults to the value returned by
135-
matchpathcon for the file, if any exists. Only valid on systems with
136+
selabel_lookup for the file, if any exists. Only valid on systems with
136137
SELinux support enabled and that have support for MCS (Multi-Category
137138
Security)."
138139

Diff for: lib/puppet/util/selinux.rb

+14-4
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ def get_selinux_current_context(file)
4646

4747
# Retrieve and return the default context of the file. If we don't have
4848
# SELinux support or if the SELinux call fails to file a default then return nil.
49+
# @deprecated matchpathcon is a deprecated method, selabel_lookup is preferred
4950
def get_selinux_default_context(file, resource_ensure = nil)
5051
return nil unless selinux_support?
5152
# If the filesystem has no support for SELinux labels, return a default of nil
@@ -68,11 +69,20 @@ def get_selinux_default_context(file, resource_ensure = nil)
6869
end
6970

7071
retval = Selinux.matchpathcon(file, mode)
71-
if retval == -1
72-
return nil
73-
end
72+
retval == -1 ? nil : retval[1]
73+
end
7474

75-
retval[1]
75+
def get_selinux_default_context_with_handle(file, handle)
76+
return nil unless selinux_support?
77+
# If the filesystem has no support for SELinux labels, return a default of nil
78+
# instead of what selabel_lookup would return
79+
return nil unless selinux_label_support?(file)
80+
81+
# Handle is needed for selabel_lookup
82+
raise ArgumentError, _("Cannot get default context with nil handle") unless handle
83+
84+
retval = Selinux.selabel_lookup(handle, file, 0)
85+
retval == -1 ? nil : retval[1]
7686
end
7787

7888
# Take the full SELinux context returned from the tools and parse it

Diff for: spec/unit/transaction_spec.rb

+5-5
Original file line numberDiff line numberDiff line change
@@ -758,15 +758,15 @@ def post_resource_eval
758758
transaction.evaluate
759759
end
760760

761-
it "should call Selinux.matchpathcon_fini in case Selinux is enabled ", :if => Puppet.features.posix? do
762-
selinux = double('selinux', is_selinux_enabled: true, matchpathcon_fini: nil)
761+
it "should call Selinux.selabel_close in case Selinux is enabled", :if => Puppet.features.posix? do
762+
handle = double('selinux_handle')
763+
selinux = class_double('selinux', is_selinux_enabled: 1, selabel_close: nil, selabel_open: handle, selabel_lookup: -1)
763764
stub_const('Selinux', selinux)
764-
765+
stub_const('Selinux::SELABEL_CTX_FILE', 0)
765766
resource = Puppet::Type.type(:file).new(:path => make_absolute("/tmp/foo"))
766767
transaction = transaction_with_resource(resource)
767768

768-
expect(Selinux).to receive(:matchpathcon_fini)
769-
expect(Puppet::Util::SELinux).to receive(:selinux_support?).and_return(true)
769+
expect(Selinux).to receive(:selabel_close).with(handle)
770770

771771
transaction.evaluate
772772
end

Diff for: spec/unit/type/file/selinux_spec.rb

+11-3
Original file line numberDiff line numberDiff line change
@@ -50,13 +50,16 @@
5050
end
5151

5252
it "should handle no default gracefully" do
53-
expect(@sel).to receive(:get_selinux_default_context).with(@path, :file).and_return(nil)
53+
skip if Puppet::Util::Platform.windows?
54+
expect(@sel).to receive(:get_selinux_default_context_with_handle).with(@path, nil).and_return(nil)
5455
expect(@sel.default).to be_nil
5556
end
5657

57-
it "should be able to detect matchpathcon defaults" do
58+
it "should be able to detect default context on platforms other than Windows", unless: Puppet::Util::Platform.windows? do
5859
allow(@sel).to receive(:debug)
59-
expect(@sel).to receive(:get_selinux_default_context).with(@path, :file).and_return("user_u:role_r:type_t:s0")
60+
hnd = double("SWIG::TYPE_p_selabel_handle")
61+
allow(@sel.provider.class).to receive(:selinux_handle).and_return(hnd)
62+
expect(@sel).to receive(:get_selinux_default_context_with_handle).with(@path, hnd).and_return("user_u:role_r:type_t:s0")
6063
expectedresult = case param
6164
when :seluser; "user_u"
6265
when :selrole; "role_r"
@@ -66,6 +69,11 @@
6669
expect(@sel.default).to eq(expectedresult)
6770
end
6871

72+
it "returns nil default context on Windows", if: Puppet::Util::Platform.windows? do
73+
expect(@sel).to receive(:retrieve_default_context)
74+
expect(@sel.default).to be_nil
75+
end
76+
6977
it "should return nil for defaults if selinux_ignore_defaults is true" do
7078
@resource[:selinux_ignore_defaults] = :true
7179
expect(@sel.default).to be_nil

Diff for: spec/unit/util/selinux_spec.rb

+29
Original file line numberDiff line numberDiff line change
@@ -241,6 +241,35 @@
241241
end
242242
end
243243

244+
describe "get_selinux_default_context_with_handle" do
245+
it "should return a context if a default context exists" do
246+
without_partial_double_verification do
247+
expect(self).to receive(:selinux_support?).and_return(true)
248+
expect(self).to receive(:find_fs).with("/foo").and_return("ext3")
249+
hnd = double("SWIG::TYPE_p_selabel_handle")
250+
expect(Selinux).to receive(:selabel_lookup).with(hnd, '/foo', 0).and_return([0, "user_u:role_r:type_t:s0"])
251+
expect(get_selinux_default_context_with_handle("/foo", hnd)).to eq("user_u:role_r:type_t:s0")
252+
end
253+
end
254+
255+
it "should raise an ArgumentError when handle is nil" do
256+
allow(self).to receive(:selinux_support?).and_return(true)
257+
allow(self).to receive(:selinux_label_support?).and_return(true)
258+
expect{get_selinux_default_context_with_handle("/foo", nil)}.to raise_error(ArgumentError, /Cannot get default context with nil handle/)
259+
end
260+
261+
it "should return nil if there is no SELinux support" do
262+
expect(self).to receive(:selinux_support?).and_return(false)
263+
expect(get_selinux_default_context_with_handle("/foo", nil)).to be_nil
264+
end
265+
266+
it "should return nil if selinux_label_support returns false" do
267+
expect(self).to receive(:selinux_support?).and_return(true)
268+
expect(self).to receive(:find_fs).with("/foo").and_return("nfs")
269+
expect(get_selinux_default_context_with_handle("/foo", nil)).to be_nil
270+
end
271+
end
272+
244273
describe "parse_selinux_context" do
245274
it "should return nil if no context is passed" do
246275
expect(parse_selinux_context(:seluser, nil)).to be_nil

0 commit comments

Comments
 (0)