1.25.defenses

1.25.defenses - CS 161 Computer Security Spring 2010...

Info iconThis preview shows pages 1–3. Sign up to view the full content.

View Full Document Right Arrow Icon

Info iconThis preview has intentionally blurred sections. Sign up to view the full version.

View Full DocumentRight Arrow Icon
This is the end of the preview. Sign up to access the rest of the document.

Unformatted text preview: CS 161 Computer Security Spring 2010 Paxson/Wagner Notes 1/25 Defending Against Memory-Safety Vulnerabilities Last lecture, we saw a class of attacks on programs, based upon exploiting memory-safety violations. This lecture, lets look at some techniques available to defend against memory-safety vulnerabilities. There are at least five: Secure coding practices. We can adopt a disciplined style of programming that avoids these bugs. Better languages/libraries. We can adopt languages or libraries that make such mistakes harder to commit. Runtime checking. We can have our compiler (or other tools) automatically inject runtime checks everywhere they might be needed to detect and prevent exploitation of memory-safety bugs, so that if our code does have a memory-safety bug, it wont be exploitable by attackers. Static analysis. We can use a compiler (or a special tool) to scan the source code and identify potential memory-safety bugs in the code, and then task developers with fixing those bugs. Testing. We can applying testing techniques to try to detect memory-safety bugs in the code, so that we can fix them before the software ships to our customers. Many of these techniques can be applied to all kinds of security bugs, but for concreteness, lets explore how they can be applied to protect against memory-safety vulnerabilities. 1 Secure Coding Practices In general, before performing any potentially unsafe operation, we can write some code to check (at runtime) whether the operation is safe to perform and abort if not. For instance, instead of char digit_to_char(int i) { // BAD char convert = "0123456789"; return convert[i]; } we can write CS 161, Spring 2010, Notes 1/25 1 char digit_to_char(int i) { // BETTER char convert = "0123456789"; if (i < 0 || i > 9) return "?"; // or, call exit() return convert[i]; } This code ensures that the array access will be within bounds. Similarly, when calling library functions, we can use a library function that incorporates these kinds of checks, rather than one that does not. Instead of char buf[512]; strcpy(buf, src); // BAD we can write char buf[512]; strlcpy(buf, src, sizeof buf); // BETTER The latter is better, because strlcpy(d,s,n) takes care to avoid writing more than n bytes into the buffer d . As another example, instead of char buf[512]; sprintf(buf, src); // BAD we can write char buf[512]; snprintf(buf, sizeof buf, src); // BETTER Instead of using gets() , we can use fgets() . And so on. In general, we can check (or otherwise ensure) that array indices are in-bounds before using them, that pointers are non-null and in-bounds before dereferencing them, that integer addition and multiplication wont overflow or wrap around before performing the operation, that integer subtraction wont underflow before performing it, that objects havent already been de-allocated before freeing them, and that memory is initialized before being used....
View Full Document

Page1 / 14

1.25.defenses - CS 161 Computer Security Spring 2010...

This preview shows document pages 1 - 3. Sign up to view the full document.

View Full Document Right Arrow Icon
Ask a homework question - tutors are online