Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions changelog.d/8930-elf-archive-group.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
Fixed ELF links that died with `undefined reference to
<futures_channel::mpsc::SenderTask>::notify` out of a well-known wrapper
archive when a compiled package pulled in `bundled-streams`.

GNU `ld` scans each archive on the command line exactly once, left to right,
and the perry archive block is mutually recursive: the wrapper archives listed
*before* perry-stdlib resolve nothing (the user objects reference only stdlib
symbols), every wrapper member is pulled from the repeat *after* stdlib on
references stdlib itself opened, and those members then reference back into
stdlib — which `ld` has already walked past. That stayed invisible until
shared-dependency pruning correctly dropped a bundled member because stdlib
exports it. The archive block is now wrapped in `-Wl,--start-group` /
`-Wl,--end-group` on ELF targets so the linker re-scans it to a fixed point.
Symbol precedence is unchanged and non-ELF link lines are untouched; a link
that already resolved produces a byte-identical executable.
6 changes: 6 additions & 0 deletions changelog.d/9289-scrypt-params.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
Fix a silent security downgrade in `node:crypto` scrypt: the callback form now
forwards `N`/`cost`, `r`/`blockSize`, `p`/`parallelization`, and `maxmem`
instead of always deriving with Node's defaults. Both callback and synchronous
forms now reject invalid combinations and insufficient `maxmem` with a
Node-compatible `RangeError`, rather than silently substituting the weaker
default work factor.
21 changes: 10 additions & 11 deletions crates/perry-codegen/src/expr/calls/crypto_kdf.rs
Original file line number Diff line number Diff line change
Expand Up @@ -127,11 +127,13 @@ pub(crate) fn arm_crypto_scrypt(
let pwd_box = lower_expr(ctx, &args[0])?;
let salt_box = lower_expr(ctx, &args[1])?;
let len_box = lower_expr(ctx, &args[2])?;
let cb_expr = if args.len() >= 5 {
let _ = lower_expr(ctx, &args[3])?;
&args[4]
let (opts_box, cb_expr) = if args.len() >= 5 {
(lower_expr(ctx, &args[3])?, &args[4])
} else {
&args[3]
(
double_literal(f64::from_bits(crate::nanbox::TAG_UNDEFINED)),
&args[3],
)
};
let cb_box = lower_expr(ctx, cb_expr)?;
let blk = ctx.block();
Expand All @@ -144,6 +146,7 @@ pub(crate) fn arm_crypto_scrypt(
(I64, &pwd_handle),
(I64, &salt_handle),
(DOUBLE, &len_box),
(DOUBLE, &opts_box),
(DOUBLE, &cb_box),
],
))
Expand Down Expand Up @@ -243,27 +246,23 @@ pub(crate) fn arm_crypto_scrypt_sync(
let salt_box = lower_expr(ctx, &args[1])?;
let keylen_box = lower_expr(ctx, &args[2])?;
let opts_box = if args.len() >= 4 {
Some(lower_expr(ctx, &args[3])?)
lower_expr(ctx, &args[3])?
} else {
None
double_literal(f64::from_bits(crate::nanbox::TAG_UNDEFINED))
};
// #2013/#3146: node validates keylen as an integer in [0, 2^31-1].
emit_validate_integer_arg(ctx, &keylen_box, "keylen", 0.0, i32::MAX as f64);
let blk = ctx.block();
let pwd_handle = unbox_to_i64(blk, &pwd_box);
let salt_handle = unbox_to_i64(blk, &salt_box);
let opts_handle = match &opts_box {
Some(b) => unbox_to_i64(blk, b),
None => "0".to_string(),
};
let buf_handle = blk.call(
I64,
"js_crypto_scrypt_bytes",
&[
(I64, &pwd_handle),
(I64, &salt_handle),
(DOUBLE, &keylen_box),
(I64, &opts_handle),
(DOUBLE, &opts_box),
],
);
Ok(nanbox_pointer_inline(blk, &buf_handle))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -274,8 +274,9 @@ pub(crate) fn declare_data_stores(module: &mut LlModule) {
module.declare_function("js_crypto_random_nonce", I64, &[]);
module.declare_function("js_crypto_scrypt", I64, &[I64, I64, DOUBLE]);
// crypto.scryptSync(password, salt, keylen, options?) -> Buffer. The 4th
// arg is the NaN-unboxed options-object pointer (0 = none).
module.declare_function("js_crypto_scrypt_bytes", I64, &[I64, I64, DOUBLE, I64]);
// arg is the full NaN-boxed options value so validation can distinguish
// objects, primitives, and undefined.
module.declare_function("js_crypto_scrypt_bytes", I64, &[I64, I64, DOUBLE, DOUBLE]);
// crypto.generateKeyPairSync(type, options) -> { publicKey, privateKey }.
module.declare_function("js_crypto_generate_key_pair_sync", DOUBLE, &[I64, I64]);
module.declare_function(
Expand Down
4 changes: 2 additions & 2 deletions crates/perry-codegen/src/runtime_decls/strings_part2.rs
Original file line number Diff line number Diff line change
Expand Up @@ -500,11 +500,11 @@ pub(crate) fn declare_phase_b_strings_part2(module: &mut LlModule) {
DOUBLE,
&[I64, I64, I64, I64, DOUBLE, DOUBLE],
);
module.declare_function("js_crypto_scrypt_bytes", I64, &[I64, I64, DOUBLE, I64]);
module.declare_function("js_crypto_scrypt_bytes", I64, &[I64, I64, DOUBLE, DOUBLE]);
module.declare_function(
"js_crypto_scrypt_async",
DOUBLE,
&[I64, I64, DOUBLE, DOUBLE],
&[I64, I64, DOUBLE, DOUBLE, DOUBLE],
);
module.declare_function("js_crypto_sign_rsa_sha256", I64, &[I64, I64, DOUBLE]);
module.declare_function("js_crypto_sign_async", DOUBLE, &[I64, I64, DOUBLE, DOUBLE]);
Expand Down
Loading
Loading