From 8ccf44142607b9db3850333018ebf4f57baf2c33 Mon Sep 17 00:00:00 2001 From: "Paul \"LeoNerd\" Evans" Date: Thu, 10 Oct 2024 19:56:15 +0100 Subject: [PATCH] Set builtin:: globs to readonly so that attempted replacements of them do not break optimisations --- MANIFEST | 1 + builtin.c | 7 +++++++ lib/builtin.pm | 12 +++++++++++- pod/perldelta.pod | 10 ++++++++++ t/lib/croak/builtin | 6 ++++++ 5 files changed, 35 insertions(+), 1 deletion(-) create mode 100644 t/lib/croak/builtin diff --git a/MANIFEST b/MANIFEST index ac9456dd3c92..4bf60b748bd6 100644 --- a/MANIFEST +++ b/MANIFEST @@ -6080,6 +6080,7 @@ t/lib/common.pl Helper for lib/{warnings,feature}.t t/lib/commonsense.t See if configuration meets basic needs t/lib/Count.pm Helper for t/op/method.t t/lib/croak.t Test calls to Perl_croak() in the C source. +t/lib/croak/builtin Test croak calls from builtin.c t/lib/croak/class Test croak calls from class.c t/lib/croak/gv Test croak calls from gv.c t/lib/croak/mg Test croak calls from mg.c diff --git a/builtin.c b/builtin.c index 34865ec9a4bb..f004a3275d79 100644 --- a/builtin.c +++ b/builtin.c @@ -804,6 +804,13 @@ Perl_boot_core_builtin(pTHX) if(builtin->checker) { cv_set_call_checker_flags(cv, builtin->checker, newSVuv(PTR2UV(builtin)), 0); } + + /* Because of all these callcheckers and other optimisations, it would + * all break if we permitted runtime replacement of the functions, + * e.g. by glob tricks like `*builtin::reftype = sub { ... }`. + * Prevent modification of the GV so as to avoid this problem. + */ + SvREADONLY_on((SV *)CvGV(cv)); } newXS_flags("builtin::import", &XS_builtin_import, __FILE__, NULL, 0); diff --git a/lib/builtin.pm b/lib/builtin.pm index 0980884359b7..f11e6b0be93b 100644 --- a/lib/builtin.pm +++ b/lib/builtin.pm @@ -1,4 +1,4 @@ -package builtin 0.015; +package builtin 0.016; use v5.40; @@ -106,6 +106,16 @@ The following bundles currently exist: :5.40 true false weaken unweaken is_weak blessed refaddr reftype ceil floor is_tainted trim indexed +=head2 Read-only Functions + +Various optimisations that apply to many functions in the L package +would be broken if the functions are ever replaced or changed, such as by +assignment into glob references. Because of this, the globs that contain +them are set read-only since Perl version 5.41.5, preventing such replacement. + + $ perl -e '*builtin::reftype = sub { "BOO" }' + Modification of a read-only value attempted at -e line 1. + =head1 FUNCTIONS =head2 true diff --git a/pod/perldelta.pod b/pod/perldelta.pod index baa03b9396ea..7aa464665049 100644 --- a/pod/perldelta.pod +++ b/pod/perldelta.pod @@ -27,6 +27,16 @@ here, but most should go in the L section. [ List each enhancement as a =head2 entry ] +=head2 Functions in the C package no longer permit replacement + +Various optimisations that apply to many functions in the L package +would be broken if the functions are ever replaced or changed, such as by +assignment into glob references. Because of this, the globs that contain +them are now set read-only, preventing such replacement. + + $ perl -e '*builtin::reftype = sub { "BOO" }' + Modification of a read-only value attempted at -e line 1. + =head1 Security XXX Any security-related notices go here. In particular, any security diff --git a/t/lib/croak/builtin b/t/lib/croak/builtin new file mode 100644 index 000000000000..a1252b02cfe5 --- /dev/null +++ b/t/lib/croak/builtin @@ -0,0 +1,6 @@ +__END__ +######## +# Attempted replacement of builtin:: functions is not allowed as of Perl 5.41.5 +*builtin::reftype = sub { "BOO" }; +EXPECT +Modification of a read-only value attempted at - line 2.