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

Core dump with obfuscated code #346

Closed
p5pRT opened this issue Aug 6, 1999 · 9 comments
Closed

Core dump with obfuscated code #346

p5pRT opened this issue Aug 6, 1999 · 9 comments

Comments

@p5pRT
Copy link
Collaborator

@p5pRT p5pRT commented Aug 6, 1999

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

Searchable as RT1179$

@p5pRT
Copy link
Collaborator Author

@p5pRT p5pRT commented Aug 6, 1999

From mgomes@cwix.com

This is some sort of RSA codec I picked up somewhere, don't ask me how it
works. If I run it as below, it dumps core. I know it's being run wrong
here, but it still shouldn't die like this. Perl should be able to compile
/dev/urandom, right?

$ perl rsa.pl
any text here.
^D
Segmentation fault (core dumped)

@p5pRT
Copy link
Collaborator Author

@p5pRT p5pRT commented Aug 6, 1999

From [Unknown Contact. See original ticket]

Brian Keefer writes​:

This is some sort of RSA codec I picked up somewhere, don't ask me how it
works. If I run it as below, it dumps core. I know it's being run wrong
here, but it still shouldn't die like this. Perl should be able to compile
/dev/urandom, right?

Perl compiles the code just fine, the problem is in executing. In
particular, at this point​:

  $m=unpack(H.$w,$m."\0"x$w);

$w is set to a very large number, equal to -2 as a signed 32-bit
integer. This makes unpack do very weird things, because it stores
the count in an I32.

Here's a patch to Perl to catch such things. It adds another error,
so there's also a patch to perldiag.

Nat

*** pp.c~ Mon Aug 2 14​:25​:07 1999
--- pp.c Thu Aug 5 22​:58​:45 1999
***************
*** 3355,3360 ****
--- 3355,3362 ----
  }
  else
  len = (datumtype != '@​');
+ if (len < 0)
+ Perl_croak(aTHX_ "Repeat count in unpack overflows");
  switch(datumtype) {
  default​:
  Perl_croak(aTHX_ "Invalid type in unpack​: '%c'", (int)datumtype);
***************
*** 4404,4409 ****
--- 4406,4413 ----
  len = *pat++ - '0';
  while (isDIGIT(*pat))
  len = (len * 10) + (*pat++ - '0');
+ if (len < 0)
+ Perl_croak(aTHX_ "Repeat count in pack overflows");
  }
  else
  len = 1;
*** pod/perldiag.pod~ Thu Aug 5 23​:00​:59 1999
--- pod/perldiag.pod Thu Aug 5 22​:59​:29 1999
***************
*** 90,95 ****
--- 90,105 ----
  checksumming process loses information, and you can't go the other
  way. See L<perlfunc/unpack>.
 
+ =item Repeat count in unpack overflows
+
+ (F) You can't specify a repeat count so large that it overflows a
+ signed 32-bit integer. See L<perlfunc/unpack>.
+
+ =item Repeat count in pack overflows
+
+ (F) You can't specify a repeat count so large that it overflows a
+ signed 32-bit integer. See L<perlfunc/pack>.
+
  =item /%s/​: Unrecognized escape \\%c passed through
 
  (W) You used a backslash-character combination which is not recognized

@p5pRT
Copy link
Collaborator Author

@p5pRT p5pRT commented Aug 6, 1999

From [Unknown Contact. See original ticket]

It looks from here like your perl is built without -DDEBUGGING in
ccflags and/or *with* -Dusemymalloc. If you'd submitted your
report with perlbug, we'd know for sure. However, my copies
mostly give "panic​: realloc at rsa.pl line 2" or "Out of
memory!".

This isn't too surprising, since that code (after fixing up the
gratuitous line-wrapping it had suffered by the time it arrived
here) wants to read from STDIN in blocks of a size derived from
@​ARGV. You gave it no arguments, and it wound up using 2GB as
the size of block. This obligated perl to try to realloc the
space for the $m variable to allow that big of a read. This
failed. In your case, that lead quickly to an attempt to
reference a presumed allocation for $m which wasn't there. Given
what I've seen before when this happens, it appears to be a lack
of suitable error-checking in perl's malloc. My good test
machine is at work, so this is as far as I'm going tonight.

--
Spider Boardman (at home) spider@​Orb.Nashua.NH.US
The management (my cats) made me say this. http​://www.ultranet.com/~spiderb
PGP public key fingerprint​: 96 72 D2 C6 E0 92 32 89 F6 B2 C2 A0 1C AB 1F DC

@p5pRT
Copy link
Collaborator Author

@p5pRT p5pRT commented Aug 6, 1999

From [Unknown Contact. See original ticket]

On Thu, 5 Aug 1999 23​:01​:51 -0600 (MDT), Nathan Torkington wrote (in part)​:

Nat> Perl compiles the code just fine, the problem is in
Nat> executing. In particular, at this point​:

Nat> $m=unpack(H.$w,$m."\0"x$w);

Nat> $w is set to a very large number, equal to -2 as a signed
Nat> 32-bit integer. This makes unpack do very weird things,
Nat> because it stores the count in an I32.

That's funny--my tests never got to the unpack. They crapped out with
the

  read(STDIN,$m,($w=2*$d-1+length($n)&~1)/2)

which attempted a read of C<2147483647> bytes. I guess it must
matter whether you're on a 64-bit machine. ;=}

($w was indeed set to C<4294967294>, which is C<-2> when stored in an I32.)

@p5pRT
Copy link
Collaborator Author

@p5pRT p5pRT commented Aug 6, 1999

From [Unknown Contact. See original ticket]

Nathan Torkington <gnat@​frii.com> wrote

+ (F) You can't specify a repeat count so large that it overflows a
+ signed 32-bit integer. See L<perlfunc/unpack>.

Good patch, but delete that "32-bit" (in two places). Not all
platforms are 32 bit.

Mike Guy

@p5pRT
Copy link
Collaborator Author

@p5pRT p5pRT commented Aug 6, 1999

From @jhi

M.J.T. Guy writes​:

Nathan Torkington <gnat@​frii.com> wrote

+ (F) You can't specify a repeat count so large that it overflows a
+ signed 32-bit integer. See L<perlfunc/unpack>.

Good patch, but delete that "32-bit" (in two places). Not all
platforms are 32 bit.

I did that deletion when I applied the patch.

--
$jhi++; # http​://www.iki.fi/jhi/
  # There is this special biologist word we use for 'stable'.
  # It is 'dead'. -- Jack Cohen

@p5pRT
Copy link
Collaborator Author

@p5pRT p5pRT commented Aug 6, 1999

From [Unknown Contact. See original ticket]

M.J.T. Guy writes​:

Good patch, but delete that "32-bit" (in two places). Not all
platforms are 32 bit.

So because len is an I32 doesn't mean that it's necessarily a 32-bit
integer value? Wow, that's a pretty impressive fakeout in the Perl
source :-)

Modified patch follows.

Nat

*** pp.c~ Mon Aug 2 14​:25​:07 1999
--- pp.c Thu Aug 5 22​:58​:45 1999
***************
*** 3355,3360 ****
--- 3355,3362 ----
  }
  else
  len = (datumtype != '@​');
+ if (len < 0)
+ Perl_croak(aTHX_ "Repeat count in unpack overflows");
  switch(datumtype) {
  default​:
  Perl_croak(aTHX_ "Invalid type in unpack​: '%c'", (int)datumtype);
***************
*** 4404,4409 ****
--- 4406,4413 ----
  len = *pat++ - '0';
  while (isDIGIT(*pat))
  len = (len * 10) + (*pat++ - '0');
+ if (len < 0)
+ Perl_croak(aTHX_ "Repeat count in pack overflows");
  }
  else
  len = 1;
*** pod/perldiag.pod~ Thu Aug 5 23​:00​:59 1999
--- pod/perldiag.pod Thu Aug 5 22​:59​:29 1999
***************
*** 90,95 ****
--- 90,105 ----
  checksumming process loses information, and you can't go the other
  way. See L<perlfunc/unpack>.
 
+ =item Repeat count in unpack overflows
+
+ (F) You can't specify a repeat count so large that it overflows a
+ signed integer. See L<perlfunc/unpack>.
+
+ =item Repeat count in pack overflows
+
+ (F) You can't specify a repeat count so large that it overflows a
+ signed integer. See L<perlfunc/pack>.
+
  =item /%s/​: Unrecognized escape \\%c passed through
 
  (W) You used a backslash-character combination which is not recognized

@p5pRT
Copy link
Collaborator Author

@p5pRT p5pRT commented Aug 6, 1999

From @doughera88

On Fri, 6 Aug 1999, Nathan Torkington wrote​:

So because len is an I32 doesn't mean that it's necessarily a 32-bit
integer value? Wow, that's a pretty impressive fakeout in the Perl
source :-)

Quoting myself in handy.h​:

/* XXX A note on the perl source internal type system. The
  original intent was that I32 be *exactly* 32 bits.

  Currently, we only guarantee that I32 is *at least* 32 bits.
  Specifically, if int is 64 bits, then so is I32. (This is the case
  for the Cray.) This has the advantage of meshing nicely with
  standard library calls (where we pass an I32 and the library is
  expecting an int), but the disadvantage that an I32 is not 32 bits.
  Andy Dougherty August 1996

  There is no guarantee that there is *any* integral type with
  exactly 32 bits. It is perfectly legal for a system to have
  sizeof(short) == sizeof(int) == sizeof(long) == 8.

  Similarly, there is no guarantee that I16 and U16 have exactly 16
  bits.

  Andy Dougherty doughera@​lafayette.edu
  Dept. of Physics
  Lafayette College, Easton PA 18042

@p5pRT
Copy link
Collaborator Author

@p5pRT p5pRT commented Aug 6, 1999

From @jhi

Nathan Torkington writes​:

M.J.T. Guy writes​:

Good patch, but delete that "32-bit" (in two places). Not all
platforms are 32 bit.

So because len is an I32 doesn't mean that it's necessarily a 32-bit
integer value?

Yes, that is the case.

--
$jhi++; # http​://www.iki.fi/jhi/
  # There is this special biologist word we use for 'stable'.
  # It is 'dead'. -- Jack Cohen

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

Successfully merging a pull request may close this issue.

None yet
1 participant
You can’t perform that action at this time.