Hey Ian!

Thanks for your swift response. Let me clarify some things that I didn't 
seem to convey well in my initial question.

Probably the most important; I'm not looking to disclose a vulnerability in 
Go here. If I was to disclose that, I would use the points of contact 
you've mentioned.
I'm trying to understand the implications of an attacker being able to 
write into the inodes created by the Go runtime.

Also, I must apologize for the wrong usage of the term "anonymous pipe". I 
must have mixed it up with what's being used in the link I've mentioned 
while writing my question.
When I create a "Hello world" Go application, I see that it creates two 
*anonymous 
inodes *(not anonymous pipes) via epoll_create(2) and eventfd(2). These 
are, as you have mentioned correctly, what the pointers are being passed to 
in the example I've sent. Now, my question is, what can an attacker do if 
he gains write access to said inodes? Or, to phrase it more generally, what 
happens with the data that's being sent there?

You've mentioned the following:
> They are used so that when some operation occurs on a file descriptor the 
runtime poller knows what to do.

Can you point to a code location in the runtime I could look at to better 
understand what's going on there?

Thanks in advance!

Best,
Moritz


Ian Lance Taylor schrieb am Donnerstag, 9. Januar 2025 um 19:00:54 UTC+1:

> On Thu, Jan 9, 2025 at 9:16 AM Moritz Sanft <gree...@gmail.com> wrote:
> >
> > I've recently came across a Go application with an arbitrary file write 
> vulnerability restricted to `/proc/self`. After researching for a little, 
> I've found the following article which exploits such a vulnerability in a 
> NodeJS application, escalating it into remote code execution by using 
> anonymous pipes for control messages of the language runtime. [^1]
> >
> > I wondered whether Go is susceptible to the same attacks, as it also 
> utilizes anonymous pipes, and checked what is sent into the pipes by a 
> benign exemplary Go application:
> >
> > ```
> > 166301 epoll_create1(EPOLL_CLOEXEC <unfinished ...> 166301 <... 
> epoll_create1 resumed>) = 3<anon_inode:[eventpoll]> 166301 
> epoll_ctl(3<anon_inode:[eventpoll]>, EPOLL_CTL_ADD, 4<pipe:[591683]>, 
> {events=EPOLLIN, data={u32=11354728, u64=11354728}}) = 0 166307 
> epoll_pwait(3<anon_inode:[eventpoll]>, <unfinished ...> 166301 
> epoll_ctl(3<anon_inode:[eventpoll]>, EPOLL_CTL_ADD, 
> 7</proc/sys/net/core/somaxconn>, 
> {events=EPOLLIN|EPOLLOUT|EPOLLRDHUP|EPOLLET, data={u32=3260835688, 
> u64=124595967125352}}) = 0 166301 epoll_ctl(3<anon_inode:[eventpoll]>, 
> EPOLL_CTL_ADD, 6<socket:[591684]>, 
> {events=EPOLLIN|EPOLLOUT|EPOLLRDHUP|EPOLLET, data={u32=3260835688, 
> u64=124595967125352}}) = 0
> > ```
> > Values like `124595967125352 (0x7151c25c6768)` look like pointers, which 
> generally look interesting depending on what the runtime does with them.
> >
> > I quickly skimmed the source code to find the relevant handlers, but to 
> no success.
> > Can anyone point me into the right direction here, or did someone even 
> analyze the security of these anon pipes before?
>
> Interesting vulnerability.
>
> An arbitrary Go program can of course create anonymous pipes and use
> them however it likes, which may possibly introduce a vulnerability in
> some cases. I assume that your question is specifically about using
> anonymous pipes in the Go runtime and standard library.
>
> On macOS the Go runtime uses an anonymous pipe to wake up the thread
> that manages the queue of incoming signals. The value sent on the pipe
> is ignored so I don't see a security issue here (other than a possible
> denial of service attack, but arbitrary file writes probably permit
> that in other ways).
>
> On NetBSD, OpenBSD, and AIX the Go runtime uses an anonymous pipe to
> wake up the network poller when a newer timer is scheduled. Again the
> value on the pipe is ignored.
>
> I don't think there is any other use of anonymous pipes.
>
> The pointers you show as the data of EPOLL_CTL_ADD, presumably on
> Linux, are internal pointers that are passed into epoll and returned
> from epoll. They are not sent on the network or received from the
> network. They are used so that when some operation occurs on a file
> descriptor the runtime poller knows what to do. These are not
> anonymous pipes, and I don't see any vulnerability there.
>
> So I don't see any security issue here for Go in general. Of course it
> would be interesting to learn otherwise. If somebody sees a security
> problem, please see https://go.dev/security for a safe way to report
> it.
>
> Ian
>

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion visit 
https://groups.google.com/d/msgid/golang-nuts/7ac8fd08-5118-4575-97cc-fb8e4678ff1fn%40googlegroups.com.

Reply via email to