[apparmor] [patch] Improve user-visible exception handling

Christian Boltz apparmor at cboltz.de
Thu Jun 25 19:36:13 UTC 2015


Hello,

this patch improves the user-visible exception handling.

Instead of always showing a backtrace,
- for AppArmorException (used for profile syntax errors etc.), print only
  the exceptions value because a backtrace is superfluous and would
  confuse users.
- for other (unexpected) exceptions, print backtrace and save detailed
  information in a file in /tmp/ (including variable content etc.) to
  make debugging easier.

This is done by adding the apparmor.fail module which contains a custom
exception handler (using cgitb, except for AppArmorException).

Also change all python aa-* tools to use the new exception handler.

Note: aa-audit did show backtraces only if the --trace option was given.
This is superfluous with the improved exception handling, therefore this
patch removes the --trace option. (The other aa-* tools never had this
option.)


If you want to test the behaviour of the new exception handler, you can
use this script:

#!/usr/bin/python

from apparmor.common import AppArmorException, AppArmorBug
from apparmor.fail import enable_aa_exception_handler

enable_aa_exception_handler()

# choose one ;-)
raise AppArmorException('Harmless example failure')
#raise AppArmorBug('b\xe4d bug!')
#raise Exception('something is broken!')



[ 56-improve-exception-handling.diff ]

=== modified file utils/aa-audit
--- utils/aa-audit      2015-06-06 14:53:16.868029000 +0200
+++ utils/aa-audit      2015-06-25 21:16:10.466581955 +0200
@@ -13,10 +13,13 @@
 #
 # ----------------------------------------------------------------------
 import argparse
-import traceback
 
 import apparmor.tools
 
+# setup exception handling
+from apparmor.fail import enable_aa_exception_handler
+enable_aa_exception_handler()
+
 # setup module translations
 from apparmor.translations import init_translation
 _ = init_translation()
@@ -25,18 +28,10 @@
 parser.add_argument('-d', '--dir', type=str, help=_('path to profiles'))
 parser.add_argument('-r', '--remove', action='store_true', help=_('remove audit mode'))
 parser.add_argument('program', type=str, nargs='+', help=_('name of program'))
-parser.add_argument('--trace', action='store_true', help=_('Show full trace'))
 parser.add_argument('--no-reload', dest='do_reload', action='store_false', default=True, help=_('Do not reload the profile after modifying it'))
 args = parser.parse_args()
 
-try:
-    tool = apparmor.tools.aa_tools('audit', args)
-
-    tool.cmd_audit()
+tool = apparmor.tools.aa_tools('audit', args)
 
-except Exception as e:
-    if not args.trace:
-        print(e.value + "\n")
+tool.cmd_audit()
 
-    else:
-        traceback.print_exc()
=== modified file utils/aa-autodep
--- utils/aa-autodep    2014-09-10 22:00:36.616976000 +0200
+++ utils/aa-autodep    2015-06-25 21:10:02.942087274 +0200
@@ -16,6 +16,10 @@
 
 import apparmor.tools
 
+# setup exception handling
+from apparmor.fail import enable_aa_exception_handler
+enable_aa_exception_handler()
+
 # setup module translations
 from apparmor.translations import init_translation
 _ = init_translation()
=== modified file utils/aa-cleanprof
--- utils/aa-cleanprof  2015-06-06 14:53:16.868029000 +0200
+++ utils/aa-cleanprof  2015-06-25 21:10:07.661811104 +0200
@@ -16,6 +16,10 @@
 
 import apparmor.tools
 
+# setup exception handling
+from apparmor.fail import enable_aa_exception_handler
+enable_aa_exception_handler()
+
 # setup module translations
 from apparmor.translations import init_translation
 _ = init_translation()
=== modified file utils/aa-complain
--- utils/aa-complain   2015-06-06 14:53:16.868029000 +0200
+++ utils/aa-complain   2015-06-25 21:09:53.710627443 +0200
@@ -16,6 +16,10 @@
 
 import apparmor.tools
 
+# setup exception handling
+from apparmor.fail import enable_aa_exception_handler
+enable_aa_exception_handler()
+
 # setup module translations
 from apparmor.translations import init_translation
 _ = init_translation()
=== modified file utils/aa-disable
--- utils/aa-disable    2015-06-06 14:53:16.868029000 +0200
+++ utils/aa-disable    2015-06-25 21:10:26.643700398 +0200
@@ -16,6 +16,10 @@
 
 import apparmor.tools
 
+# setup exception handling
+from apparmor.fail import enable_aa_exception_handler
+enable_aa_exception_handler()
+
 # setup module translations
 from apparmor.translations import init_translation
 _ = init_translation()
=== modified file utils/aa-easyprof
--- utils/aa-easyprof   2015-04-02 11:44:42.194482000 +0200
+++ utils/aa-easyprof   2015-06-25 21:11:14.502899966 +0200
@@ -14,6 +14,10 @@
 import os
 import sys
 
+# setup exception handling
+from apparmor.fail import enable_aa_exception_handler
+enable_aa_exception_handler()
+
 if __name__ == "__main__":
     def usage():
         '''Return usage information'''
=== modified file utils/aa-enforce
--- utils/aa-enforce    2015-06-06 14:53:16.868029000 +0200
+++ utils/aa-enforce    2015-06-25 21:11:23.479374717 +0200
@@ -16,6 +16,10 @@
 
 import apparmor.tools
 
+# setup exception handling
+from apparmor.fail import enable_aa_exception_handler
+enable_aa_exception_handler()
+
 # setup module translations
 from apparmor.translations import init_translation
 _ = init_translation()
=== modified file utils/aa-genprof
--- utils/aa-genprof    2015-02-20 21:48:18.195796000 +0100
+++ utils/aa-genprof    2015-06-25 21:12:00.922183789 +0200
@@ -23,6 +23,10 @@
 import apparmor.ui as aaui
 from apparmor.common import warn
 
+# setup exception handling
+from apparmor.fail import enable_aa_exception_handler
+enable_aa_exception_handler()
+
 # setup module translations
 from apparmor.translations import init_translation
 _ = init_translation()
=== modified file utils/aa-logprof
--- utils/aa-logprof    2015-02-20 21:48:18.195796000 +0100
+++ utils/aa-logprof    2015-06-25 21:12:17.963186653 +0200
@@ -17,6 +17,10 @@
 
 import apparmor.aa as apparmor
 
+# setup exception handling
+from apparmor.fail import enable_aa_exception_handler
+enable_aa_exception_handler()
+
 # setup module translations
 from apparmor.translations import init_translation
 _ = init_translation()
=== modified file utils/aa-mergeprof
--- utils/aa-mergeprof  2015-06-18 23:50:22.426586283 +0200
+++ utils/aa-mergeprof  2015-06-25 21:12:35.720147622 +0200
@@ -25,6 +25,10 @@
 import apparmor.cleanprofile as cleanprofile
 import apparmor.ui as aaui
 
+# setup exception handling
+from apparmor.fail import enable_aa_exception_handler
+enable_aa_exception_handler()
+
 # setup module translations
 from apparmor.translations import init_translation
 _ = init_translation()
=== modified file utils/aa-sandbox
--- utils/aa-sandbox    2014-09-10 22:00:36.616976000 +0200
+++ utils/aa-sandbox    2015-06-25 21:13:15.865798541 +0200
@@ -14,6 +14,10 @@
 import optparse
 import sys
 
+# setup exception handling
+from apparmor.fail import enable_aa_exception_handler
+enable_aa_exception_handler()
+
 if __name__ == "__main__":
     argv = sys.argv
     parser = optparse.OptionParser()
=== modified file utils/aa-status
--- utils/aa-status     2015-06-24 22:56:58.795938000 +0200
+++ utils/aa-status     2015-06-25 21:13:31.000912925 +0200
@@ -12,6 +12,10 @@
 
 import re, os, sys, errno
 
+# setup exception handling
+from apparmor.fail import enable_aa_exception_handler
+enable_aa_exception_handler()
+
 def cmd_enabled():
     '''Returns error code if AppArmor is not enabled'''
     if get_profiles() == {}:
=== modified file utils/aa-unconfined
--- utils/aa-unconfined 2015-02-02 19:50:07.032402088 +0100
+++ utils/aa-unconfined 2015-06-25 21:13:51.926688475 +0200
@@ -21,6 +21,10 @@
 import apparmor.ui as ui
 import apparmor.common
 
+# setup exception handling
+from apparmor.fail import enable_aa_exception_handler
+enable_aa_exception_handler()
+
 # setup module translations
 from apparmor.translations import init_translation
 _ = init_translation()
=== modified file utils/apparmor/fail.py
--- utils/apparmor/fail.py      2015-06-25 21:14:03.075036140 +0200
+++ utils/apparmor/fail.py      2015-06-25 20:26:59.312265725 +0200
@@ -0,0 +1,53 @@
+# ------------------------------------------------------------------
+#
+#    Copyright (C) 2015 Christian Boltz <apparmor at cboltz.de>
+#
+#    This program is free software; you can redistribute it and/or
+#    modify it under the terms of version 2 of the GNU General Public
+#    License published by the Free Software Foundation.
+#
+# ------------------------------------------------------------------
+
+import cgitb
+import os
+import sys
+import tempfile
+import traceback
+
+#
+# Exception handling
+#
+def handle_exception(*exc_info):
+    '''Used as exception handler in the aa-* tools.
+       For AppArmorException (used for profile syntax errors etc.), print only the exceptions
+       value because a backtrace is superfluous and would confuse users.
+       For other exceptions, print backtrace and save detailed information in a file in /tmp/
+       (including variable content etc.) to make debugging easier.
+    '''
+    (ex_cls, ex, tb) = exc_info
+
+    if ex_cls.__name__  == 'AppArmorException':  # I didn't find a way to get this working with isinstance() :-/
+        print('')
+        print(ex.value)
+    else:
+        (fd, path) = tempfile.mkstemp(prefix='apparmor-bugreport-', suffix='.txt')
+        file = os.fdopen(fd, 'w')
+        #file = open_file_write(path)  # writes everything converted to utf8 - not sure if we want this...
+
+        cgitb_hook = cgitb.Hook(display=1, file=file, format='text', context=10)
+        cgitb_hook.handle(exc_info)
+
+        file.write('Please consider reporting a bug at https://bugs.launchpad.net/apparmor/\n')
+        file.write('and attach this file.\n')
+
+        print(''.join(traceback.format_exception(*exc_info)))
+        print('')
+        print('An unexpected error occoured!')
+        print('')
+        print('For details, see %s' % path)
+        print('Please consider reporting a bug at https://bugs.launchpad.net/apparmor/')
+        print('and attach this file.')
+
+def enable_aa_exception_handler():
+    '''Setup handle_exception() as exception handler'''
+    sys.excepthook = handle_exception




Regards,

Christian Boltz
-- 
> Rechte Maustaste auf den Mülleimer -> Mülleimer lehren
Also, wenn Du dem Muelleimer 'was lehren kannst, bist Du echt gut. Ich
hoffe, Du hast aber auch eine Lehrerausbildung, sonst kann das in die
Hose gehn... :-)   [> Manfred Tremmel und Thomas Hertweck in suse-linux]




More information about the AppArmor mailing list