Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

syscall: syscall.Syscall return abnormal data #54334

Closed
hanchao886 opened this issue Aug 8, 2022 · 2 comments
Closed

syscall: syscall.Syscall return abnormal data #54334

hanchao886 opened this issue Aug 8, 2022 · 2 comments
Labels
compiler/runtime Issues related to the Go compiler and/or runtime.

Comments

@hanchao886
Copy link

hanchao886 commented Aug 8, 2022

What version of Go are you using (go version)?

$ go version
go version go1.18.5 linux/amd64

Does this issue reproduce with the latest release?

yes

What operating system and processor architecture are you using (go env)?

go env Output
$ go env
GO111MODULE=""                                                                                                                                              GOARCH="amd64"
GOBIN=""
GOCACHE="/root/.cache/go-build"
GOENV="/root/.config/go/env"
GOEXE=""
GOEXPERIMENT=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOINSECURE=""
GOMODCACHE="/root/go/pkg/mod"
GONOPROXY=""
GONOSUMDB=""
GOOS="linux"
GOPATH="/root/go"
GOPRIVATE=""
GOPROXY="https://proxy.golang.org,direct"
GOROOT="/usr/local/go"
GOSUMDB="sum.golang.org"
GOTMPDIR=""
GOTOOLDIR="/usr/local/go/pkg/tool/linux_amd64"
GOVCS=""
GOVERSION="go1.17.13"
GCCGO="gccgo"
AR="ar"
CC="gcc"
CXX="g++"
CGO_ENABLED="1"
GOMOD="/dev/null"
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -m64 -pthread -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build125081647=/tmp/go-build -gno-record-gcc-switches"

What did you do?

package main

import (
        "fmt"
        "syscall"
        "unsafe"
)

var currentDepth int

func ioctl(fd int, req uint, arg uintptr) (err error) {
        _, _, e1 := syscall.Syscall(syscall.SYS_IOCTL, uintptr(fd), uintptr(req), uintptr(arg))
        if e1 != 0 {
                fmt.Println("syscall error")
                return nil
        }
        return nil
}

func ioctlTest() (error) {
        var termios syscall.Termios
        err := ioctl(0, syscall.TCGETS, uintptr(unsafe.Pointer(&termios)))
        if (err != nil) {
                return err
        }
        if (termios.Iflag == 0) {
                fmt.Println(currentDepth, termios)
        }
        return nil
}

func tryPoc(depth int) {
        if depth > 0 {
                depth--
                tryPoc(depth)
        }
        ioctlTest()
}

func main() {
        for i := 0; i < 10000; i++ {
                currentDepth = i
                tryPoc(i)
        }
}

What did you expect to see?

The function syscall.Syscall returned is correct or return err.

What did you see instead?

image
syscall.Syscall not return err, but the return data termios all is zero.

This issue does not occur in golang1.16.

@gopherbot gopherbot added the compiler/runtime Issues related to the Go compiler and/or runtime. label Aug 8, 2022
@hanchao886 hanchao886 changed the title syscall: call functions syscall.Syscall recursively will return abnormal data syscall: syscall.Syscall return abnormal data Aug 8, 2022
@hanchao886
Copy link
Author

hanchao886 commented Aug 8, 2022

By using this POC, this issue is inevitable. Suspicion is related to the number of calling layers. And the result by using POC is the same every time. And I use golang 1.17 and golang1.18 to reproduce this issue, and they all have the same problem.

@ianlancetaylor
Copy link
Contributor

This code is using unsafe.Pointer in an invalid way. You can't write uintptr(unsafe.Pointer(&termios)) and then pass that value to another function. See the docs at https://pkg.go.dev/unsafe#Pointer. It looks like you are trying to use rule 4, but that is only valid when calling a function written in assembly code, not when calling a function like ioctl in your example.

If you change your ioctl function to take unsafe.Pointer, and pass unsafe.Pointer(&termios) without converting to uintptr, then the program works.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
compiler/runtime Issues related to the Go compiler and/or runtime.
Projects
None yet
Development

No branches or pull requests

3 participants