|
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);
|