Bug 240989 - Linuxulator: futexes can't be shared between 32- and 64-bit applications
Summary: Linuxulator: futexes can't be shared between 32- and 64-bit applications
Status: In Progress
Alias: None
Product: Base System
Classification: Unclassified
Component: kern (show other bugs)
Version: CURRENT
Hardware: Any Any
: --- Affects Some People
Assignee: Yuri Pankov
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2019-10-01 23:44 UTC by Alex S
Modified: 2020-01-10 19:13 UTC (History)
2 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Alex S 2019-10-01 23:44:31 UTC
Here's a small example:

#define _GNU_SOURCE

#include <assert.h>
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>

#include <sys/syscall.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/mman.h>

#include <linux/futex.h>

#define SHM_FILE_PATH "/futex-bug"

int main() {

  int fd = shm_open(SHM_FILE_PATH, O_CREAT | O_RDWR, 0777);
  assert(fd != -1);

  ftruncate(fd, 4);

  int* addr = mmap(NULL, 4, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
  assert(addr != MAP_FAILED);

  close(fd);

#ifdef WAIT

  struct timespec timeout = {.tv_sec = 1, .tv_nsec = 0};
  int err = -1;
  do {
    err = syscall(SYS_futex, addr, FUTEX_WAIT, 0, &timeout, NULL, 0);
    if (err == -1) {
      printf("FUTEX_WAIT: %d [%s]\n", err, strerror(errno));  
    } else {
      printf("FUTEX_WAIT: %d\n", err);
    }
  } while (err == -1 && errno == ETIMEDOUT);

  shm_unlink(SHM_FILE_PATH);

#else

  int err = syscall(SYS_futex, addr, FUTEX_WAKE, 1, NULL, NULL, 0);
  printf("FUTEX_WAKE: %d\n", err);

#endif

  return 0;
}

Compile this with:

/compat/linux/bin/cc -DWAIT -m32 --sysroot=/compat/linux futex_bug.c -lrt -o wait32
/compat/linux/bin/cc        -m32 --sysroot=/compat/linux futex_bug.c -lrt -o wake32
/compat/linux/bin/cc        -m64 --sysroot=/compat/linux futex_bug.c -lrt -o wake64

Run wait32, then try wake64 and wake32.
Comment 1 Alex S 2019-10-02 00:10:27 UTC
As for the real-life use case, Steam relies upon this for communication between steam (32-bit) and steamwebhelper (64-bit) processes. Also, in case anyone wonders, some (old) bits of Valve's IPC code can be found on GitHub, see https://github.com/ValveSoftware/steamworks-vr-api/blob/afe1f686dd23f0a65f908e47f6b446231af29ae0/src/common/vrcommon/ipcposix.cpp#L35.
Comment 2 commit-hook freebsd_committer 2019-10-18 10:28:32 UTC
A commit references this bug:

Author: yuripv
Date: Fri Oct 18 10:28:09 UTC 2019
New revision: 353724
URL: https://svnweb.freebsd.org/changeset/base/353724

Log:
  linux: provide just one instance of futex_list

  Move futex_list definition to linux.c which is included once
  in linux.ko (i386) and in linux_common.ko (amd64 and aarch64)
  allowing 32/64 bit linux programs to access the same futexes
  in the latter case.

  PR:		240989
  Reviewed by:	dchagin
  Differential Revision:	https://reviews.freebsd.org/D22073

Changes:
  head/sys/compat/linux/linux.c
  head/sys/compat/linux/linux.h
  head/sys/compat/linux/linux_futex.c
  head/sys/compat/linux/linux_futex.h
Comment 3 commit-hook freebsd_committer 2019-10-18 12:25:42 UTC
A commit references this bug:

Author: yuripv
Date: Fri Oct 18 12:25:35 UTC 2019
New revision: 353725
URL: https://svnweb.freebsd.org/changeset/base/353725

Log:
  linux: futex_mtx should follow futex_list

  Move futex_mtx to linux_common.ko for amd64 and aarch64 along
  with respective list/mutex init/destroy.

  PR:		240989
  Reported by:	Alex S <iwtcex@gmail.com>

Changes:
  head/sys/amd64/linux/linux_sysvec.c
  head/sys/amd64/linux32/linux32_sysvec.c
  head/sys/arm64/linux/linux_sysvec.c
  head/sys/compat/linux/linux.c
  head/sys/compat/linux/linux.h
  head/sys/compat/linux/linux_common.c
  head/sys/compat/linux/linux_futex.c
  head/sys/compat/linux/linux_futex.h
  head/sys/i386/linux/linux_sysvec.c
Comment 4 Alex S 2020-01-10 19:13:00 UTC
I suppose this can be closed?