How to make this code safe from buffer overflow using IF..Statement - c

#include <string.h>
void foo (char *bar)
{
char c[12];
strcpy(c, bar); // no bounds checking
}
int main (int argc, char **argv)
{
foo(argv[1]);
return 0;
}

Another ACTUAL option:
void foo (char *bar)
{
char c[12];
snprintf(c, sizeof c, "%s", bar);
}
The functions strncpy do not ensure the resulting strings are terminated by a NULL character and therefore you can have a bad resulting string.

Check whether the length of the bar is less than length of c.
code:
#include <string.h>
void foo (char *bar)
{
char c[12];
if ( strlen( bar ) < sizeof c ) {
printf("avoiding buffer overflow");
strcpy( c, bar );
}
}
int main (int argc, char **argv)
{
foo(argv[1]);
return 0;
}

I made it safe. Otherwise it's doing just the same thing as your original app, that is: nothing.
int main (int argc, char **argv)
{
return 0;
}

Related

what is wrong with this piece of code I have been asked

#include <string.h>
void foo (char *bar)
{
char c[12];
strcpy(c, bar);
}
int main (int argc, char **argv)
{
foo(argv[1]);
return(1);
}
There are two problems :
if the program has no argument argv[1] is NULL and in foo you do strcpy(c, NULL); having an undefined behavior (typically a crash).
if the firs argument of the program has at least 12 characters strcpy(c, bar); will write out of c, again with an undefined behavior.
I do not speak about the fact the strcpy is in the best case useless because c is not used after
A secure version of your program with the minimal changes is :
#include <string.h>
void foo (char *bar)
{
char c[12];
strncpy(c, bar, sizeof(c) - 1);
c[sizeof(c) - 1] = 0;
}
int main (int argc, char **argv)
{
if (argc >= 2)
foo(argv[1]);
return(1);
}

C - Pass Array of Strings as Function Parameter

I need to pass a pre-allocated array of strings as a function parameter, and strcpy() to each of the strings within the string array, as in this example:
static void string_copy(char * pointer[]) {
strcpy(pointer[0], "Hello ");
strcpy(pointer[1], "world");
}
int main(int argc, const char * argv[]) {
char my_array[10][100];
string_copy(my_array);
printf("%s%s\n", my_array[0], my_array[1]);
}
And the resulting printed string would be 'Hello world'.
How do I pass a pre-allocated string array and fill out each string within a function as shown above?
When you are doing string_copy(my_array), you are passing a char (*)[100], i.e. pointer to char[100] array to your function. But your function is expecting a char *[], i.e. array of char pointers, because you have defined your function that way.
You can fix this by making changes so that your function (string_copy()) expects a char (*)[100], instead of a char *[].
For this, you can change your function definition as:
/* Your my_array gets converted to pointer to char[100]
so, you need to change your function parameter
from `char *pointer[]` to `char (*pointer)[100]`
*/
/* static void string_copy(char *pointer []) */
static void string_copy(char (*pointer) [100])
{
strcpy(pointer[0], "Hello ");
strcpy(pointer[1], "world");
}
* Alternative Solution *
A different design/solution would be to change in your main() function so that you are actually passing a char *[], which decays into a char ** - which is fine - to string_copy(). This way you would NOT have to change your string_copy() function.
int main(int argc, const char * argv[]) {
char my_array[10][100];
int tot_char_arrs, i;
char *char_arr_ptr[10];
/* Get total number of char arrays in my_array */
tot_char_arrs = sizeof(my_array) / sizeof(my_array[0]);
// Store all char *
for (i = 0; i < tot_char_arrs; i++)
char_arr_ptr[i] = my_array[i];
/* Actually passing a char *[].
it will decay into char **, which is fine
*/
string_copy(char_arr_ptr);
printf("%s%s\n", my_array[0], my_array[1]);
}
you need to use a pointer to the array. here is an example with 1 dimension array:
#include <stdio.h>
#include <stdbool.h>
#include <string.h>
static void string_copy(char **pointer) {
strcpy(pointer[0], "Hello ");
}
int main(int argc, const char * argv[]) {
char my_array[10];
char * p_array = my_array;
string_copy(&p_array);
printf("%s\n", my_array);
}
Your function can simply accept matrix dimensions and pass a const char * that stores the array of literals (pre-allocated) strings:
#include <stdio.h>
#include <string.h>
#define STRINGS_LENGTH 100
static void string_copy(size_t n, size_t m, char pointer[n][m], const char *strings_to_copy[])
{
for (size_t i=0; i< n; i++)
{
strcpy(pointer[i], strings_to_copy[i]);
}
}
int main( void )
{
const char *strings[] = { "hello", "World" };
char my_array[sizeof(strings)/sizeof(strings[0])][STRINGS_LENGTH];
string_copy(sizeof(strings)/sizeof(strings[0]), STRINGS_LENGTH, my_array, strings);
printf("%s %s\n", my_array[0], my_array[1]);
}
You can also change the structure of your code using dynamic allocation for your output array like:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdbool.h>
static bool string_copy(char *pointer[], const char *strings_to_copy[], size_t strings)
{
for (size_t i=0; i< strings; i++)
{
pointer[i] = malloc(strlen(strings_to_copy[i])+1);
if (pointer[i] != NULL)
strcpy(pointer[i], strings_to_copy[i]);
else
return false;
}
return true;
}
int main(void)
{
const char *strings[] = { "hello", "World" };
char *my_array[sizeof(strings)/sizeof(strings[0])] = {0};
if (string_copy(my_array, strings, sizeof(strings)/sizeof(strings[0])) )
{
printf("%s %s\n", my_array[0], my_array[1]);
}
for (size_t i = 0; i<sizeof(strings)/sizeof(strings[0]); i++)
free (my_array[i]);
}

Receiving a string as a void pointer parameter and using strcpy to change it

Here's the code:
#include <stdio.h>
#include <string.h>
void print (void*);
int main (void)
{
char *a = "Mcwhat";
print(&a);
printf("\n%s", a);
return 0;
}
void print (void *text)
{
char* pchar[5];
*pchar = (char*)text;
strcpy( *pchar, "Mcthat" );
}
I am trying to make Mcwhat into Mcthat using a void parameter, but the printf gives me a segmentation fault afterwards. Where is my mistake? I managed to do it char by char but now I want to change the whole string. Didn't found enough material on this in the books on C I have.
Keep it simple and pay attention to the type of your variables :
#include <stdio.h>
#include <string.h>
void print (void*);
int main()
{
char a[] = "Mcwhat"; // a is now a read-write array
print(a); // a decays to a pointer, don't take its adress or you'll get a pointer-to-pointer
printf("\n%s", a);
return 0;
}
void print (void *text)
{
strcpy( text, "Mcthat" ); // Don't dereference text here
}
Note that this "print" function is unsafe in all imaginable ways, but that wasn't the question.
There are lot of issues in your code:
1. Char array should be big enough to store the string. char[5] cannot hold Mswhat.
2. char* pchar [5] declares 5 char pointers, whereas you need one char pointer pointing to a char array.
I have corrected it.
#include <stdio.h>
#include <string.h>
void print (char*);
int main (void)
{
char *a = malloc(10);
strcpy(a,"Mcwhat");
print(a);
printf("\n%s", a);
free(a);
return 0;
}
void print (char *text)
{
char *pchar = text;
strcpy( pchar, "Mcthat" );
}
Just write it like that
void print (char *text)
{
strcpy( text, "Mcthat" );
}
But make sure, the that size of text is large enough to put "Mcthat" inside it.
Also in main:
print(a);
instead of
print(&a); // would requite void print (char** text)
tho whole shebang:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
void print (void*);
int main (void)
{
char *a = malloc(strlen("Mcwhat")+1);
print(a);
printf("\n%s\n", a);
free(a);
return 0;
}
void print (void *text)
{
strcpy(text, "Mcthat" );
}

Return a string from function to main

I want to return a string from a function (in the example funzione) to main. How to do this? Thank you!
#include <stdio.h>
#include <string.h>
#define SIZE (10)
/* TODO*/ funzione (void)
{
char stringFUNC[SIZE];
strcpy (stringFUNC, "Example");
return /* TODO*/;
}
int main()
{
char stringMAIN[SIZE];
/* TODO*/
return 0;
}
[EDITED] For those who need it, the complete version of the previous code (but without stringMAIN) is:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define SIZE (10)
char *funzione (void)
{
char *stringa = malloc(SIZE);
strcpy (stringa, "Example");
return stringa;
}
int main()
{
char *ptr = funzione();
printf ("%s\n", ptr);
free (ptr);
return 0;
}
A string is a block of memory of variable length, and C cannot returns such objects (at least not without breaking compatibility with code that assumes strings cannot be returned)
You can return a pointer to a string, and in this case you have two options:
Option 1. Create the string dynamically within the function:
char *funzione (void)
{
char *res = malloc (strlen("Example")+1); /* or enough room to
keep your string */
strcpy (res, "Example");
return res;
}
In this case, the function that receives the resulting string is responsible for deallocate the memory used to build it. Failure to do so will lead to memory leaks in your program.
int main()
{
char *str;
str = funzione();
/* do stuff with str */
free (str);
return 0;
}
Option 2. Create a static string inside your function and returns it.
char *funzione (void)
{
static char str[MAXLENGTHNEEDED];
strcpy (str, "Example");
return str;
}
In this case you don't need to deallocate the string, but be aware that you won't be able to call this function from different threads in your program. This function is not thread-safe.
int main()
{
char *str;
str = funzione();
/* do stuff with str */
return 0;
}
Note that the object returned is a pointer to the string, so on both methods, the variable that receives the result from funzione() is not a char array, but a pointer to a char array.
#include <stdio.h>
#include <string.h>
#define SIZE 10
const char *funzione (void){
const char *string = "Example";
if(strlen(string) >= SIZE)
return "";
return string;
}
int main(void){
char stringMAIN[SIZE];
strcpy(stringMAIN, funzione());
printf("%s", stringMAIN);
return 0;
}
You can do this as
char *funzione (void)
{
char *stringFUNC = malloc(SIZE);
strcpy (stringFUNC, "Example");
return stringFUNC;
}
In main, call it as
int main()
{
char stringMAIN[SIZE];
char *ptr = funzione ()
...
free(ptr);
return 0;
}

how to return a char array from a function in C

I want to return a character array from a function. Then I want to print it in main. how can I get the character array back in main function?
#include<stdio.h>
#include<string.h>
int main()
{
int i=0,j=2;
char s[]="String";
char *test;
test=substring(i,j,*s);
printf("%s",test);
return 0;
}
char *substring(int i,int j,char *ch)
{
int m,n,k=0;
char *ch1;
ch1=(char*)malloc((j-i+1)*1);
n=j-i+1;
while(k<n)
{
ch1[k]=ch[i];
i++;k++;
}
return (char *)ch1;
}
Please tell me what am I doing wrong?
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
char *substring(int i,int j,char *ch)
{
int n,k=0;
char *ch1;
ch1=(char*)malloc((j-i+1)*1);
n=j-i+1;
while(k<n)
{
ch1[k]=ch[i];
i++;k++;
}
return (char *)ch1;
}
int main()
{
int i=0,j=2;
char s[]="String";
char *test;
test=substring(i,j,s);
printf("%s",test);
free(test); //free the test
return 0;
}
This will compile fine without any warning
#include stdlib.h
pass test=substring(i,j,s);
remove m as it is unused
either declare char substring(int i,int j,char *ch) or define it before main
Lazy notes in comments.
#include <stdio.h>
// for malloc
#include <stdlib.h>
// you need the prototype
char *substring(int i,int j,char *ch);
int main(void /* std compliance */)
{
int i=0,j=2;
char s[]="String";
char *test;
// s points to the first char, S
// *s "is" the first char, S
test=substring(i,j,s); // so s only is ok
// if test == NULL, failed, give up
printf("%s",test);
free(test); // you should free it
return 0;
}
char *substring(int i,int j,char *ch)
{
int k=0;
// avoid calc same things several time
int n = j-i+1;
char *ch1;
// you can omit casting - and sizeof(char) := 1
ch1=malloc(n*sizeof(char));
// if (!ch1) error...; return NULL;
// any kind of check missing:
// are i, j ok?
// is n > 0... ch[i] is "inside" the string?...
while(k<n)
{
ch1[k]=ch[i];
i++;k++;
}
return ch1;
}
Daniel is right: http://ideone.com/kgbo1C#view_edit_box
Change
test=substring(i,j,*s);
to
test=substring(i,j,s);
Also, you need to forward declare substring:
char *substring(int i,int j,char *ch);
int main // ...

Resources