Skip to content

Piping streams into SHA3 without end: false crashes #28245

Closed
@tniessen

Description

@tniessen
  • Version: 12.4.0
  • Platform: Windows 10 x64 and Linux 4.4.0-042stab138.1
  • Subsystem: crypto or deps

This code causes a segmentation fault in 12.4.0:

const crypto = require('crypto');
const fs = require('fs');

const myOwnCode = fs.createReadStream(__filename);
const copy = fs.createWriteStream(`${__filename}.copy`);
const hash = crypto.createHash('sha3-512');
myOwnCode.pipe(hash);
myOwnCode.pipe(copy).on('finish', () => {
  hash.digest();
});

This seems to be caused by pipe calling hash._flush when end is not set to false. This code also causes a segmentation fault:

const crypto = require('crypto');

const hash = crypto.createHash('sha3-512');
hash._flush(() => console.log('Flushed'));
hash.digest();

This seems to be at least partially caused by the implementation of _flush:

Hash.prototype._flush = function _flush(callback) {
this.push(this[kHandle].digest());
callback();
};

It bypasses the this[kState][kFinalized] safeguard:

Hash.prototype.digest = function digest(outputEncoding) {
const state = this[kState];
if (state[kFinalized])
throw new ERR_CRYPTO_HASH_FINALIZED();
outputEncoding = outputEncoding || getDefaultEncoding();
if (normalizeEncoding(outputEncoding) === 'utf16le')
throw new ERR_CRYPTO_HASH_DIGEST_NO_UTF16();
// Explicit conversion for backward compatibility.
const ret = this[kHandle].digest(`${outputEncoding}`);
state[kFinalized] = true;
return ret;
};

Note that this bug only happens when using SHA3, sha256 seems to be working just fine, so there might also be some weirdness in OpenSSL.

cc @mcollina @nodejs/crypto @nodejs/streams

Metadata

Metadata

Assignees

No one assigned

    Labels

    confirmed-bugIssues with confirmed bugs.cryptoIssues and PRs related to the crypto subsystem.opensslIssues and PRs related to the OpenSSL dependency.streamIssues and PRs related to the stream subsystem.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions