HTTPD is link-edited AC(1) and authorizes itself at startup (__autask(),
src/httpd.c:1028). On that route the module is fetched into key-8 storage and
JSCBAUTH is set afterwards, so writable module data goes unnoticed. Add an APF
entry for the LINKLIB and the picture inverts: the job step is authorized
before program fetch runs, MVS obtains the job pack area in subpool 252
key 0 — authorized code must not be patchable by problem-key code — and any
store into the module's own storage from problem state key 8 takes a protection
exception.
This is the same defect ufsd#64
turned out to be (fixed in ufsd#66), found here by running ufsd's
tools/check-module-data.py across the ecosystem. HTTPD has exactly one
exposed store, and it is on the shutdown path.
The site
stc_prev_acee (src/httpd.c:57) is written twice, and the two are not alike:
stc_identity(), src/httpd.c:103 — stc_prev_acee = old_acee; sits
inside the __super(PSWKEY0, &savekey) window opened on line 74 and
closed on line 110. Key 0, so it stores fine either way. No action needed.
stc_identity_restore(), src/httpd.c:135 — stc_prev_acee = NULL; is not
in a window, and the block comment says why: "racf_set_acee() does its own
supervisor/key switching, so no __super() here." True for the call, not
for the assignment after it. That store runs problem state key 8, so with an
APF-authorized LINKLIB P HTTPD ends in S0C4 instead of a clean shutdown —
and it does so after racf_set_acee() has already put the STC account back,
which is the part that matters for the SVC 244 release.
The read on line 132 is fine; only the store is a problem.
__stklen (src/httpd.c:22) is module data too, but it is only ever read by
the CRT startup, so it is not at risk.
Direction
The narrow fix is to give stc_identity_restore() the same __super /
__prob window stc_identity() already has — one store, called once, at
shutdown. The alternative is to move stc_prev_acee out of module storage
into the HTTPD control block, which is where per-STC state otherwise lives.
Worth noting regardless of APF
ld370 marks a load module RENT and REUS unless the module opts out with
norent / noreus, and HTTPD does not. So a writable static already breaks the
reentrancy attribute the module carries, and would fail the same way if HTTPD
were ever placed in the LPA.
Checking it
ufsd's guard is portable to any mbt v2 project — it only needs project.toml
and Python 3.11+, no toolchain:
python3 ../ufsd/tools/check-module-data.py project.toml
It reads the [[module]] blocks, checks the ac = 1 ones, and rejects mutable
file-scope data and function-local statics. ufsd runs it as its own CI job.
Note it cannot tell a key-0 window from a key-8 one — it flags the data, the
key question is still a matter of reading the code, as with the two stores
above.
HTTPD is link-edited
AC(1)and authorizes itself at startup (__autask(),src/httpd.c:1028). On that route the module is fetched into key-8 storage andJSCBAUTHis set afterwards, so writable module data goes unnoticed. Add an APFentry for the LINKLIB and the picture inverts: the job step is authorized
before program fetch runs, MVS obtains the job pack area in subpool 252
key 0 — authorized code must not be patchable by problem-key code — and any
store into the module's own storage from problem state key 8 takes a protection
exception.
This is the same defect ufsd#64
turned out to be (fixed in ufsd#66), found here by running ufsd's
tools/check-module-data.pyacross the ecosystem. HTTPD has exactly oneexposed store, and it is on the shutdown path.
The site
stc_prev_acee(src/httpd.c:57) is written twice, and the two are not alike:stc_identity(),src/httpd.c:103—stc_prev_acee = old_acee;sitsinside the
__super(PSWKEY0, &savekey)window opened on line 74 andclosed on line 110. Key 0, so it stores fine either way. No action needed.
stc_identity_restore(),src/httpd.c:135—stc_prev_acee = NULL;is notin a window, and the block comment says why: "racf_set_acee() does its own
supervisor/key switching, so no
__super()here." True for the call, notfor the assignment after it. That store runs problem state key 8, so with an
APF-authorized LINKLIB
P HTTPDends in S0C4 instead of a clean shutdown —and it does so after
racf_set_acee()has already put the STC account back,which is the part that matters for the SVC 244 release.
The read on line 132 is fine; only the store is a problem.
__stklen(src/httpd.c:22) is module data too, but it is only ever read bythe CRT startup, so it is not at risk.
Direction
The narrow fix is to give
stc_identity_restore()the same__super/__probwindowstc_identity()already has — one store, called once, atshutdown. The alternative is to move
stc_prev_aceeout of module storageinto the HTTPD control block, which is where per-STC state otherwise lives.
Worth noting regardless of APF
ld370 marks a load module RENT and REUS unless the module opts out with
norent/noreus, and HTTPD does not. So a writable static already breaks thereentrancy attribute the module carries, and would fail the same way if HTTPD
were ever placed in the LPA.
Checking it
ufsd's guard is portable to any mbt v2 project — it only needs
project.tomland Python 3.11+, no toolchain:
It reads the
[[module]]blocks, checks theac = 1ones, and rejects mutablefile-scope data and function-local statics. ufsd runs it as its own CI job.
Note it cannot tell a key-0 window from a key-8 one — it flags the data, the
key question is still a matter of reading the code, as with the two stores
above.