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

ParseNetlinkMessage parse failure is caused by an unknown bug #1

Closed
david415 opened this issue Aug 12, 2016 · 8 comments

Comments

@david415
Copy link

@david415 david415 commented Aug 12, 2016

firstly to use nfqueue i added this line to the OUTPUT chain in my ferm configuration:

proto tcp dport 8080 NFQUEUE queue-num 1 queue-bypass;
user@subgraph:~/gopath/src/github.com/david415/HoneyBadger/cmd/inferenceHose$ sudo ./inferenceHose -nfq_num 1 -patsy_ip 127.0.0.1 -target_ip 127.0.0.1 -target_port 8080
17:07:53 ▶ INFO 001 using ipv4 mode
17:07:53 ▶ INFO 002 before flutter
17:07:53 ▶ WARN 003 lo tcp %!s(int=65536) 127.0.0.1 %!s(int=8080) 127.0.0.1 %!s(bool=false) {{ } 0 0 %!s(uint32=0) %!s(uint32=0) %!s(uint8=0) %!s(bool=false) %!s(bool=false) %!s(bool=false) %!s(bool=false) %!s(bool=false) %!s(bool=false) %!s(bool=false) %!s(bool=false) %!s(bool=false) %!s(uint16=0) %!s(uint16=0) %!s(uint16=0)   []  [{%!s(layers.TCPOptionKind=0) %!s(uint8=0) } {%!s(layers.TCPOptionKind=0) %!s(uint8=0) } {%!s(layers.TCPOptionKind=0) %!s(uint8=0) } {%!s(layers.TCPOptionKind=0) %!s(uint8=0) }] {<nil>}}
17:07:53 ▶ NOTI 004 waiting for quit events
panic: runtime error: slice bounds out of range

goroutine 19 [running]:
panic(0x642560, 0xc8200140c0)
    /usr/lib/go-1.6/src/runtime/panic.go:481 +0x3e6
syscall.ParseNetlinkMessage(0xc82113e000, 0x71, 0x2000, 0x0, 0x0, 0x0, 0x0, 0x0)
    /usr/lib/go-1.6/src/syscall/netlink_linux.go:125 +0x387
github.com/subgraph/go-nfnetlink.(*NetlinkSocket).receive(0xc820062660, 0x0, 0x0)
    /home/user/gopath/src/github.com/subgraph/go-nfnetlink/nfnl_sock.go:201 +0xc0
github.com/subgraph/go-nfnetlink.(*NetlinkSocket).runReceiveLoop(0xc820062660)
    /home/user/gopath/src/github.com/subgraph/go-nfnetlink/nfnl_sock.go:177 +0x25
created by github.com/subgraph/go-nfnetlink.NewNetlinkSocket
    /home/user/gopath/src/github.com/subgraph/go-nfnetlink/nfnl_sock.go:88 +0x2fc
user@subgraph:~/gopath/src/github.com/david415/HoneyBadger/cmd/inferenceHose$ sudo ./inferenceHose -nfq_num 1 -patsy_ip 127.0.0.1 -target_ip 127.0.0.1 -target_port 8080

i then used netcat to test in and noticed that occasionally it crashes with this backtrace.

@david415

This comment has been minimized.

Copy link
Author

@david415 david415 commented Aug 12, 2016

@david415 david415 changed the title golang-1.6 syscal module's ParseNetlinkMessage parse failure golang-1.6 syscall module's ParseNetlinkMessage parse failure Aug 12, 2016
@david415

This comment has been minimized.

Copy link
Author

@david415 david415 commented Aug 12, 2016

to exercise the above described bug in the parsing code i was running the following:

was testing with this honeybadger branch:
https://github.com/david415/HoneyBadger/tree/93.add_inference_attack.0

building inferenceHose:
https://github.com/david415/HoneyBadger/blob/93.add_inference_attack.0/cmd/inferenceHose/main.go

and running it like this:

sudo ./inferenceHose -nfq_num 2 -patsy_ip 127.0.0.1 -target_ip 127.0.0.1 -target_port 8080

and then test with netcat...

nc -l 8080
nc 127.0.0.1 8080

It stops responding, I control-c, it returns an error:

2016/08/12 20:48:04 XXX ParseNetlinkMessage: decoded dlen 100 > message len 97

Aha! Out of bounds message!

@david415

This comment has been minimized.

Copy link
Author

@david415 david415 commented Aug 12, 2016

i filed a ticket with google: golang/go#16681

@david415

This comment has been minimized.

Copy link
Author

@david415 david415 commented Aug 14, 2016

i wonder how long it'll take @google to review https://go-review.googlesource.com/#/c/26990/

@Squalluca

This comment has been minimized.

Copy link

@Squalluca Squalluca commented Sep 4, 2016

Hi @david415 ,

i was tinkering with the library and got the same error you got, patching using your proposed code seems to not solve the issue, apart from letting the program silently crashing instead of printing the stack trace.

It seems like the problem is in line 199, substituting

return h, b[syscall.NLMSG_HDRLEN:], nlmAlignOf(int(h.Len)), nil

with

return h, b[syscall.NLMSG_HDRLEN:], int(h.Len), nil

seems to solve all problems of lenght mismatch, i was wondering if it is a kernel version problem, i'm running on debian with
# uname -r 4.6.0-0.bpo.1-amd64

@david415

This comment has been minimized.

Copy link
Author

@david415 david415 commented Sep 11, 2016

actually there are two sections of ParseNetlinkMessage that create slices without checking boundaries. you can see our discussion on the goolge code review link above. your suggestion might fix the bug for you but slice boundaries still need to be checked.

@david415 david415 changed the title golang-1.6 syscall module's ParseNetlinkMessage parse failure ParseNetlinkMessage parse failure is caused by an unknown bug Sep 11, 2016
@david415

This comment has been minimized.

Copy link
Author

@david415 david415 commented Sep 11, 2016

here is a very simple and concise working program that demonstrates the parse failure:

package main

import (
    "fmt"
    "github.com/subgraph/go-nfnetlink/nfqueue"
)

func main() {
    var err error
    nfq := nfqueue.NewNFQueue(2)
    receiveChan := make(<-chan *nfqueue.NFQPacket, 0)

    receiveChan, err = nfq.Open()
    if err != nil {
        panic(err)
    }
    defer nfq.Close()

    for p := range receiveChan {
        fmt.Printf("Packet: %v\n", p.Packet)
        p.Accept()
    }
}
@elevran

This comment has been minimized.

Copy link
Contributor

@elevran elevran commented Jan 19, 2017

The change proposed in this PR will return an error and fail to parse the packet from the kernel, which may or may not be acceptable, depending on the use case. I've see several cases where receive from gets a valid netlink message that is not 4B aligned (e.g., 58 and 119 bytes, in which case the aligned buffer would exceed the slice length and panic while parsing).
#2 proposes a different alternative, which attempts to fix the issue without dropping valid packets, by ensuring that we always pass an aligned buffer.

@brl brl closed this in #3 Jan 23, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
3 participants
You can’t perform that action at this time.