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

Bad SNMP client can cause infinite loop/OOM problems #401

Open
dgjustice opened this issue Mar 17, 2022 · 8 comments
Open

Bad SNMP client can cause infinite loop/OOM problems #401

dgjustice opened this issue Mar 17, 2022 · 8 comments

Comments

@dgjustice
Copy link

I will do my best to replicate this as soon as I can, but the device was fixed before I could get a proper packet capture. We had a Juniper router go bonkers and SNMP was returning a repeating series of incrementing OID's (e.g. [578.1, 578.2, 578.3, 578.1, 578.2, ...]). This check is not sufficient to guarantee loop termination: https://github.com/gosnmp/gosnmp/blob/master/walk.go#L147. My workaround was to use bulkwalk with a custom walkfn. snmpbulkwalk was able to catch it, but the gosnmp client can be put into an infinite loop in this corner case. To be clear, AppOpts is nil in my client code.

@TimRots
Copy link
Member

TimRots commented Mar 17, 2022

Hi @dgjustice. Thank you for taking the time to reach out about this issue, it's very much appreciated.

I would like to help to have the mentioned corner case fixed, but will need some additional pointers on how to trigger/replicate this behavior without the help from an actual pcap.

You mentioned snmpbulkwalk was able to catch it . Was snmpbulkwalk throwing something along the lines of Error: OID not increasing: xxx before returning with a non-zero exit status?

Any additional info that comes to mind would be very much welcomed.

@dgjustice
Copy link
Author

dgjustice commented Mar 18, 2022

Tim, thank you for being understanding given my absolute lack of supporting data. I was able to dig up the output of one of the bulkwalks we ran. It behaves as you indicated. I will try to create a test case to replicate this.

snmpbulkwalk -v3  -cr5 somehost .1.3.6.1.4.1.2636.3.60.1.2.1.1.6
iso.3.6.1.4.1.2636.3.60.1.2.1.1.6.577.0 = INTEGER: 0
iso.3.6.1.4.1.2636.3.60.1.2.1.1.6.578.0 = INTEGER: 0
iso.3.6.1.4.1.2636.3.60.1.2.1.1.6.578.1 = INTEGER: 0
iso.3.6.1.4.1.2636.3.60.1.2.1.1.6.578.2 = INTEGER: 0
iso.3.6.1.4.1.2636.3.60.1.2.1.1.6.578.3 = INTEGER: 0
iso.3.6.1.4.1.2636.3.60.1.2.1.1.6.578.32 = INTEGER: 0
iso.3.6.1.4.1.2636.3.60.1.2.1.1.6.578.33 = INTEGER: 0
iso.3.6.1.4.1.2636.3.60.1.2.1.1.6.578.34 = INTEGER: 0
iso.3.6.1.4.1.2636.3.60.1.2.1.1.6.578.35 = INTEGER: 0
iso.3.6.1.4.1.2636.3.60.1.2.1.1.6.578.64 = INTEGER: 0
iso.3.6.1.4.1.2636.3.60.1.2.1.1.6.578.65 = INTEGER: 0
iso.3.6.1.4.1.2636.3.60.1.2.1.1.6.578.66 = INTEGER: 0
iso.3.6.1.4.1.2636.3.60.1.2.1.1.6.578.67 = INTEGER: 0
iso.3.6.1.4.1.2636.3.60.1.2.1.1.6.578.96 = INTEGER: 0
iso.3.6.1.4.1.2636.3.60.1.2.1.1.6.578.97 = INTEGER: 0
iso.3.6.1.4.1.2636.3.60.1.2.1.1.6.578.98 = INTEGER: 0
iso.3.6.1.4.1.2636.3.60.1.2.1.1.6.578.99 = INTEGER: 0
iso.3.6.1.4.1.2636.3.60.1.2.1.1.6.578.128 = INTEGER: 0
iso.3.6.1.4.1.2636.3.60.1.2.1.1.6.578.129 = INTEGER: 0
iso.3.6.1.4.1.2636.3.60.1.2.1.1.6.578.130 = INTEGER: 0
iso.3.6.1.4.1.2636.3.60.1.2.1.1.6.578.131 = INTEGER: 0
iso.3.6.1.4.1.2636.3.60.1.2.1.1.6.578.160 = INTEGER: 0
iso.3.6.1.4.1.2636.3.60.1.2.1.1.6.578.161 = INTEGER: 0
iso.3.6.1.4.1.2636.3.60.1.2.1.1.6.578.162 = INTEGER: 0
iso.3.6.1.4.1.2636.3.60.1.2.1.1.6.578.163 = INTEGER: 0
iso.3.6.1.4.1.2636.3.60.1.2.1.1.6.578.192 = INTEGER: 0
iso.3.6.1.4.1.2636.3.60.1.2.1.1.6.578.193 = INTEGER: 0
iso.3.6.1.4.1.2636.3.60.1.2.1.1.6.578.194 = INTEGER: 0
iso.3.6.1.4.1.2636.3.60.1.2.1.1.6.578.195 = INTEGER: 0
iso.3.6.1.4.1.2636.3.60.1.2.1.1.6.578.224 = INTEGER: 0
iso.3.6.1.4.1.2636.3.60.1.2.1.1.6.578.225 = INTEGER: 0
iso.3.6.1.4.1.2636.3.60.1.2.1.1.6.578.226 = INTEGER: 0
iso.3.6.1.4.1.2636.3.60.1.2.1.1.6.578.227 = INTEGER: 0
iso.3.6.1.4.1.2636.3.60.1.2.1.1.6.578.0 = INTEGER: 0
Error: OID not increasing: iso.3.6.1.4.1.2636.3.60.1.2.1.1.6.578.227
 >= iso.3.6.1.4.1.2636.3.60.1.2.1.1.6.578.0

iso.3.6.1.4.1.2636.3.60.1.2.1.1.6.578.1 = INTEGER: 0
Error: OID not increasing: iso.3.6.1.4.1.2636.3.60.1.2.1.1.6.578.227
 >= iso.3.6.1.4.1.2636.3.60.1.2.1.1.6.578.1

iso.3.6.1.4.1.2636.3.60.1.2.1.1.6.578.2 = INTEGER: 0
Error: OID not increasing: iso.3.6.1.4.1.2636.3.60.1.2.1.1.6.578.227
 >= iso.3.6.1.4.1.2636.3.60.1.2.1.1.6.578.2

iso.3.6.1.4.1.2636.3.60.1.2.1.1.6.578.3 = INTEGER: 0
Error: OID not increasing: iso.3.6.1.4.1.2636.3.60.1.2.1.1.6.578.227
 >= iso.3.6.1.4.1.2636.3.60.1.2.1.1.6.578.3

iso.3.6.1.4.1.2636.3.60.1.2.1.1.6.578.32 = INTEGER: 0
Error: OID not increasing: iso.3.6.1.4.1.2636.3.60.1.2.1.1.6.578.227
 >= iso.3.6.1.4.1.2636.3.60.1.2.1.1.6.578.32

iso.3.6.1.4.1.2636.3.60.1.2.1.1.6.578.33 = INTEGER: 0
Error: OID not increasing: iso.3.6.1.4.1.2636.3.60.1.2.1.1.6.578.227
 >= iso.3.6.1.4.1.2636.3.60.1.2.1.1.6.578.33

iso.3.6.1.4.1.2636.3.60.1.2.1.1.6.578.34 = INTEGER: 0
Error: OID not increasing: iso.3.6.1.4.1.2636.3.60.1.2.1.1.6.578.227
 >= iso.3.6.1.4.1.2636.3.60.1.2.1.1.6.578.34

iso.3.6.1.4.1.2636.3.60.1.2.1.1.6.578.35 = INTEGER: 0
Error: OID not increasing: iso.3.6.1.4.1.2636.3.60.1.2.1.1.6.578.227
 >= iso.3.6.1.4.1.2636.3.60.1.2.1.1.6.578.35

iso.3.6.1.4.1.2636.3.60.1.2.1.1.6.578.64 = INTEGER: 0
Error: OID not increasing: iso.3.6.1.4.1.2636.3.60.1.2.1.1.6.578.227
 >= iso.3.6.1.4.1.2636.3.60.1.2.1.1.6.578.64

iso.3.6.1.4.1.2636.3.60.1.2.1.1.6.578.65 = INTEGER: 0
Error: OID not increasing: iso.3.6.1.4.1.2636.3.60.1.2.1.1.6.578.227
 >= iso.3.6.1.4.1.2636.3.60.1.2.1.1.6.578.65

@TimRots
Copy link
Member

TimRots commented Mar 18, 2022

Thank you Daniel for sharing this additional information. That helped a lot to better understand the issue at hand.
I will try my best to have it resolved soon.

@dgjustice
Copy link
Author

dgjustice commented Mar 18, 2022

The way I worked around it was to create a map of PDU's and check if a new value exists in the map. I am not terribly familiar with the low-level expectations of the protocol nor the library, so any ideas are greatly appreciated. Do you think the library should return an array of value and an error, or just an error? Ultimately, if someone wants particular behavior, they can implement their own walk function. I am also not sure how this should play with the max repetitions flag.

@dgjustice
Copy link
Author

Oh boy, I got to go protocol diving today. I was able to replicate the issue once I figured out how to craft the packets correctly.
You can run this test with go test github.com/gosnmp/gosnmp -run TestWalk. It should send your shell into oblivion. 😝 This was a quick-and-dirty effort. I am happy to receive feedback on how to clean it up and integrate it into the overall suite of tests if you feel it is appropriate. I don't mind spending some time on a solution, but I wanted to nail down the problem before throwing spaghetti at the wall. 😄

@dgjustice
Copy link
Author

Any updates on this? The simplest approach might be simply mentioning the edge case in the docs and pointing users to implement their own walk function.

@TimRots
Copy link
Member

TimRots commented May 27, 2022

Hi @dgjustice , sorry for my slow reply. Have been busy in private life.
I have a feature branch locally that fixed the issue, will try to work on it over the coming week and ask for your review.

@dgjustice
Copy link
Author

Awesome, no worries! I was mostly curious if my data was enough to validate the issue. Thanks for the quick follow-up!

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

2 participants