OK, it appears this command has caused a SIGSEGV when run with STDIN directed a USB printer device: # perl -e 'ioctl(STDIN,0x84005001,$result); print $result' </dev/usb/lp0 from: /usr/share/printconf/util/printconf_conf.py, @ line 1460: magic_perl = "perl -e 'ioctl(STDIN,0x84005001,$result);" magic_perl += "print $result' 2>/dev/null <" foo = os.popen (magic_perl + dev) rawid = foo.readlines () Why not use the Python fcntl.ioctl() call here ? It would be interesting to see if python also has a problem with this ioctl: # python >>> import os, fcntl, array; >>> result=array.array(1024) >>> fcntl.ioctl( os.open("/dev/usb/lp0","r"), -2080354303, result, 1 ) I've just now tried running the perl command above with STDIN directed to an RS-232 serial port, (the only serial device I have here at work) on up-to-date Rawhide, FC-4, RHEL-4 and FC-3 systems, and have not been able to reproduce the problem. I do have a USB printer at home, and I try to reproduce this problem there. But googling for 0x84005001 turned up http://home.techwiz.ca/ftp/Linux/dist/MandrakeLinux/official/9.2/i586/Mandrake/mdkinst/usr/bin/perl-install/printer/detect.pm.gz : # Calculation of IOCTL function 0x84005001 (to get device ID # string): # len = 1024 # IOCNR_GET_DEVICE_ID = 1 # LPIOC_GET_DEVICE_ID(len) = # _IOC(_IOC_READ, 'P', IOCNR_GET_DEVICE_ID, len) # _IOC(), _IOC_READ as defined in /usr/include/asm/ioctl.h # Use "eval" so that program does not stop when IOCTL fails eval { my $output = "\0" x 1024; ioctl($PORT, 0x84005001, $output); $idstr = $output; } or do { close $PORT; next; }; Note how the programmer is careful to allocate a 1024 buffer for the RW ioctl $output parameter, since the 0x84005001 says "I am passing in an 1024 byte RW buffer" . Perhaps the SEGV occurs only when a USB printer is on STDIN, because only a USB printer actually returns an ID string, which writes into the (empty) $result buffer ? Does the problem still occur if the command is ammended : perl -e '$result="\0" x 1024; ioctl(STDIN,0x84005001,$result);print $result,"\n";' </dev/usb/lp0 If not, I don't think it this a PERL bug , but a programming error - any use of ioctl(x,0x84005001,buf), invoked from a C program, will cause a SIGSEGV if the ioctl returns data in buf and buf does not point to a 1024 byte buffer . Can anyone reading this with access to a USB printer please verify, with latest versions that this is still a bug: 1. Does this command produces a SIGSEGV: # perl -e 'ioctl(STDIN,0x84005001,$result); print $result' </dev/usb/lp0 2. Does this command produce a SIGSEGV : # perl -e '$result="\0" x 1024; ioctl(STDIN,0x84005001,$result); print $result' </dev/usb/lp0 If the answer to (2) is NO, then this is not a PERL bug.
OK, I've finally found and fixed the problem here, now that I've brought my USB printer in to work from home (unecessarily! :-) perl was looking for an IOCPARM_LEN(ioctl_number) macro to return the length bits from the ioctl function number. This works OK on BSD systems. But if IOCPARM_LEN was not defined, perl.h "guessed" and defined IOCPARM_LEN(ioctl_number) to be 256 . Linux has no IOCPARM_LEN(x) macro. So any printer that returned an ID string > 256 bytes would cause a SIGSEGV . Linux has the _IOC_SIZE(x) macro, so I changed perl.h to use _IOC_SIZE(x) if IOCPARM_LEN is not defined instead of constant 256. I have submitted this bug upstream with perlbug - waiting for a RT #. So this bug is now fixed in Rawhide (FC-5) with perl-5.8.7-0.6.fc5 . It will now have to be fixed in RHEL-3, RHEL-4, FC-4, FC-3 .
From User-Agent: XML-RPC perl-5.8.5-18.FC3 has been pushed for FC3, which should resolve this issue. If these problems are still present in this version, then please make note of it in this bug report.
An advisory has been issued which should help the problem described in this bug report. This report is therefore being closed with a resolution of ERRATA. For more information on the solution and/or where to find the updated files, please follow the link below. You may reopen this bug report if the solution does not work for you. http://rhn.redhat.com/errata/RHSA-2005-880.html
This patch needed another core patch to work properly, I'm not sure why. See : https://rt.perl.org/rt3/Ticket/Display.html?id=38223
This bug is fixed: perl programs passing in the length bitfield parameter to ioctl will now get the correct length, instead of the default 256; as a result, system-config-printer works fine. The upstream refinement to this patch was to retain the previous 256 default as a minimum length; ie., if the ioctl did not pass in the length, and the argument is less than 256 bytes in length, then it is made to be 256 bytes. This does not affect system-config-printer, and is a new bug - I'm closing this bug and raising another to document it.
Have run the test script from https://rt.perl.org/rt3/Ticket/Display.html?id=38223 (will attach this file) on 3 systems with 3 format of the "perl.h" file: 1, perl 5.8.8 ./test.perl (row,col) = (54,155) => PASS Form of the patch: #ifndef IOCPARM_LEN # ifdef IOCPARM_MASK /* on BSDish systems we're safe */ # define IOCPARM_LEN(x) (((x) >> 16) & IOCPARM_MASK) # else # if defined(_IOC_SIZE) && defined(__GLIBC__) /* 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 # endif # endif #endif 2, perl 5.8.6 ./test.perl (row,col) = (54,155) => PASS Form of the patch: #ifndef IOCPARM_LEN # ifdef IOCPARM_MASK /* on BSDish systes we're safe */ # define IOCPARM_LEN(x) (((x) >> 16) & IOCPARM_MASK) # else /* otherwise guess at what's safe */ # define IOCPARM_LEN(x) 256 # endif #endif => seems it's enough to hardly set the value of IOCPARM_LEN(x) to 256 and don't take into account the Linux system's branch, because: 3, perl 5.8.6 ./test.perl Possible memory corruption: ioctl overflowed 3rd argument at ./test.perl line 5. => FAIL Form of the patch: #ifndef IOCPARM_LEN # ifdef IOCPARM_MASK /* on BSDish systems we're safe */ # define IOCPARM_LEN(x) (((x) >> 16) & IOCPARM_MASK) # else # ifdef _IOC_SIZE /* on Linux systems we're safe */ # define IOCPARM_LEN(x) _IOC_SIZE(x) # else /* otherwise guess at what's safe (we're UNSAFE!) */ # warning "unsafe assumption of IOCPARM_LEN=256" # define IOCPARM_LEN(x) 256 # endif # endif #endif This patch doesn't work. So the solution is either to use patch without the linux branch, and hardly set value of IOCPARM_LEN(x) to 256 (patch 2,), or take into account _IOC_SIZE and use the newest patch ( patch 1,).
Created attachment 126033 [details] test case from https://rt.perl.org/rt3/Ticket/Display.html?id=38223
I have raised bug 185240 to cover the issues raised in Comment #11, Comment #12, Comment #14, Comment #15 - (perlbug RT #38223) - it will be fixed in perl-5.8.5-24.RHEL4+. The specific problem with system-config-printer reported in this bug has definitely been fixed with the current perl-5.8.5-22.RHEL-4 release in RHEL-4-U3 .