Skip to content

ext/sodium: throw ValueError for pwhash argument errors#22388

Open
iliaal wants to merge 1 commit into
php:masterfrom
iliaal:sodium-pwhash-valueerror
Open

ext/sodium: throw ValueError for pwhash argument errors#22388
iliaal wants to merge 1 commit into
php:masterfrom
iliaal:sodium-pwhash-valueerror

Conversation

@iliaal

@iliaal iliaal commented Jun 21, 2026

Copy link
Copy Markdown
Contributor

Follow-up to GH-22383, as suggested in review: the four sodium pwhash functions now throw ValueError for out-of-range arguments instead of SodiumException, keeping SodiumException for internal libsodium failures. Each converted site keeps an explicit backtrace scrub so the ValueError still protects the password in caller frames, with a test covering it. Scoped to pwhash for now; changing the remaining zend_argument_error(sodium_exception_ce, ...) sites across the extension might be a bigger BC change, so keeping this one small.

@iliaal iliaal requested a review from TimWolla June 21, 2026 17:47
@iliaal iliaal force-pushed the sodium-pwhash-valueerror branch from 4bdd40d to 1c35eaa Compare June 21, 2026 17:48

@TimWolla TimWolla left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me in principle (except for the inline remarks), but I want @Girgias to double-check.

Comment on lines +17 to +29
try {
wrap($secret);
} catch (\ValueError $e) {
echo get_class($e), "\n";
echo $e->getMessage(), "\n";
$leaked = str_contains($e->getTraceAsString(), $secret);
foreach ($e->getTrace() as $frame) {
if (!empty($frame['args'])) {
$leaked = true;
}
}
var_dump($leaked);
}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this test would be more readable when you would just leave the exception unhandled:

Suggested change
try {
wrap($secret);
} catch (\ValueError $e) {
echo get_class($e), "\n";
echo $e->getMessage(), "\n";
$leaked = str_contains($e->getTraceAsString(), $secret);
foreach ($e->getTrace() as $frame) {
if (!empty($frame['args'])) {
$leaked = true;
}
}
var_dump($leaked);
}
wrap($secret);

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Switched to the uncaught form, matching exception_trace_without_args.phpt in the same dir. The fatal-error trace shows the scrubbed frames directly.

Comment thread UPGRADING Outdated
Comment on lines +138 to +139
still thrown for internal libsodium failures. Catch ValueError, or its
parent Error, for these argument errors.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
still thrown for internal libsodium failures. Catch ValueError, or its
parent Error, for these argument errors.
still thrown for internal libsodium failures.

We should encourage folks to catch these. This is also not mentioned for the other ValueError conversions.

@TimWolla TimWolla requested a review from Girgias June 21, 2026 20:14
The four password-hashing functions reported out-of-range arguments (a
non-positive or below-minimum opslimit or memlimit, an oversized hash
length or password, a wrong-length salt) as a SodiumException. These are
argument-value errors, so throw ValueError via zend_argument_value_error()
instead, matching the rest of the engine. SodiumException is still used
for internal libsodium failures.

SodiumException's create_object empties the whole backtrace, which also
protects caller frames holding the password; a plain ValueError does not,
so each converted site keeps an explicit
sodium_remove_param_values_from_backtrace(EG(exception)), mirroring the
ZPP-failure paths.
@iliaal iliaal force-pushed the sodium-pwhash-valueerror branch from 1c35eaa to cd0577c Compare June 21, 2026 20:52

@TimWolla TimWolla left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM now, but please wait for the second approval.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants