Open Source / ALEAPP #1819

Security, storage, logs and crash records from bug reports

Was a screen lock set? Was a device administrator active? What did the system log record around a time of interest, and why did the device last restart? An Android bug report holds the evidence for all of it. This contribution adds 38 tables to ALEAPP and keeps the window of each log visible.

  • Daniel Addai, SectraTEK Lab
  • Merged
  • CC BY 4.0

View the pull request on GitHub

Summary

  • ALEAPP now has 38 Bug Report artifacts in seven groups: security and device policy (13), vendor services (3), storage and databases (11), settings and config (2), device and build (2), logs (3) and boot, crash and dropbox (4). The pull request was merged on 27 October 2026.
  • The log tables are large: on one report the system log alone has 325,705 rows. Times are converted with a stated year rule and the zone the report records, and the kernel log keeps its own clock as printed.
  • Row counts equal raw-text counts on every report that has the section, and the logs equal them on all seven. Cases the reports did not contain, such as damaged zip members, exist as synthetic fixtures.
  • Crash and ANR files that live inside the zip give rows only when the tool reads the zip. The artifact notes say so.
  • 38artifacts added in seven groups
  • 244test baselines in 2 case folders
  • 325,705system log rows on the larger of two reports, equal to a raw-text count
  • 509bug report unit tests of the stack pass

Methodology note

Drafted with AI assistance and reviewed by the author before publication. Every figure uses synthetic example values or counts taken from the pull request.

The issue

An examiner has to say whether a screen lock was set, whether a device administrator or a management policy was active, whether USB debugging was on, how full storage was, what the system logged around a time of interest, and why the device last restarted. A bug report is the one file that carries the device policy and lock settings dumps, the system, event and kernel logs, the crash and hang records, and on some builds a history of restart reasons. The answers are there, but a reader has to get several things right at once.

The logs are the hardest. A system log line prints month, day and clock time with no year and no zone. The body of the log reaches back a few minutes to about three hours, and a few older stray lines can sit above the dense part, so the first line of the section is not the start of the window. In LAB-TR-0041, four of the seven research reports had such head strays. An examiner who takes the first line as the start, and then finds no record of an event before it, has drawn a conclusion from the edge of the log. The kernel log uses a different clock, seconds since boot, and the report does not print when that clock started.

The policy sections have the opposite risk: they are small and easy to misread as complete. A lock settings dump lists the names, sizes and times of the files that hold lock state, and never their contents. Crash and hang records can be in the zip as separate files, not in the main text, so a reader of the text alone finds none and reports none. Figure 1 shows how one log line is read.

One log line in the report text and the row it becomesLeft: the report time, the zone property and one invented logcat line with no year. Right: the fields of the System Log row, with the year taken from the report time and the time converted to UTC.In the report text (synthetic example)In the artifact (one row)== dumpstate: 2026-03-14 10:00:00[persist.sys.timezone]: [Europe/Paris]------ SYSTEM LOG (logcat -v threadtime -v uid) ------03-14 09:26:53.589 1000 1234 1250 I ExampleTag: service up03-14 09:26:54.012 1000 1234 1251 W ExampleTag: retry 1The row on the right is the first log line. Report time and zoneare printed in two other places in the same text file.Source SectionSYSTEM LOGTime As Printed03-14 09:26:53.589Time (UTC)2026-03-14 08:26:53.589UID1000PID1234TID1250LevelITagExampleTagMessageservice upNo year and no zone are printed. The year is the latest one (the report's, or the one before) that does not put the linemore than a day after the report time. The zone is the one the report records.Without a recorded zone, Time (UTC) stays empty.
Show this figure as a table
Fields of the row in Figure 1
FieldValue (synthetic example)
Source SectionSYSTEM LOG
Time As Printed03-14 09:26:53.589
Time (UTC)2026-03-14 08:26:53.589
UID1000
PID1234
TID1250
LevelI
TagExampleTag
Messageservice up
Figure 1One logcat line becomes one row. The user id column that the report prints beside the time is kept as printed. Source: the notes of System Log in scripts/artifacts/bugreportLogsCrash.py of the pull request. Values are invented (synthetic example).

The essence

The pull request adds 38 artifacts that read the security, storage, log, crash and reset sections of a bug report in one pass. Each row is what the dump or log printed for one entry. Policy values, flags and counters are shown as printed. A log row keeps the printed time, the user, process and thread ids, the level, the tag and the message, with a UTC time added by the rule in Figure 1 where the report allows it. The kernel log keeps seconds since boot and is not given a clock time.

Two artifacts read members of the finished zip as well as the main text: ANR Trace Threads and Tombstones. The pull request notes that they only produce rows with -t fs, so a bug report text read alone gives none of the zip-member rows.

Artifacts added by the pull request
GroupArtifactsWhat the dumps hold
Security and Device Policy (13)Device Policy Admins, State, Policies; Lock Settings Users, Files, State, Log; Biometric Statistics, Sensors, Authentication Events; Trust Agents, Trust Events; ADB Manager StateAdministrator and policy state, lock settings, biometrics, trust, ADB state
Vendor (3)knoxguard_service Log, knoxcustom State, Vendor Service LinesSamsung services with event histories or policy states
Storage and Databases (11)File Systems, File System Inodes, Mount Points, Storage Volumes, Vold Log, Storage IO Counters, Disk Statistics, Package Sizes, Open Databases, Database Files, Database OperationsFree space, mounts, volumes, and the databases apps had open
Settings and Config (2) and Device and Build (2)Device Config Flags, Platform Compat Changes; Build Release Flags, SDK ExtensionsConfiguration flags and build-time values
Logs (3)System Log, Event Log, Kernel LogLogcat and kernel messages kept at dump time
Boot, Crash and Dropbox (4)ANR Trace Threads, Tombstones, Dropbox Entries, Reset ReasonsHang and crash records, entries the dropbox kept, restart records

Our methodology

The method is the one used for the other three pull requests of the stack. We write down the layout of each section from the reports we hold, by Android version and vendor, and write the reader to that layout. The readers plug into the single-pass reader of LAB-TR-0001, which streams the report once and hands each open section only to the readers registered for it (Figure 2).

Three decisions are specific to this group. Log tables stop at a row cap and add one warning to the report, so a very large log cannot grow without limit and cannot be cut without a trace. Long messages are cut at a set length. Encoded blob lines of 60 or more base64 characters in the vendor services are counted in the log and not kept; on one report that was 3,566 lines. And the kernel log is not given a clock time, because computing one would need the start of the kernel clock, which the report does not print.

Pipeline from the bug report text to the artifact columnsFive steps: the report file and its zip members, the section index, readers for security, storage, log and crash sections, bounded tables and 38 artifacts. Below, columns of two artifacts.From the report text to the report columnsBug report textdumpstate.txt,bugreport-*.txt orbugreport-*.zip andits membersSection indexevery section entered:name, lines, durationDUMP TIMEOUT keptSection readersdevice policy, locksettings, biometrics,trust, ADB manager,storage, dbinfo,device config, systemlog, event log, kernellog, ANR traces,dropbox, reset reasonsBounded tablesrows kept as printedlog tables stop at500,000 rows, with onewarning on the reportlong messages are cut38 artifacts7 groupsHTML, TSV and LAVAoutputUTC where possibleColumns of two of the 38 artifactsSystem Log: Source Section | Time As Printed | Time (UTC) | UID | PID | TID | Level | Tag | MessageKernel Log: Source Section | Seconds Since Boot | Level | CPU or Task | Message (no clock time is computed)
Show this figure as a table
Steps of Figure 2
StepWhat happens
1. Find the fileThe same path set as the earlier artifacts; ANR Trace Threads and Tombstones also read members of a finished zip.
2. Index the sectionsEvery section is entered with kind, name, lines and duration; a time-limit marker is stored on a cut service.
3. Hand over the linesReaders registered for device policy, lock settings, biometrics, trust, the ADB manager, storage commands, dbinfo, device config, the three log sections, ANR traces, dropbox and the reset sections.
4. Keep bounded rowsRows as printed; log tables stop at the row cap with one warning; long messages are cut.
5. Present38 artifacts in seven groups; UTC added where the printed time allows it.
Figure 2The same single pass as the earlier bug report artifacts; two modules read zip members as well. Section and column names are from the pull request. Source: dumpstate_securitystorage.py, dumpstate_logscrash.py, bugreportSecurityStorage.py and bugreportLogsCrash.py in the pull request; LAB-TR-0001, section 3 (diagram).

Checking has four layers. Synthetic fixtures with invented values come first, with cases per layout (l10, l16, old and new), a cut dump, an empty report, a file that is not a report, odd bytes, two reports in one run and a zip kept on the device. The two modules have 244 baselines in two case folders, and all pass under TZ=UTC.

Second, an independent recount. On the five older research reports, security and storage row counts equal an independent raw-text count on every report that has the section, and the log and crash counts equal on all five. The zone conversion left every real row unchanged, because every research report records UTC+0; any other zone is tested only on synthetic fixtures. On the two newer Android 16 reports the whole tool ran with no failed artifact, and counts made with our own line rules equalled the System Log, Event Log, Kernel Log, Device Config Flags, Database Operations and Vendor Service Lines rows (Figure 3).

Third, the 509 bug report unit tests of the stack so far pass, and the changed files score 10.00 of 10 on pylint. Fourth, behavior on missing and damaged data is built as fixtures because no research report supplied it: logcat without a user id column or with a year, a command's time-limit lines, wrapped protobuf, damaged zip members and negative offsets in reset lines. Where a report prints no section, the table is empty, and the section index shows that the section was absent and not unread.

Rows per artifact on the two newest Samsung bug reportsGrouped horizontal bars on a logarithmic scale for twelve of the 38 artifacts, from 4 rows (Dropbox Entries) to 325,705 rows (System Log).Rows per artifact on two bug reports (logarithmic scale)Report 1Report 21101001,00010,000100,0001,000,000Rows (each gridline is ten times the one before)Device Policy State4140Lock Settings Log162446Biometric Authentication Events0200Mount Points162162Package Sizes400502Database Operations9,4646,792Device Config Flags4,6144,845System Log325,705257,540Event Log14,75212,744Kernel Log17,84023,890ANR Trace Threads2,8955,737Dropbox Entries493
Show every artifact of this pull request as a table
Rows per artifact on two bug reports
ArtifactReport 1 rowsReport 2 rows
Device Policy Admins (Security and Device Policy)11
Device Policy State (Security and Device Policy)4140
Device Policies (Security and Device Policy)13
Lock Settings Users (Security and Device Policy)11
Lock Settings Files (Security and Device Policy)614
Lock Settings State (Security and Device Policy)1115
Lock Settings Log (Security and Device Policy)162446
Biometric Statistics (Security and Device Policy)22
Biometric Sensors (Security and Device Policy)22
Biometric Authentication Events (Security and Device Policy)0200
Trust Agents (Security and Device Policy)10
Trust Events (Security and Device Policy)00
ADB Manager State (Security and Device Policy)13
knoxguard_service Log (Vendor)138102
knoxcustom State (Vendor)106108
Vendor Service Lines (Vendor)12,68336,280
File Systems (Storage and Databases)6870
File System Inodes (Storage and Databases)6870
Mount Points (Storage and Databases)162162
Storage Volumes (Storage and Databases)22
Vold Log (Storage and Databases)5,6035,064
Storage IO Counters (Storage and Databases)174286
Disk Statistics (Storage and Databases)2525
Package Sizes (Storage and Databases)400502
Open Databases (Storage and Databases)223142
Database Files (Storage and Databases)1,5562,873
Database Operations (Storage and Databases)9,4646,792
Device Config Flags (Settings and Config)4,6144,845
Platform Compat Changes (Settings and Config)354357
Build Release Flags (Device and Build)641785
SDK Extensions (Device and Build)3030
System Log (Logs)325,705257,540
Event Log (Logs)14,75212,744
Kernel Log (Logs)17,84023,890
ANR Trace Threads (Boot, Crash and Dropbox)2,8955,737
Tombstones (Boot, Crash and Dropbox)08
Dropbox Entries (Boot, Crash and Dropbox)493
Reset Reasons (Boot, Crash and Dropbox)13086
Figure 3Rows per artifact on two Android 16 bug reports; twelve of the 38 artifacts are drawn, all are in the table. The scale is logarithmic: the System Log has far more rows than the policy tables. Source: pull request description, table of rows per artifact for the two newest Samsung reports (counts only, not synthetic values).

The value

For an examiner the gain is that these questions become lookups. Which device administrators were enabled and what policy state the service printed. Which lock settings files existed for each user and when they were last modified. Which biometric sensors were present and, where a build prints them, which authentication events were recorded. Whether a trust agent was enabled and the state of the ADB manager. How full storage was, which volumes were mounted, which packages were large, and which databases an app had open and what it last executed. What the system, event and kernel logs recorded, and which hang, crash and restart records exist.

The limits come first. A lock settings dump gives names, sizes and times, never contents; the lock secret and ADB keys are never in a bug report. A log window is short, and an examiner should find where the dense part begins and read the last line before concluding that nothing happened. A missing crash or dropbox entry is not proof that nothing happened. Reset Reasons come from the Samsung builds tested only. SQL text in Database Operations is shown as the platform printed it and can contain values an app passed to the database. The tool shows a token value from one Samsung service as printed, because it runs on the examiner's own evidence; this page shows none.

What the evidence for this pull request coversThree columns: what was checked on research bug reports, what exists only as a synthetic fixture, and what was not examined.What the evidence coversChecked on research reports-Security and storage row counts equal araw-text count on every report that hasthe section-Logs and crash: counts equal on fivereports; the zone conversion left everyrow unchanged (all UTC+0)-System, Event and Kernel Log, DeviceConfig Flags, Database Operations andVendor Service Lines equal raw-textcounts on two moreSynthetic fixtures only-Device policy entries; a removablevolume; a trusted trust agent; a policywith two admins-Logcat without a uid column, or with ayear-Time zones with offsets or daylightsaving-Time-limit lines of a command; wrappedprotobuf; damaged zip members; negativeoffsets in reset linesNot examined-Android 11 to 14-Vendors other than the four seen
Show this figure as a table
Evidence coverage
ColumnItems
Checked on research reportsSecurity and storage row counts equal a raw-text count on every report that has the section; Logs and crash: counts equal on five reports; the zone conversion left every row unchanged (all UTC+0); System, Event and Kernel Log, Device Config Flags, Database Operations and Vendor Service Lines equal raw-text counts on two more
Synthetic fixtures onlyDevice policy entries; a removable volume; a trusted trust agent; a policy with two admins; Logcat without a uid column, or with a year; Time zones with offsets or daylight saving; Time-limit lines of a command; wrapped protobuf; damaged zip members; negative offsets in reset lines
Not examinedAndroid 11 to 14; Vendors other than the four seen
Figure 4Evidence ladder. All seven research reports record UTC+0, so every other zone is synthetic. Source: the 'Proven on real reports', 'Constructed only' and 'Not examined' paragraphs of the pull request description (counts only, not synthetic values).

Where this sits in the Lab's research

Three Lab reports apply. LAB-TR-0001, Making Silent Failures Visible: A Single-Pass Section Reader for Android Bug Reports (Zenodo, version 1.1, 10.5281/zenodo.23719508), describes the reader, the section index and the record of cut dumps that these artifacts rely on.

LAB-TR-0041, Attributing Interior Gaps in Phone Logs to Restarts, Log Rotation and Clock Steps, is available on this site as a preprint; the Zenodo deposit is pending. It finds head strays in four of seven bug reports, treats the system log as a dense log, and says that only a restart licenses the claim that nothing happened in a gap. The reset reason and kernel log tables here are places to look for a restart; the paper's rule says what to do with one.

LAB-TR-0017, Where Device Security Settings Live on Disk, is a white paper, available on this site as a preprint; the Zenodo deposit is pending. It maps security settings in 48 full file system extractions, warns about reads that return nothing without an error, and did not examine bug reports. The security artifacts here are the bug report side of the same questions, and the same warning applies. The grouping follows Android bug reports, category by category.

Sources

Every number and claim on this page, with where it came from. Figure values are either synthetic examples (marked) or counts from the pull request.

Sources of the numbers and claims
Number or claimWhere it came from
38 artifacts in 7 groups (13, 3, 11, 2, 2, 3, 4)Pull request description, 'What this changes'; artifact list in bugreportSecurityStorage.py (30) and bugreportLogsCrash.py (8)
Merged on 27 October 2026Pull request state and merge time (mergedAt); the review and comment lists are empty
244 baselines in 2 case folders, all pass; 509 cumulative unit tests; pylint 10.00/10Pull request description, 'Test record' table
Security and storage counts equal raw-text counts; logs and crash counts equal on five reports; zone conversion was the identity on every real rowPull request description, 'Proven on real reports'
System Log 325,705 and 257,540; Event Log 14,752 and 12,744; Kernel Log 17,840 and 23,890; Device Config Flags 4,614 and 4,845; Database Operations 9,464 and 6,792; Vendor Service Lines 12,683 and 36,280; other counts in Figure 3Pull request description, table of rows per artifact (two newest Samsung reports)
Constructed only and not examined lists (Figure 4)Pull request description, 'Constructed only' and 'Not examined'
Seven reports in four vendor families, Android 10, 15 and 16; whole tool exit 0 in 20 to 55 s per reportPull request description; device classes only
The year rule for logcat lines; the zone comes from the report; empty without a zoneNotes of System Log in bugreportLogsCrash.py
Kernel Log keeps seconds since boot; no clock time is computed because the report does not print the kernel clock's startNotes of Kernel Log in bugreportLogsCrash.py
Tombstones and ANR Trace Threads read zip members and give rows only with -t fsPull request description, 'Anything reviewers should know'
Encoded blob lines of 60 or more base64 characters in vendor services are counted in the log and not kept (3,566 on one report); a token value in knoxguard_service is shown as printedPull request description, 'Anything reviewers should know'
Lock settings dump lists names, sizes and times; contents are not in a bug reportNotes of Lock Settings Files in bugreportSecurityStorage.py
SQL text in Database Operations is shown as printed and can contain valuesNotes of Database Operations in bugreportSecurityStorage.py
Reset Reasons come from the Samsung builds tested onlyNotes of Reset Reasons in bugreportLogsCrash.py
System log body runs from a few minutes to about three hours; stray older lines can sit above it; the lock secret and ADB keys are never in a bug reportLab article LAB-0002, categories 'Logs' and 'Security and device policy'
4 of 7 bug reports had head strays; a 10-minute threshold on sparse logs gave 6 spurious holes; only a restart licenses an absence claimLAB-TR-0041, abstract, Table 2 and Table 3
Android bug reports were not examined by the security settings map; 48 full file system extractionsLAB-TR-0017, abstract and 'Not covered'
Section index; timed-out dumps recorded; 2 million linesLAB-TR-0001, abstract and section 3.3