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

Obscure build failures referencing non-existent code with error "undefined: fs in fs.FileMode" #325

Open
howardjohn opened this issue Jun 29, 2021 · 11 comments

Comments

@howardjohn
Copy link

howardjohn commented Jun 29, 2021

I am running into some weird issues trying to run go-fuzz-build.

Reproduction steps:

  • git clone http://github.com/istio/istio
  • docker run -v $PWD:$PWD -w $PWD -it --init golang:1.16
  • Inside docker:
    • go get -u github.com/dvyukov/go-fuzz/go-fuzz@latest github.com/dvyukov/go-fuzz/go-fuzz-build@latest
    • cd tests/fuzz
    • go-fuzz-build
failed to execute go build: exit status 2
# k8s.io/client-go/util/homedir
/go/pkg/mod/k8s.io/[email protected]/util/homedir/homedir.go:72: undefined: fs in fs.FileMode

But if we look at the file, there is no fs reference, nor FileMode

# head -n 73 /go/pkg/mod/k8s.io/[email protected]/util/homedir/homedir.go | tail
                        info, err := os.Stat(p)
                        if err != nil {
                                continue
                        }
                        if len(firstExistingPath) == 0 {
                                // remember the first path that exists
                                firstExistingPath = p
                        }
                        if info.IsDir() && info.Mode().Perm()&(1<<(uint(7))) != 0 {
                                // return first path that is writeable

Looking at https://github.com/kubernetes/client-go/blob/master/util/homedir/homedir.go, we can also see there have been no changes since 2019 so its not somehow picking up the wrong version I think

cc @AdamKorcz

@AdamKorcz
Copy link

AdamKorcz commented Jun 29, 2021

Just a quick heads up to use the func flag to instruct go-fuzz-build which fuzzer to build.

@howardjohn
Copy link
Author

Thanks, I do get the same errors with that as well though

@thepudds
Copy link
Collaborator

To possibly help narrow the problem, can you try with Go 1.15?

@howardjohn
Copy link
Author

go1.15 does seem to work

@thepudds
Copy link
Collaborator

thepudds commented Jun 30, 2021

A good next step likely is going back to Go 1.16 and do go-fuzz-build -x -work, which will print more details about the commands issued, as well as leave behind the temp work directory that go-fuzz-build uses for its source-to-source transform for coverage instrumentation.

The instrumented source for k8s.io/client-go/util/homedir should be located inside a gopath directory inside that temp work dir, IIRC.

(On mobile, so brief).

@howardjohn
Copy link
Author

howardjohn commented Jun 30, 2021

homedir.go.txt
Attached the instrumented code. It DOES have the fs.FileMode line mentioned in the error

Snippet:

 181   │ //line /usr/local/google/home/howardjohn/go/pkg/mod/k8s.io/[email protected]/util/homedir/homedir.go:71
 182   │             _go_fuzz_dep_.CoverTab[19912]++
 183   │                                                                 if info.IsDir() && func() bool {
 184   │ //line /usr/local/google/home/howardjohn/go/pkg/mod/k8s.io/[email protected]/util/homedir/homedir.go:72
 185   │                 _go_fuzz_dep_.CoverTab[27666]++
 186   │ //line /usr/local/google/home/howardjohn/go/pkg/mod/k8s.io/[email protected]/util/homedir/homedir.go:72
 187   │                 return func() _go_fuzz_dep_.Bool {
 188   │ //line /usr/local/google/home/howardjohn/go/pkg/mod/k8s.io/[email protected]/util/homedir/homedir.go:72
 189   │                     __gofuzz_v1 := fs.FileMode(info.Mode().Perm() & (1 << (uint(7))))
 190   │ //line /usr/local/google/home/howardjohn/go/pkg/mod/k8s.io/[email protected]/util/homedir/homedir.go:72
 191   │                     _go_fuzz_dep_.Sonar(__gofuzz_v1, 0, 23678081)
 192   │ //line /usr/local/google/home/howardjohn/go/pkg/mod/k8s.io/[email protected]/util/homedir/homedir.go:72
 193   │                     return __gofuzz_v1 != 0
 194   │ //line /usr/local/google/home/howardjohn/go/pkg/mod/k8s.io/[email protected]/util/homedir/homedir.go:72
 195   │                 }() == true
 196   │ //line /usr/local/google/home/howardjohn/go/pkg/mod/k8s.io/[email protected]/util/homedir/homedir.go:72
 197   │             }() {
 198   │ //line /usr/local/google/home/howardjohn/go/pkg/mod/k8s.io/[email protected]/util/homedir/homedir.go:72
 199   │                 _go_fuzz_dep_.CoverTab[57441]++
 200   │

Note go 1.16 does add a new "fs" package: https://golang.org/doc/go1.16#fs which may be causing some confusion somehow?

I am not too familiar with this, but it seems like perhaps it is wrapping fs.FileMode to explicitly declare the type, but since fs is not imported this fails to build?

@howardjohn
Copy link
Author

@thepudds
Copy link
Collaborator

thepudds commented Jul 1, 2021

I suspect that the ast.CallExp construction there is incorrectly handling the type alias in Go 1.16:

https://golang.org/src/os/types.go?s=798:825#L18

type FileMode = fs.FileMode

@disconnect3d
Copy link

Hey,

I also stepped on this bug while implementing some fuzzing harnesses.

If anybody is looking for a workaround for the following error:

/home/dc/go/pkg/mod/k8s.io/client-go@v0.20.5/util/homedir/homedir.go:72: undefined: fs in fs.FileMode

This can be hotfixed by modifying the problematic file and adding the io/fs import and using it anyhow, e.g. by declaring an unused type alias like this:

import (
	"os"
	"path/filepath"
	"runtime"
	"io/fs"
)
type X = fs.FileInfo

Of course I don't recommend doing this for the long term, but if you need something working right away, this works.

@thepudds
Copy link
Collaborator

thepudds commented Dec 3, 2021

Hi all, I'm curious if anyone else encountering this issue was able to successfully use the workaround that @disconnect3d suggested immediately above, or on the other hand, if anyone tried that workaround where it seemed to not help?

FWIW, when I looked at this briefly when it was first reported, my suspicion was that this has been a latent bug in go-fuzz-build for ~5 years since the introduction of type aliases in Go 1.9, but happens to be getting triggered & reported now thanks to a popular type alias for fs.FileMode introduced in Go 1.16, where that particular type also happens to have a decent shot of being nearby when the isWeirdShift logic in go-fuzz-build gets triggered. That said, not 100% sure.

@disconnect3d
Copy link

@thepudds good question and... I don't know, but Trail of Bits have a winternship project which will try to fix this and improve some other things in Go-fuzz. (I know that Go added a beta support for fuzzing, but it seems to me that we are still some time before it will make sense to switch to it)

@thepudds thepudds changed the title Obscure build failures referencing non-existent code Obscure build failures referencing non-existent code with error "undefined: fs in fs.FileMode" Dec 26, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants