mirror of
https://github.com/SELinuxProject/setools
synced 2025-04-24 20:29:56 +00:00
Switch DTA to use TypeAttr objects in the graph instead of strings.
This commit is contained in:
parent
eec812b997
commit
7b617bf938
@ -115,12 +115,15 @@ class DomainTransitionAnalysis(object):
|
|||||||
source, target, and rules for each
|
source, target, and rules for each
|
||||||
domain transition.
|
domain transition.
|
||||||
"""
|
"""
|
||||||
|
s = self.policy.lookup_type(source)
|
||||||
|
t = self.policy.lookup_type(target)
|
||||||
|
|
||||||
if self.rebuildgraph:
|
if self.rebuildgraph:
|
||||||
self._build_graph()
|
self._build_graph()
|
||||||
|
|
||||||
if source in self.G and target in self.G:
|
if s in self.G and t in self.G:
|
||||||
try:
|
try:
|
||||||
path = nx.shortest_path(self.G, source, target)
|
path = nx.shortest_path(self.G, s, t)
|
||||||
except nx.exception.NetworkXNoPath:
|
except nx.exception.NetworkXNoPath:
|
||||||
pass
|
pass
|
||||||
else:
|
else:
|
||||||
@ -143,12 +146,15 @@ class DomainTransitionAnalysis(object):
|
|||||||
source, target, and rules for each
|
source, target, and rules for each
|
||||||
domain transition.
|
domain transition.
|
||||||
"""
|
"""
|
||||||
|
s = self.policy.lookup_type(source)
|
||||||
|
t = self.policy.lookup_type(target)
|
||||||
|
|
||||||
if self.rebuildgraph:
|
if self.rebuildgraph:
|
||||||
self._build_graph()
|
self._build_graph()
|
||||||
|
|
||||||
if source in self.G and target in self.G:
|
if s in self.G and t in self.G:
|
||||||
try:
|
try:
|
||||||
paths = nx.all_simple_paths(self.G, source, target, maxlen)
|
paths = nx.all_simple_paths(self.G, s, t, maxlen)
|
||||||
except nx.exception.NetworkXNoPath:
|
except nx.exception.NetworkXNoPath:
|
||||||
pass
|
pass
|
||||||
else:
|
else:
|
||||||
@ -170,25 +176,28 @@ class DomainTransitionAnalysis(object):
|
|||||||
source, target, and rules for each
|
source, target, and rules for each
|
||||||
domain transition.
|
domain transition.
|
||||||
"""
|
"""
|
||||||
|
s = self.policy.lookup_type(source)
|
||||||
|
t = self.policy.lookup_type(target)
|
||||||
|
|
||||||
if self.rebuildgraph:
|
if self.rebuildgraph:
|
||||||
self._build_graph()
|
self._build_graph()
|
||||||
|
|
||||||
if source in self.G and target in self.G:
|
if s in self.G and t in self.G:
|
||||||
try:
|
try:
|
||||||
paths = nx.all_shortest_paths(self.G, source, target)
|
paths = nx.all_shortest_paths(self.G, s, t)
|
||||||
except nx.exception.NetworkXNoPath:
|
except nx.exception.NetworkXNoPath:
|
||||||
pass
|
pass
|
||||||
else:
|
else:
|
||||||
for p in paths:
|
for p in paths:
|
||||||
yield self.__get_steps(p)
|
yield self.__get_steps(p)
|
||||||
|
|
||||||
def transitions(self, source):
|
def transitions(self, type_):
|
||||||
"""
|
"""
|
||||||
Generator which yields all domain transitions out of a
|
Generator which yields all domain transitions out of a
|
||||||
specified source type.
|
specified source type.
|
||||||
|
|
||||||
Parameters:
|
Parameters:
|
||||||
source The starting type.
|
type_ The starting type.
|
||||||
|
|
||||||
Yield: generator(steps)
|
Yield: generator(steps)
|
||||||
|
|
||||||
@ -196,10 +205,12 @@ class DomainTransitionAnalysis(object):
|
|||||||
source, target, and rules for each
|
source, target, and rules for each
|
||||||
domain transition.
|
domain transition.
|
||||||
"""
|
"""
|
||||||
|
s = self.policy.lookup_type(type_)
|
||||||
|
|
||||||
if self.rebuildgraph:
|
if self.rebuildgraph:
|
||||||
self._build_graph()
|
self._build_graph()
|
||||||
|
|
||||||
for source, target in self.G.out_edges_iter(source):
|
for source, target in self.G.out_edges_iter(s):
|
||||||
yield source, target, \
|
yield source, target, \
|
||||||
self.G.edge[source][target]['transition'], \
|
self.G.edge[source][target]['transition'], \
|
||||||
self.__get_entrypoints(source, target), \
|
self.__get_entrypoints(source, target), \
|
||||||
@ -289,8 +300,6 @@ class DomainTransitionAnalysis(object):
|
|||||||
# 3. if the edge has an invalid dyntrans, clear the related
|
# 3. if the edge has an invalid dyntrans, clear the related
|
||||||
# lists on the edge.
|
# lists on the edge.
|
||||||
#
|
#
|
||||||
# Note: strings are used for node names temporarily, until the
|
|
||||||
# string->TypeAttr object lookup code is implemented.
|
|
||||||
def _build_graph(self):
|
def _build_graph(self):
|
||||||
self.G.clear()
|
self.G.clear()
|
||||||
|
|
||||||
@ -310,7 +319,7 @@ class DomainTransitionAnalysis(object):
|
|||||||
|
|
||||||
for r in self.policy.terules():
|
for r in self.policy.terules():
|
||||||
if r.ruletype == "allow":
|
if r.ruletype == "allow":
|
||||||
if str(r.tclass) not in ["process", "file"]:
|
if r.tclass not in ["process", "file"]:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
perms = r.perms
|
perms = r.perms
|
||||||
@ -318,47 +327,47 @@ class DomainTransitionAnalysis(object):
|
|||||||
if r.tclass == "process":
|
if r.tclass == "process":
|
||||||
if "transition" in perms:
|
if "transition" in perms:
|
||||||
for s, t in itertools.product(
|
for s, t in itertools.product(
|
||||||
(str(s) for s in r.source.expand()),
|
r.source.expand(),
|
||||||
(str(t) for t in r.target.expand())):
|
r.target.expand()):
|
||||||
self.__add_edge(s, t)
|
self.__add_edge(s, t)
|
||||||
self.G[s][t]['transition'].append(r)
|
self.G[s][t]['transition'].append(r)
|
||||||
|
|
||||||
if "dyntransition" in perms:
|
if "dyntransition" in perms:
|
||||||
for s, t in itertools.product(
|
for s, t in itertools.product(
|
||||||
(str(s) for s in r.source.expand()),
|
r.source.expand(),
|
||||||
(str(t) for t in r.target.expand())):
|
r.target.expand()):
|
||||||
self.__add_edge(s, t)
|
self.__add_edge(s, t)
|
||||||
self.G[s][t]['dyntransition'].append(r)
|
self.G[s][t]['dyntransition'].append(r)
|
||||||
|
|
||||||
if "setexec" in perms:
|
if "setexec" in perms:
|
||||||
for s in r.source.expand():
|
for s in r.source.expand():
|
||||||
setexec[str(s)].append(r)
|
setexec[s].append(r)
|
||||||
|
|
||||||
if "setcurrent" in perms:
|
if "setcurrent" in perms:
|
||||||
for s in r.source.expand():
|
for s in r.source.expand():
|
||||||
setcurrent[str(s)].append(r)
|
setcurrent[s].append(r)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
if "execute" in perms:
|
if "execute" in perms:
|
||||||
for s, t in itertools.product(
|
for s, t in itertools.product(
|
||||||
(str(s) for s in r.source.expand()),
|
r.source.expand(),
|
||||||
(str(t) for t in r.target.expand())):
|
r.target.expand()):
|
||||||
execute[s][t].append(r)
|
execute[s][t].append(r)
|
||||||
|
|
||||||
if "entrypoint" in perms:
|
if "entrypoint" in perms:
|
||||||
for s, t in itertools.product(
|
for s, t in itertools.product(
|
||||||
(str(s) for s in r.source.expand()),
|
r.source.expand(),
|
||||||
(str(t) for t in r.target.expand())):
|
r.target.expand()):
|
||||||
entrypoint[s][t].append(r)
|
entrypoint[s][t].append(r)
|
||||||
|
|
||||||
elif r.ruletype == "type_transition":
|
elif r.ruletype == "type_transition":
|
||||||
if r.tclass != "process":
|
if r.tclass != "process":
|
||||||
continue
|
continue
|
||||||
|
|
||||||
d = str(r.default)
|
d = r.default
|
||||||
for s, t in itertools.product(
|
for s, t in itertools.product(
|
||||||
(str(s) for s in r.source.expand()),
|
r.source.expand(),
|
||||||
(str(t) for t in r.target.expand())):
|
r.target.expand()):
|
||||||
type_trans[s][t][d].append(r)
|
type_trans[s][t][d].append(r)
|
||||||
|
|
||||||
invalid_edge = []
|
invalid_edge = []
|
||||||
|
57
tests/dta.py
57
tests/dta.py
@ -36,20 +36,29 @@ class InfoFlowAnalysisTest(unittest.TestCase):
|
|||||||
# don't check node list since the disconnected nodes are not
|
# don't check node list since the disconnected nodes are not
|
||||||
# removed after removing invalid domain transitions
|
# removed after removing invalid domain transitions
|
||||||
|
|
||||||
edges = sorted(self.a.G.out_edges_iter())
|
start = self.p.lookup_type("start")
|
||||||
self.assertListEqual([("dyntrans100", "bothtrans200"),
|
trans1 = self.p.lookup_type("trans1")
|
||||||
("start", "dyntrans100"),
|
trans2 = self.p.lookup_type("trans2")
|
||||||
("start", "trans1"),
|
trans3 = self.p.lookup_type("trans3")
|
||||||
("trans1", "trans2"),
|
trans4 = self.p.lookup_type("trans4")
|
||||||
("trans2", "trans3"),
|
trans5 = self.p.lookup_type("trans5")
|
||||||
("trans3", "trans5")], edges)
|
dyntrans100 = self.p.lookup_type("dyntrans100")
|
||||||
|
bothtrans200 = self.p.lookup_type("bothtrans200")
|
||||||
|
|
||||||
|
edges = set(self.a.G.out_edges_iter())
|
||||||
|
self.assertSetEqual(set([(dyntrans100, bothtrans200),
|
||||||
|
(start, dyntrans100),
|
||||||
|
(start, trans1),
|
||||||
|
(trans1, trans2),
|
||||||
|
(trans2, trans3),
|
||||||
|
(trans3, trans5)]), edges)
|
||||||
|
|
||||||
def test_001_bothtrans(self):
|
def test_001_bothtrans(self):
|
||||||
"""DTA: type_transition, setexeccon(), and setcon() transitions."""
|
"""DTA: type_transition, setexeccon(), and setcon() transitions."""
|
||||||
|
|
||||||
s = "dyntrans100"
|
s = self.p.lookup_type("dyntrans100")
|
||||||
t = "bothtrans200"
|
t = self.p.lookup_type("bothtrans200")
|
||||||
e = "bothtrans200_exec"
|
e = self.p.lookup_type("bothtrans200_exec")
|
||||||
|
|
||||||
# regular transition
|
# regular transition
|
||||||
r = self.a.G.edge[s][t]["transition"]
|
r = self.a.G.edge[s][t]["transition"]
|
||||||
@ -133,8 +142,8 @@ class InfoFlowAnalysisTest(unittest.TestCase):
|
|||||||
def test_010_dyntrans(self):
|
def test_010_dyntrans(self):
|
||||||
"""DTA: setcon() transition."""
|
"""DTA: setcon() transition."""
|
||||||
|
|
||||||
s = "start"
|
s = self.p.lookup_type("start")
|
||||||
t = "dyntrans100"
|
t = self.p.lookup_type("dyntrans100")
|
||||||
|
|
||||||
# regular transition
|
# regular transition
|
||||||
r = self.a.G.edge[s][t]["transition"]
|
r = self.a.G.edge[s][t]["transition"]
|
||||||
@ -179,9 +188,9 @@ class InfoFlowAnalysisTest(unittest.TestCase):
|
|||||||
def test_020_trans(self):
|
def test_020_trans(self):
|
||||||
"""DTA: type_transition transition."""
|
"""DTA: type_transition transition."""
|
||||||
|
|
||||||
s = "start"
|
s = self.p.lookup_type("start")
|
||||||
t = "trans1"
|
t = self.p.lookup_type("trans1")
|
||||||
e = "trans1_exec"
|
e = self.p.lookup_type("trans1_exec")
|
||||||
|
|
||||||
# regular transition
|
# regular transition
|
||||||
r = self.a.G.edge[s][t]["transition"]
|
r = self.a.G.edge[s][t]["transition"]
|
||||||
@ -247,9 +256,9 @@ class InfoFlowAnalysisTest(unittest.TestCase):
|
|||||||
def test_030_setexec(self):
|
def test_030_setexec(self):
|
||||||
"""DTA: setexec() transition."""
|
"""DTA: setexec() transition."""
|
||||||
|
|
||||||
s = "trans1"
|
s = self.p.lookup_type("trans1")
|
||||||
t = "trans2"
|
t = self.p.lookup_type("trans2")
|
||||||
e = "trans2_exec"
|
e = self.p.lookup_type("trans2_exec")
|
||||||
|
|
||||||
# regular transition
|
# regular transition
|
||||||
r = self.a.G.edge[s][t]["transition"]
|
r = self.a.G.edge[s][t]["transition"]
|
||||||
@ -312,9 +321,9 @@ class InfoFlowAnalysisTest(unittest.TestCase):
|
|||||||
def test_040_two_entrypoint(self):
|
def test_040_two_entrypoint(self):
|
||||||
"""DTA: 2 entrypoints, only one by type_transition."""
|
"""DTA: 2 entrypoints, only one by type_transition."""
|
||||||
|
|
||||||
s = "trans2"
|
s = self.p.lookup_type("trans2")
|
||||||
t = "trans3"
|
t = self.p.lookup_type("trans3")
|
||||||
e = ["trans3_exec1", "trans3_exec2"]
|
e = [self.p.lookup_type("trans3_exec1"), self.p.lookup_type("trans3_exec2")]
|
||||||
|
|
||||||
# regular transition
|
# regular transition
|
||||||
r = self.a.G.edge[s][t]["transition"]
|
r = self.a.G.edge[s][t]["transition"]
|
||||||
@ -404,9 +413,9 @@ class InfoFlowAnalysisTest(unittest.TestCase):
|
|||||||
def test_050_cond_type_trans(self):
|
def test_050_cond_type_trans(self):
|
||||||
"""DTA: conditional type_transition."""
|
"""DTA: conditional type_transition."""
|
||||||
|
|
||||||
s = "trans3"
|
s = self.p.lookup_type("trans3")
|
||||||
t = "trans5"
|
t = self.p.lookup_type("trans5")
|
||||||
e = "trans5_exec"
|
e = self.p.lookup_type("trans5_exec")
|
||||||
|
|
||||||
# regular transition
|
# regular transition
|
||||||
r = self.a.G.edge[s][t]["transition"]
|
r = self.a.G.edge[s][t]["transition"]
|
||||||
|
Loading…
Reference in New Issue
Block a user