Title: Software Implementation
1Software Implementation
- CS-300 Fall 2005
- Supreeth Venkataraman
2Introduction
- Allright folks, its time to write some code!
- The art of translating a detailed design into
working code. - Software implementation if done wrong can be
catastrophic. - Wrong implementations can waste perfectly good
designs.
3Introduction
- Not much different from other implementation
processes (hardware, bridges, automobiles etc.) - The components need to be implemented first and
then fitted properly - Coding units, integrating them
- Getting the code right can be quite difficult
even with a good design.
4Coding Standards
- Coding standards are rules that direct a set of
programmers while writing code. - Typically organizations have their own coding
standards. - The purpose of coding standards
- Helps code to be in harmony
- Readability
- Maintainability
- Quality (conformance to design)
5Coding Standards
- Coding standards work well only if
- They are incorporated before coding begins
- Everyone follows them
- They are practical and realistic
- Coding standards could address many issues
- Coding style
- Coding techniques
- Typical routine size
- Rules for commenting, naming
6Coding Standards
- Coding standards are very useful for open source
development - GNU has a coding standard that can be found at
http//www.gnu.org/prep/standards.html - Coding standards also help constrain the way
programmers write code - Usually programmers dont like this as they have
their own way of writing code.
7Coding Standards
- Cons
- Unhappy programmers
- Unrealistic coding standards reduce the quality
of the system - Programmers are more worried about conforming to
coding standards than the task at hand - Same thing if the coding standard is too large.
- The pros outweigh the cons.
- No impact on functionality. Remember this!
8Naming Standards
- Meaningful names for routines, variables and
other program elements go a long way towards
achieving code readability and understandability. - Names should indicate the what and not the
how. - getNextEmployeeID()
- getNextListNode()
9Naming Standards
- If you have difficulty in selecting a name
- It probably means that you have too many things
going on in a routine (coupling) - Your design is probably wrong
- Well named routines are usually highly cohesive.
- Abbreviated names are usually a bad idea
- gtNxtChr
- As are misspelled names
10Comments
- Comments help understand the purpose of a
computation. - Comments must tell a good precise story
- Internal documentation
- Must respect detailed design
- Invaluable to people who maintain code
- They are of help only if they are correct!
11Comments
- Modify comments when modifying code
- Imperative to have a routine header comment
- End-of-line comments are usually bad
- The distinction between code and comment on a
single line is hard to comprehend at first - They are good for variable/struct declarations.
- Avoid entire lines of s or s to beautify the
code. - Be sure to remove temporary comments!!
- Use complete sentences for comments and dont
abbreviate.
12Temporary Variables
- We tend to use a lot of temporary variables in
high level code - These variables (temp, temp1, temp2) make
reading code a pain. - The person reading the code has to be made aware
of the context (via comments) - Even better, try to do away with temporaries
altogether wherever possible.
13Programming Techniques Temporary Variables
- include ltstdio.hgt
- int main()
- int a 4, b 3, temp 0
- printf("a d b d\n", a, b)
- temp a
- a b
- b temp
- printf("a d b d\n", a, b)
-
- Swap two variables without using a temporary
- Standard interview question
- Dont google!
14Programming Techniques Temporary Variables
- include ltstdio.hgt
- int main()
- int a 4, b 3
- printf("a d b d\n", a, b)
- a a b
- b b a
- a a b
- printf("a d b d\n", a, b)
-
15Peogramming Techniques - Macros
- Some identifier (with or without arguments)
associated with a piece of code that is expanded
in the program body whenever the identifier is
encountered in the program. - In C we use define construct to define macros
- define BUFSIZE 1024
- The C pre-processor handles macro expansions.
16Macros
define max(a,b) a gt b? a b val
max(i,j) Potential problems define max(a,b) a
gt b? a b val max(i,j) define max(a,b)
((a)gt(b)?(a)(b)) val max(i,j)
17Macros
- We can write macros to compute fairly complex
stuff - Eg GCD computation
18Assertions
- Allow one to check the value of variables, data
structures etc at run time. - They are used to check the program logic and
control flow - The C library call assert() can be very
- useful
- assert (int expr)
19Assertions
- int main(int argc, charargv)
- int x 0, y 0, z 0
- assert(argc 4)
- x atoi(argv1)
- y atoi(argv2)
- z atoi(argv3)
- printf("d d d\n", x, y, z)
-
- If argc lt 4 then the program will fail the
assertion and abort. It will also dump core.
20Assertions
- In the C language, assert() is actually
implemented as a macro. - The assert() call is usually replaced by an if
else statement. - Linux versions of assert()are not limited to an
integer expression. - void assert(scalar expression)
21Assertions
- You dont need assert() to ensure the value of
some program element at run-time. You could
simply use if else statements yourself. - These are very very useful especially when
validating inputs. - Always fail safe!
22Defensive Programming
- The art of programming carefully, and cleaning up
after youre done. - Defensive programming tries to ensure that we
process only valid data, and if we do encounter
invalid data, do not process it, and fail safe - Input validation
- Authentication
- Initialization
23Input Validation
- Validate all input
- All input is evil Howard and LeBlanc
- It is vital that inputs not be assumed as valid.
- Inputs from all sources must be validated
- While validating input, always check for legal
values and reject illegal values - if ((age lt 0) (age gt 150))
24Input validation
- Whats wrong with this code?
- define MAXELEMENTSIZE 10000
- int main()
- int i
- scanf(d, i)
- if (i gt MAXELEMENTSIZE)
-
-
25Input validation
- Never ever trust command line input
- This includes the program name or argv0
- Command line inputs are low hanging fruit for
attackers. - Check every command line argument for validity.
- The same goes for HTML form elements.
26Input Validation
- int main (int argc, char argv)
- char i
- i argv1
- doSomething(i)
-
27Input Validation
- It is not enough to merely validate external
input. - Every input to all functions must be validated.
- The arguments to functions are the function
inputs. - Check each such argument.
28Input Validation
- int prepare(char input)
- char buf10
- strcpy(buf, input)
-
-
29Input Validation
- When dealing with HTML forms, all form elements
must be validated - Users can enter pretty much anything in text
fields - If you were expecting an integer value, and you
got a string instead, youll be in trouble if you
dont look for this problem.
30Input Validation
- !/usr/bin/perl
- use CGI
- print "Content-typetext/html\n\n"
- query new CGI
- amt query-gtparam("effort")
- amt contains the name of some program that
must be executed - amt
31Data Types
- Be extremely careful with data types especially
in C - int main()
- int i, float f 2.35467899
- char a A
- i a
- printf(d\n, i)
- i f
- printf(d\n, i)
32Initialization
- What is initialization?
- The process of assigning an initial value to a
variable. - Initialization of variables is very important.
Improper initialization or no initialization of
variables could lead to unpredictable results!
33Initialization problems (some)
- Variable has never been assigned a value.
- The value of the variable is not valid anymore
(outdated) - You allocated memory for a pointer but
- didn't initialize the variable it is pointing
to.
34Initialization
int foo() int z,y y z return y int
main() int x x foo() printf("d\n",
x) x foo() printf("d\n", x)
35Know how to initialize variables
- int a 0
- char string100 0
- float x 0.0
- char str ?
36Guidelines for Initialization (Code Complete)
- Check input parameters for validity.
- If invalid inputs find their way into
initializing code (especially C code)
unpredictable results can occur. - main(int argc, char argv)
- int y atoi(argv1)
- printf("d\n", y)
-
- What will be the output of the printf()?
37Guidelines for Initialization (Code Complete)
- Initialize each variable close to where it's used
- Variables like i, j, and k are common loop
counters, and - it is quite possible that these could be
used many times - within a function.
- Variables are usually initialized in a block at
the start of - the function. Always initialize variables
close to where they will be used so that the
variables have valid values when they are used.
38Guidelines for Initialization
- Pay special attention to counters and
accumulators - This is very important because we want our loop
counters to have the right initial values. Not so
necessary with "for" loops since "for loops have
an initializing expression -
- for(i 0 i lt 10 i) ...
- What about "while" loops?
39Guidelines for Initialization
- Initialize working memory at the beginning of
your program. - Do the needful memory allocations as
- early as possible so that you don't run into
uninitialized memory later in the program.
40Guidelines for Initialization
- Check the need for reinitialization.
- Based on discussions so far, why is this
important? - Initialize each variable as its declared
- Take advantage of compiler warning messages
- How would we get C to print out warning messages
that variables are uninitialized?
41Common Coding errors to avoid
- int foo(int x, int y)
- int z
- if (x y)
- z 1
- else if (x 4)
- z 2
-
- return z
-
42How to be safe?
- If you have a constant in the comparison
statement, then have the constant on the LHS. -
43Unsafe C Library functions
- gets()
- strcpy()
- strcat()
- sprintf()
- scanf(s, )
- Never ever use these functions. If you do,
include input validation of your own!!
44What to use instead?
- fgets()
- strncpy()
- strncat()
- snprintf()
- At least with these functions, one can specify
the number of bytes to be read - Dont forget to ensure that your buffer has
enough space to hold the string youre reading
in!!!
45Return values
- Functions typically return the status of
computation as an integer value - For example, strncmp() returns 0 if a perfect
match was found, and specific error codes if
errors occurred. - It is imperative that the return values be
checked so that we know it is safe to proceed.
46Find the bug in this code
- int main(int argc, char argv)
- FILE fp
- char buf1024
- fp fopen(myfile.txt, r)
- fread(buf, 1, 1024, fp)
- printf(s\n, buf)
- fclose(fp)
-
47Find the bug in this code
- include ltstdio.hgt
- main()
48Return Values
- Sometimes, just checking for some particular
return value is not enough. Whats wrong with the
code below? - int authenticate()
- int err
- err checkAccess()
- if (err ACCESSDENIED)
- exit(1)
- else
- / do the needful task /
-
-
49Too Much feedback is not good
- Dont get carried away into printing error
messages that are too friendly - You might be giving away information that could
be used to exploit your code - Save the detailed information into your log files
and print a cryptic message for the user. - For example, when someone tries to log in and
fails, just say that the operation failed - Do NOT say anything like Invalid password
50Buffer Overflows
- Public Enemy Number 1 Howard and LeBlanc.
- A buffer overflow is an array gone out of bounds.
- That is, information has been written past the
end of the array. - Buffer overflows in programs can lead to
unpredictable results.
51Buffer Overflows
- int prepare(char input)
- char buf10
- strcpy(buf, input)
-
- Attackers love buffer overflows.
- Buffer overflows are remarkably easy to exploit.
- Morris worm.
52Buffer Overflows
- According to CERT, more than 50 of all known
attacks exploit buffer overflows. - Are buffer overflows avoidable?
- You bet they are!
- Dont use C is not the solution
- Program responsibly. Its fundamental stuff
53Fail Safe by Default
- If the program fails, then care must be taken to
see that the program fails safe - If you know that you have an exceptional
situation that is critical - Exit if needed.
- Before exiting, clean up
- Free all allocated memory
- NULL all critical variables
- If deployed program fails, make sure core is not
dumped. - If you know how, wipe out all traces of sensitive
information from user memory.
54Fail safe by default
- Again, dont exit for every possible failure.
- secureChat() story.
- Know when to fail safe ?
55Least Privileges
- Always run with least privileges unless
absolutely necessary to elevate. - What happens if youre running as root and a
buffer overflow is exploited? - No need for escalation of privilege!
- You dont need root privileges at all times do
you?
56Obscuring code does not help
- The secureness of your program does not depend on
your code being kept secret! Secrecy ! Security - The secureness of your system depends upon you
keeping sensitive items like passwords or private
keys secret.
57Why do we write bad code?
- Plain irresponsible
- Ego
- I cant possibly write bad code
- Just get it done. We can worry about bugs and
security later - Magic pixie dust?
58Conclusion
- Program responsibly
- Properly initialize program elements
- Always check the bounds of arrays
- Always validate all input
- Never assume that your program will not fail
- And all the other good stuff in this lecture
59References
- LINUX and UNIX Secure Programming HOWTO David
Wheeler - http//www.dwheeler.com/secure-programs/
- Coding standards and Techniques
- http//msdn.microsoft.com/library/default.asp
?url/library/en-us/vsent7/html/vxconcodingtechniq
uesprogrammingpractices.asp - Writing Secure Code Mike Howard and David
LeBlanc Microsoft Press, 2nd edition - Code Complete Steve McConnell Microsoft Press,
1993