5 ms·
That doesn't make any sense to me. Most instructions are not atomic, so even if you had runtime checks something like a debugger could still inject invalid sta
by athrun 3y ago
That doesn't make any sense to me.
Most instructions are not atomic, so even if you had runtime checks something like a debugger could still inject invalid state in between your checks, making them ineffective.
If real-time code injection is your threat model, I don't see how runtime checks would get you anywhere.
- wahern 3y agoYou seem to be suggesting that (to use a common phrase) if something can be done, it should be done. The previous poster's example regarding a debugger was to challenge the notion that there was any meaningful reason to constrain non-accidental type subversion. You seem to be saying it's absurd to care about someone using a debugger to inject invalid code at runtime because there's nothing you can do about it, thus implying if you can do something, you should. But that only begs the question--why should you? To some people, defending against debugger code injection is no more absurd than defending against other examples where the programmer deliberately alters code to subvert static type checking. If you disagree then articulating more meaningful distinctions among cases would be worthwhile. Mere ability is generally not considered sufficient justification alone to do something.
- kiitos 3y agoThis is an inane comparison. Casting as demonstrated in the example is normal and has to be expected. Go types aren't as strict as types in other languages. Code can't assume otherwise.
- ori_b 3y ago> Casting as demonstrated in the example is normal and has to be expected. Can you give an example where someone has done similar casts accidentally? It seems like it would be hard to accidentally typo. That leaves malice, which seems difficult to defend against, in light of the kinds of system calls that are available to a program.
- kiitos 3y agoSure, by parsing a string to a Color value.
- wahern 3y agoThe example given wasn't a simple cast of a value, and definitely not an implicit coercion. The example is more like C-style type punning where you explicitly cast a pointer to the value and then write through the dereferenced pointer. I don't doubt that there are niches where such explicit type coercion patterns are common in Go and susceptible to mistakes, but I doubt usage of constant identifiers is such a niche. Rust is currently the standard bearer for strong, static type safety, and it even has both the enum types and pattern matching construct which Go lacks. AFAIU, you can use unsafe{} Rust code to perform a similar type punning trick, successfully assigning an invalid value to an enum object. I don't know if Rust's code generator always inserts runtime validity checks in match statements on an enum value without a catchall/default case, but certainly it's possible for Rust code to have an explicit if/else chain that at compile time appears comprehensive but which would neither panic nor produce the expected behavior. Does that mean Rust programmers shouldn't rely on Rust's static typing, instead always adding explicit code to handle unknown/invalid enum values? Maybe the assertion that Go code should have such checks is more reasonable than for Rust code, but you haven't explained how. At least to me, the simplest, minimal code to achieve the subversion in both Go and Rust seems similarly stilted and similarly unlikely to be written by mistake. (To be clear, the context of this subthread as I understand it assumes the interface method hack, the subversion of which requires the type punning.)
- kiitos 3y agoI don't know what point you're trying to make, beyond just objecting to the points that I'm trying to make. Not interested in continuing.
- ori_b 3y agoCan you point at a git commit where someone had a similar bug implemented by accident and fixed it? The code you posted earlier seems to be something that would be incredibly hard to write without malice. And if you're considering malice, you also need to consider mmap, foreign function interfaces, writes to /dev/memory, and other similar perverse mechamisms.