This is the mail archive of the libc-alpha@sourceware.cygnus.com mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Re: [jhw@wetware.com] libc/1574: semctl variable parameter handling


> From: Andreas Jaeger <aj@suse.de>
> Date: 02 Feb 2000 18:34:14 +0100

> >Number:         1574
> >Category:       libc
> >Synopsis:       semctl variable parameter handling
> >Originator:     jhw@wetware.com

> The prototype for the System V IPC call 'semctl' is declared in the header
> file like so:
> 
> 	int semctl(int, int, int, ...)
> 
> Nevertheless, the source code for the function in the implementation
> for Linux kernels does not key off the third argument to decide
> whether to acquire the fourth argument (always a union semun passed
> by value)-- it just reaches for it whether it was provided or not.
> 
> This causes gcc, and presumably most other compilers, to produce code that
> exhibits what the ANSI C standard euphemistically refers to as "undefined
> behavior".  It may very well be that on some architectures of Linux, the GCC
> compiler produces code that works, but on my Powerbook G3 running Linux/PPC
> 1999 and gcc-2.95.2, I get code that unceremoniously core dumps right where
> the va_arg() macro lives.
> 
> I am, of course, not surprised; and I realize that trying to use System V IPC
> on Linux/PPC with a Powerbook G3 is evidence of great sin in my life, but one
> dances with them that brung you.
> >How-To-Repeat:
> Try this on Linux/PPC 1999, or any other architecture for which structures
> passed by value are managed some other way than simply pushing them byte-for-
> byte onto the stack:
> 
> 	semctl(semid, semnum, IPC_RMID);
> 
> Observe the lovely SIGSEGV event-sequence that smells funny

I can't reproduce this with the following program, under 2.1.2 or so,
and gcc 2.95.2:

#include <sys/sem.h>

int main(void)
{
  semctl(3, 3, IPC_RMID);
}

it does not crash.

I don't see how it can possibly crash on powerpc.  On powerpc,
arguments are passed in registers, including small structures passed
by value.  The fourth argument will be whatever happened to be in r6,
and simply accessing the fourth argument should not cause trouble
(trying to dereference any pointers in it, of course, will be less
likely to work).

glibc's wrapper for semctl() does this:

int
semctl (int semid, int semnum, int cmd, ...)
{
  union semun arg;
  va_list ap;

  va_start (ap, cmd);

  /* Get the argument.  */
  arg = va_arg (ap, union semun);

  va_end (ap);

  return INLINE_SYSCALL (ipc, 5, IPCOP_semctl, semid, semnum, cmd, &arg);
}

so the kernel always gets passed a valid address of a 'union semun' on
the stack.

Probably glibc should not call va_arg for IPC calls that it knows do
not use the fourth parameter, but again, I don't see how the existing
code can explain the behaviour you're seeing.

-- 
- Geoffrey Keating <geoffk@cygnus.com>

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]