From 713359e1b8f6794357edc280a826528a3811bcee Mon Sep 17 00:00:00 2001 From: Joe MacDonald Date: Sun, 28 Sep 2014 22:34:09 -0400 Subject: userspace: update core selinux userspace tools Update to the latest stable release, 20140506. Signed-off-by: Joe MacDonald --- recipes-security/selinux/checkpolicy.inc | 2 +- recipes-security/selinux/checkpolicy_2.2.bb | 9 - recipes-security/selinux/checkpolicy_2.3.bb | 7 + recipes-security/selinux/libselinux_2.2.2.bb | 16 - recipes-security/selinux/libselinux_2.3.bb | 14 + recipes-security/selinux/libsemanage_2.2.bb | 19 - recipes-security/selinux/libsemanage_2.3.bb | 17 + recipes-security/selinux/libsepol_2.2.bb | 9 - recipes-security/selinux/libsepol_2.3.bb | 7 + recipes-security/selinux/policycoreutils.inc | 2 +- recipes-security/selinux/policycoreutils_2.2.5.bb | 18 - recipes-security/selinux/policycoreutils_2.3.bb | 16 + recipes-security/selinux/selinux_20131030.inc | 5 - recipes-security/selinux/selinux_20140506.inc | 5 + recipes-security/selinux/selinux_git.inc | 2 +- recipes-security/selinux/sepolgen_1.2.1.bb | 4 +- ...Changes-to-support-named-file_trans-rules.patch | 1511 -------------------- ...rect-invalid-prototype-for-lsetfilecon_ra.patch | 34 + recipes-security/setools/setools_3.3.8.bb | 3 +- 19 files changed, 106 insertions(+), 1594 deletions(-) delete mode 100644 recipes-security/selinux/checkpolicy_2.2.bb create mode 100644 recipes-security/selinux/checkpolicy_2.3.bb delete mode 100644 recipes-security/selinux/libselinux_2.2.2.bb create mode 100644 recipes-security/selinux/libselinux_2.3.bb delete mode 100644 recipes-security/selinux/libsemanage_2.2.bb create mode 100644 recipes-security/selinux/libsemanage_2.3.bb delete mode 100644 recipes-security/selinux/libsepol_2.2.bb create mode 100644 recipes-security/selinux/libsepol_2.3.bb delete mode 100644 recipes-security/selinux/policycoreutils_2.2.5.bb create mode 100644 recipes-security/selinux/policycoreutils_2.3.bb delete mode 100644 recipes-security/selinux/selinux_20131030.inc create mode 100644 recipes-security/selinux/selinux_20140506.inc delete mode 100644 recipes-security/setools/setools/setools-Changes-to-support-named-file_trans-rules.patch create mode 100644 recipes-security/setools/setools/setools-replcon-correct-invalid-prototype-for-lsetfilecon_ra.patch diff --git a/recipes-security/selinux/checkpolicy.inc b/recipes-security/selinux/checkpolicy.inc index e0c7377..1a21680 100644 --- a/recipes-security/selinux/checkpolicy.inc +++ b/recipes-security/selinux/checkpolicy.inc @@ -11,7 +11,7 @@ LICENSE = "GPLv2+" DEPENDS += "libsepol libselinux bison-native flex-native" -SRC_URI += "file://checkpolicy-Do-not-link-against-libfl.patch" +#SRC_URI += "file://checkpolicy-Do-not-link-against-libfl.patch" EXTRA_OEMAKE += "PREFIX=${D}" EXTRA_OEMAKE += "LEX='flex'" diff --git a/recipes-security/selinux/checkpolicy_2.2.bb b/recipes-security/selinux/checkpolicy_2.2.bb deleted file mode 100644 index 23d57c1..0000000 --- a/recipes-security/selinux/checkpolicy_2.2.bb +++ /dev/null @@ -1,9 +0,0 @@ -PR = "r99" - -include selinux_20131030.inc -include ${BPN}.inc - -LIC_FILES_CHKSUM = "file://COPYING;md5=393a5ca445f6965873eca0259a17f833" - -SRC_URI[md5sum] = "d76d5c70cd594fdb15f8d319c6536324" -SRC_URI[sha256sum] = "5d74075379cbaf17135c2a113a3053bd2e7b2a2c54ac04458de652457306c020" diff --git a/recipes-security/selinux/checkpolicy_2.3.bb b/recipes-security/selinux/checkpolicy_2.3.bb new file mode 100644 index 0000000..9f68487 --- /dev/null +++ b/recipes-security/selinux/checkpolicy_2.3.bb @@ -0,0 +1,7 @@ +include selinux_20140506.inc +include ${BPN}.inc + +LIC_FILES_CHKSUM = "file://COPYING;md5=393a5ca445f6965873eca0259a17f833" + +SRC_URI[md5sum] = "920f1a048b6023a22e1bae7b40fd413c" +SRC_URI[sha256sum] = "8072c12121613ba943417bbb6d33224d12373ea19d75c5acd1846a35e0e05b74" diff --git a/recipes-security/selinux/libselinux_2.2.2.bb b/recipes-security/selinux/libselinux_2.2.2.bb deleted file mode 100644 index d6502ad..0000000 --- a/recipes-security/selinux/libselinux_2.2.2.bb +++ /dev/null @@ -1,16 +0,0 @@ -PR = "r99" - -include selinux_20131030.inc -include ${BPN}.inc - -LIC_FILES_CHKSUM = "file://LICENSE;md5=84b4d2c6ef954a2d4081e775a270d0d0" - -SRC_URI[md5sum] = "c13ea5de171f21fee399abfd4aef9481" -SRC_URI[sha256sum] = "cc8354d67d7bef11fb2a03d23e788c6f4e8510b6760c3778dc7baf6dcfa97539" - -SRC_URI += "\ - file://libselinux-drop-Wno-unused-but-set-variable.patch \ - file://libselinux-make-O_CLOEXEC-optional.patch \ - file://libselinux-make-SOCK_CLOEXEC-optional.patch \ - file://libselinux-define-FD_CLOEXEC-as-necessary.patch \ - " diff --git a/recipes-security/selinux/libselinux_2.3.bb b/recipes-security/selinux/libselinux_2.3.bb new file mode 100644 index 0000000..81e599d --- /dev/null +++ b/recipes-security/selinux/libselinux_2.3.bb @@ -0,0 +1,14 @@ +include selinux_20140506.inc +include ${BPN}.inc + +LIC_FILES_CHKSUM = "file://LICENSE;md5=84b4d2c6ef954a2d4081e775a270d0d0" + +SRC_URI[md5sum] = "d27e249ad8450e7182203134cf4d85e2" +SRC_URI[sha256sum] = "03fe2baa7ceeea531a64fd321b44ecf09a55f3af5ef66a58a4135944f34e9851" + +SRC_URI += "\ + file://libselinux-drop-Wno-unused-but-set-variable.patch \ + file://libselinux-make-O_CLOEXEC-optional.patch \ + file://libselinux-make-SOCK_CLOEXEC-optional.patch \ + file://libselinux-define-FD_CLOEXEC-as-necessary.patch \ + " diff --git a/recipes-security/selinux/libsemanage_2.2.bb b/recipes-security/selinux/libsemanage_2.2.bb deleted file mode 100644 index 1f00d07..0000000 --- a/recipes-security/selinux/libsemanage_2.2.bb +++ /dev/null @@ -1,19 +0,0 @@ -PR = "r99" - -include selinux_20131030.inc -include ${BPN}.inc - -LIC_FILES_CHKSUM = "file://COPYING;md5=a6f89e2100d9b6cdffcea4f398e37343" - -SRC_URI[md5sum] = "2bb8f4b728a5667519764297b7725c19" -SRC_URI[sha256sum] = "9b421ce1df10594cb467eef37faeb403d5c6b341a4b7e4b407ac4cb77df95cba" - -SRC_URI += "\ - file://libsemanage-Fix-execve-segfaults-on-Ubuntu.patch \ - file://libsemanage-fix-path-len-limit.patch \ - file://libsemanage-fix-path-nologin.patch \ - file://libsemanage-drop-Wno-unused-but-set-variable.patch \ - file://libsemanage-define-FD_CLOEXEC-as-necessary.patch;striplevel=2 \ - file://libsemanage-allow-to-disable-audit-support.patch \ - file://libsemanage-disable-expand-check-on-policy-load.patch \ - " diff --git a/recipes-security/selinux/libsemanage_2.3.bb b/recipes-security/selinux/libsemanage_2.3.bb new file mode 100644 index 0000000..5eada94 --- /dev/null +++ b/recipes-security/selinux/libsemanage_2.3.bb @@ -0,0 +1,17 @@ +include selinux_20140506.inc +include ${BPN}.inc + +LIC_FILES_CHKSUM = "file://COPYING;md5=a6f89e2100d9b6cdffcea4f398e37343" + +SRC_URI[md5sum] = "cc313b400637d94e3a549bf77555d8c3" +SRC_URI[sha256sum] = "4c984379a98ee9f05b80ff6e57dd2de886273d7136146456cabdce21ac32ed7f" + +SRC_URI += "\ + file://libsemanage-Fix-execve-segfaults-on-Ubuntu.patch \ + file://libsemanage-fix-path-len-limit.patch \ + file://libsemanage-fix-path-nologin.patch \ + file://libsemanage-drop-Wno-unused-but-set-variable.patch \ + file://libsemanage-define-FD_CLOEXEC-as-necessary.patch;striplevel=2 \ + file://libsemanage-allow-to-disable-audit-support.patch \ + file://libsemanage-disable-expand-check-on-policy-load.patch \ + " diff --git a/recipes-security/selinux/libsepol_2.2.bb b/recipes-security/selinux/libsepol_2.2.bb deleted file mode 100644 index a0b7df7..0000000 --- a/recipes-security/selinux/libsepol_2.2.bb +++ /dev/null @@ -1,9 +0,0 @@ -PR = "r99" - -include selinux_20131030.inc -include ${BPN}.inc - -LIC_FILES_CHKSUM = "file://COPYING;md5=a6f89e2100d9b6cdffcea4f398e37343" - -SRC_URI[md5sum] = "2d43599ed29fea9ef41218ec9635ef64" -SRC_URI[sha256sum] = "fbd77459fd03979a9020289b10c89a0af56a52bcd0f7ae0a78455713bb04878b" diff --git a/recipes-security/selinux/libsepol_2.3.bb b/recipes-security/selinux/libsepol_2.3.bb new file mode 100644 index 0000000..0c07d41 --- /dev/null +++ b/recipes-security/selinux/libsepol_2.3.bb @@ -0,0 +1,7 @@ +include selinux_20140506.inc +include ${BPN}.inc + +LIC_FILES_CHKSUM = "file://COPYING;md5=a6f89e2100d9b6cdffcea4f398e37343" + +SRC_URI[md5sum] = "c6b3dc07bf19ab4f364f21bbecb44beb" +SRC_URI[sha256sum] = "5a4481bfd0fad6fdad1511c786d69de1fc3eddc28154eae1691e1bf4e9e505c3" diff --git a/recipes-security/selinux/policycoreutils.inc b/recipes-security/selinux/policycoreutils.inc index 153b688..44a5861 100644 --- a/recipes-security/selinux/policycoreutils.inc +++ b/recipes-security/selinux/policycoreutils.inc @@ -211,7 +211,7 @@ FILES_${PN}-setsebool += "\ FILES_system-config-selinux = " \ ${bindir}/sepolgen \ ${datadir}/system-config-selinux/* \ - ${datadir}/icons/hicolor/24x24/apps/system-config-selinux.png \ + ${datadir}/icons/hicolor/ \ ${datadir}/polkit-1/actions/org.selinux.config.policy \ " diff --git a/recipes-security/selinux/policycoreutils_2.2.5.bb b/recipes-security/selinux/policycoreutils_2.2.5.bb deleted file mode 100644 index 96cf354..0000000 --- a/recipes-security/selinux/policycoreutils_2.2.5.bb +++ /dev/null @@ -1,18 +0,0 @@ -PR = "r99" - -include selinux_20131030.inc -include ${BPN}.inc - -LIC_FILES_CHKSUM = "file://COPYING;md5=393a5ca445f6965873eca0259a17f833" - -SRC_URI[md5sum] = "f330a90c566c8b564858d45399ce3dd1" -SRC_URI[sha256sum] = "3d2c8806742004693c2d4726abbc4f412340ee07bed407976dd8abeda09a4333" - -SRC_URI += "\ - file://policycoreutils-fix-sepolicy-install-path.patch \ - file://policycoreutils-make-O_CLOEXEC-optional.patch \ - file://policycoreutils-loadpolicy-symlink.patch \ - file://policycoreutils-semanage-edit-user.patch \ - file://policycoreutils-process-ValueError-for-sepolicy-seobject.patch \ - file://policycoreutils-fix-TypeError-for-seobject.py.patch \ - " diff --git a/recipes-security/selinux/policycoreutils_2.3.bb b/recipes-security/selinux/policycoreutils_2.3.bb new file mode 100644 index 0000000..447e6c9 --- /dev/null +++ b/recipes-security/selinux/policycoreutils_2.3.bb @@ -0,0 +1,16 @@ +include selinux_20140506.inc +include ${BPN}.inc + +LIC_FILES_CHKSUM = "file://COPYING;md5=393a5ca445f6965873eca0259a17f833" + +SRC_URI[md5sum] = "4f5c508e3c3867c8beb343e993d353dd" +SRC_URI[sha256sum] = "11e8815ac13debb87897d2781381b89ec5c6c746a3d44223a493bc7ace6cc71f" + +SRC_URI += "\ + file://policycoreutils-fix-sepolicy-install-path.patch \ + file://policycoreutils-make-O_CLOEXEC-optional.patch \ + file://policycoreutils-loadpolicy-symlink.patch \ + file://policycoreutils-semanage-edit-user.patch \ + file://policycoreutils-process-ValueError-for-sepolicy-seobject.patch \ + file://policycoreutils-fix-TypeError-for-seobject.py.patch \ + " diff --git a/recipes-security/selinux/selinux_20131030.inc b/recipes-security/selinux/selinux_20131030.inc deleted file mode 100644 index 01cc52f..0000000 --- a/recipes-security/selinux/selinux_20131030.inc +++ /dev/null @@ -1,5 +0,0 @@ -SELINUX_RELEASE = "20131030" - -SRC_URI = "https://github.com/SELinuxProject/selinux/archive/${BPN}-${PV}.tar.gz" - -include selinux_common.inc diff --git a/recipes-security/selinux/selinux_20140506.inc b/recipes-security/selinux/selinux_20140506.inc new file mode 100644 index 0000000..01cc52f --- /dev/null +++ b/recipes-security/selinux/selinux_20140506.inc @@ -0,0 +1,5 @@ +SELINUX_RELEASE = "20131030" + +SRC_URI = "https://github.com/SELinuxProject/selinux/archive/${BPN}-${PV}.tar.gz" + +include selinux_common.inc diff --git a/recipes-security/selinux/selinux_git.inc b/recipes-security/selinux/selinux_git.inc index d56f25b..6112d7d 100644 --- a/recipes-security/selinux/selinux_git.inc +++ b/recipes-security/selinux/selinux_git.inc @@ -1,6 +1,6 @@ SRCREV = "edc2e99687b050d5be21a78a66d038aa1fc068d9" -SRC_URI = "git://oss.tresys.com/git/selinux.git;protocol=http" +SRC_URI = "git://github.com/SELinuxProject/selinux.git;protocol=http" include selinux_common.inc diff --git a/recipes-security/selinux/sepolgen_1.2.1.bb b/recipes-security/selinux/sepolgen_1.2.1.bb index 21dff41..b47ff26 100644 --- a/recipes-security/selinux/sepolgen_1.2.1.bb +++ b/recipes-security/selinux/sepolgen_1.2.1.bb @@ -1,6 +1,4 @@ -PR = "r99" - -include selinux_20131030.inc +include selinux_20140506.inc include ${BPN}.inc LIC_FILES_CHKSUM = "file://COPYING;md5=393a5ca445f6965873eca0259a17f833" diff --git a/recipes-security/setools/setools/setools-Changes-to-support-named-file_trans-rules.patch b/recipes-security/setools/setools/setools-Changes-to-support-named-file_trans-rules.patch deleted file mode 100644 index d44ae21..0000000 --- a/recipes-security/setools/setools/setools-Changes-to-support-named-file_trans-rules.patch +++ /dev/null @@ -1,1511 +0,0 @@ -From e0f74aa934140ccc6f5a51aa2df6fd19f0c0ee08 Mon Sep 17 00:00:00 2001 -From: Xin Ouyang -Date: Wed, 7 Mar 2012 11:00:19 +0800 -Subject: [PATCH 5/7] setools: Changes to support named file_trans rules - -Integrated from Fedora: -https://community.dev.fedoraproject.org/packages/setools/sources/patches/ ---- - libapol/include/apol/Makefile.am | 1 + - libapol/include/apol/ftrule-query.h | 198 +++++++++++++++++++ - libapol/include/apol/policy-query.h | 1 + - libapol/src/Makefile.am | 1 + - libapol/src/ftrule-query.c | 363 +++++++++++++++++++++++++++++++++++ - libapol/src/libapol.map | 1 + - libqpol/include/qpol/Makefile.am | 1 + - libqpol/include/qpol/ftrule_query.h | 116 +++++++++++ - libqpol/include/qpol/policy.h | 1 + - libqpol/src/Makefile.am | 1 + - libqpol/src/ftrule_query.c | 277 ++++++++++++++++++++++++++ - libqpol/src/libqpol.map | 1 + - libqpol/src/module_compiler.c | 12 ++ - libqpol/src/policy_define.c | 186 ++++++++++++++++++- - libqpol/src/policy_parse.y | 13 +- - libqpol/src/policy_scan.l | 1 + - secmds/sesearch.c | 101 ++++++++++ - 17 files changed, 1272 insertions(+), 3 deletions(-) - create mode 100644 libapol/include/apol/ftrule-query.h - create mode 100644 libapol/src/ftrule-query.c - create mode 100644 libqpol/include/qpol/ftrule_query.h - create mode 100644 libqpol/src/ftrule_query.c - -diff --git a/libapol/include/apol/Makefile.am b/libapol/include/apol/Makefile.am -index 0883c10..e398ff2 100644 ---- a/libapol/include/apol/Makefile.am -+++ b/libapol/include/apol/Makefile.am -@@ -27,6 +27,7 @@ apol_HEADERS = \ - relabel-analysis.h \ - render.h \ - role-query.h \ -+ ftrule-query.h \ - terule-query.h \ - type-query.h \ - types-relation-analysis.h \ -diff --git a/libapol/include/apol/ftrule-query.h b/libapol/include/apol/ftrule-query.h -new file mode 100644 -index 0000000..119c52f ---- /dev/null -+++ b/libapol/include/apol/ftrule-query.h -@@ -0,0 +1,198 @@ -+/** -+ * @file -+ * -+ * Routines to query filename_transition rules of a -+ * policy. -+ * -+ * @author Jeremy A. Mowery jmowery@tresys.com -+ * @author Jason Tang jtang@tresys.com -+ * -+ * Copyright (C) 2006-2007 Tresys Technology, LLC -+ * -+ * This library is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU Lesser General Public -+ * License as published by the Free Software Foundation; either -+ * version 2.1 of the License, or (at your option) any later version. -+ * -+ * This library is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ * Lesser General Public License for more details. -+ * -+ * You should have received a copy of the GNU Lesser General Public -+ * License along with this library; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -+ */ -+ -+#ifndef APOL_FILENAMERULE_QUERY_H -+#define APOL_FILENAMERULE_QUERY_H -+ -+#ifdef __cplusplus -+extern "C" -+{ -+#endif -+ -+#include "policy.h" -+#include "vector.h" -+#include -+ -+ typedef struct apol_filename_trans_query apol_filename_trans_query_t; -+ -+ -+/******************** filename_transition queries ********************/ -+ -+/** -+ * Execute a query against all filename_transition rules within the -+ * policy. -+ * -+ * @param p Policy within which to look up filename_transition rules. -+ * @param r Structure containing parameters for query. If this is -+ * NULL then return all filename_transition rules. -+ * @param v Reference to a vector of qpol_filename_trans_t. The vector -+ * will be allocated by this function. The caller must call -+ * apol_vector_destroy() afterwards. This will be set to NULL upon no -+ * results or upon error. -+ * -+ * @return 0 on success (including none found), negative on error. -+ */ -+ extern int apol_filename_trans_get_by_query(const apol_policy_t * p, const apol_filename_trans_query_t * r, apol_vector_t ** v); -+ -+/** -+ * Allocate and return a new filename trans query structure. All fields -+ * are initialized, such that running this blank query results in -+ * returning all filename_transitions within the policy. The caller must -+ * call apol_filename_trans_query_destroy() upon the return value -+ * afterwards. -+ * -+ * @return An initialized filename trans query structure, or NULL upon -+ * error. -+ */ -+ extern apol_filename_trans_query_t *apol_filename_trans_query_create(void); -+ -+/** -+ * Deallocate all memory associated with the referenced filename trans -+ * query, and then set it to NULL. This function does nothing if the -+ * query is already NULL. -+ * -+ * @param r Reference to a filename trans query structure to destroy. -+ */ -+ extern void apol_filename_trans_query_destroy(apol_filename_trans_query_t ** r); -+ -+/** -+ * Set a filename_trans query to return rules whose source symbol matches -+ * symbol. Symbol may be a type or attribute; if it is an alias then -+ * the query will convert it to its primary prior to searching. If -+ * is_indirect is non-zero then the search will be done indirectly. -+ * If the symbol is a type, then the query matches rules with one of -+ * the type's attributes. If the symbol is an attribute, then it -+ * matches rule with any of the attribute's types. -+ * -+ * @param p Policy handler, to report errors. -+ * @param t TE rule query to set. -+ * @param symbol Limit query to rules with this symbol as their -+ * source, or NULL to unset this field. -+ * @param is_indirect If non-zero, perform indirect matching. -+ * -+ * @return 0 on success, negative on error. -+ */ -+ extern int apol_filename_trans_query_set_source(const apol_policy_t * p, apol_filename_trans_query_t * t, const char *symbol, -+ int is_indirect); -+ -+/** -+ * Set a filename trans query to return rules with a particular target -+ * symbol. Symbol may be a type or attribute; if it is an alias then -+ * the query will convert it to its primary prior to searching. If -+ * is_indirect is non-zero then the search will be done indirectly. -+ * If the symbol is a type, then the query matches rules with one of -+ * the type's attributes. If the symbol is an attribute, then it -+ * matches rule with any of the attribute's types. -+ * -+ * @param p Policy handler, to report errors. -+ * @param r Role trans query to set. -+ * @param symbol Limit query to rules with this type or attribute as -+ * their target, or NULL to unset this field. -+ * @param is_indirect If non-zero, perform indirect matching. -+ * -+ * @return 0 on success, negative on error. -+ */ -+ extern int apol_filename_trans_query_set_target(const apol_policy_t * p, apol_filename_trans_query_t * r, const char *symbol, -+ int is_indirect); -+ -+/** -+ * Set a filename trans query to return rules with a particular default -+ * filename. This field is ignored if -+ * apol_filename_trans_query_set_source_any() is set to non-zero. -+ * -+ * @param p Policy handler, to report errors. -+ * @param r Role trans query to set. -+ * @param filename Limit query to rules with this filename as their default, or -+ * NULL to unset this field. -+ * -+ * @return 0 on success, negative on error. -+ */ -+ extern int apol_filename_trans_query_set_default(const apol_policy_t * p, apol_filename_trans_query_t * r, const char *filename); -+ -+/** -+ * Set at filename_trans query to return rules with this object (non-common) -+ * class. If more than one class are appended to the query, the -+ * rule's class must be one of those appended. (I.e., the rule's -+ * class must be a member of the query's classes.) Pass a NULL to -+ * clear all classes. Note that this performs straight string -+ * comparison, ignoring the regex flag. -+ -+ * -+ * @param p Policy handler, to report errors. -+ * @param t TE rule query to set. -+ * @param obj_class Name of object class to add to search set. -+ * -+ * @return 0 on success, negative on error. -+ */ -+ extern int apol_filename_trans_query_append_class(const apol_policy_t * p, apol_filename_trans_query_t * t, const char *obj_class); -+ -+/** -+ * Set a filename trans query to treat the source filename as any. That is, -+ * use the same symbol for either source or default of a -+ * filename_transition rule. This flag does nothing if the source filename is -+ * not set. Note that a filename_transition's target is a type, so thus -+ * this flag does not affect its searching. -+ * -+ * @param p Policy handler, to report errors. -+ * @param r Role trans query to set. -+ * @param is_any Non-zero to use source symbol for source or default -+ * field, 0 to keep source as only source. -+ * -+ * @return Always 0. -+ */ -+ extern int apol_filename_trans_query_set_source_any(const apol_policy_t * p, apol_filename_trans_query_t * r, int is_any); -+ -+/** -+ * Set a filename trans query to use regular expression searching for -+ * source, target, and default fields. Strings will be treated as -+ * regexes instead of literals. For the target type, matching will -+ * occur against the type name or any of its aliases. -+ * -+ * @param p Policy handler, to report errors. -+ * @param r Role trans query to set. -+ * @param is_regex Non-zero to enable regex searching, 0 to disable. -+ * -+ * @return Always 0. -+ */ -+ extern int apol_filename_trans_query_set_regex(const apol_policy_t * p, apol_filename_trans_query_t * r, int is_regex); -+ -+/** -+ * Render a filename_transition rule to a string. -+ * -+ * @param policy Policy handler, to report errors. -+ * @param rule The rule to render. -+ * -+ * @return A newly malloc()'d string representation of the rule, or NULL on -+ * failure; if the call fails, errno will be set. The caller is responsible -+ * for calling free() on the returned string. -+ */ -+ extern char *apol_filename_trans_render(const apol_policy_t * policy, const qpol_filename_trans_t * rule); -+ -+#ifdef __cplusplus -+} -+#endif -+ -+#endif -diff --git a/libapol/include/apol/policy-query.h b/libapol/include/apol/policy-query.h -index 315f70e..665e4cb 100644 ---- a/libapol/include/apol/policy-query.h -+++ b/libapol/include/apol/policy-query.h -@@ -71,6 +71,7 @@ extern "C" - #include "terule-query.h" - #include "condrule-query.h" - #include "rbacrule-query.h" -+#include "ftrule-query.h" - #include "range_trans-query.h" - #include "constraint-query.h" - -diff --git a/libapol/src/Makefile.am b/libapol/src/Makefile.am -index 3fa4f06..baaa4f6 100644 ---- a/libapol/src/Makefile.am -+++ b/libapol/src/Makefile.am -@@ -40,6 +40,7 @@ libapol_a_SOURCES = \ - render.c \ - role-query.c \ - terule-query.c \ -+ ftrule-query.c \ - type-query.c \ - types-relation-analysis.c \ - user-query.c \ -diff --git a/libapol/src/ftrule-query.c b/libapol/src/ftrule-query.c -new file mode 100644 -index 0000000..dc248de ---- /dev/null -+++ b/libapol/src/ftrule-query.c -@@ -0,0 +1,363 @@ -+/** -+ * @file -+ * -+ * Provides a way for setools to make queries about type enforcement -+ * filename_transs within a policy. The caller obtains a query object, fills in -+ * its parameters, and then runs the query; it obtains a vector of -+ * results. Searches are conjunctive -- all fields of the search -+ * query must match for a datum to be added to the results query. -+ * -+ * @author Jeremy A. Mowery jmowery@tresys.com -+ * @author Jason Tang jtang@tresys.com -+ * -+ * Copyright (C) 2006-2007 Tresys Technology, LLC -+ * -+ * This library is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU Lesser General Public -+ * License as published by the Free Software Foundation; either -+ * version 2.1 of the License, or (at your option) any later version. -+ * -+ * This library is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ * Lesser General Public License for more details. -+ * -+ * You should have received a copy of the GNU Lesser General Public -+ * License along with this library; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -+ */ -+ -+#include "policy-query-internal.h" -+ -+#include -+#include -+ -+struct apol_filename_trans_query -+{ -+ char *source, *target, *default_type, *name; -+ apol_vector_t *classes; -+ unsigned int flags; -+}; -+ -+ -+/******************** filename_transition queries ********************/ -+ -+int apol_filename_trans_get_by_query(const apol_policy_t * p, const apol_filename_trans_query_t * t, apol_vector_t ** v) -+{ -+ apol_vector_t *source_list = NULL, *target_list = NULL, *class_list = NULL, *default_list = NULL; -+ int retval = -1, source_as_any = 0, is_regex = 0, append_filename_trans; -+ char *bool_name = NULL; -+ *v = NULL; -+ unsigned int flags = 0; -+ qpol_iterator_t *iter = NULL, *type_iter = NULL; -+ -+ if (t != NULL) { -+ flags = t->flags; -+ is_regex = t->flags & APOL_QUERY_REGEX; -+ if (t->source != NULL && -+ (source_list = -+ apol_query_create_candidate_type_list(p, t->source, is_regex, -+ t->flags & APOL_QUERY_SOURCE_INDIRECT, -+ ((t->flags & (APOL_QUERY_SOURCE_TYPE | APOL_QUERY_SOURCE_ATTRIBUTE)) / -+ APOL_QUERY_SOURCE_TYPE))) == NULL) { -+ goto cleanup; -+ } -+ -+ if ((t->flags & APOL_QUERY_SOURCE_AS_ANY) && t->source != NULL) { -+ default_list = target_list = source_list; -+ source_as_any = 1; -+ } else { -+ if (t->target != NULL && -+ (target_list = -+ apol_query_create_candidate_type_list(p, t->target, is_regex, -+ t->flags & APOL_QUERY_TARGET_INDIRECT, -+ ((t-> -+ flags & (APOL_QUERY_TARGET_TYPE | APOL_QUERY_TARGET_ATTRIBUTE)) -+ / APOL_QUERY_TARGET_TYPE))) == NULL) { -+ goto cleanup; -+ } -+ if (t->default_type != NULL && -+ (default_list = -+ apol_query_create_candidate_type_list(p, t->default_type, is_regex, 0, -+ APOL_QUERY_SYMBOL_IS_TYPE)) == NULL) { -+ goto cleanup; -+ } -+ } -+ if (t->classes != NULL && -+ apol_vector_get_size(t->classes) > 0 && -+ (class_list = apol_query_create_candidate_class_list(p, t->classes)) == NULL) { -+ goto cleanup; -+ } -+ } -+ -+ if (qpol_policy_get_filename_trans_iter(p->p, &iter) < 0) { -+ return -1; -+ } -+ -+ if ((*v = apol_vector_create(NULL)) == NULL) { -+ ERR(p, "%s", strerror(errno)); -+ goto cleanup; -+ } -+ -+ for (; !qpol_iterator_end(iter); qpol_iterator_next(iter)) { -+ qpol_filename_trans_t *filename_trans; -+ if (qpol_iterator_get_item(iter, (void **)&filename_trans) < 0) { -+ goto cleanup; -+ } -+ int match_source = 0, match_target = 0, match_default = 0, match_bool = 0; -+ size_t i; -+ -+ if (source_list == NULL) { -+ match_source = 1; -+ } else { -+ const qpol_type_t *source_type; -+ if (qpol_filename_trans_get_source_type(p->p, filename_trans, &source_type) < 0) { -+ goto cleanup; -+ } -+ if (apol_vector_get_index(source_list, source_type, NULL, NULL, &i) == 0) { -+ match_source = 1; -+ } -+ } -+ -+ /* if source did not match, but treating source symbol -+ * as any field, then delay rejecting this filename_trans until -+ * the target and default have been checked */ -+ if (!source_as_any && !match_source) { -+ continue; -+ } -+ -+ if (target_list == NULL || (source_as_any && match_source)) { -+ match_target = 1; -+ } else { -+ const qpol_type_t *target_type; -+ if (qpol_filename_trans_get_target_type(p->p, filename_trans, &target_type) < 0) { -+ goto cleanup; -+ } -+ if (apol_vector_get_index(target_list, target_type, NULL, NULL, &i) == 0) { -+ match_target = 1; -+ } -+ } -+ -+ if (!source_as_any && !match_target) { -+ continue; -+ } -+ -+ if (default_list == NULL || (source_as_any && match_source) || (source_as_any && match_target)) { -+ match_default = 1; -+ } else { -+ const qpol_type_t *default_type; -+ if (qpol_filename_trans_get_default_type(p->p, filename_trans, &default_type) < 0) { -+ goto cleanup; -+ } -+ if (apol_vector_get_index(default_list, default_type, NULL, NULL, &i) == 0) { -+ match_default = 1; -+ } -+ } -+ -+ if (!source_as_any && !match_default) { -+ continue; -+ } -+ /* at least one thing must match if source_as_any was given */ -+ if (source_as_any && (!match_source && !match_target && !match_default)) { -+ continue; -+ } -+ -+ if (class_list != NULL) { -+ const qpol_class_t *obj_class; -+ if (qpol_filename_trans_get_object_class(p->p, filename_trans, &obj_class) < 0) { -+ goto cleanup; -+ } -+ if (apol_vector_get_index(class_list, obj_class, NULL, NULL, &i) < 0) { -+ continue; -+ } -+ } -+ -+ if (apol_vector_append(*v, filename_trans)) { -+ ERR(p, "%s", strerror(ENOMEM)); -+ goto cleanup; -+ } -+ } -+ -+ retval = 0; -+ cleanup: -+ if (retval != 0) { -+ apol_vector_destroy(v); -+ } -+ apol_vector_destroy(&source_list); -+ if (!source_as_any) { -+ apol_vector_destroy(&target_list); -+ apol_vector_destroy(&default_list); -+ } -+ apol_vector_destroy(&class_list); -+ return retval; -+} -+ -+apol_filename_trans_query_t *apol_filename_trans_query_create(void) -+{ -+ apol_filename_trans_query_t *t = calloc(1, sizeof(apol_filename_trans_query_t)); -+ if (t != NULL) { -+ t->flags = -+ (APOL_QUERY_SOURCE_TYPE | APOL_QUERY_SOURCE_ATTRIBUTE | APOL_QUERY_TARGET_TYPE | -+ APOL_QUERY_TARGET_ATTRIBUTE); -+ } -+ return t; -+} -+ -+void apol_filename_trans_query_destroy(apol_filename_trans_query_t ** r) -+{ -+ if (r != NULL && *r != NULL) { -+ free((*r)->source); -+ free((*r)->target); -+ free((*r)->default_type); -+ free((*r)->name); -+ free(*r); -+ *r = NULL; -+ } -+} -+ -+int apol_filename_trans_query_set_source(const apol_policy_t * p, apol_filename_trans_query_t * t, const char *filename, int is_indirect) -+{ -+ apol_query_set_flag(p, &t->flags, is_indirect, APOL_QUERY_TARGET_INDIRECT); -+ return apol_query_set(p, &t->source, NULL, filename); -+} -+ -+int apol_filename_trans_query_set_target(const apol_policy_t * p, apol_filename_trans_query_t * t, const char *type, int is_indirect) -+{ -+ apol_query_set_flag(p, &t->flags, is_indirect, APOL_QUERY_TARGET_INDIRECT); -+ return apol_query_set(p, &t->target, NULL, type); -+} -+ -+int apol_filename_trans_query_set_default(const apol_policy_t * p, apol_filename_trans_query_t * t, const char *symbol) -+{ -+ return apol_query_set(p, &t->default_type, NULL, symbol); -+} -+ -+int apol_filename_trans_query_append_class(const apol_policy_t * p, apol_filename_trans_query_t * t, const char *obj_class) -+{ -+ char *s = NULL; -+ if (obj_class == NULL) { -+ apol_vector_destroy(&t->classes); -+ } else if ((s = strdup(obj_class)) == NULL || (t->classes == NULL && (t->classes = apol_vector_create(free)) == NULL) -+ || apol_vector_append(t->classes, s) < 0) { -+ ERR(p, "%s", strerror(errno)); -+ free(s); -+ return -1; -+ } -+ return 0; -+} -+ -+int apol_filename_trans_query_set_name(const apol_policy_t * p, apol_filename_trans_query_t * t, const char *filename) -+{ -+ return apol_query_set(p, &t->name, NULL, filename); -+} -+ -+int apol_filename_trans_query_set_source_any(const apol_policy_t * p, apol_filename_trans_query_t * t, int is_any) -+{ -+ return apol_query_set_flag(p, &t->flags, is_any, APOL_QUERY_SOURCE_AS_ANY); -+} -+ -+int apol_filename_trans_query_set_regex(const apol_policy_t * p, apol_filename_trans_query_t * t, int is_regex) -+{ -+ return apol_query_set_regex(p, &t->flags, is_regex); -+} -+ -+char *apol_filename_trans_render(const apol_policy_t * policy, const qpol_filename_trans_t * filename_trans) -+{ -+ char *tmp = NULL; -+ const char *tmp_name = NULL; -+ const char *filename_trans_type_str; -+ int error = 0; -+ size_t tmp_sz = 0; -+ uint32_t filename_trans_type = 0; -+ const qpol_type_t *type = NULL; -+ const qpol_class_t *obj_class = NULL; -+ -+ if (!policy || !filename_trans) { -+ ERR(policy, "%s", strerror(EINVAL)); -+ errno = EINVAL; -+ return NULL; -+ } -+ -+ /* source type */ -+ if (qpol_filename_trans_get_source_type(policy->p, filename_trans, &type)) { -+ error = errno; -+ goto err; -+ } -+ if (qpol_type_get_name(policy->p, type, &tmp_name)) { -+ error = errno; -+ goto err; -+ } -+ if (apol_str_appendf(&tmp, &tmp_sz, "transition_type %s ", tmp_name)) { -+ error = errno; -+ ERR(policy, "%s", strerror(error)); -+ goto err; -+ } -+ -+ /* target type */ -+ if (qpol_filename_trans_get_target_type(policy->p, filename_trans, &type)) { -+ error = errno; -+ goto err; -+ } -+ if (qpol_type_get_name(policy->p, type, &tmp_name)) { -+ error = errno; -+ goto err; -+ } -+ if (apol_str_appendf(&tmp, &tmp_sz, "%s : ", tmp_name)) { -+ error = errno; -+ ERR(policy, "%s", strerror(error)); -+ goto err; -+ } -+ -+ /* object class */ -+ if (qpol_filename_trans_get_object_class(policy->p, filename_trans, &obj_class)) { -+ error = errno; -+ goto err; -+ } -+ if (qpol_class_get_name(policy->p, obj_class, &tmp_name)) { -+ error = errno; -+ goto err; -+ } -+ if (apol_str_appendf(&tmp, &tmp_sz, "%s ", tmp_name)) { -+ error = errno; -+ ERR(policy, "%s", strerror(error)); -+ goto err; -+ } -+ -+ /* default type */ -+ if (qpol_filename_trans_get_default_type(policy->p, filename_trans, &type)) { -+ error = errno; -+ goto err; -+ } -+ if (qpol_type_get_name(policy->p, type, &tmp_name)) { -+ error = errno; -+ goto err; -+ } -+ if (apol_str_appendf(&tmp, &tmp_sz, "%s", tmp_name)) { -+ error = errno; -+ ERR(policy, "%s", strerror(error)); -+ goto err; -+ } -+ -+ if (qpol_filename_trans_get_filename(policy->p, filename_trans, &tmp_name)) { -+ error = errno; -+ goto err; -+ } -+ -+ if (apol_str_appendf(&tmp, &tmp_sz, " %s", tmp_name)) { -+ error = errno; -+ ERR(policy, "%s", strerror(error)); -+ goto err; -+ } -+ -+ if (apol_str_appendf(&tmp, &tmp_sz, ";")) { -+ error = errno; -+ ERR(policy, "%s", strerror(error)); -+ goto err; -+ } -+ return tmp; -+ -+ err: -+ free(tmp); -+ errno = error; -+ return NULL; -+} -diff --git a/libapol/src/libapol.map b/libapol/src/libapol.map -index 4894374..7657a2d 100644 ---- a/libapol/src/libapol.map -+++ b/libapol/src/libapol.map -@@ -34,6 +34,7 @@ VERS_4.0{ - apol_protocol_to_str; - apol_qpol_context_render; - apol_range_trans_*; -+ apol_filename_trans_*; - apol_relabel_*; - apol_role_*; - apol_role_allow_*; -diff --git a/libqpol/include/qpol/Makefile.am b/libqpol/include/qpol/Makefile.am -index b55acb7..9b570e1 100644 ---- a/libqpol/include/qpol/Makefile.am -+++ b/libqpol/include/qpol/Makefile.am -@@ -25,6 +25,7 @@ qpol_HEADERS = \ - role_query.h \ - syn_rule_query.h \ - terule_query.h \ -+ ftrule_query.h \ - type_query.h \ - user_query.h \ - util.h -diff --git a/libqpol/include/qpol/ftrule_query.h b/libqpol/include/qpol/ftrule_query.h -new file mode 100644 -index 0000000..1f533a4 ---- /dev/null -+++ b/libqpol/include/qpol/ftrule_query.h -@@ -0,0 +1,116 @@ -+/** -+ * @file -+ * Defines public interface for iterating over FTRULE rules. -+ * -+ * @author Kevin Carr kcarr@tresys.com -+ * @author Jeremy A. Mowery jmowery@tresys.com -+ * @author Jason Tang jtang@tresys.com -+ * -+ * Copyright (C) 2006-2007 Tresys Technology, LLC -+ * -+ * This library is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU Lesser General Public -+ * License as published by the Free Software Foundation; either -+ * version 2.1 of the License, or (at your option) any later version. -+ * -+ * This library is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ * Lesser General Public License for more details. -+ * -+ * You should have received a copy of the GNU Lesser General Public -+ * License along with this library; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -+ */ -+ -+#ifndef QPOL_FTRULERULE_QUERY -+#define QPOL_FTRULERULE_QUERY -+ -+#ifdef __cplusplus -+extern "C" -+{ -+#endif -+ -+#include -+#include -+ -+ typedef struct qpol_filename_trans qpol_filename_trans_t; -+ -+/** -+ * Get an iterator over all filename transition rules in the policy. -+ * @param policy Policy from which to create the iterator. -+ * @param iter Iterator over items of type qpol_filename_trans_t returned. -+ * The caller is responsible for calling qpol_iterator_destroy() -+ * to free memory used by this iterator. -+ * It is important to note that this iterator is only valid as long as -+ * the policy is unmodifed. -+ * @returm 0 on success and < 0 on failure; if the call fails, -+ * errno will be set and *iter will be NULL. -+ */ -+ extern int qpol_policy_get_filename_trans_iter(const qpol_policy_t * policy, qpol_iterator_t ** iter); -+ -+/** -+ * Get the source type from a filename transition rule. -+ * @param policy The policy from which the rule comes. -+ * @param rule The rule from which to get the source type. -+ * @param source Pointer in which to store the source type. -+ * The caller should not free this pointer. -+ * @return 0 on success and < 0 on failure; if the call fails, -+ * errno will be set and *source will be NULL. -+ */ -+ extern int qpol_filename_trans_get_source_type(const qpol_policy_t * policy, const qpol_filename_trans_t * rule, -+ const qpol_type_t ** source); -+ -+/** -+ * Get the target type from a filename transition rule. -+ * @param policy The policy from which the rule comes. -+ * @param rule The rule from which to get the target type. -+ * @param target Pointer in which to store the target type. -+ * The caller should not free this pointer. -+ * @return 0 on success and < 0 on failure; if the call fails, -+ * errno will be set and *target will be NULL. -+ */ -+ extern int qpol_filename_trans_get_target_type(const qpol_policy_t * policy, const qpol_filename_trans_t * rule, -+ const qpol_type_t ** target); -+ -+/** -+ * Get the default type from a type rule. -+ * @param policy Policy from which the rule comes. -+ * @param rule The rule from which to get the default type. -+ * @param dflt Pointer in which to store the default type. -+ * The caller should not free this pointer. -+ * @returm 0 on success and < 0 on failure; if the call fails, -+ * errno will be set and *dflt will be NULL. -+ */ -+ extern int qpol_filename_trans_get_default_type(const qpol_policy_t * policy, const qpol_filename_trans_t * rule, -+ const qpol_type_t ** dflt); -+ -+/** -+ * Get the object class from a type rule. -+ * @param policy Policy from which the rule comes. -+ * @param rule The rule from which to get the object class. -+ * @param obj_class Pointer in which to store the object class. -+ * The caller should not free this pointer. -+ * @returm 0 on success and < 0 on failure; if the call fails, -+ * errno will be set and *obj_class will be NULL. -+ */ -+ extern int qpol_filename_trans_get_object_class(const qpol_policy_t * policy, const qpol_filename_trans_t * rule, -+ const qpol_class_t ** obj_class); -+ -+/** -+ * Get the transition filename type from a type rule. -+ * @param policy Policy from which the rule comes. -+ * @param rule The rule from which to get the transition filename. -+ * @param target Pointer in which to store the transition filename. -+ * The caller should not free this pointer. -+ * @returm 0 on success and < 0 on failure; if the call fails, -+ * errno will be set and *target will be NULL. -+ */ -+ extern int qpol_filename_trans_get_filename(const qpol_policy_t * policy, const qpol_filename_trans_t * rule, -+ const char ** name); -+ -+#ifdef __cplusplus -+} -+#endif -+ -+#endif /* QPOL_FTRULERULE_QUERY */ -diff --git a/libqpol/include/qpol/policy.h b/libqpol/include/qpol/policy.h -index ae4ea08..bf85718 100644 ---- a/libqpol/include/qpol/policy.h -+++ b/libqpol/include/qpol/policy.h -@@ -55,6 +55,7 @@ extern "C" - #include - #include - #include -+#include - #include - #include - #include -diff --git a/libqpol/src/Makefile.am b/libqpol/src/Makefile.am -index 34d87a6..0889a61 100644 ---- a/libqpol/src/Makefile.am -+++ b/libqpol/src/Makefile.am -@@ -48,6 +48,7 @@ libqpol_a_SOURCES = \ - syn_rule_internal.h \ - syn_rule_query.c \ - terule_query.c \ -+ ftrule_query.c \ - type_query.c \ - user_query.c \ - util.c \ -diff --git a/libqpol/src/ftrule_query.c b/libqpol/src/ftrule_query.c -new file mode 100644 -index 0000000..d6db848 ---- /dev/null -+++ b/libqpol/src/ftrule_query.c -@@ -0,0 +1,277 @@ -+/** -+ * @file -+ * Defines public interface for iterating over RBAC rules. -+ * -+ * @author Jeremy A. Mowery jmowery@tresys.com -+ * @author Jason Tang jtang@tresys.com -+ * -+ * Copyright (C) 2006-2007 Tresys Technology, LLC -+ * -+ * This library is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU Lesser General Public -+ * License as published by the Free Software Foundation; either -+ * version 2.1 of the License, or (at your option) any later version. -+ * -+ * This library is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ * Lesser General Public License for more details. -+ * -+ * You should have received a copy of the GNU Lesser General Public -+ * License along with this library; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -+ */ -+ -+#include -+#include -+#include -+#include -+#include "iterator_internal.h" -+#include "qpol_internal.h" -+#include -+ -+typedef struct filename_trans_state -+{ -+ filename_trans_t *head; -+ filename_trans_t *cur; -+} filename_trans_state_t; -+ -+static int filename_trans_state_end(const qpol_iterator_t * iter) -+{ -+ filename_trans_state_t *fts = NULL; -+ -+ if (!iter || !(fts = qpol_iterator_state(iter))) { -+ errno = EINVAL; -+ return STATUS_ERR; -+ } -+ -+ return fts->cur ? 0 : 1; -+} -+ -+static void *filename_trans_state_get_cur(const qpol_iterator_t * iter) -+{ -+ filename_trans_state_t *fts = NULL; -+ const policydb_t *db = NULL; -+ -+ if (!iter || !(fts = qpol_iterator_state(iter)) || !(db = qpol_iterator_policy(iter)) || filename_trans_state_end(iter)) { -+ errno = EINVAL; -+ return NULL; -+ } -+ -+ return fts->cur; -+} -+ -+static int filename_trans_state_next(qpol_iterator_t * iter) -+{ -+ filename_trans_state_t *fts = NULL; -+ const policydb_t *db = NULL; -+ -+ if (!iter || !(fts = qpol_iterator_state(iter)) || !(db = qpol_iterator_policy(iter))) { -+ errno = EINVAL; -+ return STATUS_ERR; -+ } -+ -+ if (filename_trans_state_end(iter)) { -+ errno = ERANGE; -+ return STATUS_ERR; -+ } -+ -+ fts->cur = fts->cur->next; -+ -+ return STATUS_SUCCESS; -+} -+ -+static size_t filename_trans_state_size(const qpol_iterator_t * iter) -+{ -+ filename_trans_state_t *fts = NULL; -+ const policydb_t *db = NULL; -+ filename_trans_t *tmp = NULL; -+ size_t count = 0; -+ -+ if (!iter || !(fts = qpol_iterator_state(iter)) || !(db = qpol_iterator_policy(iter))) { -+ errno = EINVAL; -+ return STATUS_ERR; -+ } -+ -+ for (tmp = fts->head; tmp; tmp = tmp->next) -+ count++; -+ -+ return count; -+} -+ -+int qpol_policy_get_filename_trans_iter(const qpol_policy_t * policy, qpol_iterator_t ** iter) -+{ -+ policydb_t *db = NULL; -+ filename_trans_state_t *fts = NULL; -+ int error = 0; -+ -+ if (iter) -+ *iter = NULL; -+ -+ if (!policy || !iter) { -+ ERR(policy, "%s", strerror(EINVAL)); -+ errno = EINVAL; -+ return STATUS_ERR; -+ } -+ -+ db = &policy->p->p; -+ -+ fts = calloc(1, sizeof(filename_trans_state_t)); -+ if (!fts) { -+ /* errno set by calloc */ -+ ERR(policy, "%s", strerror(errno)); -+ return STATUS_ERR; -+ } -+ fts->head = fts->cur = db->filename_trans; -+ -+ if (qpol_iterator_create -+ (policy, (void *)fts, filename_trans_state_get_cur, filename_trans_state_next, filename_trans_state_end, filename_trans_state_size, -+ free, iter)) { -+ error = errno; -+ free(fts); -+ errno = error; -+ return STATUS_ERR; -+ } -+ -+ return STATUS_SUCCESS; -+} -+ -+int qpol_filename_trans_get_source_type(const qpol_policy_t * policy, const qpol_filename_trans_t * rule, const qpol_type_t ** source) -+{ -+ policydb_t *db = NULL; -+ filename_trans_t *ft = NULL; -+ -+ if (source) { -+ *source = NULL; -+ } -+ -+ if (!policy || !rule || !source) { -+ ERR(policy, "%s", strerror(EINVAL)); -+ errno = EINVAL; -+ return STATUS_ERR; -+ } -+ -+ db = &policy->p->p; -+ ft = (filename_trans_t *) rule; -+ -+ *source = (qpol_type_t *) db->type_val_to_struct[ft->stype - 1]; -+ -+ return STATUS_SUCCESS; -+} -+ -+int qpol_filename_trans_get_target_type(const qpol_policy_t * policy, const qpol_filename_trans_t * rule, const qpol_type_t ** target) -+{ -+ policydb_t *db = NULL; -+ filename_trans_t *ft = NULL; -+ -+ if (target) { -+ *target = NULL; -+ } -+ -+ if (!policy || !rule || !target) { -+ ERR(policy, "%s", strerror(EINVAL)); -+ errno = EINVAL; -+ return STATUS_ERR; -+ } -+ -+ db = &policy->p->p; -+ ft = (filename_trans_t *) rule; -+ -+ *target = (qpol_type_t *) db->type_val_to_struct[ft->ttype - 1]; -+ -+ return STATUS_SUCCESS; -+} -+ -+int qpol_filename_trans_get_object_class(const qpol_policy_t * policy, const qpol_filename_trans_t * rule, -+ const qpol_class_t ** obj_class) -+{ -+ policydb_t *db = NULL; -+ filename_trans_t *ft = NULL; -+ -+ if (obj_class) { -+ *obj_class = NULL; -+ } -+ -+ if (!policy || !rule || !obj_class) { -+ ERR(policy, "%s", strerror(EINVAL)); -+ errno = EINVAL; -+ return STATUS_ERR; -+ } -+ -+ db = &policy->p->p; -+ ft = (filename_trans_t *) rule; -+ -+ *obj_class = (qpol_class_t *) db->class_val_to_struct[ft->tclass - 1]; -+ -+ return STATUS_SUCCESS; -+} -+ -+int qpol_filename_trans_get_trans_type(const qpol_policy_t * policy, const qpol_filename_trans_t * rule, const qpol_type_t ** output_type) -+{ -+ policydb_t *db = NULL; -+ filename_trans_t *ft = NULL; -+ -+ if (output_type) { -+ *output_type = NULL; -+ } -+ -+ if (!policy || !rule || !output_type) { -+ ERR(policy, "%s", strerror(EINVAL)); -+ errno = EINVAL; -+ return STATUS_ERR; -+ } -+ -+ db = &policy->p->p; -+ ft = (filename_trans_t *) rule; -+ -+ *output_type = (qpol_type_t *) db->type_val_to_struct[ft->otype - 1]; -+ -+ return STATUS_SUCCESS; -+} -+ -+int qpol_filename_trans_get_default_type(const qpol_policy_t * policy, const qpol_filename_trans_t * rule, const qpol_type_t ** dflt) -+{ -+ policydb_t *db = NULL; -+ filename_trans_t *ft = NULL; -+ -+ if (dflt) { -+ *dflt = NULL; -+ } -+ -+ if (!policy || !rule || !dflt) { -+ ERR(policy, "%s", strerror(EINVAL)); -+ errno = EINVAL; -+ return STATUS_ERR; -+ } -+ -+ db = &policy->p->p; -+ ft = (filename_trans_t *) rule; -+ -+ *dflt = (qpol_type_t *) db->type_val_to_struct[ft->otype - 1]; -+ -+ return STATUS_SUCCESS; -+} -+ -+int qpol_filename_trans_get_filename(const qpol_policy_t * policy, const qpol_filename_trans_t * rule, const char ** name) -+{ -+ policydb_t *db = NULL; -+ filename_trans_t *ft = NULL; -+ -+ if (name) { -+ *name = NULL; -+ } -+ -+ if (!policy || !rule || !name) { -+ ERR(policy, "%s", strerror(EINVAL)); -+ errno = EINVAL; -+ return STATUS_ERR; -+ } -+ -+ db = &policy->p->p; -+ ft = (filename_trans_t *) rule; -+ -+ *name = ft->name; -+ -+ return STATUS_SUCCESS; -+} -+ -diff --git a/libqpol/src/libqpol.map b/libqpol/src/libqpol.map -index dd293bc..6973cca 100644 ---- a/libqpol/src/libqpol.map -+++ b/libqpol/src/libqpol.map -@@ -34,6 +34,7 @@ VERS_1.2 { - qpol_policy_reevaluate_conds; - qpol_portcon_*; - qpol_range_trans_*; -+ qpol_filename_trans_*; - qpol_role_*; - qpol_syn_avrule_*; - qpol_syn_terule_*; -diff --git a/libqpol/src/module_compiler.c b/libqpol/src/module_compiler.c -index dc19798..b06e285 100644 ---- a/libqpol/src/module_compiler.c -+++ b/libqpol/src/module_compiler.c -@@ -1247,6 +1247,18 @@ void append_role_allow(role_allow_rule_t * role_allow_rules) - } - - /* this doesn't actually append, but really prepends it */ -+void append_filename_trans(filename_trans_rule_t * filename_trans_rules) -+{ -+ avrule_decl_t *decl = stack_top->decl; -+ -+ /* filename transitions are not allowed within conditionals */ -+ assert(stack_top->type == 1); -+ -+ filename_trans_rules->next = decl->filename_trans_rules; -+ decl->filename_trans_rules = filename_trans_rules; -+} -+ -+/* this doesn't actually append, but really prepends it */ - void append_range_trans(range_trans_rule_t * range_tr_rules) - { - avrule_decl_t *decl = stack_top->decl; -diff --git a/libqpol/src/policy_define.c b/libqpol/src/policy_define.c -index c94f7aa..0f3a45a 100644 ---- a/libqpol/src/policy_define.c -+++ b/libqpol/src/policy_define.c -@@ -2133,7 +2133,7 @@ int define_role_trans(void) - - /* This ebitmap business is just to ensure that there are not conflicting role_trans rules */ - #ifdef HAVE_SEPOL_USER_ROLE_MAPPING -- if (role_set_expand(&roles, &e_roles, policydbp, NULL)) -+ if (role_set_expand(&roles, &e_roles, policydbp, NULL, NULL)) - #else - if (role_set_expand(&roles, &e_roles, policydbp)) - #endif -@@ -2226,6 +2226,190 @@ int define_role_allow(void) - return 0; - } - -+avrule_t *define_cond_filename_trans(void) -+{ -+ yyerror("type transitions with a filename not allowed inside " -+ "conditionals\n"); -+ return COND_ERR; -+} -+ -+int define_filename_trans(void) -+{ -+ char *id, *name = NULL; -+ type_set_t stypes, ttypes; -+ ebitmap_t e_stypes, e_ttypes; -+ ebitmap_t e_tclasses; -+ ebitmap_node_t *snode, *tnode, *cnode; -+ filename_trans_t *ft; -+ filename_trans_rule_t *ftr; -+ class_datum_t *cladatum; -+ type_datum_t *typdatum; -+ uint32_t otype; -+ unsigned int c, s, t; -+ int add; -+ -+ if (pass == 1) { -+ /* stype */ -+ while ((id = queue_remove(id_queue))) -+ free(id); -+ /* ttype */ -+ while ((id = queue_remove(id_queue))) -+ free(id); -+ /* tclass */ -+ while ((id = queue_remove(id_queue))) -+ free(id); -+ /* otype */ -+ id = queue_remove(id_queue); -+ free(id); -+ /* name */ -+ id = queue_remove(id_queue); -+ free(id); -+ return 0; -+ } -+ -+ -+ add = 1; -+ type_set_init(&stypes); -+ while ((id = queue_remove(id_queue))) { -+ if (set_types(&stypes, id, &add, 0)) -+ goto bad; -+ } -+ -+ add =1; -+ type_set_init(&ttypes); -+ while ((id = queue_remove(id_queue))) { -+ if (set_types(&ttypes, id, &add, 0)) -+ goto bad; -+ } -+ -+ ebitmap_init(&e_tclasses); -+ while ((id = queue_remove(id_queue))) { -+ if (!is_id_in_scope(SYM_CLASSES, id)) { -+ yyerror2("class %s is not within scope", id); -+ free(id); -+ goto bad; -+ } -+ cladatum = hashtab_search(policydbp->p_classes.table, id); -+ if (!cladatum) { -+ yyerror2("unknown class %s", id); -+ goto bad; -+ } -+ if (ebitmap_set_bit(&e_tclasses, cladatum->s.value - 1, TRUE)) { -+ yyerror("Out of memory"); -+ goto bad; -+ } -+ free(id); -+ } -+ -+ id = (char *)queue_remove(id_queue); -+ if (!id) { -+ yyerror("no otype in transition definition?"); -+ goto bad; -+ } -+ if (!is_id_in_scope(SYM_TYPES, id)) { -+ yyerror2("type %s is not within scope", id); -+ free(id); -+ goto bad; -+ } -+ typdatum = hashtab_search(policydbp->p_types.table, id); -+ if (!typdatum) { -+ yyerror2("unknown type %s used in transition definition", id); -+ goto bad; -+ } -+ free(id); -+ otype = typdatum->s.value; -+ -+ name = queue_remove(id_queue); -+ if (!name) { -+ yyerror("no pathname specified in filename_trans definition?"); -+ goto bad; -+ } -+ -+ /* We expand the class set into seperate rules. We expand the types -+ * just to make sure there are not duplicates. They will get turned -+ * into seperate rules later */ -+ ebitmap_init(&e_stypes); -+ if (type_set_expand(&stypes, &e_stypes, policydbp, 1)) -+ goto bad; -+ -+ ebitmap_init(&e_ttypes); -+ if (type_set_expand(&ttypes, &e_ttypes, policydbp, 1)) -+ goto bad; -+ -+ ebitmap_for_each_bit(&e_tclasses, cnode, c) { -+ if (!ebitmap_node_get_bit(cnode, c)) -+ continue; -+ ebitmap_for_each_bit(&e_stypes, snode, s) { -+ if (!ebitmap_node_get_bit(snode, s)) -+ continue; -+ ebitmap_for_each_bit(&e_ttypes, tnode, t) { -+ if (!ebitmap_node_get_bit(tnode, t)) -+ continue; -+ -+ for (ft = policydbp->filename_trans; ft; ft = ft->next) { -+ if (ft->stype == (s + 1) && -+ ft->ttype == (t + 1) && -+ ft->tclass == (c + 1) && -+ !strcmp(ft->name, name)) { -+ yyerror2("duplicate filename transition for: filename_trans %s %s %s:%s", -+ name, -+ policydbp->p_type_val_to_name[s], -+ policydbp->p_type_val_to_name[t], -+ policydbp->p_class_val_to_name[c]); -+ goto bad; -+ } -+ } -+ -+ ft = malloc(sizeof(*ft)); -+ if (!ft) { -+ yyerror("out of memory"); -+ goto bad; -+ } -+ memset(ft, 0, sizeof(*ft)); -+ -+ ft->next = policydbp->filename_trans; -+ policydbp->filename_trans = ft; -+ -+ ft->name = strdup(name); -+ if (!ft->name) { -+ yyerror("out of memory"); -+ goto bad; -+ } -+ ft->stype = s + 1; -+ ft->ttype = t + 1; -+ ft->tclass = c + 1; -+ ft->otype = otype; -+ } -+ } -+ -+ /* Now add the real rule since we didn't find any duplicates */ -+ ftr = malloc(sizeof(*ftr)); -+ if (!ftr) { -+ yyerror("out of memory"); -+ goto bad; -+ } -+ filename_trans_rule_init(ftr); -+ append_filename_trans(ftr); -+ -+ ftr->name = strdup(name); -+ ftr->stypes = stypes; -+ ftr->ttypes = ttypes; -+ ftr->tclass = c + 1; -+ ftr->otype = otype; -+ } -+ -+ free(name); -+ ebitmap_destroy(&e_stypes); -+ ebitmap_destroy(&e_ttypes); -+ ebitmap_destroy(&e_tclasses); -+ -+ return 0; -+ -+bad: -+ free(name); -+ return -1; -+} -+ - static constraint_expr_t *constraint_expr_clone(constraint_expr_t * expr) - { - constraint_expr_t *h = NULL, *l = NULL, *e, *newe; -diff --git a/libqpol/src/policy_parse.y b/libqpol/src/policy_parse.y -index 84f4114..dc16c6f 100644 ---- a/libqpol/src/policy_parse.y -+++ b/libqpol/src/policy_parse.y -@@ -98,6 +98,7 @@ extern char *qpol_src_inputlim;/* end of data */ - %type require_decl_def - - %token PATH -+%token FILENAME - %token CLONE - %token COMMON - %token CLASS -@@ -360,7 +361,10 @@ cond_rule_def : cond_transition_def - | require_block - { $$ = NULL; } - ; --cond_transition_def : TYPE_TRANSITION names names ':' names identifier ';' -+cond_transition_def : TYPE_TRANSITION names names ':' names identifier filename ';' -+ { $$ = define_cond_filename_trans() ; -+ if ($$ == COND_ERR) return -1;} -+ | TYPE_TRANSITION names names ':' names identifier ';' - { $$ = define_cond_compute_type(AVRULE_TRANSITION) ; - if ($$ == COND_ERR) return -1;} - | TYPE_MEMBER names names ':' names identifier ';' -@@ -395,7 +399,9 @@ cond_dontaudit_def : DONTAUDIT names names ':' names names ';' - { $$ = define_cond_te_avtab(AVRULE_DONTAUDIT); - if ($$ == COND_ERR) return -1; } - ; --transition_def : TYPE_TRANSITION names names ':' names identifier ';' -+transition_def : TYPE_TRANSITION names names ':' names identifier filename ';' -+ {if (define_filename_trans()) return -1; } -+ | TYPE_TRANSITION names names ':' names identifier ';' - {if (define_compute_type(AVRULE_TRANSITION)) return -1;} - | TYPE_MEMBER names names ':' names identifier ';' - {if (define_compute_type(AVRULE_MEMBER)) return -1;} -@@ -752,6 +758,9 @@ identifier : IDENTIFIER - path : PATH - { if (insert_id(yytext,0)) return -1; } - ; -+filename : FILENAME -+ { yytext[strlen(yytext) - 1] = '\0'; if (insert_id(yytext + 1,0)) return -1; } -+ ; - number : NUMBER - { $$ = strtoul(yytext,NULL,0); } - ; -diff --git a/libqpol/src/policy_scan.l b/libqpol/src/policy_scan.l -index 75485f3..30203cd 100644 ---- a/libqpol/src/policy_scan.l -+++ b/libqpol/src/policy_scan.l -@@ -235,6 +235,7 @@ POLICYCAP { return(POLICYCAP); } - permissive | - PERMISSIVE { return(PERMISSIVE); } - "/"({alnum}|[_\.\-/])* { return(PATH); } -+\"({alnum}|[_\.\-])+\" { return(FILENAME); } - {letter}({alnum}|[_\-])*([\.]?({alnum}|[_\-]))* { return(IDENTIFIER); } - {digit}+|0x{hexval}+ { return(NUMBER); } - {digit}{1,3}(\.{digit}{1,3}){3} { return(IPV4_ADDR); } -diff --git a/secmds/sesearch.c b/secmds/sesearch.c -index ec0315f..e44b3bc 100644 ---- a/secmds/sesearch.c -+++ b/secmds/sesearch.c -@@ -575,6 +575,95 @@ static void print_te_results(const apol_policy_t * policy, const options_t * opt - free(expr); - } - -+static int perform_ft_query(const apol_policy_t * policy, const options_t * opt, apol_vector_t ** v) -+{ -+ apol_filename_trans_query_t *ftq = NULL; -+ int error = 0; -+ -+ if (!policy || !opt || !v) { -+ ERR(policy, "%s", strerror(EINVAL)); -+ errno = EINVAL; -+ return -1; -+ } -+ -+ if (!opt->type == QPOL_RULE_TYPE_TRANS && !opt->all) { -+ *v = NULL; -+ return 0; /* no search to do */ -+ } -+ -+ ftq = apol_filename_trans_query_create(); -+ if (!ftq) { -+ ERR(policy, "%s", strerror(ENOMEM)); -+ errno = ENOMEM; -+ return -1; -+ } -+ -+ apol_filename_trans_query_set_regex(policy, ftq, opt->useregex); -+ if (opt->src_name) { -+ if (apol_filename_trans_query_set_source(policy, ftq, opt->src_name)) { -+ error = errno; -+ goto err; -+ } -+ } -+ if (opt->tgt_name) { -+ if (apol_filename_trans_query_set_target(policy, ftq, opt->tgt_name, opt->indirect)) { -+ error = errno; -+ goto err; -+ } -+ } -+ -+ if (apol_filename_trans_get_by_query(policy, ftq, v)) { -+ error = errno; -+ goto err; -+ } -+ -+ apol_filename_trans_query_destroy(&ftq); -+ return 0; -+ -+ err: -+ apol_vector_destroy(v); -+ apol_filename_trans_query_destroy(&ftq); -+ ERR(policy, "%s", strerror(error)); -+ errno = error; -+ return -1; -+} -+ -+static void print_ft_results(const apol_policy_t * policy, const options_t * opt, const apol_vector_t * v) -+{ -+ qpol_policy_t *q = apol_policy_get_qpol(policy); -+ size_t i, num_rules = 0; -+ const qpol_filename_trans_t *rule = NULL; -+ char *tmp = NULL, *rule_str = NULL, *expr = NULL; -+ char enable_char = ' ', branch_char = ' '; -+ qpol_iterator_t *iter = NULL; -+ const qpol_cond_t *cond = NULL; -+ uint32_t enabled = 0, list = 0; -+ -+ if (!(num_rules = apol_vector_get_size(v))) -+ goto cleanup; -+ -+ fprintf(stdout, "Found %zd named file transition rules:\n", num_rules); -+ -+ for (i = 0; i < num_rules; i++) { -+ enable_char = branch_char = ' '; -+ if (!(rule = apol_vector_get_element(v, i))) -+ goto cleanup; -+ -+ if (!(rule_str = apol_filename_trans_render(policy, rule))) -+ goto cleanup; -+ fprintf(stdout, "%s %s\n", rule_str, expr ? expr : ""); -+ free(rule_str); -+ rule_str = NULL; -+ free(expr); -+ expr = NULL; -+ } -+ -+ cleanup: -+ free(tmp); -+ free(rule_str); -+ free(expr); -+} -+ - static int perform_ra_query(const apol_policy_t * policy, const options_t * opt, apol_vector_t ** v) - { - apol_role_allow_query_t *raq = NULL; -@@ -1128,6 +1217,18 @@ int main(int argc, char **argv) - print_te_results(policy, &cmd_opts, v); - fprintf(stdout, "\n"); - } -+ -+ if (cmd_opts.all || cmd_opts.type == QPOL_RULE_TYPE_TRANS) { -+ apol_vector_destroy(&v); -+ if (perform_ft_query(policy, &cmd_opts, &v)) { -+ rt = 1; -+ goto cleanup; -+ } -+ -+ print_ft_results(policy, &cmd_opts, v); -+ fprintf(stdout, "\n"); -+ } -+ - apol_vector_destroy(&v); - if (perform_ra_query(policy, &cmd_opts, &v)) { - rt = 1; --- -1.7.5.4 - diff --git a/recipes-security/setools/setools/setools-replcon-correct-invalid-prototype-for-lsetfilecon_ra.patch b/recipes-security/setools/setools/setools-replcon-correct-invalid-prototype-for-lsetfilecon_ra.patch new file mode 100644 index 0000000..c9bacbd --- /dev/null +++ b/recipes-security/setools/setools/setools-replcon-correct-invalid-prototype-for-lsetfilecon_ra.patch @@ -0,0 +1,34 @@ +From 74680dfb3df4c0c5b0e4bcf41717a9ea16fd8680 Mon Sep 17 00:00:00 2001 +From: Joe MacDonald +Date: Mon, 29 Sep 2014 14:19:48 -0400 +Subject: [PATCH] replcon: correct invalid prototype for lsetfilecon_raw + +Port debian patch from: + + git://anonscm.debian.org/selinux/setools.git + commit a3ab84b35efd9c42641d53ec2236ad01f7411df7 + +Upstream-Status: Denied [ the setools3 tree is in stasis and the focus is + only on setools4 now ] + +Signed-off-by: Joe MacDonald +--- + secmds/replcon.cc | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/secmds/replcon.cc b/secmds/replcon.cc +index 34f7c1a..307c39f 100644 +--- a/secmds/replcon.cc ++++ b/secmds/replcon.cc +@@ -60,7 +60,7 @@ static struct option const longopts[] = { + {NULL, 0, NULL, 0} + }; + +-extern int lsetfilecon_raw(const char *, security_context_t) __attribute__ ((weak)); ++extern int lsetfilecon_raw(const char *, const char *) __attribute__ ((weak)); + + /** + * As that setools must work with older libselinux versions that may +-- +1.9.1 + diff --git a/recipes-security/setools/setools_3.3.8.bb b/recipes-security/setools/setools_3.3.8.bb index 6f3b1dd..050f4ff 100644 --- a/recipes-security/setools/setools_3.3.8.bb +++ b/recipes-security/setools/setools_3.3.8.bb @@ -14,7 +14,6 @@ SRC_URI[sha256sum] = "44387ecc9a231ec536a937783440cd8960a72c51f14bffc1604b7525e3 SRC_URI += "file://setools-neverallow-rules-all-always-fail.patch" SRC_URI += "file://setools-Fix-sepol-calls-to-work-with-latest-libsepol.patch" -#SRC_URI += "file://setools-Changes-to-support-named-file_trans-rules.patch" SRC_URI += "file://setools-Don-t-check-selinux-policies-if-disabled.patch" SRC_URI += "file://setools-configure-ac.patch" @@ -23,6 +22,8 @@ SRC_URI += "file://setools-cross-ar.patch" SRC_URI += "file://setools-Fix-test-bug-for-unary-operator.patch" SRC_URI += "file://setools-Fix-python-setools-Makefile.am-for-cross.patch" +SRC_URI += "file://setools-replcon-correct-invalid-prototype-for-lsetfilecon_ra.patch" + LIC_FILES_CHKSUM = "file://${S}/COPYING;md5=26035c503c68ae1098177934ac0cc795 \ file://${S}/COPYING.GPL;md5=751419260aa954499f7abaabaa882bbe \ file://${S}/COPYING.LGPL;md5=fbc093901857fcd118f065f900982c24" -- cgit v1.2.3-54-g00ecf