Repository navigation
Conversation
Most builds never print the `installed services: {...}` block. They state
installedServiceCount=N in the user's attributes line and list nothing, so the
parser recorded no service at all and MVT logged "Identified a total of 0
accessibility services" — an artifact that says "no accessibility services"
about a dump that said there are five. The dump pasted in mvt-project#744 is itself an
example: it states installedServiceCount=6 and names none.
Parse the count per user and, for a user whose services the dump did not list,
keep one record carrying it, raised as LOW: a count is a coverage statement,
not a running service.
Name the service state in the alert and split its severity, as asked on mvt-project#744:
a service the dump states is switched off is LOW, enabled or bound is MEDIUM,
and a dump that does not state the enabled state stays MEDIUM, because "not
stated" is not "not enabled". A state section the dump never printed now reads
None rather than False. IOC matching is unaffected by the state: a disabled
service still returns CRITICAL on a match.
Measured over 163 bug reports carrying an accessibility section: MEDIUM alerts
305 -> 4, LOW 0 -> 407. The four that stay MEDIUM are the only records in the
set with enabled=True.
Fixes mvt-project#744
besendorf
left a comment
There was a problem hiding this comment.
I reproduced two issues on commit bdbc07a that should be fixed before merge:
-
Track state-section presence per user. In the normalization loop,
seen_statesis global. With user 0 listing one installed service but noenabled servicessection and user 10 listing one enabled service, user 0 is incorrectly assignedenabled=Falseand gets a LOWinstalled, not enabledalert. User 10 is also incorrectly assignedinstalled=False. Each user needs its own set of printed sections; please test a multiuser dump with named services and different sections. -
Report the unnamed part of a partial count. This condition suppresses the count-only record once any component was named. The existing Android 14 fixture states
installedServiceCount=2but names only one enabled component. Parsing yields one service record, no count coverage alert, and the summary says one identified with zero more unnamed. Please account for the per-user difference between the stated count and distinct named components, and add a test for that fixture.
The first case incorrectly downgrades an unknown enabled state; the second makes an incomplete service listing look complete.
|
Thanks, both fixed in ad6caa1.
This adds one new field, Lint, mypy and tests pass. |
Two issues from review: * The set of printed state sections was global, so a section printed for one user decided the flags of another. A user with an installed list and no enabled section was marked enabled=False and got a LOW "installed, not enabled" alert. Sections are now tracked per user. * A count-only record was added only when a user had no named component at all. A dump stating installedServiceCount=2 and naming one service read as complete. The count-only record is now added whenever the stated count exceeds the distinct named components for that user, and carries the difference in a new unnamed_service_count field. The module summary adds up that remainder.
ec7d03b to
ad6caa1
Compare
…-installed-service-count Carry the accessibility service count the dump states
Fixes #744
Two halves of the same parser, in the order they matter.
Change,
artifacts/dumpsys_accessibility.pyandmodules/bugreport/dumpsys_accessibility.py:installedServiceCount=Nper user. For a user whose services the dump did not list,append one record with
component/package_name/service_nameNoneandinstalled_service_count=N, and raise it as LOW — a count is a coverage statement, not arunning service, so it must not compete with one the dump says is enabled. The module's summary
line reports how many services the dump stated but did not name, so a stated count can no
longer read as "a total of 0". (You said "at least informational if not higher, could even be
low" — this is LOW. One line and one assertion if you want it back at informational.)
installed, not enabled/enabled/enabled and bound/installed, enabled state not stated) and split its severity, as you asked on this issue: aservice the dump states is switched off is LOW, enabled or bound is MEDIUM, and a
dump that does not state the enabled state stays MEDIUM — "not stated" is not "not enabled".
IOC matching is untouched by the state:
check_app_id()runs before any of this and stillreturns CRITICAL for a disabled service, which a new test pins.
Noneinstead ofFalse, so "not stated" is notrecorded as "not enabled".
Bound services:{}(printed, empty) staysFalse.Both record shapes — a service record and a count-only record — are built from one
_FIELDSlist,so they cannot drift apart.
Measured on 50 bug reports (40 that state a count without listing, 10 that list), upstream vs
patched, running the artifact code directly:
The 40 new records land one per report on the 40 that produced nothing before. No record is
dropped and no IOC match changes; what moves is the severity of the switched-off services.
Over the wider set of 163 reports the same run gives MEDIUM 305 → 4 and LOW 0 → 407 (301
switched-off services plus 106 stated counts). The 4 records that stay MEDIUM are the only ones
in the whole set with
enabled=True— both belong to the same device, and both are theaccessibility services of an app that is malicious. Every other accessibility record in 163 bug
reports is a service that is installed and switched off.
Tests: two new files — a stated count with no listed services produces one record and one LOW
alert, a listed service is unchanged, two users are kept apart, a zero count adds nothing; an
absent section reads
Nonewhile a printed-empty one readsFalse, and the alert text carriesthe state.
Two existing assertions change, both in
test_artifact_dumpsys_accessibility.py: the v14 fixturenever prints an
installed services:section, soinstalledbecomesNoneinstead ofFalse;and every service in the Samsung fixture is installed-and-off, so
test_ioc_check's threenon-IOC findings are LOW rather than MEDIUM (the IOC match itself is unchanged).
Applies to
main@777db67with no other change;pytest tests/androidthere goes from 99 passed /1 skipped to 110 passed / 1 skipped;
ruff check,ruff format --checkandmypy --platform linux(156 files) pass on the branch.Related open work (checked 2026-09-22):
is the only other work on this file. Its diff is against the pre-
008844bparser that no longerexists in
main, it defaultsenabledtoFalse, and it does not touch the count. This PRcovers the same ground on the current parser; which of the two to take is yours to decide, and I
have said so on Show which accessibility services are enabled #773 rather than leaving it unmentioned.
modules/bugreport/dumpsys_accessibility.py's__init__; this PR only editsrun(), so they should not collide.output_model; the new count-onlyrecord is a new shape in this artifact's output and would need to be in that schema.