Posts Tagged ‘C’

Unsafe Functions In C And Their Safer Replacements: Strings Part II

Tuesday, December 2nd, 2008

Subscribe To Our Feed | Follow Us On Twitter | Get Updates on Email

Last time, we advised you to use ditch the unsafe functions like strcpy and strcat, and use their safer replacements (strlcpy, strlcat) instead. However, there is a small problem with this that you might discover that your compiler (especially gcc) does not have these functions in their implementation of the c library (libc). Why is this so? Read this thread about the original patch that was submitted to add these functions to libc. Essentially, it was rejected on the basis that these functions hide problems instead of solving them and would actually lead to hard to detect bugs that creep in because of unsolicited truncation caused by these functions. A sample implementation of strlcpy looks like this:

#include <sys/types.h>
#include <string.h>
 
/*
 * Copy src to string dst of size siz.  At most siz-1 characters
 * will be copied.  Always NUL terminates (unless siz == 0).
 * Returns strlen(src); if retval >= siz, truncation occurred.
 */
size_t
strlcpy(char *dst, const char *src, size_t siz)
{
	char *d = dst;
	const char *s = src;
	size_t n = siz;
 
	/* Copy as many bytes as will fit */
	if (n != 0) {
		while (--n != 0) {
			if ((*d++ = *s++) == '\0')
				break;
		}
	}
 
	/* Not enough room in dst, add NUL and traverse rest of src */
	if (n == 0) {
		if (siz != 0)
			*d = '\0';		/* NUL-terminate dst */
		while (*s++)
			;
	}
 
	return(s - src - 1);	/* count does not include NUL */
}

Now, there are supporters for both the sides. Solaris and BSD accepted these functions while GNU/Linux refuses to do so till date. The stand that I’d like to take here is that this is at least a step towards the right direction because a truncation bug is much better than an attacker taking over the control of your network just by pushing out a long string onto the stack. However, we could indeed augment the implementation above to communicate back to the caller somehow that truncation occurred. Whichever side you choose, be aware that these problems are very real and don’t just keep on using the older unsafe versions (Even in words of Ulrich Drepper, the opposer of strlcpy: “ The users of these functions[strcpy, strcat] should be severly punished”).

© Safer Code | Unsafe Functions In C And Their Safer Replacements: Strings Part II

Liked this post? Get FREE Updates
Subscribe to RSS feed

Or
Enter Your E-mail ID below

Generic Function Pointers In C And Void *

Tuesday, November 25th, 2008

Subscribe To Our Feed | Follow Us On Twitter | Get Updates on Email

Many times people ask me about what keyword \ type they should use to declare a generic function pointer in C, or worse still, they don’t ask and steam ahead using “void *”. Well, C does not have a generic function pointer type but it does have a generic function pointer. We’ll see why void * cannot be used to denote generic function pointers and so how we can declare them, but first a brief word on why would someone need a generic function pointer in the first place.

Why do we need Generic Function Pointers?

Well, let’s explain this with the help of a slightly advanced example of a module M1 that supplies information to a lot of other modules M2, M3, M4…Mn. M1 provides this information to modules Mn through callbacks but all these modules need different kind of information and different prototypes for their callback functions. These modules register with M1, using an API, say M1_register(Mn_callback_ptr). Now, either we could have a separate registration API for each “type/class” of subscriber Modules depending on what kind of callback they are giving, or we can have a generic function pointer, to which they typecast their actual callback to and then call the registration API. M1, on the other hand, typecasts this callback pointer to its original form while calling callbacks appropriately.

Why can’t we use void* for a Generic Function Pointer?

This is because a void* is a pointer to a generic “data” type. A void * is used to denote pointers to objects and in some systems, pointers to functions can be larger than pointers to objects. So, if you convert amongst them, you’ll lose information and hence, the situation would be undefined and implementation dependent. Most compilers won’t even warn you if you convert between them but some might error out, if you try to call such a void * to function pointer converted. But even they might fail to alert you, if you take care of typecasting the call perfectly (Enclose in parentheses before function call brackets). And then, one fine day, you’ll try to compile and run your program on one of the aforementioned systems, and then keep on wondering why your program segfaults.

Note: C++ does allow this “conditionally” which means that such a conversion is allowed but a compiler is not bound to implement this feature, which again makes its usage circumspect.

So, how exactly do we declare a Generic Function Pointer?

(more…)

© Safer Code | Generic Function Pointers In C And Void *

Liked this post? Get FREE Updates
Subscribe to RSS feed

Or
Enter Your E-mail ID below

All Input is Evil

Tuesday, November 18th, 2008

Subscribe To Our Feed | Follow Us On Twitter | Get Updates on Email

In my previous posts, I have been emphasizing on validating Integer and String inputs by putting various checks in place. But now, I’ll suggest you to consider any type of input to your application or software as “Evil”. Consider the following two rules for any input data:

  1. All input is evil until proven otherwise.
  2. Data must be validated as it crosses the boundary between untrusted and trusted environments.

Till now, I explained how to validate Integer and String data, but today, I’ll explain what is to be validated in the input data. First things first, Look for valid data and reject everything else. You should deny all access until you are sure that the input in the request is valid. You should look for valid data and not look for invalid data for two reasons:

  1. There might be more than one valid way to represent the data.
      • For example: a word “Rose” can be represented in many ways like “ROSE”, “rose”, “R%6fse”, “RoSE” et cetera. All the mentioned words are the variations of single word “Rose” and they are valid variations. But, This can definitely be a problem for an application.
  2. You might miss an invalid data pattern.

Consider the following code: (more…)

© Safer Code | All Input is Evil

Liked this post? Get FREE Updates
Subscribe to RSS feed

Or
Enter Your E-mail ID below

Validating Untrusted String Inputs

Tuesday, November 11th, 2008

Subscribe To Our Feed | Follow Us On Twitter | Get Updates on Email

Alright!! In my last post about untrusted inputs, we talked about validating the data of the “integer” input parameters, checking the out parameters et cetera.This time, we’ll talk about other types of inputs. If you have written a program to take in multiple lines of strings as an input from the user, you need to make sure that the input is not tainted. It is clean and as per your expectations. For example: If your program requires an answer for a question which can be subjective, then you need to provide a string buffer good enough to get a complete answer but not large enough to crash your system or make it run out of memory. Or you need to protect your system from getting any malicious scripts being inserted.Strings are a very risky area for inputs as there is pre-defined rule for this type of validation. So, following are the points to ponder to make your code safe and secure.

  1. Firstly, do use regular expressions to validate the string input. For example, ^[A-Za-z0-9]+$ specifies that the string must be at least one character long and that it can only include upper-case letters, lower-case letters, and the digits 0 through 9 (in any order). You can use regular expressions to limit which characters are allowed and to be more specific (for example, you can often limit even further what the first character can be).If you use regular expressions, be sure to indicate that you want to match the beginning (usually symbolized by ^) and end (usually symbolized by $) of the data in your match. If you forget to include ^ or $, an attacker could include legal text inside their attack to bypass your check.
  2. Now, if your program needs more variety of input and the above point doesn’t fulfil the requirements then you need to make a bit more complicated regular expressions. If the data is a filename (or will be used to create one), be very restrictive. Ideally, don’t let users choose filenames, and if that won’t work, limit the characters to small patterns such as ^[A-Za-z0-9][A-Za-z0-9._\-]*$. You should consider omitting from the legal patterns characters like “/”, control characters (especially newline), and a leading “.”Similarly, you need to take care for email strings, locale specific strings. UTF-8 encoding characters et cetera. In most of the programs, complex regular expressions are good enough to validate a string. But in certain cases, a malicious input containing some script code can spoil the fun.
  3. If your program faces HTML tags or script related instructions in the input, the input should be rejected immidiately or your program might get infected with self executing malicious code. This technique is generally used in Cross Site scripting attack. (XSS attack). These problems are especially a problem for Web applications. Now, you need to again take care not to validate any input which looks like an HTML tag. The easiest way is to use above mentioned regular expressions which won’t allow the entry of ‘<’ or ‘>’ character. But if you must support some of the HTML tags like <a href=> etc, please validate them exclusively by filtering the whole string using a regex like ^(http|ftp|https)://[-A-Za-z0-9._/]+$. A pattern that allows some more complex patterns is: ^(http|ftp|https)://[-A-Za-z0-9._]+(\/([A-Za-z0-9\-\_\.\!\~\*\'\(\)\%\?]+))*/?$
  4. For more complex strings, like reading a data file, regular expressions, again, prove useful but the ideal way is to break the file into multiple chunks rather than reading it in one complete string.

To Keep your String input kept in well defined range or buffer, make sure that your program terminates it with a NULL character. This will ensure that even if a large buffer is inserted using the input, the sting will get truncated as soon as the buffer gets full and it will be protected from buffer overflow.

© Safer Code | Validating Untrusted String Inputs

Liked this post? Get FREE Updates
Subscribe to RSS feed

Or
Enter Your E-mail ID below

Unsafe Functions In C And Their Safer Replacements: Strings Part I

Tuesday, November 4th, 2008

Subscribe To Our Feed | Follow Us On Twitter | Get Updates on Email

A string is a fundamental part of programs all around us. Data exchange in many forms happens in strings (e.g. user input, command line arguments, web forms, text protocols and what not.) But most programs written in C are plagued by security issues because of their usage of unsafe functions. A string is not a built-in data type in C, instead it is termed as a continguous sequence of characters terminated by a NULL character (‘\0’). Now, many of the “standard” string manipulation functions written in early part of C development took this definition by heart, assumed that a programmer always knows what he is doing (though I agree that this MUST be true), and put out a code meant to be used in an everyone-is-good world. Subsequently, the shortcomings were noticed, stronger sibling functions were created but the older ones are still supported because they are “standard”. This means that naive programmers continue to use them and put their programs’ security into jeopardy. This series will do an in-depth analysis of such unsafe functions, tell you why they are unsafe, and bring out what alternatives you have in-built and what alternatives you can create.

Our first candidate is the very famous “strcpy()”. Lets see why it is unsafe.

(more…)

© Safer Code | Unsafe Functions In C And Their Safer Replacements: Strings Part I

Liked this post? Get FREE Updates
Subscribe to RSS feed

Or
Enter Your E-mail ID below

Optimizing Switch-Case Statements In C For Speed

Tuesday, October 28th, 2008

Subscribe To Our Feed | Follow Us On Twitter | Get Updates on Email

The biggest bottlenecks in making efficient code today are jumps or branches. You must have always heard of people telling you to use switch-case blocks instead of cascadin if-else’es. They were right, but partially.

This is because a cascading if-else block will check for each condition in each iteration until it reaches the correct one. On the other hand, switch-case blocks are “supposed to” (why supposed to, we’ll see just now) just execute the correct statement and move on.

Optimization Technique 1: Keep the case label values close and small (Answer to “supposed to”)

Actually switch-case statements are also many times changed into if-else cascades by the compilers. This happens when the case label values are too far apart and/or are spread over a fairly large range. If you have a small switch-case statement like below, then the compiler will generate a jump-table instead of the if-else cascade.

switch(a)
{
  case 0: /*do something*/
  case 1: /*do something*/
  case 2: /*do something*/
  case 3: /*do something*/
  default:
}

A jump table is like a “lookup table” or a “dispatch table”. You can assume that compiler creates an internal array of addresses. The array is indexed by the case lable values and the value at that index is the address of instructions corresponding to that case.

Optimization Technique 2: Place those cases first which are more likely to occur

(more…)

© Safer Code | Optimizing Switch-Case Statements In C For Speed

Liked this post? Get FREE Updates
Subscribe to RSS feed

Or
Enter Your E-mail ID below

Validating Untrusted Integer Inputs

Tuesday, October 21st, 2008

Subscribe To Our Feed | Follow Us On Twitter | Get Updates on Email

If you are writing a software which exposes APIs to be used by a third party, then first thing you have to do is to make sure that all the integers parameters have been validated. Every incoming value to your function should be considered as tainted. The function should validate the input value by checking it for all possible malicious value. After the function validates the input, then only any operation on the input value should be performed.

Consider the following code sample:

void func( int size )
{
 char* str;
 
 if(size &gt; 0 )
 {
  str = (char*)malloc(size * sizeof(char*));
  size++;
  /**
  *some code to operate on this string "str"
  **/
  free(str);
 }
}

I am sure that by now, you would have identified some loop holes in this code. Now, a caller of this function can give different input values which might result in following flaws:

1) The function might get an highest input value which results in a large memory allocation for ‘char* str’ which the function never expected.
2) The function might result in memory allocation failure as there is possiblity of the system running out of memory.
3) The function might have an overflow issue due to an increment in input value which could have been equal to SIZE_MAX.
These scenarios might serve as a boon for a hacker and he/she can instigate either a denial of service or any other buffer overflow errors.

Now, Lets rework the above depicted code again.

#define MAX_SIZE_OF_STRING ( 100 )
void func( int size )
{
 char* str;
 
 if(size &gt; 0 &amp;&amp; size &lt;= MAX_SIZE_OF_STRING)
 {
  if(str == null)
  {
   str = (char*)malloc( size * sizeof(char*));
   if(size &lt; SIZE_MAX)
   {
    size++;
   }
   /**
   *some code to operate on this string "str"
   **/
  }
  if(str != null)
  {
   free(str);
  }
 }
}

Please try to notice few defensive points from the above given code.

1) We have defined a maximum size for the string. We need to do this to make sure that large chunks of memory do not get allocated. This will result in optimized memory usage and longer life of the program.
2) We have validated the input value for its range comparing against its minimum and maximum value. By doing this, We sufficed the purpose of defining the size of the string.
3) Again, we check the input variable size for its value less than SIZE_MAX (maximum value possible for an integer). By doing this, we safeguarded against an overflow. Now, the size variable can never incremented beyond the maximum value.
4) Checking for ’size > 0′ helps in making sure that non zero number of bytes are allocated in memory, in turn, saving us from memory corruption.

By adding extra defense checks or safeguards, you might contribute towards addition in code size. But isn’t it better to have a secure code rather than less code which is vulnerable to exploits.

The point I am trying to make is very simple and is not a great deal. Everyone of us know of it but we tend to ignore these minor things resulting in misuse of code. Keeping these small points in mind while coding and adding these defense checks or safeguards will definitely result in robust and secure code.

© Safer Code | Validating Untrusted Integer Inputs

Liked this post? Get FREE Updates
Subscribe to RSS feed

Or
Enter Your E-mail ID below

int main() vs void main()

Tuesday, October 14th, 2008

Subscribe To Our Feed | Follow Us On Twitter | Get Updates on Email

What would be the best way to start a blog that talks about building safer code? Yes, it would be to talk about the first thing you think when you start coding. The “main” function (as seen in C/C++).

We’ve been brought up with many different variations of this popular function. Some books/teachers like to write it as “int main”, some write it as “void main” and then there are some who make do with just “main”, forgoing the return type altogether. So, which one out of them is correct? Or does it even make a difference?

The answer to the 2nd question is “YES”. It makes a whole world of difference as in it could:

  • do nothing
  • or give you a compile time warning
  • or crash the program
  • or cause problems in your invocation environment

Now, we go back to the first question. Which is the correct form and why?
The answer is “int main” is the correct type for C++.
But for C, it is a bit tricky and I’d say “int main” is the recommended way.
The simple reasoning is “because the C and C++ standards say so”. (See this however, which is what is leads to a bit of confusion though and makes it implementation dependent in c)

But lets take a brief look at the practical reasons for this because you might wonder “My compiler doesn’t give me a warning for void main, so why should I care?” (If your compiler does that, then its time to switch to something else. Did I hear you are using a Microsoft compiler? ;) ).
(more…)

© Safer Code | int main() vs void main()

Liked this post? Get FREE Updates
Subscribe to RSS feed

Or
Enter Your E-mail ID below

And So It Begins…

Tuesday, October 14th, 2008

Subscribe To Our Feed | Follow Us On Twitter | Get Updates on Email

Thousands of sites around the interwebs are devoted to programming and producing code. But there is something missing. This “something” is actually the most important piece of the puzzle. This piece is about how “safe” and “efficient” your code is. There are programmers all over, but a very small minority is worried about finding all the loopholes in their code. Infact, most don’t even know there could be loopholes even as they start writing their program (more on this very soon ;) ). And many times, you’d see people creating a jet fighter for something that could be solved with a bicycle (although the pace would be vice-versa).

The problem here is that there are many things that are not taught in the schools, the knowledge might be out there on the internet, but either it is fuzzy, not properly explained or is plagued by just too much of information overload. You cannot imagine yourself (and everyone else around you) to sit in a week-long class and emerge a champion programmer. It has to seep in gradually.

So, this is an attempt to solve the problem. We’ll bring you the concepts to make your code a fortress. We’ll bring them at a gradual pace that gives you time to learn, understand, ask questions and imbibe them into your daily routines. The problems and solutions would range from the very basics and trivia to the most advanced. We’d concentrate mostly on examples through C/C++ with a bit of JAVA and others interspersed here and there when needed but most concepts learned could be as well applied to any language. We’ll not tell you how to program, we assume you already know, but we’ll tell you how to program efficiently and securely.

So, if you are a college goer, or a fresher just into the corporate world, or an experienced professional, we have something for you all, to make you so capable that you can take a running program and re-write it so that it runs for years without crashing, being exploited to death, or taking a ton of memory or cycles.

Enough talking now. As Linus once said “Talk is cheap. Show me the code.”. So, lets begin…

© Safer Code | And So It Begins…

Liked this post? Get FREE Updates
Subscribe to RSS feed

Or
Enter Your E-mail ID below