From patchwork Tue Jul 26 15:15:25 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Miroslav Vadkerti X-Patchwork-Id: 9248335 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 0616B607D8 for ; Tue, 26 Jul 2016 15:22:03 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id E989E26B41 for ; Tue, 26 Jul 2016 15:22:02 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id DDC352723E; Tue, 26 Jul 2016 15:22:02 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-1.9 required=2.0 tests=BAYES_00 autolearn=unavailable version=3.3.1 Received: from emsm-gh1-uea10.nsa.gov (emsm-gh1-uea10.nsa.gov [8.44.101.8]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 02AFD26B41 for ; Tue, 26 Jul 2016 15:22:00 +0000 (UTC) X-IronPort-AV: E=Sophos;i="5.28,425,1464652800"; d="scan'208";a="15939497" IronPort-PHdr: =?us-ascii?q?9a23=3A7F3yjBfJ50pm5o3h4oRoTBrGlGMj4u6mDksu8pMi?= =?us-ascii?q?zoh2WeGdxc6/Zx7h7PlgxGXEQZ/co6odzbGH6+a+AidQvd6oizMrSNR0TRgLiM?= =?us-ascii?q?EbzUQLIfWuLgnFFsPsdDEwB89YVVVorDmROElRH9viNRWJ+iXhpQAbFhi3Dwdp?= =?us-ascii?q?POO9QteU1JXvkb7psM2PKyxzxxOFKYtoKxu3qQiD/uI3uqBFbpgL9x3Sv3FTcP?= =?us-ascii?q?5Xz247bXianhL7+9vitMU7q3cYhuglv/Jkfe26Ov1gDO8QMDNzKG0x5cv2pTHf?= =?us-ascii?q?XACP4T0aSWxQnR1WUCbf6xSve5brtTD+v/Q15iCWPsDsUbF8DTG85qtoRQX0oD?= =?us-ascii?q?0KOz4w7Cfcjckm3/ETmw6ouxEqm92cW4qSLvcrO/qFcA=3D=3D?= X-IPAS-Result: =?us-ascii?q?A2G1BgCPfpdX/wHyM5BeHAEBgyFWfLpzHQuHM0wBAQEBAQE?= =?us-ascii?q?CAlongjIEAxCCFAIEAQI3FCALAwMJAQEXKQgIAwEpBBURDgsFGASIEA65FAEBC?= =?us-ascii?q?AEBAQEBASGGKoYXgkgRAYV3BY4VixyGGIhjAoI4hzGFUgKQJVSDemwBhxOBNQE?= =?us-ascii?q?BAQ?= Received: from unknown (HELO tarius.tycho.ncsc.mil) ([144.51.242.1]) by emsm-gh1-uea10.nsa.gov with ESMTP; 26 Jul 2016 15:19:32 +0000 Received: from prometheus.infosec.tycho.ncsc.mil (prometheus [192.168.25.40]) by tarius.tycho.ncsc.mil (8.14.4/8.14.4) with ESMTP id u6QFHbG8019268; Tue, 26 Jul 2016 11:18:08 -0400 Received: from tarius.tycho.ncsc.mil (tarius.infosec.tycho.ncsc.mil [144.51.242.1]) by prometheus.infosec.tycho.ncsc.mil (8.15.2/8.15.2) with ESMTP id u6QFGRDs074323 for ; Tue, 26 Jul 2016 11:16:27 -0400 Received: from goalie.tycho.ncsc.mil (goalie [144.51.242.250]) by tarius.tycho.ncsc.mil (8.14.4/8.14.4) with ESMTP id u6QFGRBV019183 for ; Tue, 26 Jul 2016 11:16:27 -0400 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: A1BxAgDOfZdXhxy3hNFeHAEBg3d8pV6RDYQMJIV5AoE4TAEBAQEBARMBAQEKCwkJGYUMAgEDeRBRLSoZiDEOuQ4BAQEHAiWGKoYXiFEFjhWLHIYYiGMCgjiNAwKQJYJ1gVk6MgGISAEBAQ X-IPAS-Result: A1BxAgDOfZdXhxy3hNFeHAEBg3d8pV6RDYQMJIV5AoE4TAEBAQEBARMBAQEKCwkJGYUMAgEDeRBRLSoZiDEOuQ4BAQEHAiWGKoYXiFEFjhWLHIYYiGMCgjiNAwKQJYJ1gVk6MgGISAEBAQ X-IronPort-AV: E=Sophos;i="5.28,425,1464667200"; d="scan'208";a="5603364" Received: from emsm-gh1-uea10.corp.nsa.gov (HELO emsm-gh1-uea10.nsa.gov) ([10.208.41.36]) by goalie.tycho.ncsc.mil with ESMTP; 26 Jul 2016 11:16:17 -0400 IronPort-PHdr: =?us-ascii?q?9a23=3Ar/DpDhY4cVlai0br+7h4v8b/LSx+4OfEezUN459i?= =?us-ascii?q?sYplN5qZpc+ybnLW6fgltlLVR4KTs6sC0LuO9f67EjxZqb+681k6OKRWUBEEjc?= =?us-ascii?q?hE1ycBO+WiTXPBEfjxciYhF95DXlI2t1uyMExSBdqsLwaK+i760zceF13FOBZv?= =?us-ascii?q?IaytQ8iJ3pzxibv5q8SbSj4LrQL1Wal1IhSyoFeZnegtqqwmFJwMzADUqGBDYe?= =?us-ascii?q?VcyDAgD1uSmxHh+pX4p8Y7oGwD884motVNVaT8YrQQUa1TDDNgNXs8osLsq0rt?= =?us-ascii?q?VwyKs14dSGINlhNWSzbM4BL3RIvw+n//qONx2ySAIeXsQLw0UCjk5KBuHky7wB?= =?us-ascii?q?wbPiI0pTmEwvd7i7hW9Uqs?= X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: =?us-ascii?q?A0GiAwBWfZdXhxy3hNFeHAEBg3d8pV6RD?= =?us-ascii?q?YQMJIV5AoE4TAEBAQEBAQICDwEBAQoLCQkZL4IyFYIWAgEDeRBRLSoZiDEOuQw?= =?us-ascii?q?BAQEHAgEkhiqGF4hRBY4VixyGGIhjAoI4jQMCkCWCdYFZOjIBiEgBAQE?= X-IPAS-Result: =?us-ascii?q?A0GiAwBWfZdXhxy3hNFeHAEBg3d8pV6RDYQMJIV5AoE4TAE?= =?us-ascii?q?BAQEBAQICDwEBAQoLCQkZL4IyFYIWAgEDeRBRLSoZiDEOuQwBAQEHAgEkhiqGF?= =?us-ascii?q?4hRBY4VixyGGIhjAoI4jQMCkCWCdYFZOjIBiEgBAQE?= X-IronPort-AV: E=Sophos;i="5.28,425,1464652800"; d="scan'208";a="15939208" Received: from mx1.redhat.com ([209.132.183.28]) by emsm-gh1-uea10.nsa.gov with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 26 Jul 2016 15:15:46 +0000 Received: from int-mx14.intmail.prod.int.phx2.redhat.com (int-mx14.intmail.prod.int.phx2.redhat.com [10.5.11.27]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 0DB49800A8 for ; Tue, 26 Jul 2016 15:15:30 +0000 (UTC) Received: from crude.brq.redhat.com (crude.brq.redhat.com [10.34.24.82]) by int-mx14.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id u6QFFRZp016027; Tue, 26 Jul 2016 11:15:28 -0400 From: Miroslav Vadkerti To: selinux@tycho.nsa.gov Subject: [PATCH] semanage: add auditing of changes in records Date: Tue, 26 Jul 2016 17:15:25 +0200 Message-Id: <1469546125-19448-1-git-send-email-mvadkert@redhat.com> In-Reply-To: <[PATCH 1/2] semanage: add auditing of changes in records> References: <[PATCH 1/2] semanage: add auditing of changes in records> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.27 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.28]); Tue, 26 Jul 2016 15:15:30 +0000 (UTC) X-BeenThere: selinux@tycho.nsa.gov X-Mailman-Version: 2.1.20 Precedence: list List-Id: "Security-Enhanced Linux \(SELinux\) mailing list" List-Post: List-Help: Cc: linux-audit@redhat.com MIME-Version: 1.0 Errors-To: selinux-bounces@tycho.nsa.gov Sender: "Selinux" X-Virus-Scanned: ClamAV using ClamSMTP Common Criteria requirement FMT_MSA.1 needs any configuration change that affect enforcement of policy to be audited. This patch adds auditing of changes in security context mappings for network ports, interfaces, nodes and file contexts. A new function log_change is introduced that audits additions, modification and removal of the mappings via the USER_MAC_CONFIG_CHANGE audit event. The format of the audit events was discussed with the audit userspace maintainer. This patch resolves: https://bugzilla.redhat.com/show_bug.cgi?id=829175 Signed-off-by: Miroslav Vadkerti --- policycoreutils/semanage/seobject.py | 75 ++++++++++++++++++++++++++++++++++++ 1 file changed, 75 insertions(+) diff --git a/policycoreutils/semanage/seobject.py b/policycoreutils/semanage/seobject.py index 3b0b108..7d6caa3 100644 --- a/policycoreutils/semanage/seobject.py +++ b/policycoreutils/semanage/seobject.py @@ -82,6 +82,21 @@ file_type_str_to_option = {"all files": "a", "socket file": "s", "symbolic link": "l", "named pipe": "p"} + +proto_to_audit = {"tcp": 17, + "udp": 6, + "ipv4": 4, + "ipv6": 41} + +ftype_to_audit = {"": "any", + "b": "block", + "c": "char", + "d": "dir", + "f": "file", + "l": "symlink", + "p": "pipe", + "s": "socket"} + try: import audit @@ -90,6 +105,7 @@ try: def __init__(self): self.audit_fd = audit.audit_open() self.log_list = [] + self.log_change_list = [] def log(self, msg, name="", sename="", serole="", serange="", oldsename="", oldserole="", oldserange=""): @@ -109,10 +125,17 @@ try: def log_remove(self, msg, name="", sename="", serole="", serange="", oldsename="", oldserole="", oldserange=""): self.log_list.append([self.audit_fd, audit.AUDIT_ROLE_REMOVE, sys.argv[0], str(msg), name, 0, sename, serole, serange, oldsename, oldserole, oldserange, "", "", ""]) + def log_change(self, msg): + self.log_change_list.append([self.audit_fd, audit.AUDIT_USER_MAC_CONFIG_CHANGE, str(msg), "semanage", "", "", ""]) + def commit(self, success): for l in self.log_list: audit.audit_log_semanage_message(*(l + [success])) + for l in self.log_change_list: + audit.audit_log_user_comm_message(*(l + [success])) + self.log_list = [] + self.log_change_list = [] except: class logger: @@ -138,6 +161,9 @@ except: def log_remove(self, msg, name="", sename="", serole="", serange="", oldsename="", oldserole="", oldserange=""): self.log(msg, name, sename, serole, serange, oldsename, oldserole, oldserange) + def log_change(self, msg): + self.log_list.append(" %s" % msg) + def commit(self, success): if success == 1: message = "Successful: " @@ -155,6 +181,9 @@ class nulllogger: def log_remove(self, msg, name="", sename="", serole="", serange="", oldsename="", oldserole="", oldserange=""): pass + def log_change(self, msg): + pass + def commit(self, success): pass @@ -1109,6 +1138,8 @@ class portRecords(semanageRecords): semanage_port_key_free(k) semanage_port_free(p) + self.mylog.log_change("resrc=port op=add lport=%s proto=%s tcontext=%s:%s:%s:%s" % (port, proto_to_audit[proto], "system_u", "object_r", type, serange)) + def add(self, port, proto, serange, type): self.begin() self.__add(port, proto, serange, type) @@ -1150,6 +1181,8 @@ class portRecords(semanageRecords): semanage_port_key_free(k) semanage_port_free(p) + self.mylog.log_change("resrc=port op=modify lport=%s proto=%s tcontext=%s:%s:%s:%s" % (port, proto_to_audit[proto], "system_u", "object_r", setype, serange)) + def modify(self, port, proto, serange, setype): self.begin() self.__modify(port, proto, serange, setype) @@ -1168,6 +1201,7 @@ class portRecords(semanageRecords): low = semanage_port_get_low(port) high = semanage_port_get_high(port) port_str = "%s-%s" % (low, high) + (k, proto_d, low, high) = self.__genkey(port_str, proto_str) if rc < 0: raise ValueError(_("Could not create a key for %s") % port_str) @@ -1177,6 +1211,11 @@ class portRecords(semanageRecords): raise ValueError(_("Could not delete the port %s") % port_str) semanage_port_key_free(k) + if low == high: + port_str = low + + self.mylog.log_change("resrc=port op=delete lport=%s proto=%s" % (port_str, proto_to_audit[proto_str])) + self.commit() def __delete(self, port, proto): @@ -1199,6 +1238,8 @@ class portRecords(semanageRecords): semanage_port_key_free(k) + self.mylog.log_change("resrc=port op=delete lport=%s proto=%s" % (port, proto_to_audit[proto])) + def delete(self, port, proto): self.begin() self.__delete(port, proto) @@ -1380,6 +1421,8 @@ class nodeRecords(semanageRecords): semanage_node_key_free(k) semanage_node_free(node) + self.mylog.log_change("resrc=node op=add laddr=%s netmask=%s proto=%s tcontext=%s:%s:%s:%s" % (addr, mask, proto_to_audit[self.protocol[proto]], "system_u", "object_r", ctype, serange)) + def add(self, addr, mask, proto, serange, ctype): self.begin() self.__add(addr, mask, proto, serange, ctype) @@ -1421,6 +1464,8 @@ class nodeRecords(semanageRecords): semanage_node_key_free(k) semanage_node_free(node) + self.mylog.log_change("resrc=node op=modify laddr=%s netmask=%s proto=%s tcontext=%s:%s:%s:%s" % (addr, mask, proto_to_audit[self.protocol[proto]], "system_u", "object_r", setype, serange)) + def modify(self, addr, mask, proto, serange, setype): self.begin() self.__modify(addr, mask, proto, serange, setype) @@ -1452,6 +1497,8 @@ class nodeRecords(semanageRecords): semanage_node_key_free(k) + self.mylog.log_change("resrc=node op=delete laddr=%s netmask=%s proto=%s" % (addr, mask, proto_to_audit[self.protocol[proto]])) + def delete(self, addr, mask, proto): self.begin() self.__delete(addr, mask, proto) @@ -1581,6 +1628,8 @@ class interfaceRecords(semanageRecords): semanage_iface_key_free(k) semanage_iface_free(iface) + self.mylog.log_change("resrc=interface op=add netif=%s tcontext=%s:%s:%s:%s" % (interface, "system_u", "object_r", ctype, serange)) + def add(self, interface, serange, ctype): self.begin() self.__add(interface, serange, ctype) @@ -1618,6 +1667,8 @@ class interfaceRecords(semanageRecords): semanage_iface_key_free(k) semanage_iface_free(iface) + self.mylog.log_change("resrc=interface op=modify netif=%s tcontext=%s:%s:%s:%s" % (interface, "system_u", "object_r", setype, serange)) + def modify(self, interface, serange, setype): self.begin() self.__modify(interface, serange, setype) @@ -1646,6 +1697,8 @@ class interfaceRecords(semanageRecords): semanage_iface_key_free(k) + self.mylog.log_change("resrc=interface op=delete netif=%s" % interface) + def delete(self, interface): self.begin() self.__delete(interface) @@ -1775,6 +1828,8 @@ class fcontextRecords(semanageRecords): if i.startswith(target + "/"): raise ValueError(_("File spec %s conflicts with equivalency rule '%s %s'") % (target, i, fdict[i])) + self.mylog.log_change("resrc=fcontext op=add-equal %s %s" % (audit.audit_encode_nv_string("sglob", target, 0), audit.audit_encode_nv_string("tglob", substitute, 0))) + self.equiv[target] = substitute self.equal_ind = True self.commit() @@ -1785,6 +1840,9 @@ class fcontextRecords(semanageRecords): raise ValueError(_("Equivalence class for %s does not exists") % target) self.equiv[target] = substitute self.equal_ind = True + + self.mylog.log_change("resrc=fcontext op=modify-equal %s %s" % (audit.audit_encode_nv_string("sglob", target, 0), audit.audit_encode_nv_string("tglob", substitute, 0))) + self.commit() def createcon(self, target, seuser="system_u"): @@ -1879,6 +1937,11 @@ class fcontextRecords(semanageRecords): semanage_fcontext_key_free(k) semanage_fcontext_free(fcontext) + if not seuser: + seuser = "system_u" + + self.mylog.log_change("resrc=fcontext op=add %s ftype=%s tcontext=%s:%s:%s:%s" % (audit.audit_encode_nv_string("tglob", target, 0), ftype_to_audit[ftype], seuser, "object_r", type, serange)) + def add(self, target, type, ftype="", serange="", seuser="system_u"): self.begin() self.__add(target, type, ftype, serange, seuser) @@ -1939,6 +2002,11 @@ class fcontextRecords(semanageRecords): semanage_fcontext_key_free(k) semanage_fcontext_free(fcontext) + if not seuser: + seuser = "system_u" + + self.mylog.log_change("resrc=fcontext op=modify %s ftype=%s tcontext=%s:%s:%s:%s" % (audit.audit_encode_nv_string("tglob", target, 0), ftype_to_audit[ftype], seuser, "object_r", type, serange)) + def modify(self, target, setype, ftype, serange, seuser): self.begin() self.__modify(target, setype, ftype, serange, seuser) @@ -1964,6 +2032,8 @@ class fcontextRecords(semanageRecords): raise ValueError(_("Could not delete the file context %s") % target) semanage_fcontext_key_free(k) + self.mylog.log_change("resrc=fcontext op=delete %s ftype=%s" % (audit.audit_encode_nv_string("tglob", target, 0), ftype_to_audit[ftype_str])) + self.equiv = {} self.equal_ind = True self.commit() @@ -1972,6 +2042,9 @@ class fcontextRecords(semanageRecords): if target in self.equiv.keys(): self.equiv.pop(target) self.equal_ind = True + + self.mylog.log_change("resrc=fcontext op=delete-equal %s ftype=%s" % (audit.audit_encode_nv_string("tglob", target, 0), ftype_to_audit[ftype])) + return (rc, k) = semanage_fcontext_key_create(self.sh, target, file_types[ftype]) @@ -1996,6 +2069,8 @@ class fcontextRecords(semanageRecords): semanage_fcontext_key_free(k) + self.mylog.log_change("resrc=fcontext op=delete %s ftype=%s" % (audit.audit_encode_nv_string("tglob", target, 0), ftype_to_audit[ftype])) + def delete(self, target, ftype): self.begin() self.__delete(target, ftype)