10 ms·
> So, you create something that does not fulfill the C library invariant of what constitutes a "string", and then pass it to a copy function that assumes this i
by thristian 14y ago
> So, you create something that does not fulfill the C library invariant of what constitutes a "string", and then pass it to a copy function that assumes this invariant?
From the article:
> Some folks then defend this function (despite the proof above) by claiming that the strings in the proof aren't C strings. They want to apply an artful dodge that says "the function is not defective because you aren't giving it the right inputs", but I'm saying the function is defective because most of the possible inputs cause it to crash the software.
Zed's point is not that K&R is bad because their example code doesn't match C library invariants, he's saying it's bad because it encourages people to write code that blindly assumes C library invariants will always hold.
Certainly, if you're going to write C code there's some things that really do require blind trust (for example: that your code will be compiled by a conformant C compiler), but "all strings are safely null-terminated" is incorrect so often, and the cause of so many historic security vulnerabilities and crashes, that perhaps we shouldn't be encouraging new C programmers to do it.
- revelation 14y agoSo in a dynamically typed language, we then add type checks everywhere? Because we wouldn't want a function to accidentally process data that wasn't meant for it, no?
- jfager 14y agoThe equivalent errors in dynamically typed languages don't lead to critical security vulnerabilities like they do in C. You get a nice exception and a clean crash, not a hook to grab root.
- PommeDeTerre 14y agoRealistically, just about every mainstream dynamic language today has its major implementation(s) written using C or C++. Some of them have significant amounts of C code underlying their common libraries, as well. Some of the most popular third-party libraries or modules are in fact nothing more than thin wrappers over existing C or C++ code. Don't think that you're escaping C or C++ just because you're using Ruby, or JavaScript, or Python, or Perl, or Tcl, or even Java. Don't think that you aren't as vulnerable using a dynamic language as you are using C or C++ directly. Furthermore, it is quite easy for dynamically typed languages to suffer from very serious security vulnerabilities. There was one affecting Ruby and Ruby on Rails widely publicized just a few days ago. You can read more about it at: http://news.ycombinator.com/item?id=5002006 http://news.ycombinator.com/item?id=5002006
- pretoriusB 14y ago>Don't think that you're escaping C or C++ just because you're using Ruby, or JavaScript, or Python, or Perl, or Tcl, or even Java. Don't think that you aren't as vulnerable using a dynamic language as you are using C or C++ directly. Actually this is completely backwards. Think exactly that you are NOT AS vulnerable as using C or C++ directly. That it's C/C++ underneath has little importance. It FAR MORE difficult and FAR LESS common to reach runtime/interpreter bugs that to produce bugs of your own in the higher level language. >Furthermore, it is quite easy for dynamically typed languages to suffer from very serious security vulnerabilities. Of a different kind, that doesn't pertain to the current discussion.
- zxcdw 14y agoBut the beauty of modern programming languages is that the responsibility has gone from sole programmers to actual implementation developers. You would expect that people who implement the runtmies and libraries are far, far more knowledgeable, experienced and trustworthy. And it often is so -- the end user(programmer) can't be trusted to know all about security implications, possible vulberabilities let alone how to exploit them! The whole idea that "Well it's insecure because you program in insecure way!" is outright idiotic, and should be killed. If that means getting rid of C and C++ and people who write in these languages(Hey, myself included!) then so be it. The faster the better. Sure, there are cases in which it's hardly possible, but I'd take 10 times slower computer for 1) fewer bugs 2) more advanced software 3) cheaper software 4) far less security concerns any day. Now, I'm going to close the C++ project and go write some Python. Makes me feel happy and far less stressed, although C++ does damn well in comparison to C.
- PommeDeTerre 14y agoBut using a language like Ruby or PHP, for instance, doesn't really lead to fewer bugs, or more advanced software, or cheaper software, or fewer security concerns in practice. What it often actually leads to is untalented developers creating a lot of bug-ridden and vulnerable code extremely quickly. It's efficiency in all the wrong ways. Do you remember that Diaspora social networking project that received a lot of hype a couple of years ago? It was a Ruby on Rails app, and the early releases were absolutely filled with some particularly nasty bugs and security flaws. The only reason they were eventually fixed is because the code was made public, and people pointed out these flaws. There is a lot of Ruby code out there, for instance, that isn't public, yet is still riddled with the same types of problems. That's not to say that the same isn't true for Python, or Java, or C#, or C++, or any other language. But we shouldn't be claiming that using a language like Ruby or Python somehow leads to more secure code. It doesn't, and it's dangerous to think that it does.
- Evbn 14y agoSo they have infinity minus one problems. You still have critical systems crashing or silently misbehaving.
- InclinedPlane 14y agoDoes the absence of type checks in dynamically typed code result in remote execution vulnerabilities typically? It's twenty goddamn thirteen, stop writing trivial buffer overflow vulnerabilities already. And that applies whether you are a novice or an expert.
- pretoriusB 14y agoWhen you use a dynamically typed language you have CHOSEN to live without those concerns -- you traded checking for flexibility. In a statically typed language, where you already made the effort of using types, it would be a shame for your program to die or cause havoc because you didn't also think about enforcing some invariants. Plus, those kind of errors in C can cause buffer overflows, privilege escalation and such. In a dynamic language it's usually just a halt and a stack-trace. (And actually there is a move to do exactly what you say --add type checks in dynamic languages. See Dash and Typescript, with their optional type annotations and checks. But if it was possible to optionally have those checks by pure inference, without adding anything to a dynamic language's syntax, most people would jump at it instantly).