lkml.org 
[lkml]   [1998]   [Jan]   [18]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
/
Date
From
SubjectRe: gcc-2.8.0 miscompiles kernel (Was: gcc-2.8 out...)
On Fri, 16 Jan 1998, Christopher Seawood wrote:

> On Fri, 16 Jan 1998, Jesse Thilo wrote:
>
> > > They're not.
> > > gcc 2.8 is aimed at being 100% reliable,
> >
> > For what it's worth, it doesn't seem to have quite reached that aim
> > yet. When I compile kernel 2.0.33 with gcc 2.7.2.3, it works fine.
> > When I compile the same kernel (same configuration, after executing
> > "make mrproper") with gcc 2.8.0, my X servers and certain other
> > programs dump core. I don't have detailed information yet, but it
> > appears that the programs are dumping core in routines that perform
> > I/O port access.
>
> Last I heard, this was a known problem as some kernel code relied upon a
> gcc hack that got fixed. It is fixed in the lastest development kernels.
> Anyone know when/if these fixes will be backported to 2.0.x ?
>
> Regards
> Christopher

Hello Christopher,

I compiled ./arch/i386/kernel/ioport.c (sys_iopl) with both 2.7.2.3
and 2.8.0 to find out just why this should be considered a kernel
code bug and not a compiler bug. Here's what I came up with.

The output of objdump -d -S seems to indicate that the line..
*(&eflags) = (eflags & 0xffffcfff) | (level << 12);
.. was simply optimized away by 2.8.0.

Since the manipulation in question is to a local variable, and there
are no references past this line, it's OK for gcc to throw it away as
it is not valid after the function returns.

It looks like the compiler is now smart enough to take advantage of
the opportunity. If I'm wrong about this, I'll surely hear :)

Cheers,

-Mike
---------------------------------------------------------------------
asmlinkage int sys_iopl(long ebx,long ecx,long edx,
long esi, long edi, long ebp, long eax, long ds,
long es, long fs, long gs, long orig_eax,
long eip,long cs,long eflags,long esp,long ss)
{
120: 55 pushl %ebp
121: 89 e5 movl %esp,%ebp
unsigned int level = ebx;

if (level > 3)
123: 83 7d 08 03 cmpl $0x3,0x8(%ebp)
127: 76 07 jbe 130 <sys_iopl+0x10>
return -EINVAL;
129: b8 ea ff ff ff movl $0xffffffea,%eax
12e: eb 1e jmp 14e <sys_iopl+0x2e>
* normal permissions checks first, and check suser() last.
*/
extern inline int suser(void)
{
if (current->euid == 0) {
130: a1 00 00 00 00 movl 0x0,%eax
135: 66 83 b8 1a 01 cmpw $0x0,0x11a(%eax)
13a: 00 00 00
13d: 74 09 je 148 <sys_iopl+0x28>
if (!suser())
return -EPERM;
13f: b8 ff ff ff ff movl $0xffffffff,%eax
144: eb 08 jmp 14e <sys_iopl+0x2e>
146: 89 f6 movl %esi,%esi
*/
extern inline int suser(void)
{
if (current->euid == 0) {
current->flags |= PF_SUPERPRIV;
148: 80 48 15 01 orb $0x1,0x15(%eax)
*(&eflags) = (eflags & 0xffffcfff) | (level << 12);
return 0; <=== insert missing assembler here :)
14c: 31 c0 xorl %eax,%eax
}
14e: 89 ec movl %ebp,%esp
150: 5d popl %ebp
151: c3 ret


\
 
 \ /
  Last update: 2005-03-22 13:41    [W:0.078 / U:0.556 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site