Bug 267616 - Linuxulator: get_robust_list is slightly broken on amd64 for 32-bit apps
Summary: Linuxulator: get_robust_list is slightly broken on amd64 for 32-bit apps
Status: Closed FIXED
Alias: None
Product: Base System
Classification: Unclassified
Component: kern (show other bugs)
Version: 13.1-RELEASE
Hardware: Any Any
: --- Affects Only Me
Assignee: freebsd-bugs (Nobody)
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2022-11-07 14:15 UTC by Alex S
Modified: 2022-11-14 10:28 UTC (History)
3 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 2022-11-07 14:15:15 UTC
New Steam beta fails with "Fatal error: futex robust_list not initialized by pthreads".

% uname -a
FreeBSD desktop 13.1-RELEASE FreeBSD 13.1-RELEASE releng/13.1-n250148-fc952ac2212 GENERIC amd64
% cat robust.c
#include <assert.h>
#include <unistd.h>
#include <stdio.h>
#include <linux/futex.h>
#include <sys/syscall.h>

int main() {

  assert(sizeof(size_t) == sizeof(void*));

  {
    void* x[2];

    int err = syscall(SYS_get_robust_list, 0, &x[0], &x[1]);
    assert(err == 0);

    struct robust_list_head* head =         x[0];
    size_t len                    = (size_t)x[1];

    printf("head: %p, len: 0x%x, offset = %ld\n", head, len, head->futex_offset);
  }

  {
    void* x[2];

    int err = syscall(SYS_get_robust_list, 0, &x[1], &x[0]);
    assert(err == 0);

    struct robust_list_head* head =         x[1];
    size_t len                    = (size_t)x[0];

    printf("head: %p, len: 0x%x, offset = %ld\n", head, len, head->futex_offset);
  }

  return 0;
}
% /compat/linux/bin/cc robust.c -pthread -m32 -Wall -o robust32
% ./robust3
head: 0x28261770, len: 0x0, offset = -20 # len is being overwritten by the previous argument, not ok
head: 0x28261770, len: 0xc, offset = -20 # ok

I locally patched the issue like this:

--- linux_futex.c.orig	2022-11-07 16:09:35.911266000 +0300
+++ linux_futex.c	2022-11-07 16:12:48.581662000 +0300
@@ -1179,7 +1179,7 @@ linux_get_robust_list(struct thread *td, struct linux_
 		return (EFAULT);
 	}
 
-	error = copyout(&head, args->head, sizeof(head));
+	error = copyout(&head, args->head, sizeof(l_uintptr_t));
 	if (error) {
 		LIN_SDT_PROBE1(futex, linux_get_robust_list, copyout_error,
 		    error);
Comment 1 Mark Johnston freebsd_committer freebsd_triage 2022-11-07 14:21:17 UTC
This looks right to me.
Comment 2 Dmitry Chagin freebsd_committer freebsd_triage 2022-11-07 16:54:48 UTC
Wow, agreed, will fix
Comment 3 commit-hook freebsd_committer freebsd_triage 2022-11-08 21:18:24 UTC
A commit in branch main references this bug:

URL: https://cgit.FreeBSD.org/src/commit/?id=9f7bf94ee2a88a702cef9fdb67166404c275afaf

commit 9f7bf94ee2a88a702cef9fdb67166404c275afaf
Author:     Alex S <iwtcex@gmail.com>
AuthorDate: 2022-11-08 21:17:17 +0000
Commit:     Dmitry Chagin <dchagin@FreeBSD.org>
CommitDate: 2022-11-08 21:17:17 +0000

    linux(4): Fix get_robust_list() syscall return value.

    The system call returns the head of the robust futex list. The list head is stored
    in the location pointed to by the head argument. When copying data between address
    spaces use proper head storage size as it depends on an emulated ABI.

    PR:             267616
    MFC after:      3 days

 sys/compat/linux/linux_futex.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
Comment 4 commit-hook freebsd_committer freebsd_triage 2022-11-14 10:23:36 UTC
A commit in branch stable/13 references this bug:

URL: https://cgit.FreeBSD.org/src/commit/?id=312fa66091f9989e64370291e2482eab8d8ab013

commit 312fa66091f9989e64370291e2482eab8d8ab013
Author:     Alex S <iwtcex@gmail.com>
AuthorDate: 2022-11-08 21:17:17 +0000
Commit:     Dmitry Chagin <dchagin@FreeBSD.org>
CommitDate: 2022-11-14 10:21:26 +0000

    linux(4): Fix get_robust_list() syscall return value.

    The system call returns the head of the robust futex list. The list head is stored
    in the location pointed to by the head argument. When copying data between address
    spaces use proper head storage size as it depends on an emulated ABI.

    PR:             267616
    MFC after:      3 days

    (cherry picked from commit 9f7bf94ee2a88a702cef9fdb67166404c275afaf)

 sys/compat/linux/linux_futex.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
Comment 5 Dmitry Chagin freebsd_committer freebsd_triage 2022-11-14 10:28:25 UTC
10x