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

[PATCH] ioctl IOCPARM_LEN(x) should be _IOC_SIZE(x) on Linux, not 256 #8169

Closed
p5pRT opened this issue Oct 25, 2005 · 4 comments
Closed

[PATCH] ioctl IOCPARM_LEN(x) should be _IOC_SIZE(x) on Linux, not 256 #8169

p5pRT opened this issue Oct 25, 2005 · 4 comments

Comments

@p5pRT
Copy link

p5pRT commented Oct 25, 2005

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

Searchable as RT37535$

@p5pRT
Copy link
Author

p5pRT commented Oct 25, 2005

From jvdias@redhat.com

Created by jvdias@redhat.com

perl.h incorrectly guessed the IOCPARM_LEN on Linux to be constant 256 .

The IOCPARM_LEN(ioctl_number) macro is meant to extract the length / size
field from the ioctl_number, which must be the size of the memory
pointed to by the pointer RW argument passed to ioctl.

On Linux, the _IOC_SIZE(ioctl_number) macro is provided for this purpose,
and there is no IOCPARM_LEN macro, so at pp_sys.c, in Perl_pp_ioctl,
@​line 2210​:

  if (SvPOK(argsv) || !SvNIOK(argsv)) {
  STRLEN len;
  STRLEN need;
  s = SvPV_force(argsv, len);
  need = IOCPARM_LEN(func);
  if (len < need) {
  s = Sv_Grow(argsv, need + 1);
  SvCUR_set(argsv, need);
  }

"need" was ALWAYS set to '257' on linux .
( BTW, shouldn't 'len' be initialized to 0 here? )

This bug was found to be the root cause of Red Hat Bugzilla #171111​:
  https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=171111
where some printers would return a printer id string > 256 bytes long,
which caused perl to generate a SIGSEGV in the
  ioctl(STDIN,0x84005001,$result)
call, where $result was undef, because perl made $result only 257
bytes long.

Here's a patch to perl.h which fixes this problem​:

Inline Patch
--- perl-5.8.7/perl.h.IOC_SIZE  2005-05-07 16:11:45.000000000 -0400
+++ perl-5.8.7/perl.h   2005-10-25 16:56:10.000000000 -0400
@@ -2508,11 +2508,17 @@

 #ifndef IOCPARM_LEN
 #   ifdef IOCPARM_MASK
-       /* on BSDish systes we're safe */
+       /* on BSDish systems we're safe */
 #      define IOCPARM_LEN(x)  (((x) >> 16) & IOCPARM_MASK)
 #   else
-       /* otherwise guess at what's safe */
-#      define IOCPARM_LEN(x)   256
+#      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 has been applied in the Red Hat perl-5.8.7-0.6.fc5 (Rawhide) release\.

Please consider applying the above patch, and fix this issue in future
perl 5.8.8+ / 6.x releases.

Thank You,

Jason Vas Dias <jvdias@​redhat.com>
Red Hat perl package maintainer

Perl Info

Flags:
    category=core
    severity=medium

This perlbug was built using Perl v5.8.7 in the Red Hat build system.
It is being executed now by Perl v5.8.7 - Tue Oct 25 17:23:30 EDT 2005.

Site configuration information for perl v5.8.7:

Configured by Red Hat, Inc. at Tue Oct 25 17:23:30 EDT 2005.

Summary of my perl5 (revision 5 version 8 subversion 7) configuration:
  Platform:
    osname=linux, osvers=2.6.13-1.1624_fc5, archname=i386-linux-thread-multi
    uname='linux jvdias 2.6.13-1.1624_fc5 #1 mon oct 24 01:16:31 edt 2005 i686 i686 i386 gnulinux '
    config_args='-des -Doptimize=-O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector --param=ssp-buffer-size=4 -m32 -march=i386 -mtune=pentium4 -fasynchronous-unwind-tables -Dversion=5.8.7 -Dmyhostname=localhost -Dperladmin=root@localhost -Dcc=gcc -Dcf_by=Red Hat, Inc. -Dinstallprefix=/usr -Dprefix=/usr -Darchname=i386-linux -Dvendorprefix=/usr -Dsiteprefix=/usr -Duseshrplib -Dusethreads -Duseithreads -Duselargefiles -Dd_dosuid -Dd_semctl_semun -Di_db -Ui_ndbm -Di_gdbm -Di_shadow -Di_syslog -Dman3ext=3pm -Duseperlio -Dinstallusrbinperl=n -Ubincompat5005 -Uversiononly -Dpager=/usr/bin/less -isr -Dd_gethostent_r_proto -Ud_endhostent_r_proto -Ud_sethostent_r_proto -Ud_endprotoent_r_proto -Ud_setprotoent_r_proto -Ud_endservent_r_proto -Ud_setservent_r_proto -Dinc_version_list=5.8.6 5.8.5 5.8.4 5.8.3 -Dscriptdir=/usr/bin'
    hint=recommended, useposix=true, d_sigaction=define
    usethreads=define use5005threads=undef useithreads=define usemultiplicity=define
    useperlio=define d_sfio=undef uselargefiles=define usesocks=undef
    use64bitint=undef use64bitall=undef uselongdouble=undef
    usemymalloc=n, bincompat5005=undef
  Compiler:
    cc='gcc', ccflags ='-D_REENTRANT -D_GNU_SOURCE -fno-strict-aliasing -pipe -I/usr/local/include -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -I/usr/include/gdbm',
    optimize='-O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector --param=ssp-buffer-size=4 -m32 -march=i386 -mtune=pentium4 -fasynchronous-unwind-tables',
    cppflags='-D_REENTRANT -D_GNU_SOURCE -fno-strict-aliasing -pipe -I/usr/local/include -I/usr/include/gdbm'
    ccversion='', gccversion='4.0.2 20051007 (Red Hat 4.0.2-3)', 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=-lresolv -lnsl -lgdbm -ldb -ldl -lm -lcrypt -lutil -lpthread -lc
    perllibs=-lresolv -lnsl -ldl -lm -lcrypt -lutil -lpthread -lc
    libc=/lib/libc-2.3.90.so, so=so, useshrplib=true, libperl=libperl.so
    gnulibc_version='2.3.90'
  Dynamic Linking:
    dlsrc=dl_dlopen.xs, dlext=so, d_dlsymun=undef, ccdlflags='-Wl,-E -Wl,-rpath,/usr/lib/perl5/5.8.7/i386-linux-thread-multi/CORE'
    cccdlflags='-fPIC', lddlflags='-shared -L/usr/local/lib'

Locally applied patches:



@INC for perl v5.8.7:
    /usr/lib/perl5/site_perl/5.8.7/i386-linux-thread-multi
    /usr/lib/perl5/site_perl/5.8.6/i386-linux-thread-multi
    /usr/lib/perl5/site_perl/5.8.5/i386-linux-thread-multi
    /usr/lib/perl5/site_perl/5.8.4/i386-linux-thread-multi
    /usr/lib/perl5/site_perl/5.8.3/i386-linux-thread-multi
    /usr/lib/perl5/site_perl/5.8.7
    /usr/lib/perl5/site_perl/5.8.6
    /usr/lib/perl5/site_perl/5.8.5
    /usr/lib/perl5/site_perl/5.8.4
    /usr/lib/perl5/site_perl/5.8.3
    /usr/lib/perl5/site_perl
    /usr/lib/perl5/vendor_perl/5.8.7/i386-linux-thread-multi
    /usr/lib/perl5/vendor_perl/5.8.6/i386-linux-thread-multi
    /usr/lib/perl5/vendor_perl/5.8.5/i386-linux-thread-multi
    /usr/lib/perl5/vendor_perl/5.8.4/i386-linux-thread-multi
    /usr/lib/perl5/vendor_perl/5.8.3/i386-linux-thread-multi
    /usr/lib/perl5/vendor_perl/5.8.7
    /usr/lib/perl5/vendor_perl/5.8.6
    /usr/lib/perl5/vendor_perl/5.8.5
    /usr/lib/perl5/vendor_perl/5.8.4
    /usr/lib/perl5/vendor_perl/5.8.3
    /usr/lib/perl5/vendor_perl
    /usr/lib/perl5/5.8.7/i386-linux-thread-multi
    /usr/lib/perl5/5.8.7
    .


Environment for perl v5.8.7:
    HOME=/root
    LANG=en_US.UTF-8
    LANGUAGE (unset)
    LD_LIBRARY_PATH (unset)
    LOGDIR (unset)
    PATH=/usr/kerberos/sbin:/usr/kerberos/bin:/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/usr/X11R6/bin:/root/bin
    PERL_BADLANG (unset)
    SHELL=/bin/bash

@p5pRT
Copy link
Author

p5pRT commented Oct 26, 2005

From @rgs

Jason Vas Dias (via RT) wrote​:

( BTW, shouldn't 'len' be initialized to 0 here? )

No, it's set by the SvPV_force macro.

Here's a patch to perl.h which fixes this problem​:

Thanks, I applied it with a minor tweak as change #25852 in the
development branch, from where it will be eventually integrated in the
maintenance 5.8.x branch. As _IOC_SIZE is a private macro, I protected
it by __GLIBC__ too in order to avoid breaking some other random
platform by side-effect. (this would be kind of difficult to detect.)

==== //depot/perl/perl.h#638 (text) ====

@​@​ -2959,11 +2959,16 @​@​

#ifndef IOCPARM_LEN
# ifdef IOCPARM_MASK
- /* on BSDish systes we're safe */
+ /* 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 */
+# define IOCPARM_LEN(x) _IOC_SIZE(x)
+# else
  /* otherwise guess at what's safe */
-# define IOCPARM_LEN(x) 256
+# define IOCPARM_LEN(x) 256
+# endif
# endif
#endif

@p5pRT
Copy link
Author

p5pRT commented Oct 26, 2005

The RT System itself - Status changed from 'new' to 'open'

@p5pRT
Copy link
Author

p5pRT commented Oct 26, 2005

@rgs - 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