agiledragon / gomonkey

gomonkey is a library to make monkey patching in unit tests easy
MIT License
1.96k stars 179 forks source link

macOS 10.15 syscall.Mprotect panic: permission denied #10

Open luckyzachary opened 4 years ago

luckyzachary commented 4 years ago

Hi: After I was update my macOS to about 10.14, It will report panic: permission denied when I run ApplyFunc or ApplyMethod. I searched this problem in google, but I don't have answer. Which permission I should set? Thanks a lot. This is panic stack.

panic: permission denied [recovered] panic: permission denied

goroutine 13 [running]: testing.tRunner.func1(0xc4202081e0) /.../goroot/go/src/testing/testing.go:742 +0x29d panic(0x4e697e0, 0xc4205a7c18) /.../goroot/go/src/runtime/panic.go:502 +0x229 github.com/agiledragon/gomonkey.modifyBinary(0x4bf4570, 0xc420229a7c, 0xc, 0xc) /.../gopath/src/github.com/agiledragon/gomonkey/modify_binary_darwin.go:11 +0x198 github.com/agiledragon/gomonkey.replace(0x4bf4570, 0x5099668, 0xc420229b58, 0x59aa580, 0x4dd7500) /.../gopath/src/github.com/agiledragon/gomonkey/patch.go:164 +0x112 github.com/agiledragon/gomonkey.(Patches).applyCore(0xc420086c40, 0x4dd7560, 0x5099ba8, 0x13, 0x4dd7560, 0x5099668, 0x13, 0x10) /.../gopath/src/github.com/agiledragon/gomonkey/patch.go:140 +0x161 github.com/agiledragon/gomonkey.(Patches).ApplyFunc(0xc420086c40, 0x4dd7560, 0x5099ba8, 0x4dd7560, 0x5099668, 0x4009d7d) /.../gopath/src/github.com/agiledragon/gomonkey/patch.go:60 +0xbf github.com/agiledragon/gomonkey.ApplyFunc(0x4dd7560, 0x5099ba8, 0x4dd7560, 0x5099668, 0x2ae) /.../gopath/src/github.com/agiledragon/gomonkey/patch.go:22 +0xa2

agiledragon commented 4 years ago

My Mac OS is 10.13.6, it has no this problem. You can try it with the root user.

cheaterlin commented 4 years ago

My Mac OS is 10.13.6, it has no this problem. You can try it with the root user.

Catalina(10.15.2) has this problem. Sudo can't solve the problem

kakisong commented 4 years ago

does anybody figure this out

itaymeller commented 4 years ago

getting the same problem as well. anyone solved it?

abhineet-plivo commented 4 years ago

I am also facing this issue any idea what's the resolution?

larryyu2 commented 4 years ago

me too. By another patch tool: https://github.com/bouk/monkey#notes, bouk said Monkey won't work on some security-oriented operating system that don't allow memory pages to be both write and execute at the same time. With the current approach there's not really a reliable fix for this. Maybe this is the cause.

larryyu2 commented 4 years ago

I don't know how to fix this ,but I found a way to bypass this. Use the docker with official golang image, map your gopath to the container's gopath, then in the container's terminal, you can run the tests likes in your mac.

hello2mao commented 4 years ago

+1 macos 10.15.4 go version go1.14.2 darwin/amd64

agiledragon commented 4 years ago

// modify_binary_darwin.go err := syscall.Mprotect(page, syscall.PROT_READ|syscall.PROT_WRITE|syscall.PROT_EXEC)

If your macOS is Catalina 10.15.x, please try to replace "err := syscall.Mprotect(page, syscall.PROT_READ|syscall.PROT_WRITE|syscall.PROT_EXEC)" with "err := syscall.Mprotect(page, syscall.PROT_READ|syscall.PROT_WRITE)" or "err := syscall.Mprotect(page, syscall.PROT_WRITE)".

tobegit3hub commented 4 years ago

Please try printf '\x07' | dd of=<executable> bs=1 seek=160 count=1 conv=notrunc.

Refer to https://stackoverflow.com/questions/60654834/using-mprotect-to-make-text-segment-writable-on-macos .

agiledragon commented 4 years ago

I don't know how to fix this ,but I found a way to bypass this. Use the docker with official golang image, map your gopath to the container's gopath, then in the container's terminal, you can run the tests likes in your mac.

Good idea! Maybe it is the best way to fix this.

agiledragon commented 4 years ago

Please try printf '\x07' | dd of=<executable> bs=1 seek=160 count=1 conv=notrunc.

Refer to https://stackoverflow.com/questions/60654834/using-mprotect-to-make-text-segment-writable-on-macos .

Does anyone try this?

brzyangg commented 4 years ago

Please try printf '\x07' | dd of=<executable> bs=1 seek=160 count=1 conv=notrunc. Refer to https://stackoverflow.com/questions/60654834/using-mprotect-to-make-text-segment-writable-on-macos .

Does anyone try this?

I don't know how to set <executable>

paco0x commented 4 years ago

Please try printf '\x07' | dd of=<executable> bs=1 seek=160 count=1 conv=notrunc. Refer to https://stackoverflow.com/questions/60654834/using-mprotect-to-make-text-segment-writable-on-macos .

Does anyone try this?

It works on my Mac with macOS 10.15.5.

Please try printf '\x07' | dd of=<executable> bs=1 seek=160 count=1 conv=notrunc. Refer to https://stackoverflow.com/questions/60654834/using-mprotect-to-make-text-segment-writable-on-macos .

Does anyone try this?

I don't know how to set <executable>

go test actually includes three steps:

  1. compile the test functions into a binary
  2. execute the binary
  3. delete the binary

To work around this issue, we need to first generate the test binary, the modify the compiled binary with dd. e.g.

$ go test -c -o test-bin mytest/abc

With -c and -o option, go test will generate a binary named test-bin. Then modify the binary with dd according to https://stackoverflow.com/questions/60654834/using-mprotect-to-make-text-segment-writable-on-macos#:

$  printf '\x07' | dd of=test-bin bs=1 seek=160 count=1 conv=notrunc

Finally, you can run the test binary:

./test-bin
LaryCaka commented 4 years ago

// modify_binary_darwin.go err := syscall.Mprotect(page, syscall.PROT_READ|syscall.PROT_WRITE|syscall.PROT_EXEC)

If your macOS is Catalina 10.15.x, please try to replace "err := syscall.Mprotect(page, syscall.PROT_READ|syscall.PROT_WRITE|syscall.PROT_EXEC)" with "err := syscall.Mprotect(page, syscall.PROT_READ|syscall.PROT_WRITE)" or "err := syscall.Mprotect(page, syscall.PROT_WRITE)".

i try this ,but i can't solve the problem,

agiledragon commented 4 years ago

// modify_binary_darwin.go err := syscall.Mprotect(page, syscall.PROT_READ|syscall.PROT_WRITE|syscall.PROT_EXEC) If your macOS is Catalina 10.15.x, please try to replace "err := syscall.Mprotect(page, syscall.PROT_READ|syscall.PROT_WRITE|syscall.PROT_EXEC)" with "err := syscall.Mprotect(page, syscall.PROT_READ|syscall.PROT_WRITE)" or "err := syscall.Mprotect(page, syscall.PROT_WRITE)".

i try this ,but i can't solve the problem,

There are two methods:

  1. Use the docker with official golang image, map your gopath to the container's gopath, then in the container's terminal, you can run the tests likes in your mac.

  2. A brute workaround is to manually modify and set __TEXT(max_prot) to 0x7 after linking. printf '\x07' | dd of= bs=1 seek=160 count=1 conv=notrunc Refer to https://stackoverflow.com/questions/60654834/using-mprotect-to-make-text-segment-writable-on-macos .

zhangzhen8230 commented 4 years ago

Please try printf '\x07' | dd of=<executable> bs=1 seek=160 count=1 conv=notrunc. Refer to https://stackoverflow.com/questions/60654834/using-mprotect-to-make-text-segment-writable-on-macos .

Does anyone try this?

It works on my Mac with macOS 10.15.5.

Please try printf '\x07' | dd of=<executable> bs=1 seek=160 count=1 conv=notrunc. Refer to https://stackoverflow.com/questions/60654834/using-mprotect-to-make-text-segment-writable-on-macos .

Does anyone try this?

I don't know how to set <executable>

go test actually includes three steps:

  1. compile the test functions into a binary
  2. execute the binary
  3. delete the binary

To work around this issue, we need to first generate the test binary, the modify the compiled binary with dd. e.g.

$ go test -c -o test-bin mytest/abc

With -c and -o option, go test will generate a binary named test-bin. Then modify the binary with dd according to https://stackoverflow.com/questions/60654834/using-mprotect-to-make-text-segment-writable-on-macos#:

$  printf '\x07' | dd of=test-bin bs=1 seek=160 count=1 conv=notrunc

Finally, you can run the test binary:

./test-bin

can solve the problem,But it's too cumbersome to execute every time

So,It is recommended to use docker to solve this problem。

kamly commented 4 years ago

Please try printf '\x07' | dd of=<executable> bs=1 seek=160 count=1 conv=notrunc. Refer to https://stackoverflow.com/questions/60654834/using-mprotect-to-make-text-segment-writable-on-macos .

Does anyone try this?

It works on my Mac with macOS 10.15.5.

Please try printf '\x07' | dd of=<executable> bs=1 seek=160 count=1 conv=notrunc. Refer to https://stackoverflow.com/questions/60654834/using-mprotect-to-make-text-segment-writable-on-macos .

Does anyone try this?

I don't know how to set <executable>

go test actually includes three steps:

  1. compile the test functions into a binary
  2. execute the binary
  3. delete the binary

To work around this issue, we need to first generate the test binary, the modify the compiled binary with dd. e.g.

$ go test -c -o test-bin mytest/abc

With -c and -o option, go test will generate a binary named test-bin. Then modify the binary with dd according to https://stackoverflow.com/questions/60654834/using-mprotect-to-make-text-segment-writable-on-macos#:

$  printf '\x07' | dd of=test-bin bs=1 seek=160 count=1 conv=notrunc

Finally, you can run the test binary:

./test-bin

can solve the problem,But it's too cumbersome to execute every time

So,It is recommended to use docker to solve this problem。

i also meet the problem and use this method printf '\x07' | dd of=test-bin bs=1 seek=160 count=1 conv=notrunc fix it .

but i want to know that if gomonkey can fix it ?

ddavidzhang commented 3 years ago

Please try printf '\x07' | dd of=<executable> bs=1 seek=160 count=1 conv=notrunc. Refer to https://stackoverflow.com/questions/60654834/using-mprotect-to-make-text-segment-writable-on-macos .

Does anyone try this?

It works on my Mac with macOS 10.15.5.

Please try printf '\x07' | dd of=<executable> bs=1 seek=160 count=1 conv=notrunc. Refer to https://stackoverflow.com/questions/60654834/using-mprotect-to-make-text-segment-writable-on-macos .

Does anyone try this?

I don't know how to set <executable>

go test actually includes three steps:

  1. compile the test functions into a binary
  2. execute the binary
  3. delete the binary

To work around this issue, we need to first generate the test binary, the modify the compiled binary with dd. e.g.

$ go test -c -o test-bin mytest/abc

With -c and -o option, go test will generate a binary named test-bin. Then modify the binary with dd according to https://stackoverflow.com/questions/60654834/using-mprotect-to-make-text-segment-writable-on-macos#:

$  printf '\x07' | dd of=test-bin bs=1 seek=160 count=1 conv=notrunc

Finally, you can run the test binary:

./test-bin

can solve the problem,But it's too cumbersome to execute every time So,It is recommended to use docker to solve this problem。

i also meet the problem and use this method printf '\x07' | dd of=test-bin bs=1 seek=160 count=1 conv=notrunc fix it .

but i want to know that if gomonkey can fix it ?

+1

eisenxp commented 3 years ago

https://github.com/eisenxp/macos-golink-wrapper may help.

aduan commented 3 years ago

https://github.com/eisenxp/macos-golink-wrapper may help.

It may be the best solution of this problem.

JasonRock commented 3 years ago

https://github.com/eisenxp/macos-golink-wrapper may help.

It's work well!

luckyzachary commented 3 years ago

The best way is to use docker. Another way is https://github.com/eisenxp/macos-golink-wrapper . Thanks a lot @eisenxp .

hsqStephenZhang commented 3 years ago

i found a repository: https://github.com/eisenxp/macos-golink-wrapper my colleagues have tried this method, all problems were settled

butcoder commented 2 years ago

arm64 MacOS can use amd64 version go, I change to go1.16.11 darwin/amd64,and https://github.com/eisenxp/macos-golink-wrapper

LaryCaka commented 2 years ago

谢谢哟,愿你开心每一天~

guyunzh commented 2 years ago

arm64 MacOS可以使用amd64版本go,我换成go1.16.11 darwin/amd64,和https://github.com/eisenxp/macos-golink-wrapper

it will be get other question. such as: can not debug. golang version: go version go1.16.15 darwin/arm64 system : mac m1 goland: 2021.3(m1 soc) 如果把GOARCH改成amd64,会导致无法debug。我新遇到的问题

LaryCaka commented 2 years ago

谢谢哟,愿你开心每一天~

agiledragon commented 9 months ago

v2.11.0 has been released!

LaryCaka commented 9 months ago

谢谢哟,愿你开心每一天~