misc/124114: 7.0 shared libs cannot read errno when loaded into a 6.0 pthreaded program

Martin Simmons martin at lispworks.com
Thu May 29 22:00:10 UTC 2008


>Number:         124114
>Category:       misc
>Synopsis:       7.0 shared libs cannot read errno when loaded into a 6.0 pthreaded program
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Thu May 29 22:00:10 UTC 2008
>Closed-Date:
>Last-Modified:
>Originator:     Martin Simmons
>Release:        7.0-RELEASE
>Organization:
LispWorks Ltd
>Environment:
FreeBSD heapbsd7.cam.lispworks.com 7.0-RELEASE FreeBSD 7.0-RELEASE #0: Sun Feb 24 19:59:52 UTC 2008     root at logan.cse.buffalo.edu:/usr/obj/usr/src/sys/GENERIC  i386

>Description:
There is something wrong with the way that errno is resolved when running 6.0 programs on 7.0-RELEASE with the compat6x-i386-6.3.602114.200711 pkg.

If a 7.0 shared library that uses errno is loaded into a 6.0 program that uses pthreads, then the value of errno in the library code will be incorrect.  In particular, it will access the global errno value instead of the thread-specific one.

I've included two test cases.  The X11 one is pretty much how the problem was discovered.  The libc one is doing the same thing as the libX11 function _XRead, where the problem occurs in the X11 example.

It also fails when compiled on FreeBSD 5.4 and run on FreeBSD 7.0 with compat5x.

This kind of code worked without any problems when built and run on FreeBSD 5 and also when run on FreeBSD 6 with compat5x.

>How-To-Repeat:
Test case 1: X11
----------------
a. Make the file below available on a 6.0 machine.

$ cat xerror.c
#include <X11/Xlib.h>
#include <stdio.h>
#include <pthread.h>

void *do_x11(void *arg)
{
  Display *disp;
  Atom primary;
  Window root;
  Atom actual_type;
  int actual_format;
  unsigned long nitems;
  unsigned long bytesafter;
  unsigned char *prop;
  int i;

  printf("Opening display\n");
  disp = XOpenDisplay(NULL);
  primary = XInternAtom(disp, "PRIMARY", 0);
  root = XRootWindow(disp, DefaultScreen(disp));
  printf("Atom is %d\nRoot is %d\n", (int)primary, (int)root);
  fflush(stdout);

  for (i = 0; i < 10000; i++) {
    XGetWindowProperty(disp, root, primary, 0, 0, False, primary,
		       &actual_type,
		       &actual_format,
		       &nitems,
		       &bytesafter,
		       &prop);
  }

  printf("Closing display\n");
  fflush(stdout);
  XCloseDisplay(disp);
  return NULL;
}

int main()
{
  pthread_t pt;

  pthread_create(&pt, NULL, do_x11, NULL);
  pthread_join(pt, NULL);

  return 0;
}


b. Compile it on a 6.0 machine to make a.out:
$ cc -pthread -I/usr/X11R6/include xerror.c -L/usr/X11R6/lib -lX11

c. Copy a.out to a 7.0 machine and run it with compat6x installed.
$ ./a.out
Opening display
Atom is 1
Root is 91
XIO:  fatal IO error 0 (Unknown error: 0) on X server "heap:0.0"
      after 8 requests (7 known processed) with 0 events remaining.

d. It should return without printing any X errors


Test case 2: libc
-----------------
a. Make the two files below available on a 6.0 machine.

$ cat lib.c
#include <errno.h>
#include <unistd.h>
int readerror()
{
  char buf[1];
  read(-1, buf, 1);
  return errno;
}

$ cat user.c
#include <stdio.h>
#include <pthread.h>

extern int readerror(void);

void *do_error(void *arg)
{
  printf("errno = %d\n", readerror());
}

int main()
{
  pthread_t pt;

  pthread_create(&pt, NULL, do_error, NULL);
  pthread_join(pt, NULL);

  return 0;
}

b. Compile them on a 6.0 machine to make lib.so and a.out:
$ cc -shared -o lib.so lib.c
$ cc -pthread user.c lib.so

c. Copy a.out and lib.c to a 7.0 machine and compile lib.c again:
$ cc -shared -o lib.so lib.c

d. Run the 6.0 a.out on the 7.0 machine with compat6x installed:
$ env LD_LIBRARY_PATH=`pwd` ./a.out
errno = 0

e. It should print errno = 9 (i.e. EBADF).


>Fix:


>Release-Note:
>Audit-Trail:
>Unformatted:


More information about the freebsd-bugs mailing list