4 ms·
FWIW, Go absolutely would not stop you writing unbounded data into a bounded struct. Idiomatic Go would be to use byte slices which auto-resize, unlike idiomati
by JulianMorrison 5y ago
FWIW, Go absolutely would not stop you writing unbounded data into a bounded struct. Idiomatic Go would be to use byte slices which auto-resize, unlike idiomatic C, but you still have to do it.
- slownews45 5y agoWhat's the exploit path assuming no use of unsafe? I can see situations where I could probably get go to crash, but not sure how I get go to act badly. Note: Not a go / Haskell / C# expert so understanding is light here.
- JulianMorrison 5y agoGo has no "unsafe" keyword and several parts of the language are unsafe, you're thinking of Rust which has much tighter guarantees. Go idioms, like accepting data into buffers that are resized by "append", work around the unsafe parts of the language.
- slownews45 5y agoGo has an unsafe package. Is there an example of even "bad" go code that gets you from a overflow to an exploit? I'm curious, folks (usually rust folks) do keep making this claim, is there a quick example?
- ptaq 5y agoYou can totally do this with bad concurrency in Go: read-after-write of an interface value may cause an arbitrarily bad virtual method call, which is somewhat UB. I am not aware of single goroutone exploits, though.
- slownews45 5y agoConcurrency issues / bad program flow feel a bit different don't they? I mean, I can store the action to take on a record in a string in any language, then if I'm not paying attention on concurrency someone else can switch to a different action and then when that record is processed I end up deleting instead of editing etc. I mention this because in SQL folks not being careful end up in all sorts of messed up situations with high concurrency situations.
- saagarjha 5y agoIt's a different kind of bug–changing the type on a record cannot give you a shell, it can just let you do something funny with the record, such as deleting it. Which is bad, of course, but a bounded bad. Memory corruption is unbounded bad: in general, corruption is arbitrary code execution. Your program might never interact with the shell but it's going to anyways, because an attacker is going to redirect code execution through the libc in your process. This is just not possible in languages like Java* , which provide details of what kinds of (mis)behaviors are permissible when a race occurs. The list of things is always something like "one of the two writes succeeds" or similar, not "¯\_(ツ)_/¯". *Barring bugs in the runtime, which do exist…but often because they're written in unsafe languages ;) Although, a bug in runtime written in a safe language will also give you arbitrary code execution…but that's because the job of the code is to enable arbitrary code execution.
- deleted 5y ago[deleted]
- cjbprime 5y agoGo is sometimes considered memory unsafe because of the presence of data races. (This is a controversial semantics.)
- senderista 5y agoThen Java is also unsafe by the same standard.
- cjbprime 5y agoWhy do you say that? Go's data races can produce memory corruption through bounds checking failures. I'm not aware of Java having that kind of memory corruption.
- josephg 5y agoYes. Java and C# are unsafe by the same standard. Last I checked, they both allow multiple threads to nonatomically modify a raw variable - which can lead to data races and data corruption. I haven't heard of anyone getting RCE out of this class of bug in C# or java though.
- astrange 5y agoIt's common to exploit JavaScript engines with this kind of bug, and JS engines probably have better security teams at this point, so I expect you could get an RCE if you really tried.
- saagarjha 5y agoYes, but those would be bugs in the runtime itself, rather than in the programming language. Java and JavaScript both define behavior of racy code; Go does not.
- fulafel 5y agoJVM semantics[1] don't allow this to corrupt program state arbitrarily, just the data variables in question, right? Whereas in Go.. Search for "corruption" in https://research.swtch.com/gomm https://research.swtch.com/gomm [1] Not just Java, meaning all the many nice JVM languages enjoy this is as well, eg Clojure, Scala etc
- foobiekr 5y agoIdiomatic go would have you using bounded readers though.
- JulianMorrison 5y agoEither you read data into a fixed byte[] and stop at its capacity, or you read data into an unbounded byte[] by using append, and Go looks after the capacity, either way, you can't go off the end.
- jerf 5y agoGo would stop this from being exploitable. You might be able to make a slice larger than it is "supposed" to be, but it won't overwrite anything else because Go will be allocating new memory for your bigger slice. But this is hardly a big claim for Go. The reality is that of all current languages in use, only C and C++ will let this mistake happen and have the consequence of overwriting whatever happens to be in the way. Everything else is too memory safe for this to happen.
- asdfasgasdgasdg 5y agoIs it idiomatic go to memcpy into a struct? I would think that this whole paradigm would be impossible in safe golang code.
- slownews45 5y agoThat's what I'm trying to understand. Let's ignore idiomatic code, people do crazy stuff all the time. What's the go example that gets you from for example an overflow to exploit? That's what I'm trying to follow (not being an expert).
- asdfasgasdgasdg 5y agoI am skeptical that you could do it without either using the assembler or the unsafe package, but we will see what Julian says.