-
Notifications
You must be signed in to change notification settings - Fork 193
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
With Go program, when server program does a read, getting permission denied. #261
Comments
try to config above parameter to manifest
and ensure there have |
Is it possible to try this Go program in TCP mode (switch from a UDP connection to the TCP connection)? This will give us some more info on which part of Graphene fails. In particular, the UDP handling code in Graphene is buggy -- not many programs use UDP, so didn't have enough testing in Graphene. |
I tested with some sample Go program that launches a TCP server, that listens on a TCP port. Client is able to connect to it, and send a buffer. TCP server is able to read that buffer(sent by client), without any issues, when running in Graphene. Attaching the test TCP program in Go->(gopro_tcp_testing.zip ) Also here are the logs, when running TCP program in Go(using Graphene-SGX): //Part of graphene's log(when launching TCP server) //Client -> Using a terminal: |
@dimakuv , you seem to be right that when I tried a sample TCP server Go program, it worked fine in Graphene. So, it appears like issue is seen when having UDP server in Go running in Graphene. Also, for the actual Go application server that I am using-> https://github.com/omec-project/upf-epc/tree/master/pfcpiface, the team that supports this application, have informed that they need to use UDP server for their use-case. |
@sudharkrish Have you tried gramineproject/graphene#2679? This solves a problem with partial writes, both in TCP and in UDP modes. Not sure if this can help. Anyway, can you run your failing app with |
@dimakuv , I applied PR gramineproject/graphene#2679 but it did not make a difference. I am attaching logs with loader.log_level = "all"-> ( |
@dimakuv did some debugging and here is some info. Later, when Go server code, does a read, I can break at shim_do_read-> (hdl type is socket)-> shim_socket.c::do_recvmsg-> DkStreamRead(which returns -13 Permission Denied)... DkStreamRead calls _DkStreamRead...and here Looked into PAL code, when socket fd gets created for UDP stream, the handler-functions in db_socket, such as udp_receive From the code, it looks like Graphene’s PAL does NOT support a UDP server object that So when udp-server’s code in Go (sConn.Read(buf) ), invokes a read(without address parameter), Graphene’s PAL layer errors out saying -PAL_ERROR_NOTSUPPORT, struct handle_ops g_udpsrv_ops = { I added an experimental change to add entry for .read = &udp_receive in the above struct for g_udpsrv_ops And with this change in Pal, I am seeing a different error, |
Here is some GDB trace output:
Since the handler for udp’s socket_read function is NOT set, it is NULL,
|
@sudharkrish Thanks for debugging this. Indeed, you are correct. UDP support in the PAL code is... bad. To explain again what Sudha already found out. (We have the same problem in Linux and Linux-SGX PALs, so below I describe on the example of the Linux PAL.) We have two PAL handle types in Gramine: We have two implementations of the recv function for UDP: gramine/Pal/src/host/Linux/db_sockets.c Lines 715 to 785 in 74420be
So far so good. But then we have rather interesting mapping "PAL handle type -> supported operations" here: gramine/Pal/src/host/Linux/db_sockets.c Lines 1150 to 1170 in 74420be
In other words:
So the UDP client can never use Conclusion: Our current UDP code doesn't support the code in this issue. Someone needs to add this functionality... |
You see this error because we have these checks:
@sudharkrish What happens if you simply remove these checks? Then your Go program may start working. |
@dimakuv per your suggestion, after allowing udp-server objects to invoke udp_receive which does NOT take address parameter, read works.
In general, UDP-server code in C, passes address parameter passed along with read or write on that UDP socket handle, so Graphene's UDP-server code is able to handle it. Question is, how to formalize these changes. Besides this additional use-case, where udp-server instance can do a read(without passing address parameter), not sure if there are other cases. For example, I am not sure, if it is feasible to do a write on udp-server instance, that is call to udp_send, without a address parameter. |
@sudharkrish Could you show your resulting modifications to Gramine (via |
@dimakuv , it is just 2 lines of change, here is the diff below:
|
@dimakuv did some reading on this UDP topic. As per info in this blog-> (https://dadrian.io/blog/posts/udp-in-go/), atleast in Golang, it is not possible to do a udp_write(without a address parameter) for a non-connected socket. But udp_read is possible on a non-connected socket. This is the use-case this PR tries to resolve(that is udp_read(from a UDP-server) for a non-connected socket, in which case, no need to provide peer's address). |
Thanks, @sudharkrish, this is very useful. I assigned this issue labels, we'll need to add such UDP functionality to Gramine. Probably not just yet because it needs more reading and testing, and we are currently busy with other things. |
@sudharkrish please verify that #579 fixes the issue. It does for me. |
@boryspoplawski , due to system upgrade to newer ubuntu, and other setup issues, not able to quickly test this. Since, it works for you, you can close this PR. |
Description of the problem
With Go program, when server program does a read, getting permission denied.
Steps to reproduce
Able to reproduce on a recent graphene pull(Aug 30th, 2021), commit-id-> c321726229eaf0a1b52dc5e2507c9cfab423ea94
Also able to reproduce on https://github.com/oscarlab/graphene/releases/tag/v1.2-rc1
Providing Sample Go program and scripts to reproduce the issue.
In graphene repo, under your /home->/graphene/Examples directory, copy this zip file->(
go_sample.zip) , and then unzip it,
to create go_sample directory under /graphene/Examples/go_sample.
Under /graphene/Examples/go_sample$
Run the script -> ./launch_in_graphene_locally.sh
This will build the sample Go program(in a docker container), and then do a graphene-sgx build, and
then it will launch it locally on your host system.
When the Go Server code does a read, getting permission denied.
Expected results
Output below, when running the same Go program, outside of Graphene.
Examples/go_sample$ ./main
SK_DBG: listening on 172.17.0.1:8805
client: wrote: hello
server: read: hello
Actual results
In Graphene, when the Go Server code does a read, getting permission denied.
[P17460:T1:main] debug: Allocating stack at 0x0 (size = 8388608)
[P17460:T1:main] debug: loading "file:./main"
[P17460:T1:main] debug: adding a library for gdb: file:./main
[P17460:T1:main] debug: Creating pipe: pipe.srv:17460
debug: sock_getopt (fd = 11, sockopt addr = 0x7ffda07f52b0) is not implemented and always returns 0
[P17460:T1:main] debug: Shim process initialized
[P17460:shim] debug: IPC worker started
[P17460:T1:main] debug: Created sigframe for sig: 23 at 0xc4009390 (handler: 0x460be0, restorer: 0x460d20)
debug: sock_getopt (fd = 12, sockopt addr = 0x7ffda07f52b0) is not implemented and always returns 0
[P17460:T1:main] debug: Creating pipe: pipe.srv:8fcf6dd6dc08723b8328139ef1955390c16982da3379e1b7f6c07bc4bdc66514
debug: sock_getopt (fd = 15, sockopt addr = 0x7ffda07f52b0) is not implemented and always returns 0
debug: sock_getopt (fd = 16, sockopt addr = 0x7ffda07f52b0) is not implemented and always returns 0
debug: sock_getopt (fd = 17, sockopt addr = 0x7ffda07f52b0) is not implemented and always returns 0
[P17460:T1:main] debug: add fd 5 (handle 0xfb098610) to epoll handle 0xfb098550
[P17460:T1:main] debug: add fd 3 (handle 0xfb0983c0) to epoll handle 0xfb098550
SK_DBG: listening on 172.17.0.1:8805
Allowing access to an unknown file due to file_check_policy settings: file:/etc/localtime
2021/09/03 18:08:33 read udp 172.17.0.1:8805: read: permission denied
Additional information
Go sample code under gopro2 folder in zip file attached.
When Go Program calls net.ListenUDP, this api invokes 2 syscalls, 1. to create socket, 2. bind
When Go server program calls net.ListenUDP these 2 syscalls are successful.
Go program launches a light-weight thread that runs the Client-function, which tries to connect to the server using
Go's net.DialUDP function, and then does a write. Later, server code tries to do a read, and this is where it fails,
with permission denied error(shown in the log above).
The text was updated successfully, but these errors were encountered: