sidney has asked for the wisdom of the Perl Monks concerning the following question:

I have code in a CPAN module I maintain that tests fine on all but a few CPAN test runners. I haven't figured out what the runners that fail have in common other than being the owned by the same person, and not all of that person's runners. I cannot reproduce the error on any platform I have tried, including trying to match anything about the test runner that is included in the CPAN test report.

Insecure dependency in mkdir while running with -T switch at ... File/Temp.pm line 542

The line number in the error message indicates that it is running File::Temp version 0.2311 (the latest) or 0.2310, as they are the only versions with the mkdir call being on exactly line 542. I looked through File::Temp github history.

The failing test runners have various older versions of perl, but so do many of the many more test machines that don't fail, and I used plenv on my test machine to check for that.

The call to tempdir specifies DIR="log" so it is not referencing whatever is set up for the system temp storage. (see code below)

As an example, here is one of the failing CPAN test reports
A cpantesters test report

Here are the lines of code that I think are involved, including my attempt in the above example to make absolutely sure that what gets passed to File::Temp::tempdir is untainted. In every case the call to sa_t_init is passed a string literal, e.g., sa_t_init("footest"), but for this testing I added the $tname=untaint_var($tname) to see if it would help. It didn't.

This is the only call to File::Temp::tempdir that is called in all the failing tests, so I am certain it is the line that is involved.

use File::Temp qw(tempdir); sub sa_t_init { my $tname = shift; $tname = untaint_var($tname); ... unless (-d "log") { mkdir ("log", 0755) or die ("Error creating log dir: $!"); } chmod (0755, "log"); # in case already exists with wrong permissions ... $workdir = tempdir("$tname.XXXXXX", DIR => "log"); # Simple version of untaint_var for internal use sub untaint_var { local($1); $_[0] =~ /^(.*)\z/s; return $1; }

Can anyone think of a set of circumstances that could result in this call to tempdir getting an insecure dependency in mkdir, when most times it does not? Is there some way that mkdir can think that the representation of the current directory is tainted and so fail trying to mkdir in the current directory?

  • Comment on Insecure dependency in mkdir while running with -T switch at ... File/Temp.pm line 542
  • Download Code

Replies are listed 'Best First'.
Re: Insecure dependency in mkdir while running with -T switch at ... File/Temp.pm line 542
by hv (Prior) on Dec 10, 2022 at 02:10 UTC

    My first guess is that on some platforms the File::Spec->splitpath, File::Spec->splitdir or File::Spec->catdir calls near line 1673 may be giving a tainted result, perhaps because they need to turn a relative path into an absolute one.

    Maybe if you get the current working directory, untaint it, and then provide an absolute path for DIR that would avoid the problem.

Re: Insecure dependency in mkdir while running with -T switch at ... File/Temp.pm line 542
by kcott (Archbishop) on Dec 10, 2022 at 06:52 UTC

    G'day sidney,

    Welcome to the Monastery.

    "The line number in the error message indicates that it is running File::Temp version 0.2311 (the latest) or 0.2310, as they are the only versions with the mkdir call being on exactly line 542."

    I did a bit of checking:

    1. The CPAN Testers report you gave as an example (https://www.cpantesters.org/cpan/report/a2c77f6e-77eb-11ed-aba6-9a79f339625c) has: "FAIL Mail-SpamAssassin-4.0.0-rc4a-TRIAL 5.18.2 GNU/Linux".
    2. https://perldoc.perl.org/5.18.2/File::Temp shows: "version 0.23". It also has a "Taint mode" note; this is very light on details but suggests a problem with File::Spec.
    3. "File::Temp v0.23 source" has at line 542: "... mkdir( $path, 0700) ...".

    I haven't looked any further. Some potential avenues for your further troubleshooting.

    Another idea might be to use Carp::Always to get a stacktrace leading to the "Insecure dependency in mkdir ..." message. I've often found this to be very useful in the past (e.g. in "Re: Image modules not returning or accepting GD::Image" just last week). Of course, that would require a "Mail-SpamAssassin-4.0.0-rc4b-TRIAL" (or whatever you call it) release and then awaiting subsequent CPAN Tester results; so, perhaps, an "if-all-else-fails" option.

    — Ken

      Ken, that makes a whole lot of sense. I was off by one commit when looking at what I thought was version 0.23 in the github history and missed that old version also having mkdir at line 542. Probably just a weird coincidence that the only other versions with mkdir at that line are the two most recent, leading me to assume that the CPAN modules on the runner had been updated for some reason, even though it is a core module.

      It is still confusing in that besides the various 5.18.x perls on some failing reports, other have perl versions 5.14.x and a 5.20.0 but still say line 542, which is not correct for their bundled versions of File::Temp.

      I just noticed that because my module lists File::Spec as a dependency, the CPAN test report includes it in a list with the version that is actually loaded. So I should be able to upload another TRIAL version and in about 24 hours see what these test runners with the failures say the actual versions are they are using. To add to the confusion all of the failing reports show File::Spec 3.75 loaded, whatever the perl version is.

        "... not correct for their bundled versions ..."

        Some core modules are bound to a particular Perl version; for instance, if you look at B or strict (on CPAN) you'll see that their distributions are Perl releases. With these, the Perl version and core module are aligned.

        Other core modules have their own distributions on CPAN; for example, File::Temp and File::Spec. With these, assuming there are no backwards incompatibilities, you can install a version later than the core version and use it without any problems. I believe the majority of core modules fall into this category; although, that's just a gut feeling and I'd be happy to be corrected on this.

        So, the idea of correctness, in this context, will often have no validity.

        "... CPAN modules on the runner had been updated for some reason, even though it is a core module."

        There are quite a few scenarios where such updates might occur. A couple off the top of my head:

        • I want to use a core module. There's a newer version on CPAN with an optimisation/bug fix/security fix/new feature/whatever that I'd like. I install the newer CPAN version.
        • I install some arbitrary module. It has a prerequisite for a core module with a later version than I have. The newer version gets installed as part of the overall installation process. Unless I'm closely monitoring the installation output, I may not even notice that this has occurred.
        "To add to the confusion all of the failing reports show File::Spec 3.75 loaded, whatever the perl version is."

        The latest "File::Spec CPAN version" is 3.75, and has been since August 2018. The latest "File::Spec 5.36.0 core version" is 3.84, released May 2022. So, the latest CPAN version isn't necessarily more recent than the latest core version.

        Overall, I wouldn't get too bogged down with what module versions testers have at the time they test your module. Unless there's some indication that an update occurred to meet one of your prerequisites, it's unlikely their current version has any direct bearing on your module.

        Purely out of interest (I don't use Mail::SpamAssassin) I successfully installed your module:

        SIDNEY/Mail-SpamAssassin-4.0.0-rc4a-TRIAL.tar.gz /usr/bin/make install -- OK

        When the CPAN Testers Matrix is next updated, you should see a shiny, new, green swatch against 5.36.0 in the cygwin column. :-)

        I'll just note that three of your optional modules failed:

        Failed during this command: (optional) GRUBER/Net-Patricia-1.22.tar.gz : make_test NO (optional) MAXMIND/MaxMind-DB-Reader-XS-1.000009.tar.gz: writemakefil +e NO '/home/ken/perl5/perlbrew/perls/perl-5.36.0/bin/perl Build.PL' r +eturned status 256 (optional) JMEHNLE/mail-spf/Mail-SPF-v2.9.0.tar.gz: make_test NO

        I sent testers reports for all of those. That may be of interest to you; it isn't to me. :-)

        — Ken