Skip to content

x/sys/unix, syscall: incorrect return value as output parameter on s390x Big Endian #70302

@xbt573

Description

@xbt573

Go version

go version go1.23.2 linux/s390x

Output of go env in your module/workspace:

GO111MODULE=''
GOARCH='s390x'
GOBIN=''
GOCACHE='/home/xbt573/.cache/go-build'
GOENV='/home/xbt573/.config/go/env'
GOEXE=''
GOEXPERIMENT=''
GOFLAGS=''
GOHOSTARCH='s390x'
GOHOSTOS='linux'
GOINSECURE=''
GOMODCACHE='/home/xbt573/go/pkg/mod'
GONOPROXY=''
GONOSUMDB=''
GOOS='linux'
GOPATH='/home/xbt573/go'
GOPRIVATE=''
GOPROXY='direct'
GOROOT='/usr/lib/golang'
GOSUMDB='off'
GOTMPDIR=''
GOTOOLCHAIN='local'
GOTOOLDIR='/usr/lib/golang/pkg/tool/linux_s390x'
GOVCS=''
GOVERSION='go1.23.2'
GODEBUG=''
GOTELEMETRY='local'
GOTELEMETRYDIR='/home/xbt573/.config/go/telemetry'
GCCGO='gccgo'
AR='ar'
CC='gcc'
CXX='g++'
CGO_ENABLED='1'
GOMOD='/dev/null'
GOWORK=''
CGO_CFLAGS='-O2 -g'
CGO_CPPFLAGS=''
CGO_CXXFLAGS='-O2 -g'
CGO_FFLAGS='-O2 -g'
CGO_LDFLAGS='-O2 -g'
PKG_CONFIG='pkg-config'
GOGCCFLAGS='-fPIC -m64 -march=z196 -pthread -Wl,--no-gc-sections -fmessage-length=0 -ffile-prefix-map=/tmp/go-build1678900633=/tmp/go-build -gno-record-gcc-switches'

What did you do?

package main

import (
        "os"
        "fmt"
        "syscall"
        "unsafe"
        "golang.org/x/sys/unix"
)

func main() {
        f, err := os.Open(os.Args[1])
        if err != nil {
                panic(err)
        }
        defer f.Close()

        var attr int

        _, _, rerr := unix.Syscall(syscall.SYS_IOCTL, f.Fd(), uintptr(unix.FS_IOC_GETFLAGS), uintptr(unsafe.Pointer(&attr)))
        if rerr != 0 {
                panic(rerr)
        }

        fmt.Println(attr)
}
$ ./playground /path/to/file/

C equivalent if you want to test it on the same machine:

#include <stdio.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <unistd.h>

#include <linux/fs.h>

int main(int argc, char **argv) {
        int fd, r, f;

        fd = open(argv[1], O_RDONLY|O_NONBLOCK|O_NOFOLLOW);
        if (fd == -1) {
                return 1;
        }
        r = ioctl(fd, FS_IOC_GETFLAGS, &f);
        if (r == -1) {
                return 2;
        }

        printf("%d\n", f);

        close(fd);

}

What did you see happen?

This program returns 549755813888 for file, which flags supposed to be 128, almost identical C program also returns 128 as it is expected. Note that 128 << 32 == 549755813888. I think this bug is caused by big-endianness of s390x architecture.

What did you expect to see?

I expected to see correct return value from output parameter (number 128).

Example file with the same flags (128) can be created with following commands

$ touch example
# chattr +A example

Metadata

Metadata

Assignees

No one assigned

    Labels

    FrozenDueToAgearch-s390xIssues solely affecting the s390x architecture.compiler/runtimeIssues related to the Go compiler and/or runtime.

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions