Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SelfLoader: Untaint DATA after it's reopened #10078

Closed
p5pRT opened this issue Jan 13, 2010 · 41 comments
Closed

SelfLoader: Untaint DATA after it's reopened #10078

p5pRT opened this issue Jan 13, 2010 · 41 comments

Comments

@p5pRT
Copy link

p5pRT commented Jan 13, 2010

Migrated from rt.perl.org#72062 (status was 'resolved')

Searchable as RT72062$

@p5pRT
Copy link
Author

p5pRT commented Jan 13, 2010

From lubo.rintel@gooddata.com

DATA handle is untainted on startup, but as we close and reopen it it
gets the taint flag. It's safe to untaint it though, since we still hold
the file descriptor open and don't reassign it to another file.

This was probably broken by changeset 29606, (c96b238 in perl git).


lib/SelfLoader.pm | 4 +++-
1 files changed, 3 insertions(+), 1 deletions(-)

Inline Patch
diff --git a/lib/SelfLoader.pm b/lib/SelfLoader.pm
index 047f776..20e02cc 100644
--- a/lib/SelfLoader.pm
+++ b/lib/SelfLoader.pm
@@ -1,7 +1,8 @@
 package SelfLoader;
 use 5.008;
 use strict;
-our $VERSION = "1.17";
+use IO::Handle;
+our $VERSION = "1.18";
 
 # The following bit of eval-magic is necessary to make this work on
 # perls < 5.009005.
@@ -102,6 +103,7 @@ sub _load_stubs {
       close $fh or die "close: $!";                 # autocloses, but be paranoid
       open $fh, '<&', $nfh or croak "reopen2: $!";  # dup() the fd "back"
       close $nfh or die "close after reopen: $!";   # autocloses, but be paranoid
+      $fh->untaint;
     }
     $Cache{"${currpack}::<DATA"} = 1;   # indicate package is cached
 
-- 
1.6.5.2

@p5pRT
Copy link
Author

p5pRT commented Jan 13, 2010

@p5pRT
Copy link
Author

p5pRT commented Jan 19, 2010

From lubo.rintel@gooddata.com

On Wed Jan 13 05​:00​:50 2010, lkundrak wrote​:

DATA handle is untainted on startup, but as we close and reopen it it
gets the taint flag. It's safe to untaint it though, since we still
hold
the file descriptor open and don't reassign it to another file.

This was probably broken by changeset 29606, (c96b238 in perl git).
---
lib/SelfLoader.pm | 4 +++-
1 files changed, 3 insertions(+), 1 deletions(-)

Any chance for anyone at p5p to review this?

Thanks

@p5pRT
Copy link
Author

p5pRT commented Jan 19, 2010

lubo.rintel@gooddata.com - Status changed from 'new' to 'open'

@p5pRT
Copy link
Author

p5pRT commented Jan 19, 2010

From @rgarcia

2010/1/13 Lubomir Rintel <perlbug-followup@​perl.org>​:

DATA handle is untainted on startup, but as we close and reopen it it
gets the taint flag. It's safe to untaint it though, since we still hold
the file descriptor open and don't reassign it to another file.

This was probably broken by changeset 29606, (c96b238 in perl git).
---
 lib/SelfLoader.pm |    4 +++-
 1 files changed, 3 insertions(+), 1 deletions(-)

diff --git a/lib/SelfLoader.pm b/lib/SelfLoader.pm
index 047f776..20e02cc 100644
--- a/lib/SelfLoader.pm
+++ b/lib/SelfLoader.pm
@​@​ -1,7 +1,8 @​@​
 package SelfLoader;
 use 5.008;
 use strict;
-our $VERSION = "1.17";
+use IO​::Handle;

I don't like silently loading IO​::Handle in such a low-level module.
What's missing is probably a way to untaint a FH without loading
IO​::Handle. (Like a new internal subroutine Internals​::untaintfh)

@p5pRT
Copy link
Author

p5pRT commented Jan 19, 2010

From @xdg

Which META ticket should this attach to? Is it a 5.12 blocker?

@p5pRT
Copy link
Author

p5pRT commented Jan 20, 2010

From @rgarcia

2010/1/19 David Golden via RT <perlbug-followup@​perl.org>​:

Which META ticket should this attach to?  Is it a 5.12 blocker?

No. I already commented that I didn't like the patch. We'll address
that after 5.12 is out.

@p5pRT
Copy link
Author

p5pRT commented Jan 20, 2010

From @xdg

On Wed, Jan 20, 2010 at 5​:08 AM, Rafael Garcia-Suarez <rgs@​consttype.org> wrote​:

2010/1/19 David Golden via RT <perlbug-followup@​perl.org>​:

Which META ticket should this attach to?  Is it a 5.12 blocker?

No. I already commented that I didn't like the patch. We'll address
that after 5.12 is out.

Not liking the patch and not blocking are two separate things. :-)

I'll add the ticket to the "non-critical bugs" meta ticket.

David

@p5pRT
Copy link
Author

p5pRT commented Jan 20, 2010

From lubo.rintel@gooddata.com

DATA handle is untainted on startup, but as we close and reopen it it
gets the taint flag. It's safe to untaint it though, since we still hold
the file descriptor open and don't reassign it to another file.

This was probably broken by changeset 29606, (c96b238 in perl git).
Regression test included.


dist/SelfLoader/lib/SelfLoader.pm | 3 ++-
lib/SelfLoader.t | 20 ++++++++++++++++++++
universal.c | 19 +++++++++++++++++++
3 files changed, 41 insertions(+), 1 deletions(-)
create mode 100644 lib/SelfLoader.t

Inline Patch
diff --git a/dist/SelfLoader/lib/SelfLoader.pm b/dist/SelfLoader/lib/SelfLoader.pm
index 047f776..759e975 100644
--- a/dist/SelfLoader/lib/SelfLoader.pm
+++ b/dist/SelfLoader/lib/SelfLoader.pm
@@ -1,7 +1,7 @@
 package SelfLoader;
 use 5.008;
 use strict;
-our $VERSION = "1.17";
+our $VERSION = "1.18";
 
 # The following bit of eval-magic is necessary to make this work on
 # perls < 5.009005.
@@ -102,6 +102,7 @@ sub _load_stubs {
       close $fh or die "close: $!";                 # autocloses, but be paranoid
       open $fh, '<&', $nfh or croak "reopen2: $!";  # dup() the fd "back"
       close $nfh or die "close after reopen: $!";   # autocloses, but be paranoid
+      Internals::untaintfh($fh);
     }
     $Cache{"${currpack}::<DATA"} = 1;   # indicate package is cached
 
diff --git a/lib/SelfLoader.t b/lib/SelfLoader.t
new file mode 100644
index 0000000..d14184a
--- /dev/null
+++ b/lib/SelfLoader.t
@@ -0,0 +1,20 @@
+#!./perl -Tw
+
+use strict;
+use Test::More tests => 4;
+
+use_ok('SelfLoader');
+is(routine (), 1, "Can call self-loaded subroutine");
+
+package pkg;
+Test::More::is(routine (), 2, "Can self-load subroutine from another package");
+
+package main;
+is(pkg::routine2 (), 3, "Can self-load other package's routine");
+
+__DATA__
+sub routine { return 1; }
+
+package pkg;
+sub routine { return 2; }
+sub routine2 { return 3; }
diff --git a/universal.c b/universal.c
index 5a2cddb..03dde5d 100644
--- a/universal.c
+++ b/universal.c
@@ -241,6 +241,7 @@ XS(XS_PerlIO_get_layers);
 XS(XS_Internals_hash_seed);
 XS(XS_Internals_rehash_seed);
 XS(XS_Internals_HvREHASH);
+XS(XS_Internals_untaintfh);
 XS(XS_re_is_regexp); 
 XS(XS_re_regname);
 XS(XS_re_regnames);
@@ -310,6 +311,7 @@ Perl_boot_core_UNIVERSAL(pTHX)
     newXSproto("Internals::hash_seed",XS_Internals_hash_seed, file, "");
     newXSproto("Internals::rehash_seed",XS_Internals_rehash_seed, file, "");
     newXSproto("Internals::HvREHASH", XS_Internals_HvREHASH, file, "\\%");
+    newXSproto("Internals::untaintfh", XS_Internals_untaintfh, file, "*");
     newXSproto("re::is_regexp", XS_re_is_regexp, file, "$");
     newXSproto("re::regname", XS_re_regname, file, ";$$");
     newXSproto("re::regnames", XS_re_regnames, file, ";$");
@@ -1131,6 +1133,23 @@ XS(XS_Internals_HvREHASH)	/* Subject to change  */
     Perl_croak(aTHX_ "Internals::HvREHASH $hashref");
 }
 
+XS(XS_Internals_untaintfh)
+{
+    dVAR;
+    dXSARGS;
+    struct io *handle;
+
+    if (items != 1)
+	croak_xs_usage(cv, "io handle");
+
+    handle = sv_2io(ST(0));
+    if (IoFLAGS(handle) & IOf_UNTAINT)
+        XSRETURN(0);
+
+    IoFLAGS(handle) |= IOf_UNTAINT;
+    XSRETURN(1);
+}
+
 XS(XS_re_is_regexp)
 {
     dVAR; 
-- 
1.6.5.2

@p5pRT
Copy link
Author

p5pRT commented Jan 21, 2010

From @nwc10

On Wed, Jan 20, 2010 at 05​:10​:09PM +0100, Lubomir Rintel (GoodData) wrote​:

+XS(XS_Internals_untaintfh)
+{
+ dVAR;
+ dXSARGS;
+ struct io *handle;
+
+ if (items != 1)
+ croak_xs_usage(cv, "io handle");
+
+ handle = sv_2io(ST(0));
+ if (IoFLAGS(handle) & IOf_UNTAINT)
+ XSRETURN(0);
+
+ IoFLAGS(handle) |= IOf_UNTAINT;
+ XSRETURN(1);
+}

This doesn't look right. XSRETURN() is a macro to indicate the number of
items returned, not to return that value.

The intent seems to be to

ensure that the file handle is not tainted
return 1 if the file handle was tainted on entry
return 0 if the file handle was already not tainted

The interface isn't consistent with most of the analogous XS "Internals"
routines in universal.c, which return status if given 1 argument, and set
the status if given 2.

Nicholas Clark

@p5pRT
Copy link
Author

p5pRT commented Jan 21, 2010

From lubo.rintel@gooddata.com

On Thu, 2010-01-21 at 11​:54 +0100, Lubomir Rintel (GoodData) wrote​:

+XS(XS_Internals_untaintfh)
+{
+ dVAR;
+ dXSARGS;
+ struct io *handle;

Compared to other Internals​:: subroutines in universal.c, I did not
include PERL_UNUSED_ARG(cv) -- what exactly is it used for? dXSARGS
macro expands to NOTE(ARGUNUSED(cv)), isn't that sufficient?

Thanks,
--
Lubomir Rintel (GoodData)

@p5pRT
Copy link
Author

p5pRT commented Jan 21, 2010

From lubo.rintel@gooddata.com

DATA handle is untainted on startup, but as we close and reopen it it
gets the taint flag. It's safe to untaint it though, since we still hold
the file descriptor open and don't reassign it to another file.

This was probably broken by changeset 29606, (c96b238 in perl git).
Regression test included.


dist/SelfLoader/lib/SelfLoader.pm | 3 ++-
lib/SelfLoader.t | 20 ++++++++++++++++++++
universal.c | 31 +++++++++++++++++++++++++++++++
3 files changed, 53 insertions(+), 1 deletions(-)
create mode 100644 lib/SelfLoader.t

Inline Patch
diff --git a/dist/SelfLoader/lib/SelfLoader.pm b/dist/SelfLoader/lib/SelfLoader.pm
index 047f776..ac69a01 100644
--- a/dist/SelfLoader/lib/SelfLoader.pm
+++ b/dist/SelfLoader/lib/SelfLoader.pm
@@ -1,7 +1,7 @@
 package SelfLoader;
 use 5.008;
 use strict;
-our $VERSION = "1.17";
+our $VERSION = "1.18";
 
 # The following bit of eval-magic is necessary to make this work on
 # perls < 5.009005.
@@ -102,6 +102,7 @@ sub _load_stubs {
       close $fh or die "close: $!";                 # autocloses, but be paranoid
       open $fh, '<&', $nfh or croak "reopen2: $!";  # dup() the fd "back"
       close $nfh or die "close after reopen: $!";   # autocloses, but be paranoid
+      #Internals::untaintfh($fh, 1);
     }
     $Cache{"${currpack}::<DATA"} = 1;   # indicate package is cached
 
diff --git a/lib/SelfLoader.t b/lib/SelfLoader.t
new file mode 100644
index 0000000..d14184a
--- /dev/null
+++ b/lib/SelfLoader.t
@@ -0,0 +1,20 @@
+#!./perl -Tw
+
+use strict;
+use Test::More tests => 4;
+
+use_ok('SelfLoader');
+is(routine (), 1, "Can call self-loaded subroutine");
+
+package pkg;
+Test::More::is(routine (), 2, "Can self-load subroutine from another package");
+
+package main;
+is(pkg::routine2 (), 3, "Can self-load other package's routine");
+
+__DATA__
+sub routine { return 1; }
+
+package pkg;
+sub routine { return 2; }
+sub routine2 { return 3; }
diff --git a/universal.c b/universal.c
index 5a2cddb..9cd2da5 100644
--- a/universal.c
+++ b/universal.c
@@ -241,6 +241,7 @@ XS(XS_PerlIO_get_layers);
 XS(XS_Internals_hash_seed);
 XS(XS_Internals_rehash_seed);
 XS(XS_Internals_HvREHASH);
+XS(XS_Internals_untaintfh);
 XS(XS_re_is_regexp); 
 XS(XS_re_regname);
 XS(XS_re_regnames);
@@ -310,6 +311,7 @@ Perl_boot_core_UNIVERSAL(pTHX)
     newXSproto("Internals::hash_seed",XS_Internals_hash_seed, file, "");
     newXSproto("Internals::rehash_seed",XS_Internals_rehash_seed, file, "");
     newXSproto("Internals::HvREHASH", XS_Internals_HvREHASH, file, "\\%");
+    newXSproto("Internals::untaintfh", XS_Internals_untaintfh, file, "*$");
     newXSproto("re::is_regexp", XS_re_is_regexp, file, "$");
     newXSproto("re::regname", XS_re_regname, file, ";$$");
     newXSproto("re::regnames", XS_re_regnames, file, ";$");
@@ -1131,6 +1133,35 @@ XS(XS_Internals_HvREHASH)	/* Subject to change  */
     Perl_croak(aTHX_ "Internals::HvREHASH $hashref");
 }
 
+XS(XS_Internals_untaintfh)
+{
+    dVAR;
+    dXSARGS;
+    struct io *handle;
+
+    handle = sv_2io(ST(0));
+    if (items == 1) {
+	/* Query whether handle is tainted */
+        if (IoFLAGS(handle) & IOf_UNTAINT)
+	    XSRETURN_YES;
+	else
+	    XSRETURN_NO;
+    }
+    else if (items == 2) {
+	/* Set or unset handle's UNTAINT flag */
+        if (SvTRUE(ST(1))) {
+            IoFLAGS(handle) |= IOf_UNTAINT;
+            XSRETURN_YES;
+        }
+        else {
+            IoFLAGS(handle) &= ~IOf_UNTAINT;
+            XSRETURN_NO;
+        }
+    }
+
+    XSRETURN_UNDEF; /* Prototype prevents reaching this */
+}
+
 XS(XS_re_is_regexp)
 {
     dVAR; 
-- 
1.6.5.2

@p5pRT
Copy link
Author

p5pRT commented Jan 21, 2010

From @tonycoz

On Thu, Jan 21, 2010 at 11​:58​:04AM +0100, Lubomir Rintel wrote​:

On Thu, 2010-01-21 at 11​:54 +0100, Lubomir Rintel (GoodData) wrote​:

+XS(XS_Internals_untaintfh)
+{
+ dVAR;
+ dXSARGS;
+ struct io *handle;

Compared to other Internals​:: subroutines in universal.c, I did not
include PERL_UNUSED_ARG(cv) -- what exactly is it used for? dXSARGS
macro expands to NOTE(ARGUNUSED(cv)), isn't that sufficient?

PERL_UNUSED_ARG(cv) does whatever magic is needed to prevent the
compiler from warning about cv as an unused argument.

NOTE(ARGUNUSED(cv)) is only compiled in when passing the code through
lint or splint.

So you still need it.

Tony

@p5pRT
Copy link
Author

p5pRT commented Jan 21, 2010

From lubo.rintel@gooddata.com

DATA handle is untainted on startup, but as we close and reopen it it
gets the taint flag. It's safe to untaint it though, since we still hold
the file descriptor open and don't reassign it to another file.

This was probably broken by changeset 29606, (c96b238 in perl git).
Regression test included.


dist/SelfLoader/lib/SelfLoader.pm | 3 ++-
lib/SelfLoader.t | 20 ++++++++++++++++++++
universal.c | 32 ++++++++++++++++++++++++++++++++
3 files changed, 54 insertions(+), 1 deletions(-)
create mode 100644 lib/SelfLoader.t

Inline Patch
diff --git a/dist/SelfLoader/lib/SelfLoader.pm b/dist/SelfLoader/lib/SelfLoader.pm
index 047f776..ac69a01 100644
--- a/dist/SelfLoader/lib/SelfLoader.pm
+++ b/dist/SelfLoader/lib/SelfLoader.pm
@@ -1,7 +1,7 @@
 package SelfLoader;
 use 5.008;
 use strict;
-our $VERSION = "1.17";
+our $VERSION = "1.18";
 
 # The following bit of eval-magic is necessary to make this work on
 # perls < 5.009005.
@@ -102,6 +102,7 @@ sub _load_stubs {
       close $fh or die "close: $!";                 # autocloses, but be paranoid
       open $fh, '<&', $nfh or croak "reopen2: $!";  # dup() the fd "back"
       close $nfh or die "close after reopen: $!";   # autocloses, but be paranoid
+      #Internals::untaintfh($fh, 1);
     }
     $Cache{"${currpack}::<DATA"} = 1;   # indicate package is cached
 
diff --git a/lib/SelfLoader.t b/lib/SelfLoader.t
new file mode 100644
index 0000000..d14184a
--- /dev/null
+++ b/lib/SelfLoader.t
@@ -0,0 +1,20 @@
+#!./perl -Tw
+
+use strict;
+use Test::More tests => 4;
+
+use_ok('SelfLoader');
+is(routine (), 1, "Can call self-loaded subroutine");
+
+package pkg;
+Test::More::is(routine (), 2, "Can self-load subroutine from another package");
+
+package main;
+is(pkg::routine2 (), 3, "Can self-load other package's routine");
+
+__DATA__
+sub routine { return 1; }
+
+package pkg;
+sub routine { return 2; }
+sub routine2 { return 3; }
diff --git a/universal.c b/universal.c
index 5a2cddb..8e44925 100644
--- a/universal.c
+++ b/universal.c
@@ -241,6 +241,7 @@ XS(XS_PerlIO_get_layers);
 XS(XS_Internals_hash_seed);
 XS(XS_Internals_rehash_seed);
 XS(XS_Internals_HvREHASH);
+XS(XS_Internals_untaintfh);
 XS(XS_re_is_regexp); 
 XS(XS_re_regname);
 XS(XS_re_regnames);
@@ -310,6 +311,7 @@ Perl_boot_core_UNIVERSAL(pTHX)
     newXSproto("Internals::hash_seed",XS_Internals_hash_seed, file, "");
     newXSproto("Internals::rehash_seed",XS_Internals_rehash_seed, file, "");
     newXSproto("Internals::HvREHASH", XS_Internals_HvREHASH, file, "\\%");
+    newXSproto("Internals::untaintfh", XS_Internals_untaintfh, file, "*$");
     newXSproto("re::is_regexp", XS_re_is_regexp, file, "$");
     newXSproto("re::regname", XS_re_regname, file, ";$$");
     newXSproto("re::regnames", XS_re_regnames, file, ";$");
@@ -1131,6 +1133,36 @@ XS(XS_Internals_HvREHASH)	/* Subject to change  */
     Perl_croak(aTHX_ "Internals::HvREHASH $hashref");
 }
 
+XS(XS_Internals_untaintfh)
+{
+    dVAR;
+    dXSARGS;
+    struct io *handle;
+    PERL_UNUSED_ARG(cv);
+
+    handle = sv_2io(ST(0));
+    if (items == 1) {
+	/* Query whether handle is tainted */
+        if (IoFLAGS(handle) & IOf_UNTAINT)
+	    XSRETURN_YES;
+	else
+	    XSRETURN_NO;
+    }
+    else if (items == 2) {
+	/* Set or unset handle's UNTAINT flag */
+        if (SvTRUE(ST(1))) {
+            IoFLAGS(handle) |= IOf_UNTAINT;
+            XSRETURN_YES;
+        }
+        else {
+            IoFLAGS(handle) &= ~IOf_UNTAINT;
+            XSRETURN_NO;
+        }
+    }
+
+    XSRETURN_UNDEF; /* Prototype prevents reaching this */
+}
+
 XS(XS_re_is_regexp)
 {
     dVAR; 
-- 
1.6.5.2

@p5pRT
Copy link
Author

p5pRT commented Jan 21, 2010

From lubo.rintel@gooddata.com

On Thu Jan 21 05​:18​:10 2010, tonyc wrote​:

On Thu, Jan 21, 2010 at 11​:58​:04AM +0100, Lubomir Rintel wrote​:

On Thu, 2010-01-21 at 11​:54 +0100, Lubomir Rintel (GoodData) wrote​:

+XS(XS_Internals_untaintfh)
+{
+ dVAR;
+ dXSARGS;
+ struct io *handle;

Compared to other Internals​:: subroutines in universal.c, I did not
include PERL_UNUSED_ARG(cv) -- what exactly is it used for? dXSARGS
macro expands to NOTE(ARGUNUSED(cv)), isn't that sufficient?

PERL_UNUSED_ARG(cv) does whatever magic is needed to prevent the
compiler from warning about cv as an unused argument.

NOTE(ARGUNUSED(cv)) is only compiled in when passing the code through
lint or splint.

Thank you. Attaching a new patch which has it.

@p5pRT
Copy link
Author

p5pRT commented Jan 21, 2010

From @tonycoz

On Thu, Jan 21, 2010 at 02​:54​:04PM +0100, Lubomir Rintel (GoodData) wrote​:

DATA handle is untainted on startup, but as we close and reopen it it
gets the taint flag. It's safe to untaint it though, since we still hold
the file descriptor open and don't reassign it to another file.

This was probably broken by changeset 29606, (c96b238 in perl git).
Regression test included.
---
dist/SelfLoader/lib/SelfLoader.pm | 3 ++-
lib/SelfLoader.t | 20 ++++++++++++++++++++
universal.c | 32 ++++++++++++++++++++++++++++++++
3 files changed, 54 insertions(+), 1 deletions(-)
create mode 100644 lib/SelfLoader.t

diff --git a/dist/SelfLoader/lib/SelfLoader.pm b/dist/SelfLoader/lib/SelfLoader.pm
index 047f776..ac69a01 100644
--- a/dist/SelfLoader/lib/SelfLoader.pm
+++ b/dist/SelfLoader/lib/SelfLoader.pm
@​@​ -1,7 +1,7 @​@​
package SelfLoader;
use 5.008;
use strict;
-our $VERSION = "1.17";
+our $VERSION = "1.18";

# The following bit of eval-magic is necessary to make this work on
# perls < 5.009005.
@​@​ -102,6 +102,7 @​@​ sub _load_stubs {
close $fh or die "close​: $!"; # autocloses, but be paranoid
open $fh, '<&', $nfh or croak "reopen2​: $!"; # dup() the fd "back"
close $nfh or die "close after reopen​: $!"; # autocloses, but be paranoid
+ #Internals​::untaintfh($fh, 1);

Should this be commented out?

Tony

@p5pRT
Copy link
Author

p5pRT commented Jan 22, 2010

From lubo.rintel@gooddata.com

DATA handle is untainted on startup, but as we close and reopen it it
gets the taint flag. It's safe to untaint it though, since we still hold
the file descriptor open and don't reassign it to another file.

This was probably broken by changeset 29606, (c96b238 in perl git).
Regression test included.


dist/SelfLoader/lib/SelfLoader.pm | 3 ++-
lib/SelfLoader.t | 20 ++++++++++++++++++++
universal.c | 32 ++++++++++++++++++++++++++++++++
3 files changed, 54 insertions(+), 1 deletions(-)
create mode 100644 lib/SelfLoader.t

Inline Patch
diff --git a/dist/SelfLoader/lib/SelfLoader.pm b/dist/SelfLoader/lib/SelfLoader.pm
index 047f776..ac69a01 100644
--- a/dist/SelfLoader/lib/SelfLoader.pm
+++ b/dist/SelfLoader/lib/SelfLoader.pm
@@ -1,7 +1,7 @@
 package SelfLoader;
 use 5.008;
 use strict;
-our $VERSION = "1.17";
+our $VERSION = "1.18";
 
 # The following bit of eval-magic is necessary to make this work on
 # perls < 5.009005.
@@ -102,6 +102,7 @@ sub _load_stubs {
       close $fh or die "close: $!";                 # autocloses, but be paranoid
       open $fh, '<&', $nfh or croak "reopen2: $!";  # dup() the fd "back"
       close $nfh or die "close after reopen: $!";   # autocloses, but be paranoid
+      #Internals::untaintfh($fh, 1);
     }
     $Cache{"${currpack}::<DATA"} = 1;   # indicate package is cached
 
diff --git a/lib/SelfLoader.t b/lib/SelfLoader.t
new file mode 100644
index 0000000..d14184a
--- /dev/null
+++ b/lib/SelfLoader.t
@@ -0,0 +1,20 @@
+#!./perl -Tw
+
+use strict;
+use Test::More tests => 4;
+
+use_ok('SelfLoader');
+is(routine (), 1, "Can call self-loaded subroutine");
+
+package pkg;
+Test::More::is(routine (), 2, "Can self-load subroutine from another package");
+
+package main;
+is(pkg::routine2 (), 3, "Can self-load other package's routine");
+
+__DATA__
+sub routine { return 1; }
+
+package pkg;
+sub routine { return 2; }
+sub routine2 { return 3; }
diff --git a/universal.c b/universal.c
index 5a2cddb..8e44925 100644
--- a/universal.c
+++ b/universal.c
@@ -241,6 +241,7 @@ XS(XS_PerlIO_get_layers);
 XS(XS_Internals_hash_seed);
 XS(XS_Internals_rehash_seed);
 XS(XS_Internals_HvREHASH);
+XS(XS_Internals_untaintfh);
 XS(XS_re_is_regexp); 
 XS(XS_re_regname);
 XS(XS_re_regnames);
@@ -310,6 +311,7 @@ Perl_boot_core_UNIVERSAL(pTHX)
     newXSproto("Internals::hash_seed",XS_Internals_hash_seed, file, "");
     newXSproto("Internals::rehash_seed",XS_Internals_rehash_seed, file, "");
     newXSproto("Internals::HvREHASH", XS_Internals_HvREHASH, file, "\\%");
+    newXSproto("Internals::untaintfh", XS_Internals_untaintfh, file, "*$");
     newXSproto("re::is_regexp", XS_re_is_regexp, file, "$");
     newXSproto("re::regname", XS_re_regname, file, ";$$");
     newXSproto("re::regnames", XS_re_regnames, file, ";$");
@@ -1131,6 +1133,36 @@ XS(XS_Internals_HvREHASH)	/* Subject to change  */
     Perl_croak(aTHX_ "Internals::HvREHASH $hashref");
 }
 
+XS(XS_Internals_untaintfh)
+{
+    dVAR;
+    dXSARGS;
+    struct io *handle;
+    PERL_UNUSED_ARG(cv);
+
+    handle = sv_2io(ST(0));
+    if (items == 1) {
+	/* Query whether handle is tainted */
+        if (IoFLAGS(handle) & IOf_UNTAINT)
+	    XSRETURN_YES;
+	else
+	    XSRETURN_NO;
+    }
+    else if (items == 2) {
+	/* Set or unset handle's UNTAINT flag */
+        if (SvTRUE(ST(1))) {
+            IoFLAGS(handle) |= IOf_UNTAINT;
+            XSRETURN_YES;
+        }
+        else {
+            IoFLAGS(handle) &= ~IOf_UNTAINT;
+            XSRETURN_NO;
+        }
+    }
+
+    XSRETURN_UNDEF; /* Prototype prevents reaching this */
+}
+
 XS(XS_re_is_regexp)
 {
     dVAR; 
-- 
1.6.5.2

@p5pRT
Copy link
Author

p5pRT commented Jan 22, 2010

From lubo.rintel@gooddata.com

DATA handle is untainted on startup, but as we close and reopen it it
gets the taint flag. It's safe to untaint it though, since we still hold
the file descriptor open and don't reassign it to another file.

This was probably broken by changeset 29606, (c96b238 in perl git).
Regression test included.


dist/SelfLoader/lib/SelfLoader.pm | 3 ++-
lib/SelfLoader.t | 20 ++++++++++++++++++++
universal.c | 32 ++++++++++++++++++++++++++++++++
3 files changed, 54 insertions(+), 1 deletions(-)
create mode 100644 lib/SelfLoader.t

Inline Patch
diff --git a/dist/SelfLoader/lib/SelfLoader.pm b/dist/SelfLoader/lib/SelfLoader.pm
index 047f776..d6c8499 100644
--- a/dist/SelfLoader/lib/SelfLoader.pm
+++ b/dist/SelfLoader/lib/SelfLoader.pm
@@ -1,7 +1,7 @@
 package SelfLoader;
 use 5.008;
 use strict;
-our $VERSION = "1.17";
+our $VERSION = "1.18";
 
 # The following bit of eval-magic is necessary to make this work on
 # perls < 5.009005.
@@ -102,6 +102,7 @@ sub _load_stubs {
       close $fh or die "close: $!";                 # autocloses, but be paranoid
       open $fh, '<&', $nfh or croak "reopen2: $!";  # dup() the fd "back"
       close $nfh or die "close after reopen: $!";   # autocloses, but be paranoid
+      Internals::untaintfh($fh, 1);
     }
     $Cache{"${currpack}::<DATA"} = 1;   # indicate package is cached
 
diff --git a/lib/SelfLoader.t b/lib/SelfLoader.t
new file mode 100644
index 0000000..d14184a
--- /dev/null
+++ b/lib/SelfLoader.t
@@ -0,0 +1,20 @@
+#!./perl -Tw
+
+use strict;
+use Test::More tests => 4;
+
+use_ok('SelfLoader');
+is(routine (), 1, "Can call self-loaded subroutine");
+
+package pkg;
+Test::More::is(routine (), 2, "Can self-load subroutine from another package");
+
+package main;
+is(pkg::routine2 (), 3, "Can self-load other package's routine");
+
+__DATA__
+sub routine { return 1; }
+
+package pkg;
+sub routine { return 2; }
+sub routine2 { return 3; }
diff --git a/universal.c b/universal.c
index 5a2cddb..8e44925 100644
--- a/universal.c
+++ b/universal.c
@@ -241,6 +241,7 @@ XS(XS_PerlIO_get_layers);
 XS(XS_Internals_hash_seed);
 XS(XS_Internals_rehash_seed);
 XS(XS_Internals_HvREHASH);
+XS(XS_Internals_untaintfh);
 XS(XS_re_is_regexp); 
 XS(XS_re_regname);
 XS(XS_re_regnames);
@@ -310,6 +311,7 @@ Perl_boot_core_UNIVERSAL(pTHX)
     newXSproto("Internals::hash_seed",XS_Internals_hash_seed, file, "");
     newXSproto("Internals::rehash_seed",XS_Internals_rehash_seed, file, "");
     newXSproto("Internals::HvREHASH", XS_Internals_HvREHASH, file, "\\%");
+    newXSproto("Internals::untaintfh", XS_Internals_untaintfh, file, "*$");
     newXSproto("re::is_regexp", XS_re_is_regexp, file, "$");
     newXSproto("re::regname", XS_re_regname, file, ";$$");
     newXSproto("re::regnames", XS_re_regnames, file, ";$");
@@ -1131,6 +1133,36 @@ XS(XS_Internals_HvREHASH)	/* Subject to change  */
     Perl_croak(aTHX_ "Internals::HvREHASH $hashref");
 }
 
+XS(XS_Internals_untaintfh)
+{
+    dVAR;
+    dXSARGS;
+    struct io *handle;
+    PERL_UNUSED_ARG(cv);
+
+    handle = sv_2io(ST(0));
+    if (items == 1) {
+	/* Query whether handle is tainted */
+        if (IoFLAGS(handle) & IOf_UNTAINT)
+	    XSRETURN_YES;
+	else
+	    XSRETURN_NO;
+    }
+    else if (items == 2) {
+	/* Set or unset handle's UNTAINT flag */
+        if (SvTRUE(ST(1))) {
+            IoFLAGS(handle) |= IOf_UNTAINT;
+            XSRETURN_YES;
+        }
+        else {
+            IoFLAGS(handle) &= ~IOf_UNTAINT;
+            XSRETURN_NO;
+        }
+    }
+
+    XSRETURN_UNDEF; /* Prototype prevents reaching this */
+}
+
 XS(XS_re_is_regexp)
 {
     dVAR; 
-- 
1.6.5.2

@p5pRT
Copy link
Author

p5pRT commented Apr 22, 2010

From lubo.rintel@gooddata.com

From​: Lubomir Rintel (GoodData) <lubo.rintel@​gooddata.com>

DATA handle is untainted on startup, but as we close and reopen it it
gets the taint flag. It's safe to untaint it though, since we still hold
the file descriptor open and don't reassign it to another file.

This was probably broken by changeset 29606, (c96b238 in perl git).
Regression test included.


dist/SelfLoader/lib/SelfLoader.pm | 3 ++-
lib/SelfLoader.t | 20 ++++++++++++++++++++
universal.c | 32 ++++++++++++++++++++++++++++++++
3 files changed, 54 insertions(+), 1 deletions(-)
create mode 100644 lib/SelfLoader.t

Inline Patch
diff --git a/dist/SelfLoader/lib/SelfLoader.pm b/dist/SelfLoader/lib/SelfLoader.pm
index 047f776..d6c8499 100644
--- a/dist/SelfLoader/lib/SelfLoader.pm
+++ b/dist/SelfLoader/lib/SelfLoader.pm
@@ -1,7 +1,7 @@
 package SelfLoader;
 use 5.008;
 use strict;
-our $VERSION = "1.17";
+our $VERSION = "1.18";
 
 # The following bit of eval-magic is necessary to make this work on
 # perls < 5.009005.
@@ -102,6 +102,7 @@ sub _load_stubs {
       close $fh or die "close: $!";                 # autocloses, but be paranoid
       open $fh, '<&', $nfh or croak "reopen2: $!";  # dup() the fd "back"
       close $nfh or die "close after reopen: $!";   # autocloses, but be paranoid
+      Internals::untaintfh($fh, 1);
     }
     $Cache{"${currpack}::<DATA"} = 1;   # indicate package is cached
 
diff --git a/lib/SelfLoader.t b/lib/SelfLoader.t
new file mode 100644
index 0000000..d14184a
--- /dev/null
+++ b/lib/SelfLoader.t
@@ -0,0 +1,20 @@
+#!./perl -Tw
+
+use strict;
+use Test::More tests => 4;
+
+use_ok('SelfLoader');
+is(routine (), 1, "Can call self-loaded subroutine");
+
+package pkg;
+Test::More::is(routine (), 2, "Can self-load subroutine from another package");
+
+package main;
+is(pkg::routine2 (), 3, "Can self-load other package's routine");
+
+__DATA__
+sub routine { return 1; }
+
+package pkg;
+sub routine { return 2; }
+sub routine2 { return 3; }
diff --git a/universal.c b/universal.c
index ce56d0b..4fa214f 100644
--- a/universal.c
+++ b/universal.c
@@ -241,6 +241,7 @@ XS(XS_PerlIO_get_layers);
 XS(XS_Internals_hash_seed);
 XS(XS_Internals_rehash_seed);
 XS(XS_Internals_HvREHASH);
+XS(XS_Internals_untaintfh);
 XS(XS_re_is_regexp); 
 XS(XS_re_regname);
 XS(XS_re_regnames);
@@ -310,6 +311,7 @@ Perl_boot_core_UNIVERSAL(pTHX)
     newXSproto("Internals::hash_seed",XS_Internals_hash_seed, file, "");
     newXSproto("Internals::rehash_seed",XS_Internals_rehash_seed, file, "");
     newXSproto("Internals::HvREHASH", XS_Internals_HvREHASH, file, "\\%");
+    newXSproto("Internals::untaintfh", XS_Internals_untaintfh, file, "*$");
     newXSproto("re::is_regexp", XS_re_is_regexp, file, "$");
     newXSproto("re::regname", XS_re_regname, file, ";$$");
     newXSproto("re::regnames", XS_re_regnames, file, ";$");
@@ -1131,6 +1133,36 @@ XS(XS_Internals_HvREHASH)	/* Subject to change  */
     Perl_croak(aTHX_ "Internals::HvREHASH $hashref");
 }
 
+XS(XS_Internals_untaintfh)
+{
+    dVAR;
+    dXSARGS;
+    struct io *handle;
+    PERL_UNUSED_ARG(cv);
+
+    handle = sv_2io(ST(0));
+    if (items == 1) {
+	/* Query whether handle is tainted */
+        if (IoFLAGS(handle) & IOf_UNTAINT)
+	    XSRETURN_YES;
+	else
+	    XSRETURN_NO;
+    }
+    else if (items == 2) {
+	/* Set or unset handle's UNTAINT flag */
+        if (SvTRUE(ST(1))) {
+            IoFLAGS(handle) |= IOf_UNTAINT;
+            XSRETURN_YES;
+        }
+        else {
+            IoFLAGS(handle) &= ~IOf_UNTAINT;
+            XSRETURN_NO;
+        }
+    }
+
+    XSRETURN_UNDEF; /* Prototype prevents reaching this */
+}
+
 XS(XS_re_is_regexp)
 {
     dVAR; 
-- 
1.7.0.1

@p5pRT
Copy link
Author

p5pRT commented Apr 22, 2010

From @avar

Mabye instead of adding Internals​::untaintfh (which is bound to get
called in user code) it would be better to add a proper interface to
the taint guts. Like my Taint​::Util to core?

Taint​::Util probably doesn't do IOf_UNTAINT support yet, but it would
be easy to alter it to do so.

@p5pRT
Copy link
Author

p5pRT commented Apr 26, 2010

From @rgarcia

On 22 April 2010 18​:49, Ævar Arnfjörð Bjarmason <avarab@​gmail.com> wrote​:

Mabye instead of adding Internals​::untaintfh (which is bound to get
called in user code) it would be better to add a proper interface to
the taint guts. Like my Taint​::Util to core?

Taint​::Util probably doesn't do IOf_UNTAINT support yet, but it would
be easy to alter it to do so.

Is it not possible to use IO​::Handle->untaint here ?

@p5pRT
Copy link
Author

p5pRT commented Apr 26, 2010

From @avar

On Mon, Apr 26, 2010 at 10​:09, Rafael Garcia-Suarez <rgs@​consttype.org> wrote​:

On 22 April 2010 18​:49, Ævar Arnfjörð Bjarmason <avarab@​gmail.com> wrote​:

Mabye instead of adding Internals​::untaintfh (which is bound to get
called in user code) it would be better to add a proper interface to
the taint guts. Like my Taint​::Util to core?

Taint​::Util probably doesn't do IOf_UNTAINT support yet, but it would
be easy to alter it to do so.

Is it not possible to use IO​::Handle->untaint here ?

Not for this part of the patch​:

  IoFLAGS(handle) &= ~IOf_UNTAINT;

but it should work for​:

  IoFLAGS(handle) |= IOf_UNTAINT;

@p5pRT
Copy link
Author

p5pRT commented Apr 26, 2010

From lubo.rintel@gooddata.com

On Mon, 2010-04-26 at 03​:10 -0700, Rafael Garcia-Suarez via RT wrote​:

On 22 April 2010 18​:49, Ævar Arnfjörð Bjarmason <avarab@​gmail.com> wrote​:

Mabye instead of adding Internals​::untaintfh (which is bound to get
called in user code) it would be better to add a proper interface to
the taint guts. Like my Taint​::Util to core?

Taint​::Util probably doesn't do IOf_UNTAINT support yet, but it would
be easy to alter it to do so.

Is it not possible to use IO​::Handle->untaint here ?

In fact, it is. I thought you objected it?
http​://rt.perl.org/rt3/Public/Bug/Display.html?id=72062#txn-651162

--
Lubomir Rintel (GoodData), phone​: #7715

@p5pRT
Copy link
Author

p5pRT commented Apr 26, 2010

From @rgarcia

On 26 April 2010 12​:44, Lubomir Rintel <lubo.rintel@​gooddata.com> wrote​:

On Mon, 2010-04-26 at 03​:10 -0700, Rafael Garcia-Suarez via RT wrote​:

On 22 April 2010 18​:49, Ævar Arnfjörð Bjarmason <avarab@​gmail.com> wrote​:

Mabye instead of adding Internals​::untaintfh (which is bound to get
called in user code) it would be better to add a proper interface to
the taint guts. Like my Taint​::Util to core?

Taint​::Util probably doesn't do IOf_UNTAINT support yet, but it would
be easy to alter it to do so.

Is it not possible to use IO​::Handle->untaint here ?

In fact, it is. I thought you objected it?
http​://rt.perl.org/rt3/Public/Bug/Display.html?id=72062#txn-651162

Haha, looks like I can't make my mind about it. Or was it a subliminal
reminiscence of your older patch ?

I believe your Internals​::untaintfh patch can go in. Do other porters
have strong objections ?

@p5pRT
Copy link
Author

p5pRT commented Apr 26, 2010

From @nwc10

On Mon, Apr 26, 2010 at 02​:42​:27PM +0200, Rafael Garcia-Suarez wrote​:

On 26 April 2010 12​:44, Lubomir Rintel <lubo.rintel@​gooddata.com> wrote​:

On Mon, 2010-04-26 at 03​:10 -0700, Rafael Garcia-Suarez via RT wrote​:

On 22 April 2010 18​:49, Ævar Arnfjörð Bjarmason <avarab@​gmail.com> wrote​:

Mabye instead of adding Internals​::untaintfh (which is bound to get
called in user code) it would be better to add a proper interface to
the taint guts. Like my Taint​::Util to core?

Taint​::Util probably doesn't do IOf_UNTAINT support yet, but it would
be easy to alter it to do so.

Is it not possible to use IO​::Handle->untaint here ?

In fact, it is. I thought you objected it?
http​://rt.perl.org/rt3/Public/Bug/Display.html?id=72062#txn-651162

Haha, looks like I can't make my mind about it. Or was it a subliminal
reminiscence of your older patch ?

I believe your Internals​::untaintfh patch can go in. Do other porters
have strong objections ?

Yes, roughly "Oh $deity, not more Internals​::*"?

Is it really unavoidable?
Why can't this go in IO?

Nicholas Clark

@p5pRT
Copy link
Author

p5pRT commented Apr 26, 2010

From @rgarcia

On 26 April 2010 14​:44, Nicholas Clark <nick@​ccl4.org> wrote​:

On Mon, Apr 26, 2010 at 02​:42​:27PM +0200, Rafael Garcia-Suarez wrote​:

On 26 April 2010 12​:44, Lubomir Rintel <lubo.rintel@​gooddata.com> wrote​:

On Mon, 2010-04-26 at 03​:10 -0700, Rafael Garcia-Suarez via RT wrote​:

On 22 April 2010 18​:49, Ævar Arnfjörð Bjarmason <avarab@​gmail.com> wrote​:

Mabye instead of adding Internals​::untaintfh (which is bound to get
called in user code) it would be better to add a proper interface to
the taint guts. Like my Taint​::Util to core?

Taint​::Util probably doesn't do IOf_UNTAINT support yet, but it would
be easy to alter it to do so.

Is it not possible to use IO​::Handle->untaint here ?

In fact, it is. I thought you objected it?
http​://rt.perl.org/rt3/Public/Bug/Display.html?id=72062#txn-651162

Haha, looks like I can't make my mind about it. Or was it a subliminal
reminiscence of your older patch ?

I believe your Internals​::untaintfh patch can go in. Do other porters
have strong objections ?

Yes, roughly "Oh $deity, not more Internals​::*"?

Is it really unavoidable?
Why can't this go in IO?

Depends where and how many side-effects we can expect by loading
IO​::File. I believe the situation improved with 5.12 (thanks to you)
so I might be wrong.

@p5pRT
Copy link
Author

p5pRT commented Apr 27, 2010

From lubo.rintel@gooddata.com

On Mon, 2010-04-26 at 15​:03 +0200, Rafael Garcia-Suarez wrote​:

On 26 April 2010 14​:44, Nicholas Clark <nick@​ccl4.org> wrote​:

On Mon, Apr 26, 2010 at 02​:42​:27PM +0200, Rafael Garcia-Suarez wrote​:

On 26 April 2010 12​:44, Lubomir Rintel <lubo.rintel@​gooddata.com> wrote​:

On Mon, 2010-04-26 at 03​:10 -0700, Rafael Garcia-Suarez via RT wrote​:

On 22 April 2010 18​:49, Ævar Arnfjörð Bjarmason <avarab@​gmail.com> wrote​:

Mabye instead of adding Internals​::untaintfh (which is bound to get
called in user code) it would be better to add a proper interface to
the taint guts. Like my Taint​::Util to core?

Taint​::Util probably doesn't do IOf_UNTAINT support yet, but it would
be easy to alter it to do so.

Is it not possible to use IO​::Handle->untaint here ?

In fact, it is. I thought you objected it?
http​://rt.perl.org/rt3/Public/Bug/Display.html?id=72062#txn-651162

Haha, looks like I can't make my mind about it. Or was it a subliminal
reminiscence of your older patch ?

I believe your Internals​::untaintfh patch can go in. Do other porters
have strong objections ?

Yes, roughly "Oh $deity, not more Internals​::*"?

Is it really unavoidable?
Why can't this go in IO?

Depends where and how many side-effects we can expect by loading
IO​::File. I believe the situation improved with 5.12 (thanks to you)
so I might be wrong.

I'm not sure which side effects are you talking about, would it be of
any use if I posted a patch that would use IO here?

--
Lubomir Rintel (GoodData), phone​: #7715

@p5pRT
Copy link
Author

p5pRT commented Apr 27, 2010

From @ikegami

On Tue, Apr 27, 2010 at 3​:01 PM, Lubomir Rintel <lubo.rintel@​gooddata.com>wrote​:

I'm not sure which side effects are you talking about

Any. An example of a pre-5.12 side-effect of loading FileHandle​:

$ perl -e'STDOUT->foo'
Can't locate object method "foo" via package "IO​::Handle" at -e line 1.

$ perl -MFileHandle -e'STDOUT->foo'
Can't locate object method "foo" via package "FileHandle" at -e line 1.

Mind you, the side-effect in this particular case affected an aspect that
Perl 5.12 broke willingly.

$ perl -e'STDOUT->foo'
Can't locate object method "foo" via package "IO​::File" at -e line 1.

$ perl -MFileHandle -e'STDOUT->foo'
Can't locate object method "foo" via package "IO​::File" at -e line 1.

@p5pRT
Copy link
Author

p5pRT commented Apr 27, 2010

From @nwc10

On Tue, Apr 27, 2010 at 04​:15​:47PM -0400, Eric Brine wrote​:

On Tue, Apr 27, 2010 at 3​:01 PM, Lubomir Rintel <lubo.rintel@​gooddata.com>wrote​:

I'm not sure which side effects are you talking about

Any. An example of a pre-5.12 side-effect of loading FileHandle​:

$ perl -e'STDOUT->foo'
Can't locate object method "foo" via package "IO​::Handle" at -e line 1.

$ perl -MFileHandle -e'STDOUT->foo'
Can't locate object method "foo" via package "FileHandle" at -e line 1.

Mind you, the side-effect in this particular case affected an aspect that
Perl 5.12 broke willingly.

$ perl -e'STDOUT->foo'
Can't locate object method "foo" via package "IO​::File" at -e line 1.

$ perl -MFileHandle -e'STDOUT->foo'
Can't locate object method "foo" via package "IO​::File" at -e line 1.

Broke what?

$ perl -MIO​::File -le 'print IO​::File->isa("IO​::Handle")'1
1
$ perl -MFileHandle -le 'print FileHandle->isa("IO​::Handle")'
1

Sure, the error message changes. But both FileHandle and IO​::File are
subclasses of IO​::Handle, and all the methods on FileHandle are from IO​::File,
or its superclasses.

What breakage is there, unless code is making assumptions about the precise
text of error messages, or monkey patching FileHandle?

Nicholas Clark

@p5pRT
Copy link
Author

p5pRT commented Apr 27, 2010

From @ikegami

On Tue, Apr 27, 2010 at 4​:30 PM, Nicholas Clark <nick@​ccl4.org> wrote​:

Broke what?

->isa can return differently

5.10.0​:
$ perl -MFileHandle -le '
  open(my $fh, "<", $ARGV[0]) or die;
  $fh = *$fh{IO};
  print $fh->isa("FileHandle") ?1​:0;
' some_file
1

5.12.0​:
$ perl -MFileHandle -le '
  open(my $fh, "<", $ARGV[0]) or die;
  $fh = *$fh{IO};
  print $fh->isa("FileHandle") ?1​:0;
' some_file
0

I'm not saying that I care that it got changed.

@p5pRT
Copy link
Author

p5pRT commented Jul 23, 2010

From lubo.rintel@gooddata.com

I somehow lost track here.

Was a consensus reached that there are any outstanding issues in the
latest revision of the patch? If not, is there anything I can do to help
move this forward? Otherwise please point me to what is to be improved
and I'll happily adjust the patch to match the requirements.

Thank you.

@p5pRT
Copy link
Author

p5pRT commented Jul 26, 2010

From lubo.rintel@gooddata.com

Refreshing the patch given it no longer applied.

@p5pRT
Copy link
Author

p5pRT commented Jul 26, 2010

From lubo.rintel@gooddata.com

0001-perl-72062-Untaint-DATA-after-it-s-reopened.patch
From 1770a7f4ca824b344b0a79aa90edb02e3f29b73b Mon Sep 17 00:00:00 2001
From: Lubomir Rintel (GoodData) <lubo.rintel@gooddata.com>
Date: Mon, 11 Jan 2010 19:27:54 +0100
Subject: [PATCH] [perl #72062] Untaint DATA after it's reopened

DATA handle is untainted on startup, but as we close and reopen it it
gets the taint flag. It's safe to untaint it though, since we still hold
the file descriptor open and don't reassign it to another file.

This was probably broken by changeset 29606, (c96b2385 in perl git).
Regression test included.
---
 dist/SelfLoader/lib/SelfLoader.pm |    3 ++-
 lib/SelfLoader.t                  |   20 ++++++++++++++++++++
 universal.c                       |   31 +++++++++++++++++++++++++++++++
 3 files changed, 53 insertions(+), 1 deletions(-)
 create mode 100644 lib/SelfLoader.t

diff --git a/dist/SelfLoader/lib/SelfLoader.pm b/dist/SelfLoader/lib/SelfLoader.pm
index 047f776..d6c8499 100644
--- a/dist/SelfLoader/lib/SelfLoader.pm
+++ b/dist/SelfLoader/lib/SelfLoader.pm
@@ -1,7 +1,7 @@
 package SelfLoader;
 use 5.008;
 use strict;
-our $VERSION = "1.17";
+our $VERSION = "1.18";
 
 # The following bit of eval-magic is necessary to make this work on
 # perls < 5.009005.
@@ -102,6 +102,7 @@ sub _load_stubs {
       close $fh or die "close: $!";                 # autocloses, but be paranoid
       open $fh, '<&', $nfh or croak "reopen2: $!";  # dup() the fd "back"
       close $nfh or die "close after reopen: $!";   # autocloses, but be paranoid
+      Internals::untaintfh($fh, 1);
     }
     $Cache{"${currpack}::<DATA"} = 1;   # indicate package is cached
 
diff --git a/lib/SelfLoader.t b/lib/SelfLoader.t
new file mode 100644
index 0000000..d14184a
--- /dev/null
+++ b/lib/SelfLoader.t
@@ -0,0 +1,20 @@
+#!./perl -Tw
+
+use strict;
+use Test::More tests => 4;
+
+use_ok('SelfLoader');
+is(routine (), 1, "Can call self-loaded subroutine");
+
+package pkg;
+Test::More::is(routine (), 2, "Can self-load subroutine from another package");
+
+package main;
+is(pkg::routine2 (), 3, "Can self-load other package's routine");
+
+__DATA__
+sub routine { return 1; }
+
+package pkg;
+sub routine { return 2; }
+sub routine2 { return 3; }
diff --git a/universal.c b/universal.c
index 07a0aa6..f93bad9 100644
--- a/universal.c
+++ b/universal.c
@@ -1015,6 +1015,36 @@ XS(XS_Internals_HvREHASH)	/* Subject to change  */
     Perl_croak(aTHX_ "Internals::HvREHASH $hashref");
 }
 
+XS(XS_Internals_untaintfh)
+{
+    dVAR;
+    dXSARGS;
+    struct io *handle;
+    PERL_UNUSED_ARG(cv);
+
+    handle = sv_2io(ST(0));
+    if (items == 1) {
+	/* Query whether handle is tainted */
+        if (IoFLAGS(handle) & IOf_UNTAINT)
+	    XSRETURN_YES;
+	else
+	    XSRETURN_NO;
+    }
+    else if (items == 2) {
+	/* Set or unset handle's UNTAINT flag */
+        if (SvTRUE(ST(1))) {
+            IoFLAGS(handle) |= IOf_UNTAINT;
+            XSRETURN_YES;
+        }
+        else {
+            IoFLAGS(handle) &= ~IOf_UNTAINT;
+            XSRETURN_NO;
+        }
+    }
+
+    XSRETURN_UNDEF; /* Prototype prevents reaching this */
+}
+
 XS(XS_re_is_regexp)
 {
     dVAR; 
@@ -1517,6 +1547,7 @@ struct xsub_details details[] = {
     {"Internals::hash_seed", XS_Internals_hash_seed, ""},
     {"Internals::rehash_seed", XS_Internals_rehash_seed, ""},
     {"Internals::HvREHASH", XS_Internals_HvREHASH, "\\%"},
+    {"Internals::untaintfh", XS_Internals_untaintfh, file, "*$"},
     {"re::is_regexp", XS_re_is_regexp, "$"},
     {"re::regname", XS_re_regname, ";$$"},
     {"re::regnames", XS_re_regnames, ";$"},
-- 
1.7.1

@p5pRT
Copy link
Author

p5pRT commented Sep 27, 2010

From @cpansprout

On Mon Apr 26 05​:44​:37 2010, nicholas wrote​:

On Mon, Apr 26, 2010 at 02​:42​:27PM +0200, Rafael Garcia-Suarez wrote​:

I believe your Internals​::untaintfh patch can go in. Do other
porters
have strong objections ?

Is it really unavoidable?
Why can't this go in IO?

Do you mind if I go ahead and apply this? I’m sure that if you are
sufficiently dissatisfied with it, you will change it. :-)

Anyway, this is the most efficient solution. I would not want to risk
breaking SelfLoader.

@p5pRT
Copy link
Author

p5pRT commented Sep 27, 2010

From @rgarcia

On 27 September 2010 02​:14, Father Chrysostomos via RT
<perlbug-followup@​perl.org> wrote​:

On Mon Apr 26 05​:44​:37 2010, nicholas wrote​:

On Mon, Apr 26, 2010 at 02​:42​:27PM +0200, Rafael Garcia-Suarez wrote​:

I believe your Internals​::untaintfh patch can go in. Do other
porters
have strong objections ?

Is it really unavoidable?
Why can't this go in IO?

Do you mind if I go ahead and apply this? I’m sure that if you are
sufficiently dissatisfied with it, you will change it. :-)

Anyway, this is the most efficient solution. I would not want to risk
breaking SelfLoader.

I have no strong objection, except that probably Internals​::untaintfh
should be added in a separate patch. Also the place of the new test is
wrong, it should go in dist/SelftLoader/t with the other tests. I
notice as well that the prototype for untaintfh should be "*;$"
instead of "*$".

Then of course we have the bikeshed issue of "no more Internals​::
functions"... but there's not general purpose taint-related utility
module in the core.

@p5pRT
Copy link
Author

p5pRT commented Sep 27, 2010

From @nwc10

On Mon, Sep 27, 2010 at 12​:11​:15PM +0200, Rafael Garcia-Suarez wrote​:

On 27 September 2010 02​:14, Father Chrysostomos via RT
<perlbug-followup@​perl.org> wrote​:

On Mon Apr 26 05​:44​:37 2010, nicholas wrote​:

On Mon, Apr 26, 2010 at 02​:42​:27PM +0200, Rafael Garcia-Suarez wrote​:

I believe your Internals​::untaintfh patch can go in. Do other
porters
have strong objections ?

Is it really unavoidable?
Why can't this go in IO?

Do you mind if I go ahead and apply this? I?m sure that if you are
sufficiently dissatisfied with it, you will change it. :-)

Anyway, this is the most efficient solution. I would not want to risk
breaking SelfLoader.

I have no strong objection, except that probably Internals​::untaintfh
should be added in a separate patch. Also the place of the new test is
wrong, it should go in dist/SelftLoader/t with the other tests. I
notice as well that the prototype for untaintfh should be "*;$"
instead of "*$".

Then of course we have the bikeshed issue of "no more Internals​::
functions"... but there's not general purpose taint-related utility
module in the core.

Yes, but equally well it could be an IO function. And we *do* have an IO
utility module, in dist/

I believe that it should go in IO.
And no-one has made any coherent argument *against* that.

Nicholas Clark

@p5pRT
Copy link
Author

p5pRT commented Oct 13, 2010

From lubo.rintel@gooddata.com

On Mon Sep 27 03​:15​:59 2010, nicholas wrote​:

On Mon, Sep 27, 2010 at 12​:11​:15PM +0200, Rafael Garcia-Suarez wrote​:

On 27 September 2010 02​:14, Father Chrysostomos via RT
<perlbug-followup@​perl.org> wrote​:

On Mon Apr 26 05​:44​:37 2010, nicholas wrote​:

On Mon, Apr 26, 2010 at 02​:42​:27PM +0200, Rafael Garcia-Suarez wrote​:

I believe your Internals​::untaintfh patch can go in. Do other
porters
have strong objections ?

Is it really unavoidable?
Why can't this go in IO?

Do you mind if I go ahead and apply this? I?m sure that if you are
sufficiently dissatisfied with it, you will change it. :-)

Anyway, this is the most efficient solution. I would not want to risk
breaking SelfLoader.

I have no strong objection, except that probably Internals​::untaintfh
should be added in a separate patch. Also the place of the new test is
wrong, it should go in dist/SelftLoader/t with the other tests. I
notice as well that the prototype for untaintfh should be "*;$"
instead of "*$".

Then of course we have the bikeshed issue of "no more Internals​::
functions"... but there's not general purpose taint-related utility
module in the core.

Yes, but equally well it could be an IO function. And we *do* have an IO
utility module, in dist/

I believe that it should go in IO.
And no-one has made any coherent argument *against* that.

Would appropriate fix involving IO be any different from the first patch
I posted here?

http​://rt.perl.org/rt3/Ticket/Display.html?id=72062#txn-649184

@p5pRT
Copy link
Author

p5pRT commented Oct 21, 2010

From @cpansprout

On Wed Oct 13 04​:36​:40 2010, lkundrak wrote​:

On Mon Sep 27 03​:15​:59 2010, nicholas wrote​:

On Mon, Sep 27, 2010 at 12​:11​:15PM +0200, Rafael Garcia-Suarez wrote​:

On 27 September 2010 02​:14, Father Chrysostomos via RT
<perlbug-followup@​perl.org> wrote​:

On Mon Apr 26 05​:44​:37 2010, nicholas wrote​:

On Mon, Apr 26, 2010 at 02​:42​:27PM +0200, Rafael Garcia-Suarez
wrote​:

I believe your Internals​::untaintfh patch can go in. Do other
porters
have strong objections ?

Is it really unavoidable?
Why can't this go in IO?

Do you mind if I go ahead and apply this? I?m sure that if you are
sufficiently dissatisfied with it, you will change it. :-)

Anyway, this is the most efficient solution. I would not want to
risk
breaking SelfLoader.

I have no strong objection, except that probably Internals​::untaintfh
should be added in a separate patch. Also the place of the new test is
wrong, it should go in dist/SelftLoader/t with the other tests. I
notice as well that the prototype for untaintfh should be "*;$"
instead of "*$".

Then of course we have the bikeshed issue of "no more Internals​::
functions"... but there's not general purpose taint-related utility
module in the core.

Yes, but equally well it could be an IO function. And we *do* have an IO
utility module, in dist/

I believe that it should go in IO.
And no-one has made any coherent argument *against* that.

Would appropriate fix involving IO be any different from the first patch
I posted here?

http​://rt.perl.org/rt3/Ticket/Display.html?id=72062#txn-649184

No. I have applied it as a3a44df. Thank
you.

@p5pRT
Copy link
Author

p5pRT commented Oct 21, 2010

@cpansprout - Status changed from 'open' to 'resolved'

@p5pRT p5pRT closed this as completed Oct 21, 2010
@p5pRT
Copy link
Author

p5pRT commented Oct 24, 2010

From @cpansprout

On Thu Oct 21 06​:00​:36 2010, sprout wrote​:

On Wed Oct 13 04​:36​:40 2010, lkundrak wrote​:

On Mon Sep 27 03​:15​:59 2010, nicholas wrote​:

On Mon, Sep 27, 2010 at 12​:11​:15PM +0200, Rafael Garcia-Suarez wrote​:

On 27 September 2010 02​:14, Father Chrysostomos via RT
<perlbug-followup@​perl.org> wrote​:

On Mon Apr 26 05​:44​:37 2010, nicholas wrote​:

On Mon, Apr 26, 2010 at 02​:42​:27PM +0200, Rafael Garcia-Suarez
wrote​:

I believe your Internals​::untaintfh patch can go in. Do other
porters
have strong objections ?

Is it really unavoidable?
Why can't this go in IO?

Do you mind if I go ahead and apply this? I?m sure that if you are
sufficiently dissatisfied with it, you will change it. :-)

Anyway, this is the most efficient solution. I would not want to
risk
breaking SelfLoader.

I have no strong objection, except that probably
Internals​::untaintfh
should be added in a separate patch. Also the place of the new
test is
wrong, it should go in dist/SelftLoader/t with the other tests. I
notice as well that the prototype for untaintfh should be "*;$"
instead of "*$".

Then of course we have the bikeshed issue of "no more Internals​::
functions"... but there's not general purpose taint-related utility
module in the core.

Yes, but equally well it could be an IO function. And we *do* have
an IO
utility module, in dist/

I believe that it should go in IO.
And no-one has made any coherent argument *against* that.

Would appropriate fix involving IO be any different from the first patch
I posted here?

http​://rt.perl.org/rt3/Ticket/Display.html?id=72062#txn-649184

No. I have applied it as a3a44df. Thank
you.

Could you provide a test case? The one included in your most recent
patch (the one that used the Internals​:: approach) passes for me even
without your patch applied.

@p5pRT
Copy link
Author

p5pRT commented Oct 28, 2010

From @cpansprout

On Sun Oct 24 13​:30​:35 2010, sprout wrote​:

On Thu Oct 21 06​:00​:36 2010, sprout wrote​:

On Wed Oct 13 04​:36​:40 2010, lkundrak wrote​:

Would appropriate fix involving IO be any different from the first
patch
I posted here?

http​://rt.perl.org/rt3/Ticket/Display.html?id=72062#txn-649184

No. I have applied it as a3a44df. Thank
you.

Could you provide a test case? The one included in your most recent
patch (the one that used the Internals​:: approach) passes for me even
without your patch applied.

I was wrong. I was piping the tests through STDIN, which was why they
passed. There were already tests almost identical to yours in
dist/SelfLoader/t/01SelfLoader.t, so I added another script to run that
one under taint mode (commit 3bd1fdf).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant