Public bug reported:
apport decides whether a crash report has already been shown to the user only
by comparing timestamps:
# apport/fileutils.py
def seen_report(report):
st = os.stat(report)
return (st.st_atime > st.st_mtime) or (st.st_size == 0)
On a relatime filesystem (the Ubuntu default), the first read of a freshly
written file by
*any* process sets atime > mtime. So any program that reads new files in
/var/crash marks every
report as "seen" before the user is asked: antivirus/EDR agents, backup tools,
file indexers,
audit tools, or an admin running `head`. The crash dialog then never appears,
and nothing is
logged. Crash reporting is disabled without anyone noticing.
On the affected machine, a third-party security agent scans every new file. As
a result the crash
dialog never appeared, although reports kept accumulating in /var/crash.
### Evidence (bpftrace on openat of /var/crash/*, times relative to the crash)
t+0 ms apport creates the report for a crashed coreutils binary
t+980 ms report fully written (mtime)
t+1211 ms root-owned security-agent process opens it O_RDONLY
-> atime of the report is now later than mtime -> "seen"
User journal for the same crash:
update-notifier-crash: yes <- apport-checkreports ran before the
scan: report is new
(apport-gtk starts, run_crashes() -> get_new_reports() returns nothing,
exits 0, no dialog)
### Minimal reproducer (no third-party software needed)
import os, shutil, apport.fileutils as fu
src = "/var/crash/<any existing>.crash"; dst =
"/var/crash/_atime_demo.1000.crash"
shutil.copyfile(src, dst) # a fresh report
print(fu.seen_report(dst), dst in fu.get_new_reports()) # False True
open(dst, "rb").read(1) # one byte, by any process
print(fu.seen_report(dst), dst in fu.get_new_reports()) # True False
os.unlink(dst)
Output on 26.04.1 (apport 2.34.1-0ubuntu0.1):
before read: seen=False in get_new_reports=True
after 1-byte read: seen=True in get_new_reports=False (38.5 ms total)
End to end: crash any packaged program while something reads new files in
/var/crash.
update-notifier-crash.path fires, apport-checkreports may still see the report
as new, but by
the time apport-gtk calls get_new_reports() it is "seen", so no dialog is
shown. Opening the same
report explicitly with `apport-gtk -c <file>` works, which shows the report
itself is fine.
### Expected
The "already presented to the user" state should not depend on whether some
unrelated process has
read the file. For example, apport could record it explicitly when the UI
presents a report (a
`.seen` stamp or an xattr, like the existing `.upload`/`.uploaded` stamps),
instead of inferring it
from atime. That would also fix the noatime case from bug #85809.
### Environment
- Ubuntu 26.04.1 LTS, kernel 7.0.0-34-generic, root filesystem mounted
`relatime` (default)
- apport / apport-gtk 2.34.1-0ubuntu0.1, update-notifier 3.207.2
- Crash path: systemd-coredump → apport-coredump-hook → apport
--from-systemd-coredump
- KDE Plasma 6.6.6 (update-notifier-crash.path user unit active;
update-notifier autostart has NotShowIn=KDE)
- Real-world trigger: a security agent that scans newly created files; the
reproducer above needs no third-party software
** Affects: apport (Ubuntu)
Importance: Undecided
Status: New
** Affects: update-notifier (Ubuntu)
Importance: Undecided
Status: New
** Attachment added: "apport-atime-demo.py"
https://bugs.launchpad.net/bugs/2169793/+attachment/6006667/+files/apport-atime-demo.py
** Also affects: update-notifier (Ubuntu)
Importance: Undecided
Status: New
--
You received this bug notification because you are a member of Ubuntu
Bugs, which is subscribed to Ubuntu.
https://bugs.launchpad.net/bugs/2169793
Title:
Crash dialogs silently never appear when another process reads new
reports in /var/crash (seen_report() relies on atime)
To manage notifications about this bug go to:
https://bugs.launchpad.net/ubuntu/+source/apport/+bug/2169793/+subscriptions
--
ubuntu-bugs mailing list
[email protected]
https://lists.ubuntu.com/mailman/listinfo/ubuntu-bugs
