diff -Nru apport-2.20.9/data/apport apport-2.20.9/data/apport --- apport-2.20.9/data/apport 2020-07-15 07:36:37.000000000 -0500 +++ apport-2.20.9/data/apport 2020-08-21 10:12:55.000000000 -0500 @@ -15,7 +15,7 @@ import sys, os, os.path, subprocess, time, traceback, pwd, io import signal, inspect, grp, fcntl, socket, atexit, array, struct -import errno +import errno, argparse import apport, apport.fileutils @@ -358,6 +358,47 @@ return False +def parse_arguments(): + parser = argparse.ArgumentParser(epilog=""" + Alternatively, the following command line is understood for legacy hosts: + [global pid] + """) + + # TODO: Use type=int + parser.add_argument("-p", "--pid", help="process id (%%p)") + parser.add_argument("-s", "--signal-number", help="signal number (%%s)") + parser.add_argument("-c", "--core-ulimit", help="core ulimit (%%c)") + parser.add_argument("-d", "--dump-mode", help="dump mode (%%d)") + parser.add_argument("-P", "--global-pid", nargs='?', help="pid in root namespace (%%P)") + parser.add_argument("-E", "--executable-path", nargs='?', help="path of executable (%%E)") + + options, rest = parser.parse_known_args() + + if options.pid is not None: + for arg in rest: + error_log("Unknown argument: %s", arg) + + elif len(rest) in (4, 5, 6): + # Translate legacy command line + options.pid = rest[0] + options.signal_number = rest[1] + options.core_ulimit = rest[2] + options.dump_mode = rest[3] + try: + options.global_pid = rest[4] + except IndexError: + options.global_pid = None + try: + options.exe_path = rest[5].replace('!', '/') + except IndexError: + options.exe_path = None + else: + parser.print_usage() + sys.exit(1) + + return options + + ################################################################# # # main @@ -406,16 +447,7 @@ error_log('Received a bad number of arguments from forwarder, received %d, expected 5, aborting.' % len(sys.argv)) sys.exit(1) -# Normal startup -if len(sys.argv) not in (5, 6, 7): - try: - print('Usage: %s [global pid] [exe path]' % sys.argv[0]) - print('The core dump is read from stdin.') - except IOError: - # sys.stderr might not actually exist, expecially not when being called - # from the kernel - pass - sys.exit(1) +options = parse_arguments() init_error_log() @@ -423,8 +455,8 @@ # then compare it with the local PID. If they don't match, it's an # indication that the crash originated from another PID namespace. # Simply log an entry in the host error log and exit 0. -if len(sys.argv) >= 6: - host_pid = int(sys.argv[5]) +if options.global_pid is not None: + host_pid = int(options.global_pid) if not is_same_ns(host_pid, "pid") and not is_same_ns(host_pid, "mnt"): # If the crash came from a container, don't attempt to handle @@ -434,7 +466,7 @@ # forward the process information there. if not os.path.exists('/proc/%d/root/run/apport.socket' % host_pid): error_log('host pid %s crashed in a container without apport support' % - host_pid) + options.global_pid) sys.exit(0) proc_host_pid_fd = os.open('/proc/%d' % host_pid, os.O_RDONLY | os.O_PATH | os.O_DIRECTORY) @@ -507,7 +539,7 @@ sock.connect('/run/apport.socket') except Exception as e: error_log('host pid %s crashed in a container with a broken apport' % - sys.argv[5]) + options.global_pid) sys.exit(0) # Send all arguments except for the first (exec path) and last (global pid) @@ -538,14 +570,17 @@ # sandbox will use container namespaces as a security measure but are # still otherwise host processes. When that's the case, we need to keep # handling those crashes locally using the global pid. - sys.argv[1] = str(host_pid) + options.pid = str(host_pid) check_lock() try: setup_signals() - (pid, signum, core_ulimit, dump_mode) = sys.argv[1:5] + pid = options.pid + signum = options.signal_number + core_ulimit = options.core_ulimit + dump_mode = options.dump_mode get_pid_info(pid) @@ -606,10 +641,8 @@ # We already need this here to figure out the ExecutableName (for scripts, # etc). - if len(sys.argv) >= 7: - exec_path = sys.argv[6].replace('!', '/') - if os.path.exists(exec_path): - info['ExecutablePath'] = exec_path + if options.exe_path is not None and os.path.exists(options.exe_path): + info['ExecutablePath'] = options.exe_path euid = os.geteuid() egid = os.getegid() diff -Nru apport-2.20.9/debian/changelog apport-2.20.9/debian/changelog --- apport-2.20.9/debian/changelog 2020-08-05 20:08:39.000000000 -0500 +++ apport-2.20.9/debian/changelog 2020-08-21 10:12:55.000000000 -0500 @@ -1,3 +1,10 @@ +apport (2.20.9-0ubuntu7.18) bionic; urgency=medium + + * data/apport: Introduce support for non-positional arguments so we can + easily extend core_pattern in the future (LP: #1732962) + + -- Matthieu Clemenceau Fri, 21 Aug 2020 10:12:55 -0500 + apport (2.20.9-0ubuntu7.17) bionic; urgency=medium [ Brian Murray ] diff -Nru apport-2.20.9/etc/init.d/apport apport-2.20.9/etc/init.d/apport --- apport-2.20.9/etc/init.d/apport 2020-02-26 21:18:45.000000000 -0600 +++ apport-2.20.9/etc/init.d/apport 2020-08-21 10:12:55.000000000 -0500 @@ -50,7 +50,12 @@ rm -f /var/lib/pm-utils/resume-hang.log fi - echo "|$AGENT %p %s %c %d %P %E" > /proc/sys/kernel/core_pattern + # Old compatibility mode, switch later to second one + if true; then + echo "|$AGENT %p %s %c %d %P %E" > /proc/sys/kernel/core_pattern + else + echo "|$AGENT -p%p -s%s -c%c -d%d -P%P -E%E" > /proc/sys/kernel/core_pattern + fi echo 2 > /proc/sys/fs/suid_dumpable } diff -Nru apport-2.20.9/NEWS apport-2.20.9/NEWS --- apport-2.20.9/NEWS 2019-11-11 15:57:56.000000000 -0600 +++ apport-2.20.9/NEWS 2020-08-21 10:12:55.000000000 -0500 @@ -29,6 +29,8 @@ * data/general-hooks/generic.py: change JournalErrors to contain errors not warnings. (LP: #1738581) * data/apport: wait for lock, with 30s timeout (LP: #1746874) + * data/apport: Introduce support for non-positional arguments so we + can easily extend core_pattern in the future (LP: #1732962) 2.20.8 (2017-11-15) ------------------- diff -Nru apport-2.20.9/use-local apport-2.20.9/use-local --- apport-2.20.9/use-local 2019-11-11 15:57:56.000000000 -0600 +++ apport-2.20.9/use-local 2020-08-21 10:12:55.000000000 -0500 @@ -4,4 +4,4 @@ # making changes to bin/apport and want to test them without copying them to # /usr/share/apport/ every time. -echo "|$(readlink -f $(dirname $0)/data/apport) %p %s %c %d %P" > /proc/sys/kernel/core_pattern +echo "|$(readlink -f $(dirname $0)/data/apport) -p%p -s%s -c%c -d%d -P%P" | tee /proc/sys/kernel/core_pattern