Subject: COMPAT_LINUX/powerpc: netscape and setgid (long)
To: None <tech-kern@netbsd.org>
From: Emmanuel Dreyfus <p99dreyf@criens.u-psud.fr>
List: tech-kern
Date: 01/26/2001 00:23:41
Hi!

Thanks to Carl Alexander, I have now access to a LinuxPPC box with
glibc-2, and I can try fixing new problems. The first one is that
Linux's netscape crashes on NetBSD (SIGSEGV).

If I compare the kernel trace before the SIGSEGV, I can see two
intersting things.

first, Netscape does a setgid on Linux, and it turns into a chown on
NetBSD. 

NetBSD:
   212 netscape-communi CALL  getgid
   212 netscape-communi RET   getgid 500/0x1f4
   212 netscape-communi CALL  chown(0x1f4,0,0x746f7200)
   212 netscape-communi RET   chown -1 errno -14 Bad address
   212 netscape-communi CALL  getuid
   212 netscape-communi RET   getuid 500/0x1f4
   212 netscape-communi CALL  setuid(0x1f4)
   212 netscape-communi RET   setuid 0

Linux:
getgid()                                = 2001
setgid(2001)                            = 0
getuid()                                = 2001
setuid(2001)                            = 0

This is extremely wierd. I checked syscalls definitions. Here is the
revelent line in NetBSD's Linux emulation syscalls.master:
46 NOARGS      { int sys_setgid(gid_t gid); }
And here is the defintition from Linux:
   .long sys_brk     /* 45 */
   .long sys_setgid

So it's 46, no doubt. Arguments are the same size (uid_t is 32 bit large
on both OSes), everything seems fine, except this changed setgid.

If I use setgid() in a sample program, built on Linux:
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>

int main (int arc, char** argv) {
        gid_t gid;
        int res;

        gid=getgid();

        printf("my gid is %d\n",gid);

        res=setgid(gid);
        if (res<0) {
                perror ("setgid failed");
                exit (-1);
        }       
        
        return 0;
}

The program is okay, so does the kernel trace:
   538 setgid   CALL  getgid
   538 setgid   RET   getgid 500/0x1f4
   538 setgid   CALL  fstat(0x1,0x7fffdff8)
   538 setgid   RET   fstat 0
   538 setgid   CALL  powerpc_mmap(0,0x10000,0x3,0x22,0xffffffff,0)
   538 setgid   RET   powerpc_mmap 1343479808/0x5013e000
   538 setgid   CALL  ioctl(0x1,TIOCGETA,0x7fffdf08)
   538 setgid   RET   ioctl 0
   538 setgid   CALL  write(0x1,0x5013e000,0xe)
   538 setgid   GIO   fd 1 wrote 14 bytes
       "my gid is 500
       "
   538 setgid   RET   write 14/0xe
   538 setgid   CALL  setgid(0x1f4)
   538 setgid   RET   setgid 0

So I have no idea why the setgid was transformed into a chown in
Netscape. I'm looking for idea of where to look for a bug. 

second, Netscape attemps to do a llseek() on file descriptors optained
by pipe(). The llseek() fails, but it also fails on Linux, therefore I
assume this is not an issue, but if anyone think otherwise, let me know:

NetBSD:
   212 netscape-communi RET   powerpc_mmap 1356357632/0x50d86000
   212 netscape-communi CALL  llseek(0x5,0,0,0x7fffd5a8,0x1)
   212 netscape-communi RET   llseek -1 errno -29 Illegal seek
   212 netscape-communi PSIG  SIGSEGV SIG_DFL

Linux:
_llseek(0x5, 0, 0, 0x7fffe9f8, 0x1)     = -1 ESPIPE (Illegal seek)
munmap(0x30015000, 4096)                = 0
munmap(0x30016000, 4096)                = 0
brk(0)                                  = 0x27ab000
brk(0x27ac000)                          = 0x27ac000
open("/dev/zero", O_RDWR)               = 3


-- 
Emmanuel Dreyfus
UNIX *is* user friendly. It is just a bit selective about his friends
p99dreyf@criens.u-psud.fr