--- apport-2.20.11/data/apport 2019-05-16 20:18:33.000000000 +0100 +++ ../apport 2019-09-09 13:14:11.598361300 +0100 @@ -432,9 +432,55 @@ if options.global_pid is not None: options.global_pid) sys.exit(0) + # Validate that the crashed binary is owned by the user namespace of the process + task_uid = os.stat("/proc/%d/exe" % host_pid).st_uid + if os.path.exists("/proc/%d/uid_map" % host_pid): + with open("/proc/%d/uid_map" % host_pid, "r") as fd: + for line in fd: + fields = line.split() + if len(fields) != 3: + continue + + host_start = int(fields[1]) + host_end = host_start + int(fields[2]) + + if task_uid >= host_start and task_uid <= host_end: + break + + else: + error_log("host pid %s crashed in a container with no access to the binary" + % options.global_pid) + sys.exit(0) + + task_gid = os.stat("/proc/%d/exe" % host_pid).st_gid + if os.path.exists("/proc/%d/gid_map" % host_pid): + with open("/proc/%d/gid_map" % host_pid, "r") as fd: + for line in fd: + fields = line.split() + if len(fields) != 3: + continue + + host_start = int(fields[1]) + host_end = host_start + int(fields[2]) + + if task_gid >= host_start and task_gid <= host_end: + break + + else: + error_log("host pid %s crashed in a container with no access to the binary" + % options.global_pid) + sys.exit(0) + + # Chdir and chroot to the task + # WARNING: After this point, all "import" calls are security issues + __builtins__.__dict__['__import__'] = None + + os.chdir("/proc/%d/cwd" % host_pid) + os.chroot("/proc/%d/root" % host_pid) + sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) try: - sock.connect('/proc/%d/root/run/apport.socket' % host_pid) + sock.connect('/run/apport.socket') except Exception: error_log('host pid %s crashed in a container with a broken apport' % options.global_pid) @@ -452,7 +498,6 @@ if options.global_pid is not None: sock.shutdown(socket.SHUT_RDWR) except socket.timeout: error_log('Container apport failed to process crash within 30s') - sys.exit(0) sys.exit(0) elif not is_same_ns(host_pid, "mnt"):