Bug 185242 - ioctl default minimum argument length of 256 should be restored
ioctl default minimum argument length of 256 should be restored
Status: CLOSED CURRENTRELEASE
Product: Fedora
Classification: Fedora
Component: perl (Show other bugs)
4
All Linux
medium Severity medium
: ---
: ---
Assigned To: Jason Vas Dias
David Lawrence
http://rt.perl.org/rt3/Ticket/Display...
:
Depends On: 185240
Blocks:
  Show dependency treegraph
 
Reported: 2006-03-12 13:58 EST by Jason Vas Dias
Modified: 2007-11-30 17:11 EST (History)
4 users (show)

See Also:
Fixed In Version: FC5
Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of:
Environment:
Last Closed: 2006-09-21 22:19:48 EDT
Type: ---
Regression: ---
Mount Type: ---
Documentation: ---
CRM:
Verified Versions:
Category: ---
oVirt Team: ---
RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: ---


Attachments (Terms of Use)

  None (edit)
Description Jason Vas Dias 2006-03-12 13:58:56 EST
+++ This bug was initially created as a clone of Bug #185240 +++

Description of problem:
This is perl bug request ticket 38223 .

Owing to the fix for bug 171111, where the length bitfield of the ioctl 
number argument, which specifies the length of the optional RD ioctl output
third argument, was not being extracted correctly, and perl used 256 as the 
minimum length of the third argument in all cases, perl now does not ascribe 
any minimum length to the third argument unless the length bitfield is
specified.

This has the result that unless the length bitfield of the ioctl number is
specified, a third argument of a buffer with insufficient length for the
ioctl output will be overflowed, and perl will suffer a buffer overflow
and a potential memory access violation or memory corruption, 
as generated by the following code (from perlbug RT# 38223):

#!/usr/bin/perl
require 'sys/ioctl.ph';
die "no TIOCGWINSZ " unless defined &TIOCGWINSZ;
open(TTY, "+</dev/tty") or die "No tty: $!";
unless (ioctl(TTY, &TIOCGWINSZ, $winsize='')) {
die sprintf "$0: ioctl TIOCGWINSZ (%08x: $!)\n", &TIOCGWINSZ;
}
($row, $col, $xpixel, $ypixel) = unpack('S4', $winsize);
print "(row,col) = ($row,$col)";
print " (xpixel,ypixel) = ($xpixel,$ypixel)" if $xpixel || $ypixel;
print "\n";

Perl now correctly detects the buffer overflow:

Possible memory corruption: ioctl overflowed 3rd argument at ./bug38223.pl 
line 5.

This would not have occurred with perl versions before perl-5.8.6-18,
because the length of all the ioctl third output arguments was made a 
minimum of 256 bytes.

The overflow would not have occurred if the ioctl call had been :
  ioctl(TTY, &TIOCGWINSZ, $winsize='x'x16)
or 
  ioctl(TTY, &TIOCGWINSZ | (16 << &_IOC_SIZESHIFT), $winsize='')

The default size of 256 has been restored in the latest upstream patch for 
this issue:

==== //depot/perl/perl.h#657 (text) ====
Index: perl/perl.h
--- perl/perl.h.~1~ Fri Jan 13 04:10:49 2006
+++ perl/perl.h Fri Jan 13 04:10:49 2006
@@ -2977,8 +2977,8 @@
# define IOCPARM_LEN(x) (((x) >> 16) & \ # IOCPARM_MASK)
# else
# if defined(_IOC_SIZE) && defined(__GLIBC__)
- /* on Linux systems we're safe */
-# define IOCPARM_LEN(x) _IOC_SIZE(x)
+ /* on Linux systems we're safe; except when we're not [perl #38223] */
+# define IOCPARM_LEN(x) (_IOC_SIZE(x) < 256 ? 256 : \ _IOC_SIZE(x))
# else
/* otherwise guess at what's safe */
# define IOCPARM_LEN(x) 256
End of Patch.

Version-Release number of selected component (if applicable):
perl-5.8.6-22

How reproducible:
100%

Steps to Reproduce:
Invoke a READ ioctl with a 0 length bitfield and and output buffer 
third argument of insufficient length to hold the potential ioctl output. 
  
Actual results:
Perl exits with error:
Possible memory corruption: ioctl overflowed 3rd argument

Expected results:
Perl should enforce a minimum length of 256 bytes for the ioctl output buffer.
Comment 1 Rafael Garcia-Suarez 2006-03-13 02:13:54 EST
FWIW it's upstream change #26815.
Comment 2 Jason Vas Dias 2006-03-13 13:03:23 EST
Actually, I'm not sure the upstream patch is totally correct :

  # define IOCPARM_LEN(x) (_IOC_SIZE(x) < 256 ? 256 : _IOC_SIZE(x))

This ignores any non-zero _IOC_SIZE passed in if it is less than 256 ;
why would the programmer pass in a non-zero _IOC_SIZE if it is not the 
size required ?

I'm going to make it:
 
 # define IOCPARM_LEN(x) (_IOC_SIZE(x) ? _IOC_SIZE(x) : 256)

which allows people to pass in a non-zero _IOC_SIZE that is less than 256, and
will also fix the case where _IOC_SIZE is 0 and users depend on the default 256 
length.

Any objections ?
Comment 3 Jason Vas Dias 2006-03-13 17:02:34 EST
Now fixed with perl-5.8.6-24 for FC-4, shortly to be released to Updates/Testing.
Comment 4 Fedora Update System 2006-03-13 17:12:50 EST
From User-Agent: XML-RPC

perl-5.8.6-24 has been pushed for FC4, which should resolve this issue.  If these problems are still present in this version, then please make note of it in this bug report.
Comment 5 Fedora Update System 2006-03-27 12:07:26 EST
perl-5.8.6-24 has been pushed for FC4, which should resolve this issue.  If these problems are still present in this version, then please make note of it in this bug report.
Comment 6 Bill Nottingham 2006-09-21 22:19:48 EDT
Closing bugs in MODIFIED state from prior Fedora releases. If this bug persists
in a current Fedora release (such as Fedora Core 5 or later), please reopen and
set the version appropriately.

Note You need to log in before you can comment on or make changes to this bug.