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

Seth Arnold seth.arnold at canonical.com
Fri Jun 26 05:23:46 UTC 2015


On Thu, Jun 25, 2015 at 09:36:13PM +0200, Christian Boltz wrote:
> 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.)
> 
> 

I like it. :)

I think the message printed to the user should include the filename; it's
not obvious to me that a user would know where to find the file.

Acked-by: Seth Arnold <seth.arnold at canonical.com>

Thanks

> 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]
> 
> 
> -- 
> AppArmor mailing list
> AppArmor at lists.ubuntu.com
> Modify settings or unsubscribe at: https://lists.ubuntu.com/mailman/listinfo/apparmor
> 
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 473 bytes
Desc: Digital signature
URL: <https://lists.ubuntu.com/archives/apparmor/attachments/20150625/4d976de6/attachment.pgp>


More information about the AppArmor mailing list