Skip to content

The STC's resting identity is STC/STCGROUP, which holds ALTER on every data set — adopt the low-privilege startup logon (httpd#177 review) #65

Description

@mgrossmann

The review mvslovers/httpd#177 asked for. Same finding as there and as
mvslovers/ftpd#97; filed here because it applies to this STC independently — and
ufsd is more exposed than either sibling.

The finding

RAKF has no started-procedures table. Its RACINIT path uses the started procedure
name only to decide that the caller is an STC, never which one, and assigns one
hardcoded account (SRCLIB/ICHSFR00.hlasm):

RACISSTC LA    R4,STCUID-L'CBLKNEXT POINT TO UID
STCUID   DC    AL4(0),X'03',CL8'STC',X'08',C'STCGROUP'

Combined with the usual profile

DATASET *          STCGROUP  ALTER

every started task rests on an identity that holds ALTER on every data set on the
system. USER= on the PROC changes nothing — this path consults nothing. Upstream
ticket: MVS-sysgen/RAKF#8.

Why ufsd is the most exposed of the three servers

httpd and ftpd both mitigate this at startup (stc_identity() in
httpd/src/httpd.c; ftpd.c:196-217). ufsd does nothing of the kind — and unlike
them it has no identity handling at all:

  • zero racf_login/racf_set_acee/racf_auth calls repo-wide (grep, src/ and
    include/);
  • per-client permission checks are a deliberate Phase-1 simplification —
    ufsd#fil.c:13: "No permission/ACEE checks"; the client ACEE slot exists but
    is unused (libufs.h:99: "ACEE pointer (Phase 1 unused)"). ufs_setuser()
    feeds the UFS-internal unix-style owner/group model, not RACF.

So every data set OPEN ufsd performs — the UFS container data sets, its config —
runs under the resting identity, for the life of the address space. With the
default RAKF profile that identity is close to omnipotent; and per the
displacement finding in mvslovers/httpd#177 the resting value is not even stable
in address spaces that host per-request identity switches. ufsd should not depend
on it either way.

Proposal

Port the httpd mitigation: at startup, before the config member and the container
data sets are opened, log on to a configured low-privilege userid and install it:

ACEE *stc = racf_login(cfg_stc_user, NULL, cfg_stc_group, &rc);
if (stc) racf_set_acee(stc);

pass == NULL bypasses password checking, so nothing is stored in config. httpd's
decisions transfer directly and are worth adopting wholesale:

  • Parameters, not config keywords — the logon must precede the config open, so
    STCUSER=/STCGROUP= come from the JCL PARM (httpd's reasoning; STCGRP as
    the symbolic, seven-char limit).
  • Secure default — default to a dedicated userid, not to today's behaviour;
    defaulting to STC/STCGROUP would ship the exposure on by default.
  • Failure policy — warn and continue (a profile typo must not be an outage);
    neither path silent.
  • Ordering — RACINIT needs key 0, so the logon runs after APF/authorization
    setup, before the first OPEN.

ufsd-specific points to settle

  • Entitlements. Unlike httpd (READ-only needs), ufsd legitimately needs
    UPDATE on its UFS container data sets. Enumerate exactly what it opens and
    grant the low-privilege userid exactly that — the point is to shrink "ALTER on
    everything" down to "UPDATE on its own containers".
  • The userid is a login-able account. RAKF 1.2.x rejects a blank password in
    the users table, so the STC userid necessarily carries a real password. Keep it
    off FTPAUTH and any other login surface (ftpd#97 documents this).
  • CSA/subtask interactions — confirm the ACEE is allocated where no
    request-scoped reclaim can reach it (httpd#177 settled the same point).

Out of scope

Per-client permission enforcement inside ufsd (the Phase-1 "no ACEE checks"
simplification, libufs.h acee slot) is a separate design topic with its own
trade-offs — this ticket is only about what identity the address space rests on.

Related

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions