How to secure C
The C language is very powerful and uses a lot - especially in the Linux kernel - but it's very dangerous. One of the developers of the Linux kernel told how to deal with security vulnerabilities C.
You can do almost any thing on C, but that does not mean that it needs to be done. Code C is very fast, but rushes without seat belts. Even if you are an expert, like Most Linux kernel developers , still possible deadly errors.
In addition to the pitfalls of type , kernel security engineer for Google Linux, reviewed at [leech=https://events.linuxfoundation.org/events/linux-security-summit-north-america-2018/] conference on Linux security. in Vancouver.
holes in the security and vulnerable infrastructure. "
If you use C in your projects, you should pay attention to security issues.
Protection of the Linux kernel
Over time, Cook and colleagues discovered numerous problems of native C. To eliminate them, the kernel self-defense project - - was launched. Kernel Self Protection Project . He is slowly and steadily working on protecting the Linux kernel from attacks, removing the problem code from there.
It's complicated, Cook says, because "the kernel needs to do very specific things for the specific architecture of memory management, interrupt handling, sdulings and so on." A large amount of code refers to specific tasks that need to be carefully checked. For example, "C does not have an API for setting page tables or switching to 64-bit mode," he said.
With this load and with the weak standard libraries in C, there is too much undefined behavior. Cook quoted - and agreed - with the article on Raf Levien's blog "With indefinite behavior, everything is possible" .
Cook gave concrete examples: "What is the content of" uninitialized "variables? This is all that was in memory before! In void pointers, there is no type, but can you call typed functions through them? Of course! Assembly does not care: you can apply to any address! Why
memcpy ()no argument 'max destination length'? It does not matter, just do as you say; all areas of memory are the same! "
Ignoring warnings but not always
With some of these features it's relatively easy to manage. Cook commented: "Linus[Торвальдсу]like the idea of always initializing local variables. So just do it. "
But with a reservation. If you initialize a local variable in switch, you get a warning: "The operator will never be executed
[-Wswitch-unreachable]"Because of how the compiler handles the code. This warning can be ignored.
But not all warnings can be ignored. "Variable-length arrays are always bad," Cook said. Among other problems - stack exhaustion, linear overflow and violation of page protection. In addition, Cook drew attention to slowness of VLA . Removing all VLAs from the kernel increased performance by 13%. Improving both speed and security is a double benefit.
Although VLA was almost removed from the kernel, they still remained in some code. Fortunately, VLA is easy to find using the
compiler flag. -Wvla.
Another problem is hidden in the semantics of C. If a break is missing in the switch, what did the programmer mean? Skipping break can lead to code execution from several conditions; this is a well-known problem.
If you are looking for break /switch statements in an existing code, you can use
-Wimplicit-fallthroughto add a new switch statement. In fact, this is a comment, but modern compilers disassemble it. You can also explicitly mark the absence of a break with the comment "fallthrough" .
Cook also found a performance decrease when checking the boundaries for allocation of memory slab . For example, check
strcpy () - familyreduces performance by 2%. Alternatives like
strncpy ()their problems. It turns out that Strncpy does not always end with a null character. Cook sadly turned to the audience: "Where can I get the best API?"
During the Q & A session, a Linux developer asked: "Can I get rid of old, bad APIs?" Cook replied that for a while Linux was supporting the concept of an outdated API. Nevertheless, Torvalds refused this idea, arguing that if some API is out of date, it should be completely discarded. However, permanently throwing the API "politically dangerous," Cook added. So while we are stuck with them.
Long-term solution to the problem? More developers who understand the security problems
Cook foresees a long and difficult journey. Once the idea of creating a Linux C dialect seemed attractive, but it would not. The real problem with the dangerous code is that "people do not want to do the job of cleaning the code - not only bad code, but also C itself," he said. As in all open-source projects, "we need more dedicated developers, reviewers, testers and specialists in backporting."
Dangerous C: lessons
C is a mature and powerful language, but it creates technical difficulties and security problems.
Linux developers pay special attention to securing C (without losing its power), because it is written on most of the operating system.
The kernel security engineer for Google Linux identified specific language vulnerabilities and explained how to avoid them.