From da4a0e76fbd2a0b7a2ecf14846c402e1b2aba4f1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michal=20Josef=20=C5=A0pa=C4=8Dek?= Date: Thu, 5 Jun 2025 16:28:09 +0200 Subject: [PATCH] Add resolving of $PROGRAM_NAME from /dev/fd/ There are situations when $PROGRAM_NAME is something /dev/fd/ 1) example like sudo /usr/local/bin/ with checksum verification (GH#23351) 2) example with pipe: perl <( echo '#!perl -DA'; echo 'print "$0\n"'); --- AUTHORS | 1 + perl.c | 13 +++++++++++++ 2 files changed, 14 insertions(+) diff --git a/AUTHORS b/AUTHORS index 6b244913fa18..186ed2093187 100644 --- a/AUTHORS +++ b/AUTHORS @@ -988,6 +988,7 @@ Michael Somos Michael Stevens Michael van Elst Michael Witten +Michal Josef Špaček Michele Sardo Michiel Beijen Mik Firestone diff --git a/perl.c b/perl.c index 5c87e47ee294..e7dab8376b7f 100644 --- a/perl.c +++ b/perl.c @@ -4227,6 +4227,19 @@ S_open_script(pTHX_ const char *scriptname, bool dosearch, bool *suidscript) Safefree(PL_origfilename); PL_origfilename = (char *)scriptname; } + else { + char proc_fd_path[64]; + snprintf(proc_fd_path, sizeof(proc_fd_path), "/proc/self/fd/%d", fdscript); + char target_path[MAXPATHLEN]; + SSize_t len = readlink(proc_fd_path, target_path, sizeof(target_path) - 1); + if (len != -1) { + Stat_t statbuf; + target_path[len] = '\0'; + if (PerlLIO_stat(target_path, &statbuf) == 0 && S_ISREG(statbuf.st_mode)) { + scriptname = PL_origfilename = find_script(target_path, dosearch, NULL, 1); + } + } + } } }