OpenSolaris

Printable Version Enter a New Search
Bug ID 6308413
Synopsis sysi86(SI86DSCR) rejects the first valid custom descriptor #6 with errno
State 10-Fix Delivered (Fix available in build)
Category:Subcategory kernel:arch-x86
Keywords DSEVEN | ITCTO | opensolaris | oss-request
Sponsor
Submitter jk
Responsible Engineer Russell Blaine
Reported Against snv_21 , s10u1_fcs
Duplicate Of
Introduced In
Commit to Fix snv_32
Fixed In snv_32
Release Fixed solaris_nevada(snv_32) , solaris_10u3(s10u3_02) (Bug ID:2137548)
Related Bugs 6214604
Submit Date 9-August-2005
Last Update Date 16-January-2007
Description
Category
   kernel
Sub-Category
   arch-x86
Description
   On Solaris 10 x86 or Nevada b19, mplayer (http://www.mplayerhq.hu/) gets an
EINVAL error when trying to install a user defined segment descriptor #6
using the sysi86() system call.  The user defined segment descriptor is
needed for using win32 codecs under unix.  Segment descriptor #6 used to
work with old Solaris x86 releases - for example Solaris 2.5.1, Solaris 8
or Solaris 9 x86.
Rejecting descriptor #6 in S10 or snv_19 breaks binary compatibility.
Frequency
   Always
Regression
   Solaris 9
Steps to Reproduce
   Compile and run the following C program:
==========================================================================
/*
 * BugID: 6214604
 * Synopsis: Fix for 6210868 breaks mplayer/totem on amd64
 * State: Closed, fixed
 *
 * But selector index #6 still cannot be installed with S10 (sysi86 fails with
 * error EINVAL).  Selector index > 6 works.  Selector index #6 used to work
 * upto Solaris 9 x86.
 */
#include <sys/segment.h>
#include <sys/sysi86.h>
/* user level (privilege level: 3) ldt (1<<2) segment selector */
#define       LDT_SEL(idx) ((idx) << 3 | 1 << 2 | 3)
#define MODIFY_LDT_CONTENTS_DATA        0
#define MODIFY_LDT_CONTENTS_STACK       1
#define MODIFY_LDT_CONTENTS_CODE        2
char *data = "Hello, world!\n";
int
main(int argc, char **argv)
{
        int sel_idx = 6;
        int read_exec_only = 1;
        int contents = MODIFY_LDT_CONTENTS_DATA;
        struct ssd ssd;
        if (argv[1])
                sel_idx = atoi(argv[1]);
        ssd.sel = LDT_SEL(sel_idx);
        ssd.bo = (int) data;
        ssd.ls = strlen(data);
        ssd.acc1 = ((read_exec_only == 0) << 1) |
                (contents << 2) |
                0xf0;   /* P(resent) | DPL3 | S */
        ssd.acc2 = 0x4;   /* byte limit, 32-bit segment */
        if (sysi86(SI86DSCR, &ssd) < 0) {
                perror("sysi86(SI86DSCR)");
                exit(1);
        }
}
==========================================================================
% gcc -o si86dscr si86dscr.c
% ./si86dscr 
sysi86(SI86DSCR): Invalid argument
Or:  Run mplayer and force use of any win32 audio or video codec:
% /home/leo/src/X11/mplayer/MPlayer-1.0pre6a/mplayer -vfm dshow /home/leo/avi/Sa
lsaSampleWeb.wmv
...
Trying to force video codec driver family dshow...
Opening video decoder: [dmo] DMO video codecs
sysi86(SI86DSCR): Invalid argument
Couldn't install fs segment, expect segfault
MPlayer interrupted by signal 11 in module: init_video_codec
- MPlayer crashed by bad usage of CPU/FPU/RAM.
  Recompile MPlayer with --enable-debug and make a 'gdb' backtrace and
  disassembly. Details in DOCS/HTML/en/bugreports_what.html#bugreports_crash.
- MPlayer crashed. This shouldn't happen.
  It can be a bug in the MPlayer code _or_ in your drivers _or_ in your
  gcc version. If you think it's MPlayer's fault, please read
  DOCS/HTML/en/bugreports.html and follow the instructions there. We can't and
  won't help unless you provide this information when reporting a possible bug.
%
OR
==========================================================================
% mplayer -afm acm filename_for_an_mp3_compressed_audio_file.mp3
...
Trying to force audio codec driver family acm...
Opening audio decoder: [acm] Win32/ACM decoders
sysi86(SI86DSCR): Invalid argument
Couldn't install fs segment, expect segfault
MPlayer interrupted by signal 11 in module: init_audio_codec
- MPlayer crashed by bad usage of CPU/FPU/RAM.
  Recompile MPlayer with --enable-debug and make a 'gdb' backtrace and
  disassembly. Details in DOCS/HTML/en/bugreports_what.html#bugreports_crash.
- MPlayer crashed. This shouldn't happen.
  It can be a bug in the MPlayer code _or_ in your drivers _or_ in your
  gcc version. If you think it's MPlayer's fault, please read
  DOCS/HTML/en/bugreports.html and follow the instructions there. We can't and
  won't help unless you provide this information when reporting a possible bug.
Expected Result
   The kernel should accept the first available custom segment descriptor #6.
The test program attached should print no error message.
An unmodified MPlayer binary should be able to use win32 codecs on S10 x6 
or Nevada x86.
Actual Result
   custom segment descriptor #6 is rejected with errno == EINVAL.
  % ./si86dscr
  sysi86(SI86DSCR): Invalid argument
  %
(Note: using descriptor #7 is ok:
  % ./si86dscr 7
  % 
)
An unmodified MPlayer binary crashes with a SIGSEGV.
Error Message(s)
   
Test Case
   /*
 * BugID: 6214604
 * Synopsis: Fix for 6210868 breaks mplayer/totem on amd64
 * State: Closed, fixed
 *
 * But selector index #6 still cannot be installed with S10 (sysi86 fails with
 * error EINVAL).  Selector index > 6 works.  Selector index #6 used to work
 * upto Solaris 9 x86.
 */
#include <sys/segment.h>
#include <sys/sysi86.h>
/* user level (privilege level: 3) ldt (1<<2) segment selector */
#define       LDT_SEL(idx) ((idx) << 3 | 1 << 2 | 3)
#define MODIFY_LDT_CONTENTS_DATA        0
#define MODIFY_LDT_CONTENTS_STACK       1
#define MODIFY_LDT_CONTENTS_CODE        2
char *data = "Hello, world!\n";
int
main(int argc, char **argv)
{
        int sel_idx = 6;
        int read_exec_only = 1;
        int contents = MODIFY_LDT_CONTENTS_DATA;
        struct ssd ssd;
        if (argv[1])
                sel_idx = atoi(argv[1]);
        ssd.sel = LDT_SEL(sel_idx);
        ssd.bo = (int) data;
        ssd.ls = strlen(data);
        ssd.acc1 = ((read_exec_only == 0) << 1) |
                (contents << 2) |
                0xf0;   /* P(resent) | DPL3 | S */
        ssd.acc2 = 0x4;   /* byte limit, 32-bit segment */
        if (sysi86(SI86DSCR, &ssd) < 0) {
                perror("sysi86(SI86DSCR)");
                exit(1);
        }
}
Workaround
   Change the source code for the program using custom segment descriptors and use
a descriptor > 6.
Suggested fix to fix this issue in the Solaris kernel:
--- usr/src/uts/intel/ia32/os/sysi86.c~ Sa Jul 23 00:32:41 2005
+++ usr/src/uts/intel/ia32/os/sysi86.c  Mo Aug  8 09:39:46 2005
@@ -410,7 +410,7 @@
         * check the selector index.
         */
        seli = SELTOIDX(ssd.sel);
-       if (seli >= MAXNLDT || seli <= LDT_UDBASE)
+       if (seli >= MAXNLDT || seli < LDT_UDBASE)
                return (EINVAL);
        mutex_enter(&pp->p_ldtlock);
Submitter wants to work on bug
   Yes
Additional configuration information
   S10 GA or SNV_19, 32-bit kernel.
Work Around
Change the source code for the program using custom segment descriptors and use
a descriptor > 6.
Suggested fix to fix this issue in the Solaris kernel:
--- usr/src/uts/intel/ia32/os/sysi86.c~ Sa Jul 23 00:32:41 2005
+++ usr/src/uts/intel/ia32/os/sysi86.c  Mo Aug  8 09:39:46 2005
@@ -410,7 +410,7 @@
         * check the selector index.
         */
        seli = SELTOIDX(ssd.sel);
-       if (seli >= MAXNLDT || seli <= LDT_UDBASE)
+       if (seli >= MAXNLDT || seli < LDT_UDBASE)
                return (EINVAL);
        mutex_enter(&pp->p_ldtlock);
Comments
N/A