Skip to content

WIP: implement Perl taint mode - #905

Merged
fglock merged 26 commits into
masterfrom
feature/taint-mode
Aug 10, 2026
Merged

WIP: implement Perl taint mode#905
fglock merged 26 commits into
masterfrom
feature/taint-mode

Conversation

@fglock

@fglock fglock commented Aug 9, 2026

Copy link
Copy Markdown
Owner

Work in progress

This PR tracks the implementation of Perl taint mode.

Current work:

  • mark external inputs including $^X, %ENV, @ARGV, file reads, and directory reads
  • preserve taint across scalar assignment and core arithmetic/string operations
  • reject tainted process, eval, module-loading, pipe-open, filesystem, and signal inputs
  • keep JVM and interpreter backends aligned
  • add Perl-validated regression coverage

Current verification:

  • system Perl taint regression: 39/39
  • PerlOnJava JVM backend: 39/39
  • PerlOnJava interpreter backend: 39/39
  • full make: passing

Remaining work will be recorded in follow-up commits. Major open areas include secure environment/path behavior and the remaining operator propagation audit needed by perl5_t/t/op/taint.t.

Generated with Codex

fglock and others added 26 commits August 9, 2026 17:34
Track tainted external inputs, propagate taint through core scalar operations,
and reject tainted values at security-sensitive runtime operations.

Generated with [Codex](https://openai.com/codex/)

Co-Authored-By: Codex <codex@openai.com>
Track join taint for Perl's legacy join-and-kill taint detection idiom and
clear the probe state after use. Remove the duplicate progress ledger from the
design document so the draft PR commit history remains the implementation log.

This advances perl5_t/t/op/taint.t from 23 to 858 tests reached.

Generated with [Codex](https://openai.com/codex/)

Co-Authored-By: Codex <codex@openai.com>
Localize the given topic so read-only foreach aliases remain assignable and
restore correctly. Carry a matching when clause's final value across its
synthetic control-flow exit in both JVM and interpreter backends without
exposing the internal value to generic last-expression analysis.

This lets perl5_t/t/op/taint.t complete all 1065 cases and preserves taint in
the given result while avoiding an overload-analysis regression.

Generated with [Codex](https://openai.com/codex/)

Co-Authored-By: Codex <codex@openai.com>
Preserve taint through crypt, bitwise complement, split, vec, pack, and
sprintf results. Reject tainted printf and sprintf format strings, and track
only the arguments consumed by sprintf format directives.

This advances perl5_t/t/op/taint.t from 820 to 852 passing cases while the
test continues through all 1065 cases.

Generated with [Codex](https://openai.com/codex/)

Co-Authored-By: Codex <codex@openai.com>
Reject tainted paths and flags for write-capable open and sysopen operations
while retaining Perl's allowance for tainted read-only paths. Check truncate,
utime, and chown inputs before early returns or exception handling, and preserve
taint through binary bitwise flag expressions.

This advances perl5_t/t/op/taint.t from 852 to 897 passing cases.

Generated with [Codex](https://openai.com/codex/)

Co-Authored-By: Codex <codex@openai.com>
Propagate dynamic pattern taint into captures and compiled regex values,
and implement lexical use re 'taint' capture behavior. Keep ordinary
captures as an untainting boundary and match booleans clean.

Core op/taint.t improves from 897 to 928 passing assertions.

Generated with [Codex](https://openai.com/codex/)

Co-Authored-By: Codex <codex@openai.com>
Track source, pattern, replacement, capture, target, copy, and global
count taint independently for s///. Preserve replacement overload taint,
lexical use re 'taint', and observable /ge target state between matches.

Core op/taint.t improves from 928 to 1003 passing assertions.

Generated with [Codex](https://openai.com/codex/)

Co-Authored-By: Codex <codex@openai.com>
Retain taint on scalar results returned by overloaded stringification across
single and mixed interpolation, join, concatenation fallback, and regex
replacement evaluation.

Core op/taint.t improves from 1003 to 1013 passing assertions.

Generated with [Codex](https://openai.com/codex/)

Co-Authored-By: Codex <codex@openai.com>
Reject empty, relative, and world-writable Unix PATH components before
process launch, and reject tainted TERM values containing metacharacters.
Keep direct tainted-variable diagnostics ahead of structural validation.

Core op/taint.t improves from 1013 to 1028 passing assertions.

Generated with [Codex](https://openai.com/codex/)

Co-Authored-By: Codex <codex@openai.com>
Use complete RuntimeScalar copies when lazy regex special variables cross
subroutine, block, and interpreter mutation boundaries. This preserves taint
and the existing scalar metadata without making match taint sticky.

Core op/taint.t improves from 1028 to 1029 passing assertions.

Generated with [Codex](https://openai.com/codex/)

Co-Authored-By: Codex <codex@openai.com>
Mark subprocess output, symlink targets, selected passwd fields, program
name, and file EOF undef values as external input while taint mode is active.
Apply the same behavior in scalar and list contexts.

Core op/taint.t improves from 1029 to 1037 passing assertions.

Generated with [Codex](https://openai.com/codex/)

Co-Authored-By: Codex <codex@openai.com>
Carry the source scalar's taint onto the old integer value returned by the
post-increment fast path. The lvalue already retained taint; this aligns the
returned pre-mutation value with the slower increment and decrement paths.

Core op/taint.t improves from 1037 to 1038 passing assertions.

Generated with [Codex](https://openai.com/codex/)

Co-Authored-By: Codex <codex@openai.com>
Return Perl undef rather than a defined false scalar for sysopen failures,
including ordinary open, create, O_EXCL, and O_NOFOLLOW failures. This keeps
read-only tainted inputs permitted while preserving failure definedness.

Core op/taint.t improves from 1038 to 1041 passing assertions.

Generated with [Codex](https://openai.com/codex/)

Co-Authored-By: Codex <codex@openai.com>
Reject tainted command and data arguments before filehandle validation or
native dispatch. Keep the security exceptions outside broad native fallback
handlers so Perl receives the expected diagnostic in $@.

Core op/taint.t improves from 1041 to 1043 passing assertions.

Generated with [Codex](https://openai.com/codex/)

Co-Authored-By: Codex <codex@openai.com>
Preserve existing $^A taint and combine it with formline picture and value
taint when appending formatted output. Snapshot provenance before scalar set
operations clear metadata.

Core op/taint.t improves from 1043 to 1045 passing assertions.

Generated with [Codex](https://openai.com/codex/)

Co-Authored-By: Codex <codex@openai.com>
Track tainted repeat-count provenance without tainting a bare repetition,
expose it when the value is composed into a dynamic picture, and consume it
in formline. Copy, localize, and clear the internal metadata with scalar state.

Core op/taint.t improves from 1045 to 1047 passing assertions.

Generated with [Codex](https://openai.com/codex/)

Co-Authored-By: Codex <codex@openai.com>
Keep runtime scalar keys intact through bytecode array and tied hash
assignment paths so STORE receives the same taint provenance as Perl.

Generated with [Codex](https://openai.com/codex/)

Co-Authored-By: Codex <codex@openai.com>
Preserve the requested method scalar through method resolution and apply
its taint provenance to the fully qualified AUTOLOAD variable value.

Generated with [Codex](https://openai.com/codex/)

Co-Authored-By: Codex <codex@openai.com>
Transfer taint provenance from qr values to their bare-regex scalar form so
substitution and matching retain the compiled pattern's security metadata.

Generated with [Codex](https://openai.com/codex/)

Co-Authored-By: Codex <codex@openai.com>
Reject tainted interpolated user-defined Unicode properties and runtime
eval groups before regex cache lookup, matching Perl taint-mode security.

Generated with [Codex](https://openai.com/codex/)

Co-Authored-By: Codex <codex@openai.com>
Implement scalar-versus-array smartmatch candidate traversal without
consuming or replacing the tainted left operand between comparisons.

Generated with [Codex](https://openai.com/codex/)

Co-Authored-By: Codex <codex@openai.com>
Materialize system and exec indirect program expressions with their argument
lists so interpreter taint checks inspect every process command component.

Generated with [Codex](https://openai.com/codex/)

Co-Authored-By: Codex <codex@openai.com>
Represent $^O with a protected runtime scalar and preserve that special type
through local scopes so tainted assignments fail without tainting reads.

Generated with [Codex](https://openai.com/codex/)

Co-Authored-By: Codex <codex@openai.com>
Track whether %ENV was installed from a hash reference or named typeglob and
report Perl-compatible alias diagnostics before other environment checks.

Generated with [Codex](https://openai.com/codex/)

Co-Authored-By: Codex <codex@openai.com>
Only inspect and propagate taint provenance while taint mode is active so
normal execution does not add tied FETCH calls. Preserve taint across lvalue
substring and UTF-8 mutations, and reuse a single tied substitution FETCH.

Generated with [Codex](https://openai.com/codex/)

Co-Authored-By: Codex <codex@openai.com>
Add taint mode to the work-in-progress changelog and update the feature
matrix for -T support, backend parity, and the remaining -t limitation.

Generated with [Codex](https://openai.com/codex/)

Co-Authored-By: Codex <codex@openai.com>
@fglock
fglock marked this pull request as ready for review August 10, 2026 07:25
@fglock
fglock merged commit c9880af into master Aug 10, 2026
2 checks passed
@fglock
fglock deleted the feature/taint-mode branch August 10, 2026 07:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant