[PATCH 2/3] libselinux: generate Python glue code using "sed"

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



libselinux currently uses "gcc -aux-info" in order to generate glue code
for its Python bindings that throws an exception when a function returns
a negative integer value. This causes issues when another compiler than
gcc is used (such as clang or icc), as option -aux-info is specific to
gcc.

Replace "gcc -aux-info" with a command that parses the content of header
files using "sed". As this is more fragile (because the declaration of
functions is not normalized), add a new target to the Makefile in order
to test that the new method does not produce different results with
"make CC=gcc test".

When reverting commit cfe487409307 ("libselinux: mark all exported
function "extern""), "make test" now fails as expected:

    bash -e exception.sh test
    Error ensuring that all exported functions that return an int are handled by exception.sh.
    Here are functions that were not found in "gcc -aux-info" but that were collected by "sed":
    Here are functions in "gcc -aux-info" that may be missing "extern" in header file:
    selinuxfs_exists
    make: *** [Makefile:202: test] Error 1

Original thread: https://lore.kernel.org/selinux/20191012172357.GB19655@xxxxxxxxxxxxxxxxx/T/#ma78bd7fe71fb5784387a8c0cebd867d6c02ee6e4

Signed-off-by: Nicolas Iooss <nicolas.iooss@xxxxxxx>
Cc: Michael Shigorin <mike@xxxxxxxxxxxx>
---
 libselinux/Makefile         |  1 +
 libselinux/src/Makefile     |  5 ++++-
 libselinux/src/exception.sh | 38 +++++++++++++++++++++++++++++++------
 3 files changed, 37 insertions(+), 7 deletions(-)

diff --git a/libselinux/Makefile b/libselinux/Makefile
index 16531fe95bf5..c0ae884f8ede 100644
--- a/libselinux/Makefile
+++ b/libselinux/Makefile
@@ -67,3 +67,4 @@ clean-rubywrap:
 	$(MAKE) -C src clean-rubywrap $@
 
 test:
+	$(MAKE) -C src test
diff --git a/libselinux/src/Makefile b/libselinux/src/Makefile
index 63d6b0eda270..c12230a17b1d 100644
--- a/libselinux/src/Makefile
+++ b/libselinux/src/Makefile
@@ -198,7 +198,10 @@ clean: clean-pywrap clean-rubywrap
 distclean: clean
 	rm -f $(GENERATED) $(SWIGFILES)
 
+test:
+	bash -e exception.sh test
+
 indent:
 	../../scripts/Lindent $(filter-out $(GENERATED),$(wildcard *.[ch]))
 
-.PHONY: all clean clean-pywrap clean-rubywrap pywrap rubywrap swigify install install-pywrap install-rubywrap distclean
+.PHONY: all clean clean-pywrap clean-rubywrap pywrap rubywrap swigify install install-pywrap install-rubywrap distclean test indent
diff --git a/libselinux/src/exception.sh b/libselinux/src/exception.sh
index d6c8c71713ad..adbb632c2f04 100755
--- a/libselinux/src/exception.sh
+++ b/libselinux/src/exception.sh
@@ -1,11 +1,12 @@
+#!/bin/bash -e
 function except() {
-case $1 in
+case "$1" in
     selinux_file_context_cmp) # ignore
     ;;
     *)
 echo "
 %exception $1 {
-  \$action 
+  \$action
   if (result < 0) {
      PyErr_SetFromErrno(PyExc_OSError);
      SWIG_fail;
@@ -15,10 +16,35 @@ echo "
 ;;
 esac
 }
-if ! ${CC:-gcc} -x c -c -I../include - -aux-info temp.aux < ../include/selinux/selinux.h
+
+if [ $# -eq 1 ] && [ "$1" = "test" ]
 then
-    # clang does not support -aux-info so fall back to gcc
-    gcc -x c -c -I../include - -aux-info temp.aux < ../include/selinux/selinux.h
+    # Ensure that "gcc -aux-info" produces the same list of functions as the sed command.
+    # The main difference between these way of producing the list of exported
+    # functions is that "gcc -aux-info" automatically inserts "extern" to all
+    # declarations and writes each one on a single line.
+    # clang does not support -aux-info, so skip the test if generating the aux file failed.
+    if ${CC:-gcc} -x c -c -I../include - -aux-info temp.aux < ../include/selinux/selinux.h
+    then
+        FCT_FROM_AUX="$(awk '/<stdin>.*extern int/ { print $6 }' temp.aux | sort -u)"
+        FCT_FROM_SED="$(sed -n 's/^extern \+int \+\([0-9A-Za-z_]\+\) *(.*$/\1/p' < ../include/selinux/selinux.h | sort -u)"
+        if [ "$FCT_FROM_AUX" != "$FCT_FROM_SED" ]
+        then
+            echo >&2 'Error ensuring that all exported functions that return an int are handled by exception.sh.'
+            echo >&2 'Here are functions that were not found in "gcc -aux-info" but that were collected by "sed":'
+            comm -13 <(echo "$FCT_FROM_AUX") <(echo "$FCT_FROM_SED")
+            echo >&2 'Here are functions in "gcc -aux-info" that may be missing "extern" in header file:'
+            comm -23 <(echo "$FCT_FROM_AUX") <(echo "$FCT_FROM_SED")
+            exit 1
+        fi
+    fi
+    rm -f -- temp.aux -.o
+    exit
 fi
-for i in `awk '/<stdin>.*extern int/ { print $6 }' temp.aux`; do except $i ; done 
+
+# shellcheck disable=SC2013
+for i in $(sed -n 's/^extern \+int \+\([0-9A-Za-z_]\+\) *(.*$/\1/p' < ../include/selinux/selinux.h)
+do
+    except "$i"
+done
 rm -f -- temp.aux -.o
-- 
2.23.0




[Index of Archives]     [Selinux Refpolicy]     [Linux SGX]     [Fedora Users]     [Fedora Desktop]     [Yosemite Photos]     [Yosemite Camping]     [Yosemite Campsites]     [KDE Users]     [Gnome Users]

  Powered by Linux