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

taint propagation regression, tests fail to spot this #6852

Closed
p5pRT opened this issue Oct 19, 2003 · 9 comments
Closed

taint propagation regression, tests fail to spot this #6852

p5pRT opened this issue Oct 19, 2003 · 9 comments

Comments

@p5pRT
Copy link

p5pRT commented Oct 19, 2003

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

Searchable as RT24248$

@p5pRT
Copy link
Author

p5pRT commented Oct 19, 2003

From @nwc10

Created by @nwc10

Tony Finch brought this problem to my attention

I consider this to be critical because we have

1​: A regression from 5.8.0 to 5.8.1
2​: Our regression tests completely fail to spot this
3​: Taint propagation seems to be broken in fairly fundamental ways.
  (How can $1 be tainted? How can a copy of $1 fail to get that taint?)

Consider these 4 variations of the same script untainting @​ARGV​:

0,2 match on $ARGV[0] directly, 1,3 match on a copy
0,1 interpolate $1 directly, 2,3 interpolate a copy

#!perl -T
{
  local $ENV{PATH} = "/bin";

  my $r = "foo";

  $ARGV[0] =~ /($r)/;

  my $c = "echo $1";
  system $c;
}
__END__
#!perl -T
{
  local $ENV{PATH} = "/bin";

  my $r = "foo";

  my $argv = $ARGV[0];
  $argv =~ /($r)/;

  my $c = "echo $1";
  system $c;
}
__END__
#!perl -T
{
  local $ENV{PATH} = "/bin";

  my $r = "foo";

  $ARGV[0] =~ /($r)/;

  my $l = $1;
  my $c = "echo $l";
  system $c;
}
__END__
#!perl -T
{
  local $ENV{PATH} = "/bin";

  my $r = "foo";

  my $argv = $ARGV[0];
  $argv =~ /($r)/;

  my $l = $1;
  my $c = "echo $l";
  system $c;
}
__END__

All 4 are semantically equivalent, yet​:

$ perl5.8.0 -T t/taint0 foo
Insecure dependency in system while running with -T switch at t/taint0 line 10.
$ perl5.8.0 -T t/taint1 foo
foo
$ perl5.8.0 -T t/taint2 foo
foo
$ perl5.8.0 -T t/taint3 foo
foo

$ perl5.8.1 -T t/taint0 foo
Insecure dependency in system while running with -T switch at t/taint0 line 10.
$ perl5.8.1 -T t/taint1 foo
foo
$ perl5.8.1 -T t/taint2 foo
Insecure dependency in system while running with -T switch at t/taint2 line 11.
$ perl5.8.1 -T t/taint3 foo
foo

Hence there is a regression from 5.8.0 to 5.8.1 for taint2

It seems that

1​: taint is not being picked up by the regexp engine when matching on a copy
  of $ARGV[0] (pre 5.8.0 bug)
2​: taint is being wrongly propagated into a copy of $1 (new 5.8.1 bug)
  but isn't in $1 itself
3​: we seem to have no regression tests dealing with this class of bugs

The interpolation into the regexp seems to be crucial here. Tony's original
interpolation was of a qr// regexp, but it seems that a plain string will
do.

(5.8.1 I tested with is release 5.8.1 - bug still present in today's maint)

Nicholas Clark

Perl Info

Flags:
    category=core
    severity=critical

Site configuration information for perl v5.8.1:

Configured by nick at Sun Oct 19 13:42:04 BST 2003.

Summary of my perl5 (revision 5.0 version 8 subversion 1) configuration:
  Platform:
    osname=linux, osvers=2.4.20, archname=i686-linux
    uname='linux penfold.unixbeard.net 2.4.20 #1 sat apr 5 03:15:50 bst 2003 i686 gnulinux '
    config_args='-Dusedevel=y -Dcc=ccache gcc -Dld=gcc -Ubincompat5005 -Uinstallusrbinperl -Dcf_email=nick@ccl4.org -Dperladmin=nick@ccl4.org -Dinc_version_list=  -Dinc_version_list_init=0 -Doptimize=-O3 -Dusethreads=n -Accccflags=-DPERL_COPY_ON_WRITE -Dinstallman1dir=none -Dinstallman3dir=none -Duseperlio -Dprefix=/usr/local/perl5.8.2-snap21489 -de'
    hint=recommended, useposix=true, d_sigaction=define
    usethreads=undef use5005threads=undef useithreads=undef usemultiplicity=undef
    useperlio=define d_sfio=undef uselargefiles=define usesocks=undef
    use64bitint=undef use64bitall=undef uselongdouble=undef
    usemymalloc=n, bincompat5005=undef
  Compiler:
    cc='ccache gcc', ccflags ='-fno-strict-aliasing -I/usr/local/include -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64',
    optimize='-O3',
    cppflags='-fno-strict-aliasing -I/usr/local/include'
    ccversion='', gccversion='3.3.2 20031005 (Debian prerelease)', gccosandvers=''
    intsize=4, longsize=4, ptrsize=4, doublesize=8, byteorder=1234
    d_longlong=define, longlongsize=8, d_longdbl=define, longdblsize=12
    ivtype='long', ivsize=4, nvtype='double', nvsize=8, Off_t='off_t', lseeksize=8
    alignbytes=4, prototype=define
  Linker and Libraries:
    ld='gcc', ldflags =' -L/usr/local/lib'
    libpth=/usr/local/lib /lib /usr/lib
    libs=-lnsl -ldb -ldl -lm -lcrypt -lutil -lc
    perllibs=-lnsl -ldl -lm -lcrypt -lutil -lc
    libc=/lib/libc-2.3.2.so, so=so, useshrplib=false, libperl=libperl.a
    gnulibc_version='2.3.2'
  Dynamic Linking:
    dlsrc=dl_dlopen.xs, dlext=so, d_dlsymun=undef, ccdlflags='-rdynamic'
    cccdlflags='-fpic', lddlflags='-shared -L/usr/local/lib'

Locally applied patches:
    MAINT21379


@INC for perl v5.8.1:
    lib
    /usr/local/perl5.8.2-snap21489/lib/5.8.1/i686-linux
    /usr/local/perl5.8.2-snap21489/lib/5.8.1
    /usr/local/perl5.8.2-snap21489/lib/site_perl/5.8.1/i686-linux
    /usr/local/perl5.8.2-snap21489/lib/site_perl/5.8.1
    /usr/local/perl5.8.2-snap21489/lib/site_perl
    .


Environment for perl v5.8.1:
    HOME=/home/nick
    LANG=C
    LANGUAGE (unset)
    LD_LIBRARY_PATH (unset)
    LOGDIR (unset)
    PATH=/home/nick/bin:/usr/local/bin:/bin:/usr/bin:/usr/X11/bin:/usr/contrib/bin:/usr/games:/usr/sbin:/usr/ucb:/sbin:/usr/etc:/data3/src/emacs/bin/i386-unknown-bsdi2.1/
    PERL_BADLANG (unset)
    SHELL=/bin/bash

@p5pRT
Copy link
Author

p5pRT commented Oct 22, 2003

From rick@bort.ca

On Sun, Oct 19, 2003 at 02​:44​:20PM -0000, Nicholas Clark wrote​:

I consider this to be critical because we have

1​: A regression from 5.8.0 to 5.8.1
2​: Our regression tests completely fail to spot this
3​: Taint propagation seems to be broken in fairly fundamental ways.

Yes, indeed.

(How can $1 be tainted? How can a copy of $1 fail to get that taint?)

Consider these 4 variations of the same script untainting @​ARGV​:

0,2 match on $ARGV[0] directly, 1,3 match on a copy
0,1 interpolate $1 directly, 2,3 interpolate a copy

#!perl -T
{
local $ENV{PATH} = "/bin";

my $r = "foo";

$ARGV[0] =~ /($r)/;

my $c = "echo $1";
system $c;
}
__END__

More variations (5.8.0, assuming script named "foo")​:

#!perl -T
{
  local $ENV{PATH} = "/bin";
  my $r = "foo";
  $0 =~ /($r)/;

  my $c = "echo $1";
  system $c;
}
__END__
foo

{
local $ENV{PATH} = "/bin";

my $r = "foo";

my $argv = $ARGV[0];
$argv =~ /($r)/;

my $c = "echo $1";
system $c;
}
__END__

#!perl -T
{
  local $ENV{PATH} = "/bin";
  my $r = "foo";
  my @​argv = @​ARGV;
  $argv[0] =~ /($r)/;

  my $c = "echo $1";
  system $c;
}
__END__
Insecure dependency in system while running with -T switch at ./foo line 9.

#!perl -T
{
  local $ENV{PATH} = "/bin";
  my $r = "foo";
  ($a = $0) =~ /($r)/;

  my $c = "echo $1";
  system $c;
}
__END__
Insecure dependency in system while running with -T switch at ./foo line 8.

It appears that any expression more complicated than a simple scalar
variable is wrongly propagating its taint into the regexp. I don't know
if it's intended that a tainted regexp should taint $1 without
'use re "taint"' (I think that's reasonable) but that's another issue.

--
Rick Delaney
rick@​bort.ca

@p5pRT
Copy link
Author

p5pRT commented Oct 25, 2003

From rick@bort.ca

On Wed, Oct 22, 2003 at 12​:49​:07AM -0400, Rick Delaney wrote​:

On Sun, Oct 19, 2003 at 02​:44​:20PM -0000, Nicholas Clark wrote​:

I consider this to be critical because we have

1​: A regression from 5.8.0 to 5.8.1
2​: Our regression tests completely fail to spot this
3​: Taint propagation seems to be broken in fairly fundamental ways.

Yes, indeed.

[snip]

It appears that any expression more complicated than a simple scalar
variable is wrongly propagating its taint into the regexp. I don't know
if it's intended that a tainted regexp should taint $1 without
'use re "taint"' (I think that's reasonable) but that's another issue.

I've poked through the source a bit with a ten-foot pole and started
writing regression tests (TODO) for all the bugs I'm finding there but
there's a class of bugs I'm not sure are bugs at all. perlsec says​:

  sub is_tainted {
  return ! eval { eval("#" . substr(join("", @​_), 0, 0)); 1 };
  }

  This function makes use of the fact that the presence of tainted data
  anywhere within an expression renders the entire expression tainted. It
  would be inefficient for every operator to test every argument for
  taintedness. Instead, the slightly more efficient and conservative
  approach is used that if any tainted value has been accessed within the
  same expression, the whole expression is considered tainted.

What that really means is that if PL_tainted is set by some operation in
an expression then other parts may act as if tainted. What it doesn't
say is that some operators may cavalierly call TAINT_NOT, rendering
the expression untainted in some cases. Or that in some cases
PL_tainted will not be set. So for example​:

  $0, kill 0; # kill succeeds (PL_tainted never set)
  "".$0, kill 0; # dies​: Insecure dependency in kill
  "".$0, /1/, kill 0; # kill succeeds (pp_match calls TAINT_NOT)
  "".$0, $a = 1, kill 0; # kill succeeds (pp_sassign calls TAINT_NOT)

My question is, "Is this behaviour acceptable?" Should operators reset
PL_tainted so that in examples like this the kill always bails? There
is no security risk here that I can see but maybe it's important to
adhere to the semantic of "the presence of tainted data anywhere within
an expression renders the entire expression tainted".

--
Rick Delaney
rick@​bort.ca

@p5pRT
Copy link
Author

p5pRT commented Nov 6, 2003

From rick@bort.ca

While waiting for opinions on my questions I've formed my own opinions.
Patch and comments below.

On Sun, Oct 19, 2003 at 02​:44​:20PM -0000, Nicholas Clark wrote​:

Consider these 4 variations of the same script untainting @​ARGV​:

0,2 match on $ARGV[0] directly, 1,3 match on a copy
0,1 interpolate $1 directly, 2,3 interpolate a copy

#!perl -T
{
local $ENV{PATH} = "/bin";

my $r = "foo";

$ARGV[0] =~ /($r)/;

my $c = "echo $1";
system $c;
}
__END__
#!perl -T
{
local $ENV{PATH} = "/bin";

my $r = "foo";

my $argv = $ARGV[0];
$argv =~ /($r)/;

my $c = "echo $1";
system $c;
}
__END__
#!perl -T
{
local $ENV{PATH} = "/bin";

my $r = "foo";

$ARGV[0] =~ /($r)/;

my $l = $1;
my $c = "echo $l";
system $c;
}
__END__
#!perl -T
{
local $ENV{PATH} = "/bin";

my $r = "foo";

my $argv = $ARGV[0];
$argv =~ /($r)/;

my $l = $1;
my $c = "echo $l";
system $c;
}
__END__

All 4 are semantically equivalent, yet​:

$ perl5.8.0 -T t/taint0 foo
Insecure dependency in system while running with -T switch at t/taint0 line 10.
$ perl5.8.0 -T t/taint1 foo
foo
$ perl5.8.0 -T t/taint2 foo
foo
$ perl5.8.0 -T t/taint3 foo
foo

$ perl5.8.1 -T t/taint0 foo
Insecure dependency in system while running with -T switch at t/taint0 line 10.
$ perl5.8.1 -T t/taint1 foo
foo
$ perl5.8.1 -T t/taint2 foo
Insecure dependency in system while running with -T switch at t/taint2 line 11.
$ perl5.8.1 -T t/taint3 foo
foo

Hence there is a regression from 5.8.0 to 5.8.1 for taint2

It seems that

1​: taint is not being picked up by the regexp engine when matching on a copy
of $ARGV[0] (pre 5.8.0 bug)

PL_tainted is being set to true in an expression more complicated than a
simple scalar variable (gvsv) which results in a tainted regexp. This
bug is in both 5.8.0 and 5.8.1.

2​: taint is being wrongly propagated into a copy of $1 (new 5.8.1 bug)
but isn't in $1 itself

I don't see this in the examples. 5.8.0 appears to be losing the taint
on the copy of $1. Both the original and copy are tainted "properly" in
5.8.1, given the bug in #1. I think the fix for bug 20020704.001 would
be the cause of the difference.

  http​://www.xray.mpe.mpg.de/mailing-lists/perl5-porters/2002-08/msg00204.html

3​: we seem to have no regression tests dealing with this class of bugs

Rectified in below patch which also makes all of the above examples
print "foo".

Note 1​: pp_regcmaybe possibly needs the same change but since I don't
know what it's for I'm not sure.

Note 2​: If we were to add these tests​:

  test 221, !eval { "x".$TAINT, $notaint =~ /(1)/, kill 0; 1 };
  test 222, !eval { "x".$TAINT, $notaint =~ /($notaint)/, kill 0; 1 };
  test 223, !eval { "x".$TAINT, $notaint =~ s/(1)/1/, kill 0; 1 };
  test 224, !eval { "x".$TAINT, $notaint =~ s/($notaint)/1/, kill 0; 1 };

they would all fail after my patch while only 221 and 223 fail before my
patch. This does not mean the patch is wrong; the only reason 222 and
224 pass pre-patch is because the regexp is wrongly tainted. My
interpretation of perlsec is NOT that these tests SHOULD all pass (i.e.
the kill should bail with an "Insecure dependency") but rather that
there is no guarantee that the kill will succeed if it is in a larger
expression that contains tainted data, even when the args to kill are
untainted. So the above tests should not be included and the patch
below is sufficient, IMO.

--
Rick Delaney
rick@​bort.ca

Inline Patch
--- t/op/taint.t.orig	Wed Nov  5 14:53:48 2003
+++ t/op/taint.t	Wed Nov  5 16:55:43 2003
@@ -124,7 +124,7 @@
 
 my $TEST = catfile(curdir(), 'TEST');
 
-print "1..208\n";
+print "1..220\n";
 
 # First, let's make sure that Perl is checking the dangerous
 # environment variables. Maybe they aren't set yet, so we'll
@@ -993,3 +993,35 @@
     eval { system("lskdfj"); };
     test 208, $@ =~ /^%ENV is aliased to %nonmagicalenv while running with -T switch/;
 }
+{
+    # [perl #24248]
+    $TAINT =~ /(.*)/;
+    test 209, !tainted($1);
+    my $notaint = $1;
+    test 210, !tainted($notaint);
+
+    my $l;
+    $notaint =~ /($notaint)/;
+    $l = $1;
+    test 211, !tainted($1);
+    test 212, !tainted($l);
+    $notaint =~ /($TAINT)/;
+    $l = $1;
+    test 213, tainted($1);
+    test 214, tainted($l);
+
+    $TAINT =~ /($notaint)/;
+    $l = $1;
+    test 215, !tainted($1);
+    test 216, !tainted($l);
+    $TAINT =~ /($TAINT)/;
+    $l = $1;
+    test 217, tainted($1);
+    test 218, tainted($l);
+
+    my $r;
+    ($r = $TAINT) =~ /($notaint)/;
+    test 219, !tainted($1);
+    ($r = $TAINT) =~ /($TAINT)/;
+    test 220, tainted($1);
+}
--- pp_ctl.c.orig	Wed Nov  5 14:46:59 2003
+++ pp_ctl.c	Wed Nov  5 16:49:23 2003
@@ -59,6 +59,7 @@
     /* XXXX Should store the old value to allow for tie/overload - and
        restore in regcomp, where marked with XXXX. */
     PL_reginterp_cnt = 0;
+    TAINT_NOT;
     return NORMAL;
 }
 

@p5pRT
Copy link
Author

p5pRT commented Nov 6, 2003

From ams@wiw.org

At 2003-11-05 23​:02​:41 -0500, rick@​bort.ca wrote​:

While waiting for opinions on my questions I've formed my own opinions.
Patch and comments below.

That's a nice kind of opinion.
Thanks, applied. (#21674)

-- ams

@p5pRT
Copy link
Author

p5pRT commented Nov 7, 2003

From @hvds

Rick Delaney <rick@​bort.ca> wrote​:
:While waiting for opinions on my questions I've formed my own opinions.
[...]
:Note 2​: If we were to add these tests​:
:
: test 221, !eval { "x".$TAINT, $notaint =~ /(1)/, kill 0; 1 };
: test 222, !eval { "x".$TAINT, $notaint =~ /($notaint)/, kill 0; 1 };
: test 223, !eval { "x".$TAINT, $notaint =~ s/(1)/1/, kill 0; 1 };
: test 224, !eval { "x".$TAINT, $notaint =~ s/($notaint)/1/, kill 0; 1 };
:
:they would all fail after my patch while only 221 and 223 fail before my
:patch. This does not mean the patch is wrong; the only reason 222 and
:224 pass pre-patch is because the regexp is wrongly tainted. My
:interpretation of perlsec is NOT that these tests SHOULD all pass (i.e.
:the kill should bail with an "Insecure dependency") but rather that
:there is no guarantee that the kill will succeed if it is in a larger
:expression that contains tainted data, even when the args to kill are
:untainted. So the above tests should not be included and the patch
:below is sufficient, IMO.

I didn't fully understand that, and it made me worry that something
like this​:
  $should_taint = ("x".$TAINT, $notaint =~ /($notaint)/)[0];
would result in an untainted $should_taint, but trying it I find
that it doesn't.

Are we talking only about whether complexity of expressions _preceding_
that pattern match will cause taintedness to propagate into otherwise
untainted values _following_ the pattern match? If so, I think that is
fine​: tainting safe values in complex expressions is something I believe
we do only for simplicity of implementation, not because it makes
anything more secure, and I don't think it should be a problem if we
reduce the number of situations in which safe values get marked tainted.

Hugo

@p5pRT
Copy link
Author

p5pRT commented Nov 7, 2003

From rick@bort.ca

On Fri, Nov 07, 2003 at 04​:30​:33PM +0000, hv@​crypt.org wrote​:

Rick Delaney <rick@​bort.ca> wrote​:
:While waiting for opinions on my questions I've formed my own opinions.
[...]
:Note 2​: If we were to add these tests​:
:
: test 221, !eval { "x".$TAINT, $notaint =~ /(1)/, kill 0; 1 };
: test 222, !eval { "x".$TAINT, $notaint =~ /($notaint)/, kill 0; 1 };
: test 223, !eval { "x".$TAINT, $notaint =~ s/(1)/1/, kill 0; 1 };
: test 224, !eval { "x".$TAINT, $notaint =~ s/($notaint)/1/, kill 0; 1 };
:
:they would all fail after my patch while only 221 and 223 fail before my
:patch. This does not mean the patch is wrong; the only reason 222 and
:224 pass pre-patch is because the regexp is wrongly tainted. My
:interpretation of perlsec is NOT that these tests SHOULD all pass (i.e.
:the kill should bail with an "Insecure dependency") but rather that
:there is no guarantee that the kill will succeed if it is in a larger
:expression that contains tainted data, even when the args to kill are
:untainted. So the above tests should not be included and the patch
:below is sufficient, IMO.

I didn't fully understand that, and it made me worry that something
like this​:
$should_taint = ("x".$TAINT, $notaint =~ /($notaint)/)[0];
would result in an untainted $should_taint, but trying it I find
that it doesn't.

Are we talking only about whether complexity of expressions _preceding_
that pattern match will cause taintedness to propagate into otherwise
untainted values _following_ the pattern match? If so, I think that is

Yes.

fine​: tainting safe values in complex expressions is something I believe
we do only for simplicity of implementation, not because it makes
anything more secure, and I don't think it should be a problem if we
reduce the number of situations in which safe values get marked tainted.

That was the conclusion I came to as well. I brought it up in case
others didn't share my opinion and felt that perlsec guaranteed that
"tainted data anywhere within an expression renders the entire expression
tainted". Thanks for sharing your opinion.

--
Rick Delaney
rick@​bort.ca

@p5pRT
Copy link
Author

p5pRT commented Nov 15, 2008

From @smpeters

On Sun Oct 19 07​:44​:18 2003, nicholas wrote​:

This is a bug report for perl from nick@​ccl4.org,
generated with the help of perlbug 1.34 running under perl v5.8.1.

-----------------------------------------------------------------
[Please enter your report here]

Tony Finch brought this problem to my attention

I consider this to be critical because we have

1​: A regression from 5.8.0 to 5.8.1
2​: Our regression tests completely fail to spot this
3​: Taint propagation seems to be broken in fairly fundamental ways.
(How can $1 be tainted? How can a copy of $1 fail to get that
taint?)

Consider these 4 variations of the same script untainting @​ARGV​:

0,2 match on $ARGV[0] directly, 1,3 match on a copy
0,1 interpolate $1 directly, 2,3 interpolate a copy

#!perl -T
{
local $ENV{PATH} = "/bin";

my $r = "foo";

$ARGV[0] =~ /($r)/;

my $c = "echo $1";
system $c;
}
__END__
#!perl -T
{
local $ENV{PATH} = "/bin";

my $r = "foo";

my $argv = $ARGV[0];
$argv =~ /($r)/;

my $c = "echo $1";
system $c;
}
__END__
#!perl -T
{
local $ENV{PATH} = "/bin";

my $r = "foo";

$ARGV[0] =~ /($r)/;

my $l = $1;
my $c = "echo $l";
system $c;
}
__END__
#!perl -T
{
local $ENV{PATH} = "/bin";

my $r = "foo";

my $argv = $ARGV[0];
$argv =~ /($r)/;

my $l = $1;
my $c = "echo $l";
system $c;
}
__END__

All 4 are semantically equivalent, yet​:

$ perl5.8.0 -T t/taint0 foo
Insecure dependency in system while running with -T switch at t/taint0
line 10.
$ perl5.8.0 -T t/taint1 foo
foo
$ perl5.8.0 -T t/taint2 foo
foo
$ perl5.8.0 -T t/taint3 foo
foo

$ perl5.8.1 -T t/taint0 foo
Insecure dependency in system while running with -T switch at t/taint0
line 10.
$ perl5.8.1 -T t/taint1 foo
foo
$ perl5.8.1 -T t/taint2 foo
Insecure dependency in system while running with -T switch at t/taint2
line 11.
$ perl5.8.1 -T t/taint3 foo
foo

Hence there is a regression from 5.8.0 to 5.8.1 for taint2

It seems that

1​: taint is not being picked up by the regexp engine when matching on
a copy
of $ARGV[0] (pre 5.8.0 bug)
2​: taint is being wrongly propagated into a copy of $1 (new 5.8.1 bug)
but isn't in $1 itself
3​: we seem to have no regression tests dealing with this class of bugs

The interpolation into the regexp seems to be crucial here. Tony's
original
interpolation was of a qr// regexp, but it seems that a plain string
will
do.

(5.8.1 I tested with is release 5.8.1 - bug still present in today's
maint)

Nicholas Clark

We did have a nice patch (change #21674) that seemed to resolve this problem. Or didn't it.
If so, let me know and I'll resolve this bug.

Steve

@p5pRT
Copy link
Author

p5pRT commented Nov 27, 2008

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

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