Domain: splint.org
Stories and comments across the archive that link to splint.org.
Comments · 46
-
Re:Static analysis
There are also other statical analysis tools like splint. The catch is that it produces a large volume of data which is tedious to sift through, but once done you will have found the majority of the bugs in your code.
However the root cause is that the language itself permits illegal and bad constructs. It's of course a performance trade-off, but by coding part of the code in a high level language and leave the performance critical parts to a low level may lower the exposure and force focus on the problems to a certain limited area.
A secondary cause is that if you write code - write it as clean as possible and broken down into pieces. If coding C there's always the option of declaring a function as "static inline" to tell the compiler that what you do is going to get right into the execution flow because you know that it will improve performance.
Dynamic analysis is also good - like Valgrind, but they have shortcomings. Just be aware that fuzzing can confuse dynamic analysis tools as well producing inconsistent results, which means that for the initial tests you need to be able to turn off fuzzing to get rid of the consistent problems.
-
Re:From today's TheDailyWTF
Start with teaching the employees the importance of writing good code.
Also teach them how to refactor code in the IDE they use to avoid gigantic monolitic methods/functions/classes.
Then provide them with the tools. In addition to compile at the highest warning level and using the built-in support in the IDEs they should look at Stylecop for C# (even though it's more about style than finding potential bugs), Splint for C, FindBugs for Java.
People that are willing to take in and understand the importance of writing good code will end up being better.
And don't forget that people are competitive to some degree - so if you find a way to measure the quality of the code produced it's fine, and let it come with a small advantage. A movie ticket, a box of chocolate or something similar.
-
Re:OS X is THE superior OS
"Not very bright and petulant is no way to go through life son. I worked on the team that developed vax/vms, and worked for Jim Allchin and David Cutler before they went to microsoft to create the current instances of windows. Take the advice of a more experienced person..."
That's pretty good advice. Could you point me to any?
"To say that any large code piece is more or less susceptible to viruses is in and of itself foolish."
That is a phenomenally absurd statement. Your claim suggests that there is no such thing as slint, for example. If I have two code bases - one which has code that passes slint in its entirety and one which is chock full of code that does not - then I would be a moron not to say that the latter is more susceptible to viruses. It's great that you were David Cutler's chauffeur, but it doesn't qualify you to have opinions which you have firmly established are unfounded in skill or knowledge of security principles.
-
Re:What's worse that no documentation?
And the only correct documentation is the code itself. Anything else is a opinion and should be viewed accordingly.
Of course the code itself only tells you what the code does, not what the code is supposed to do, nor why it is doing it. Note that the difference can be rather crucial in maintenance and bug fixing.
I don't know how many times over my 30 year career that I've read documentation and started work only to find out later that it hadn't been updated. The first standard in your documentation rules should be that all relevant documentation is created and updated before code goes into production. No excuses.
Which is why it's always nice to have documentation that can be tested against the code. Now the "why" part of documentation is rather hard to verufy against code, but the "what it is supposed to do" should be able to be automatically verified if it is sensibly written: for instance in Eiffel requires and ensures clauses, or in JML, or splint, or SPARK; which allow for varying levels of static checking, runtime assertions, and automatic unit test generation (depending on what you are using) to ensure that if code and documentation falls out of sync an error should be immediately flagged.
-
Re:Ockham's Razor tells me....
Perl is in itself neither good or bad.
And neither are the programmers of history really guilty.
The big issue here is that what started out as something small and neat has been growing over time with different programmers involved. This is caused by various input from different areas within a company and after a while the structure that once was consistent is now degraded and there is a lot of dead code. And the evolution of the language has also contributed because what once was the only way to do something can now be done in three different ways.
But this is still nothing that's unique to Perl. Most languages suffers from this problem, and the problem arises from the fact that there is often no compile-time verification of the code to find any inconsistencies between modules.
Languages with strong and static typing are a bit better to cover for problems like these, since they can verify the worst problems at compile time. Additional tools like Findbugs and Splint can also help.
Weak and dynamic typing are fatal problems waiting to happen. You may claim that it's resolved by better testing, but that drives up the cost since the iterations will be longer. And some cases are missed during tests because that code is only executed in rare cases.
So if anything - what should be hated are weakly and dynamically typed programming languages. Regardless of what the language is called. But we can't live completely without them either since they come in handy from time to time. But at least the usage shall be limited to keep things safe.
And back to the issue where code has evolved over time - it is sometimes the best to actually bring together a set of engineers that has to analyze the functionality of an existing system and then rewrite the whole system in a consistent way using a language like Ada, Java or C#. In some cases special languages may be needed because there can be functionality that can be best expressed in Erlang or Fortran. This means that it's important to not be too obstinate about using a single language for development. Select one main language and make it interact with other languages when needed.
Lines of code is of course not a good measurement of the complexity of an application or the task ahead. A programmer may use weeks to code something that's a 1000 lines long, but other parts can be 5000 lines in a day.
Comments in code are useful - but only to a degree, too much comments will just obscure the code instead.
Breaking down code into reasonable modules is also important. Tools like Eclipse have some refactoring capabilities which allows you to actually break out a certain code segment into a new method in Java.
And yet another factor that's easily forgotten is that there are three types of systems;
1. Architect designed systems.
2. Hacks.
3. Evolved systems.
Both 1 and 2 can converge into an evolved system, but the evolution depends strongly on the programmers involved and their experience. An experienced programmer can actually restructure a hack into a structured evolved system, but inexperienced programmers can easily cause a designed system to be evolved into an unstructured evolved system. Available tools and methods also bear their share for the quality of an evolved system. -
Define "work"
They will indeed find certain classes of bugs, and code that is lint-free (especially with more modern versions of lint has fewer defects. Other metrics, like McCabe cyclomatic complexity, can also point out areas in which bugs have a high probability.
On the other hand, no tool can find 100 percent of bugs. This is a theorem (via Turning's halting and equivalence theorems), and also because some bugs are places where the code is doing what it was supposed to do, but that isn't what the user actually wanted. -
Re:Of course they can workSuch tools work in a very similar way to what is already being done in many modern language compilers (such as javac). Basically, they implement semantic checks that verify whether the program makes sense, or is likely to work as intended in some respect. The keywords here, for the purposes of good static analysis tools, are "work as intended". Knowing what code is intended to do isn't trivial, and it can be severely limiting in what static analysis tools can check for (or, alternatively, they can spit back a lot of false positives). A good solution is provide the static analysis tool with some hints as to what the programmers intentions are -- that means annotations as used by splint, or ESC/Java2, or something similar. The benefits for static analysis (and API documentation depending on the tools) can far outweigh the "extra" work*; consider the sorts of errors ESC/Java2 can successfully catch for instance. Of course you have to be interested in doing static anaylsis to begin with, btu the benefits are definitely available.
* Note that "extra" is in scare quotes because ultimately most of the annotations are usually things you should be documenting anyway, so it's not so much "extra" work as documentation that gets done sooner rather than later. -
Re:The crux of the exploit:
Don't blame the pipe-wrench for making a poor hammer. Blame the craftsman too lazy to find a hammer.
A more accurate analogy would be "don't blame the hammer because your shelf is uneven since you didn't bother to use a level.
Splintand friends will show up NULL pointer bugs very quickly even when using it's most liberal setting.
Of course the average C programmer hasn't progressed beyond not fixing compile warnings so they haven't gotten to the splint part yet. Sometimes I wish "-WERROR" was GCC's default.
-
Re:I can't wait for RMS to die
If it's this splint, then it's not Stallman's work
-
Re:I can't wait for RMS to die
If it's this splint, then it's not Stallman's work
-
SPLINT is the answer for C.See www.splint.org for a really good tool for static code checking when it comes to C.
I have used it sometimes, and as I have noticed that in some cases the version from CVS is better than the released version. (but as always, your mileage may vary).
For C++ it's a lot harder, but the programming rules for C++ and the compilers are a bit stricter too, so you may be helped there.
To make things worse (or better, depending on how you see it
:-) ) you can always take a look at PurifyPlus from IBM. It contains three components, Purify; which checks runtime for memory leaks and illegal memory access, Quantify; which checks for performance bottlenecks and PureCoverage; which checks so that all parts of your code actually has been executing during your tests.C++ is also a lot harder to do static checking on due to the fact that it contains inheritance and still allows a lot of features from C so an object can be passed around in a perfectly legal manner and still be hiding from the syntax checker. Openings for really strange bugs if someone decides to do "smart programming".
-
C and C++ Static Analysis tools
I work on a C/C++ code base that is a lot bigger than 500k lines. I've worked with results produced by Klocwork and also with the output from Reasoning. Both of these services/packages will cost you money but both provide good insight into your code. The commercial packages generally produce more focused results with less false-positives, so while they cost you money up front, your developers will spend less time weeding out the noise.
If paying money out for a commercial package isn't your thing, don't overlook the old standby lint or splint, an updated successor.
Also well worth investigating to see how your code is actually running is Valgrind and it's associated tools. The Valgrind toolkit will give you a good idea where memory is being leaked, where variables and pointers are going off the rails. Valgrind hooks into a running program, so it's important to make sure that you test all the corners of the codebase if you go this route.
Cheers,
Toby Haynes -
Careful what you wish for
Whatever you use, make sure you adjust the settings to only capture those problems that you think are critical. With 500k lines of code, unless your codebase is *extremely* solid running a Lint tool will result in a LOT of action items. I've used SPLINT (a lint for secure programming - http://www.splint.org/) in a project with a codebase much smaller than 500k and it took weeks to finish addressing all the issues - sometimes these things can be more of a curse than a blessing.
-
Splint
http://www.splint.org/
END OF LINE -
Same way you hunt bugs
0) Don't "roll your own" security unless absolutely necessary. Find someone else's implementations and work with those.
1) Design the code for security, code to that design. I've seen of security bugs creep into code because it was never designed to be secure.
2) Use static code checkers--such as Splint for C/C++ and FindBugs for Java--that look for security vulnerabilities.
3) Peer reviews/code audits. Sit down with your code (and have others who know how to look for security vulnerabilities sit down with your code) and do a full review.
Nothing is foolproof, but every little bit helps. It should be noted that all of the above also improve the overall quality of the code and reduce the number of overall bugs: Finding existent implementations of features that can be used can reduce maintenance and reduce bugs; Designing the code and putting it through a proper design review can catch a lot of logic problems and ensure that the code fits the requirements list--I've seen a huge number of synchronization bugs in Java simply because the author didn't know how to use synchronization properly; static code checkers find a lot more than just security bugs; and Peer Reviews/Code Audits can help isolate a variety of problems.
-
Re:27 clicks later
It's nice to see the suggestions to actually use available tools to see what your code is actually doing and where it might be going wrong. There are many available, and some are remarkably good. Splint, for instance, has a talent for turning up unlooked for errors, and if you're willing to add a few annotations here and there it can do even better. I'm constantly surprised such tools don't see much wider use.
-
Re:Yes, it works, but it's not easy
Others answered the question but I can add practical experience here. For A while I tied splint [1] and after after a while it became clear that the greatest problem whas the lack of array bound.
I tried hard, realy hard to get splints bound checking to work - but in the end it did not work out.
The project is not stalled since 2004 [2] and for me it is now clear that the "Secure Programming Lint" was a hopeless endeavor.
As for casting: Ada has about 3 different ways of type convertions and is still provable. The difference here is implicid type conversing. My favorite example:
unsigned i = -1;
The result depends on the compiler in particular if it is a 16 bit, 32 bit or 64 bit compiler.
And last not least: C has been patched to many times. The first C is from about around 1973 and did not feature unsigned (the reason why Unix file I/O features a 2 and not 4 GB limit), struct and arrays. Yep, the [] syntax was patched on later.
Now speaking of patching the C language: C99 does have propper arrays with bounds attached to them. But there is allmost no compiler which implements this C99 feature. M$ and Borland have no plans for variant arrary, GNU C has it on the bug list for years now (depite the fact that GNU Ada has variant arrarys since the first release from ruffly 1998).
Martin
PS: I have programmed in Ada, C, C++, Java and Pascal and my favorite language is now Ada.
[1] http://www.splint.org/
[2] http://sourceforge.net/projects/splint -
Re:Hardware?
Lot of good that is. I also checked splint which fails to detect the out of bounds array reference in my first example but, thankfully, does detect that p has been assigned NULL and is then dereferenced. However this program:
void foo(char *p)
{
if (p == NULL)
*p = '1';
}
int main()
{
return 0;
}
Elicits no warnings. Which is just pathetic. Maybe this is something I can add, but I honestly thought splint was the shit. -
As I have been stating before.You should try to impose a few rules of coding.
- Instanciate coding guidelines - code must be easy to read. Minor variation in coding flavour shouldnt be here, merely the large scope.
- Avoid if...else if...else if...else if... - constructs. They are especially hard to follow, and can often be replaced by switch/case-statements.
- Require large modularization of code. - No function/method should be more than about 40 to 100 lines, the fewer the better, but don't be too rigid here - some functions/methods are better of being straight-on than modularized.
- Code for each case-statement in a switch should be a call to a method/function that encapsulates actions and declarations. (not always possible, but if the code exceeds 4-5 lines a function/method should be considered).
- Don't nest a switch/case inside a switch/case - do the nested switch in a called function/method.
- All code must be reviewed.
- Test cases for each module, which requires writing a bunch f test code that can be used for regression testing changes.
- Don't allow compiler warnings. (-Wall shall be used if using gcc, possibly also other options)
- Declare your own types to manage code neatly.
- It's better to write code cleanly than to write it in the most compact manner unless it's a real performance issue.
- Document each module to describe why it is and what it is doing.
- Place each class in it's own file - like Java.
- Be sure to keep as much as possibly 'private' and only relax to 'protected' or 'public' when needed.
- Variables in classes should have get/set methods and shouldn't be accessed directly unless there is a performance issue. Set methods can then be able to validate indata and reject or throw an exception on bad data.
- If something can't be resloved without a compiler warning - think again and if still not possible - document that reason before the code review.
- Run the code under analysis of leak and memory access testing software like Valgrind and/or PurifyPlus. Preferrably both during unit testing and system testing.
- Be paranoid. Check for 'null' results and do detailed try/catch blocks instead of a try/catch over a large block. Using detailed checks allows you to take appropriate action on detail errors.
- Instaciate an extensive beta-testing program.
- Inline-declare function/methods that are broken out if they should be inline with the code for performance reasons.
For code written in C you can use Splint
-
Re:Development Practices
There are no silver bullets no, but there are tools that can help. Splint is a good example of something you can employ to make static checking for buffer overflows, and various dynamic memory errors like misuse of null pointers, dead storage, memory leaks, and dangerous aliasing in C and C++. It doesn't make your code bullet proof, but it can catch a lot of errors that you probably wouldn't otherwise spot. There's a nice paper about what it can do (warning PDF).
Jedidiah. -
Re:Dynamic typing
You have to realize that, for the vast majority of programmers, that the structure is necessary. Those programmers working in dynamically-typed languages fail; they produce spaghetti. Sure, you *can* maintain structure in a dynamically typed language such as Smalltalk or Ruby. But programming is a constant struggle to keep the code from descending into chaos.
What gets me though, is that people will make these sorts of comments all the time, and yet when you suggest that it's quite easy to take the same idea just a little further it all of a sudden becomes completely unpalatable and "too much work". Never mind that that's the same argument the dynamic type people use against static types. Never mind that for the extra work of contracts or specifying a little more than just type signatures you can get static checking gains and improvements in maintainability on par with what you get from using static types over dynamic types.
If you really believe that specifying static types really does help reduce bugs and improve maintainability (and it certainly can) then check out the options for doing a little better again.
Jedidiah. -
Re:Dynamic typing
For the amount of time that i've lost to define a method twice to deal with 2 different types of objects, i've saved tons of time dealing with bugs that result from dynamic typing.
And just think of the extra time you can save by adding a few annotations to your code and allowing a static checking tool like ESC/Java2 or Splint catch all the extra errors for you. Better yet you can get tools that will extract that extra documentation of the method out and include it in the automatically generated documentation - making it much easier to keept your documentation exact and up to date.
Jedidiah. -
Re:Ah. Dynamic typing. Again.
To me static checking (that is consistency checks that are done at compile time) are like an Engineer designing a plane, he does it with tools that declare the wings and the parts of the plane sound, even before the tests that have to be done to confirm the project.
And I think something that static typing advocates who use this sort of argument need to realise is that static types are not the be all and end all of declarations you can make to ensure consistency with intended function. In theory the Curry-Howard isomorphism means that indeed types are propositions. In practice most type systems provide a very poor syntax for clearly stating your propositions. The best way to get around that in most languages is to provide extra syntax that allows expressive descriptions of your propositions, or, if you like, your assumptions. Yes, the type signature of a function declares certain properties that ensure a certain amount of consistency that can be checked statically. There is a lot more in the way of assumptions you can decalre that will ensure far more important consistency properties that can still be checked entirely statically.
Check out JML and ESC/Java2 for Java to see how much extra static checking you can get above and beyond simple type checking. The same sorts of things for C are provided by Splint. If you're someone who prefers ML then take the time to check out EML which adds the ability to define and check axioms in Standard ML.
Jedidiah. -
There are obviously several alternatives.As stated, Valgrind and Electric Fence are two alternatives. I would also like to point out Purify (now owned by IBM) which I have been using from time to time. Of course the catch with that tool is that it's commercial, but you should at least evaluate it.
Using a complete hardened Linux distro is not necessary for "normal" development work, but it may be a good idea to verify that your application actually works there too.
In addition to the run-time checkers you can also look for static checkers like Splint. It can provide you with some extra information about potential problems that only occurs under certain conditions that maybe aren't met during runtime.
If the effort of trying to track down stack corruption is worth it? - YES! Absolutely! Catching bugs in an early stage is essential to keep down the lifecycle cost of a system. Also consider the risk of badwill if your product is prone to strange behavior and crashes.
-
Re:Excel and Subversion are your friendsOne step up from using Excel as a bug tracker is to use Mantis which is simple to use and written in PHP.
Subversion or CVS as version control is about the same when it comes to a small project. Subversion is the successor to CVS and should normally be the choice unless there are other factors that makes it hard to implement.
Obviously - the boss in question is probably also rejecting ISO 9000. And I even wonder about what the accounting looks like. So it may be a good idea to silently look for another job and change before the shit hits the fan.
I'm personally considering the following rules when coding:
- No compiler warnings - unless there are very strong reasons for leaving one alone.
- Any kind of simple version control. (cvs, svn, cms, rcs or whatever is convenient/available)
- Some kind of bug tracker - like Mantis. Excel isn't really good enough.
- Check C code with Splint.
- Write well-structured code - not necessarily with a lot of comments - but the code shall be easy to read.
- If self-healing can be handled in the code - use it. (like checking if a file was closed when the finalize() method is called in Java and then close the file if it wasn't)
- If possible - run the code through Purify or a similar tool.
- ALWAYS braces (or what the language used dictates) around the body of an IF-statement.
- Each method/function shall have a comment describing that comment. (OK, I'm not always doing this)
- Try to keep variables fairly short - too long variable names cuts down on the readability.
- Use of single letter variables are permitted - using the old-fashioned variables i, j and k as index variables in loops.
- Indent code properly - using SPACES to get compatibility with most editors. Eclipse is fairly good at this.
- Align the braces so that an opening brace is in the same column as a closing brace - this makes the code a lot easier to read than if an opening brace is over the right edge somewhere.
- Keep opening/closing braces on their own line. - Yet another readability issue.
-
Re:You know what would really help...
That works just fine if you define your string with "char s[n];" where n > 1. If you use "char *s;" and later do a calloc() (or malloc() if you want to use uninitialized pointers), you're asking the compiler to keep track of all kinds of variables. That's not its job.
That's why I said "... likely knows
...". I'm aware of the problems of variable tracking; I've written small compilers and studied large compilers myself.In practice most uses of gets() etc. in legacy code I've seen do use static buffers - programmers smart enough to use the malloc() family are usually, though unfortunately not always, smart enough to recognise the problems of buffer overflow and basic memory management in general.
In any case smart compilers are already doing sophisticated variable tracking for the purposes of optimization. Carrying around a memory block size on a pointer variable with all the other information being tracked would actually be fairly simple, by compiler standards anyway. It could even be used for optimisation, with pointers to large blocks being cached more aggressively.
If you really want to do something, take calls like gets(), scanf(), and such out of the standard library and replace them with macros that give compiler errors. Those calls are only useful in controlled environments like academia (hmmmmm...). Put them in the real world, and you have all kinds of problems.
That is quick and a little dirty but may be a better way to go for new code. Like e.g. splint. I was thinking mainly of large legacy code bases that people don't want to touch.
---
Are you a creator or a consumer?
-
Re:Selling some sort of hardened Linux, perhaps?
They will reveal things like buffer overflows, memory leaks, pointer problems, malformed expression problems, etc.
These are all currently found using tools like lint / splint which in the case of splint, is FREE (as in NOT the 100-200k cost range pal). Vulnerabilities still exist. These tools have been around for some time. Automated analysis isn't a magic bullet. Its about good coding practices and comprehension of the system you're running your code on.
-
Re:IndeedSorry for being a moron, but I think that if you are going for a mission critical solution with high availability I would propose an OpenVMS system.
OK, the EULA is probably not permitting it to be used for mission critical solutions either, but in my opinion it's one of the better commercially available OS:es. (There's even a hobbyist license available). (anybody knowing of an OS that has an EULA that actually claims that the OS is intended for mission critical use?)
I think it's about time to require that software companies are responsible for their code. There are too many simple bugs passed through every day that would have been caught if a thorough software testing was done. One tool for doing it is Purify Plus, and another is Splint.
Splint is available to the public, unfortunately it's only checking C and not C++. (anyone in the mood for implementing a C++ version?)
And not even NASA and ESA software are always bug-free, but their software is as close as you can come to mission critical applications. I wouldn't like to have a computer running Windows on a mission to Mars, it isn't stable enough.
-
Cscope, LintFrom the Cscope web site:
Cscope is a developer's tool for browsing source code. It has an impeccable Unix pedigree, having been originally developed at Bell Labs back in the days of the PDP-11. Cscope was part of the official AT&T Unix distribution for many years, and has been used to manage projects involving 20 million lines of code!
In April, 2000, thanks to the Santa Cruz Operation, Inc. (SCO) (since merged with Caldera), the code for Cscope was open sourced under the BSD license.
- Allows searching code for:
- all references to a symbol
- global definitions
- functions called by a function
- functions calling a function
- text string
- regular expression pattern
- a file
- files including a file
From the Split (a modern version of Lint) web site:
Splint[1] is a tool for statically checking C programs for security vulnerabilities and programming mistakes. Splint does many of the traditional lint checks including unused declarations, type inconsistencies, use before definition, unreachable code, ignored return values, execution paths with no return, likely infinite loops, and fall through cases. More powerful checks are made possible by additional information given in source code annotations. Annotations are stylized comments that document assumptions about functions, variables, parameters and types. In addition to the checks specifically enabled by annotations, many of the traditional lint checks are improved by exploiting this additional information.
As more effort is put into annotating programs, better checking results. A representational effort-benefit curve for using Splint is shown in Figure 1. Splint is designed to be flexible and allow programmers to select appropriate points on the effort-benefit curve for particular projects. As different checks are turned on and more information is given in code annotations the number of bugs that can be detected increases dramatically.
Problems detected by Splint include:
- Dereferencing a possibly null pointer (Section 2);
- Using possibly undefined storage or returning storage that is not properly defined (Section 3);
- Type mismatches, with greater precision and flexibility than provided by C compilers (Section 4.1-4.2);
- Violations of information hiding (Section 4.3);
- Memory management errors including uses of dangling references and memory leaks (Section 5);
- Dangerous aliasing (Section 6);
- Modifications and global variable uses that are inconsistent with specified interfaces (Section 7);
- Problematic control flow such as likely infinite loops (Section 8.3.1), fall through cases or incomplete switches (Section 8.3.2), and suspicious statements (Section 8.4);
- Buffer overflow vulnerabilities (Section 9);
- Dangerous macro implementations or invocations (Section 11); and
- Violations of customized naming conventions. (Section 12).
-
Code analysis?Well, if source code analysis is really what you want, I would suggest splint at http://www.splint.org/. A static lint-type checker. Really good and sufficiently pedantic. Most C coders should check this out...
P.
-
The scoop
Any advice for the poor schmuck who's going to get the blame?
Yeah... you shouldn't have written:
char buf[8];
printf ( "Hey, what's the scoop, newsboy? " );
gets ( buf );
printf ( "Good one my boy, now off to the presses to publish %s!!\n", buf );
(It pays to use Splint) -
Re:Perl's taint modeWhy don't you use splint to do statical analysis whether tainting is handled correctly?
splint allows you to define attribute for taintedness and describe how functions behave in respect to that attribute - a bit like in C you can use 'const' attribute.
-
The human factor
Anything we do to improve software security must work without the programmer having to switch languages
I agree; it's not so much the language--or the tools--each developer on a project must be personally aware of vulnerabilities and exploits. Using "managed code" does not "secure" your projects. These days, a C programmer ignoring the dangers of gets(), for example, is incompetent and should not be trusted. It's not, as the article reads, "sloppy"... it's ignorance pure and simple.
Also, relying on tools like an updated gcc, gprof, or splint--helpful as they are--without experience and education in writing secure code... is asking for trouble also. -
Re:Writing is bad enough, testing is worse
You can do that today. Splint
-
Re:Worst kind of science
-
Another way?
Use source analyzers to find common mistakes, here are a few
Flawfinder
RATS
ITS4
Splint
also look at Splint's Links page for more on the topic -
Another way?
Use source analyzers to find common mistakes, here are a few
Flawfinder
RATS
ITS4
Splint
also look at Splint's Links page for more on the topic -
it's not really the language that's the problem.
It's bad programming habits and the lack of tools that catch those program time errors.
Static analysis, the use of programs to analysis code that has not been compile completely to machine code, has historically been undeveloped in open source. I use to have a list, was my research focus for a while, but basically we have one decent static analyzer Splint, and it's not that hot compared to commercial offerings.
For instance the HANDS group from stanford has tracked down lots of kernel bugs using their in house analyzer, in lots of obscure places. MS has an in house program I hear they guard closer than the kernel itself! I have a friend that did kernel work for them that agreed with this, they give him the kernel source but not the ananlyzer binaries even. The guy who wrote it, known in pointer analysis circles often goes on about how he's found tons of bugs in open source projects ( bet you he's not filing bug reports )
There are lots of groups working on static analysis, but no one wants to open source their code.
Hind, Michael http://www.research.ibm.com/people/h/hind/
Hind has written amongst other things probably the best and most recent introductory papers on pointer analysis at http://www.research.ibm.com/people/h/hind/paste01
. ps.SUIF compiler suif
I had a few other links, but the lameness filter is complaining about "too many junk characters". You'd think slashcode would have a better filter by now.
-
Re:linux should have non-exec stack by defualt
Steady on - C++ is a high level language, at least by the standards people always used to use, and it does have a good range of bounds-checked containers (safe arrays and the like). It does allow you to do low-level stuff if you need to and you know what you're doing; the trouble is that too many people who don't really need the low-level memory access still don't use safe containers for spurious performance reasons. Yes, moving everyone to Lisp or ML or Perl or even Java would solve a lot of memory scribbling problems, but so would making sure everyone uses safe string libraries rather than char*s and safe container libraries rather than raw arrays.
Also you can use tools like Splint and CCured to check at compile time and at run time for unsafe memory accesses. As with so much else in C and C++, you can write safe and correct memory access, and you can shoot yourself in the foot. You just have to take care and do the right thing, or if you don't want to worry about being careful then switch to a different language. But switching is not the only way to solve the problem.
-
Re:lint is horrible
Check out Splint (formerly LCLint). Whereas traditional lint is less needed now that compilers have -W switches, splint has a whole bunch of extra stuff which gcc won't warn about. The only trouble with it is that by default, it wants you to add annotations to your program to help it be checked (for example if a function parameter is a pointerm you can annotate whether it is allowed to be null). If you go along with that then splint can give lots of help in finding places where null pointer dereferences could happen, and other bugs. But even if you don't want to annotate and you use the less strict checking it's still a handy tool. (OK, maybe C99 has some of this stuff too, but splint has more.)
-
Define "very little"
- Very little code financed by the Federal government is ever licensed under either of these two licenses - the choice is basically agency-proprietary (the Federal agency asked for the rights in the contract, and kept them) or company-proprietary (the agency didn't ask for the rights, and the contractor kept them).
NASA uses and produces software under the GPL license.
Any number of of projects funded by NSF, and other Governmental Agency, grants end up licensing software under the GPL.
There is an aspect to this discussion that I don't think gets enough play. The GPL is a great boon to academics who don't have to purchase costly software, and risk throwing obstacles in the way of those who would reproduce their work, or reinvent wheels. This boon comes with the very small cost that the software so produced should be shared with others. I think that this is in harmony with the spirit of Scientific Research, the "standing on the shoulders of Giants" as Newton said.
-
splint.org
wow,
I've had splint.org in my sig for a while now. I think it's one of those projects that needs more attention. This project used to be called lclint but got renamed to splint.
There are lots of papers out there on static checkers. One good intro paper is at http://www.research.ibm.com/people/h/hind/paste01
. ps. This would give you a nice intro on pointer analysis, a sub topic in static analysis.. -
Re:Dumb security question
This already exists, try splint formally lclint at http://splint.org/
A static checker will find most of those errors, including sometimes range issues like the last OpenSSH hole.
If you're interested in static analysis...
http://www.cs.berkeley.edu/~weimer/osq/
http://suif.stanford.edu/
http://www.research.ibm.com/people/h/hind/
Make sure you check out Hind's intro paper at http://www.research.ibm.com/people/h/hind/paste01
. ps -
Re:Purify vs Static Analysis
partial answer: splint
-
Re:Please stop writing network apps in C!
- Splint (lclint) provides for bounds checking
- bounds checking and other extensions for gcc
-
Splint: Secure LintFYI, Dave Evans has released Splint, the successor to his popular LCLint program. This GPL program will automatically find security problems in your source code.
Splint is a GPL'd extended-lint type code analysis program which not only checks syntax (and semantics!) but now includes checks for security vulnerabilities. Essentially you run your code through Splint and it will spit out a detailed list of problems. As with LCLint you can "decorate" your code with stylized comments to provide semanatic information to the parser which allows even more thorough checking. Click here for more details and downloads of Splint.