Skip Menu |

This queue is for tickets about the Compress-Bzip2 CPAN distribution.

Report information
The Basics
Id: 132711
Status: resolved
Priority: 0/
Queue: Compress-Bzip2

People
Owner: RURBAN [...] cpan.org
Requestors: ppisar [...] redhat.com
Cc:
AdminCc:

Bug Information
Severity: (no value)
Broken in: 2.26
Fixed in: (no value)



Subject: A NULL pointer derefernce in bzfile_clearerr()
bzfile_clearerr() function is written like this: int bzfile_clearerr( bzFile *obj ) { int error_num = obj == NULL ? global_bzip_errno : obj->bzip_errno; ... else if ( error_num == BZ_OK ) { if ( obj->pending_io_error ) { ... If obj is NULL and global_bzip_errno is BZ_OK then the "obj->pending_io_error" expression experiences a NULL pointer dereference. I know that bzfile_clearerr() is called only from Compress::Bzip2::bzclearerr() method, so the object reference should not NULL, but still bzfile_clearerr() starts with a code that clearly compares the reference against NULL. So there is a little discrepancy. Also one should consider that bzfile_clearerr() is not declared as a static function, and thus any C (XS) code can call it.
When attempting to reproduce it from Perl, I noticed that DESTROY suffers from a similar issue leading to crash: $ gdb --args perl -Iblib/{arch,lib} -MCompress::Bzip2 -e '$a=undef; bless \$a, q{Compress::Bzip2}; $a->bzclearerr; print qq{Ok.\n}' [...] (gdb) run Starting program: /usr/bin/perl -Iblib/arch -Iblib/lib -MCompress::Bzip2 -e \$a=undef\;\ bless\ \\\$a,\ q\{Compress::Bzip2\}\;\ \$a-\>bzclearerr\;\ print\ qq\{Ok.\\n\} [Thread debugging using libthread_db enabled] Using host libthread_db library "/lib64/libthread_db.so.1". Can't call method "bzclearerr" on an undefined value at -e line 1. Program received signal SIGSEGV, Segmentation fault. XS_Compress__Bzip2_DESTROY (my_perl=<optimized out>, cv=0x555555795308) at Bzip2.xs:1714 1714 if (obj->verbosity>=1) It seems that a destructor is exempted from the sanity check in perl's method resolver that safes from entering MY_bzclearerr(), but it enters DESTROY().
Dne Út 26.Květen.2020 07:58:05, ppisar napsal(a): Show quoted text
> bzfile_clearerr() function is written like this: > > int bzfile_clearerr( bzFile *obj ) { > int error_num = obj == NULL ? global_bzip_errno : obj->bzip_errno; > ... > > else if ( error_num == BZ_OK ) { > if ( obj->pending_io_error ) { > ... > > If obj is NULL and global_bzip_errno is BZ_OK then the "obj-
> >pending_io_error" expression experiences a NULL pointer dereference.
>
A similar flaw exists in the same function sooner in (error_num == BZ_IO_ERROR) branch: if ( error_num == BZ_IO_ERROR ) { PerlIO_clearerr( obj->handle ); }
yeah, and a couple more. Fixing it.
On Tue May 26 09:46:52 2020, RURBAN wrote: Show quoted text
> yeah, and a couple more. > Fixing it.
https://github.com/rurban/Compress-Bzip2/pull/new/nullderef -- Reini Urban
Dne Út 26.Květen.2020 09:49:49, RURBAN napsal(a): Show quoted text
> On Tue May 26 09:46:52 2020, RURBAN wrote:
> > yeah, and a couple more. > > Fixing it.
> > https://github.com/rurban/Compress-Bzip2/pull/new/nullderef >
Thanks. All tests pass on my side. And I confirm the crash was fixed.
Fixed with 2.27