I have this code in which I have to find security vulnerabilities.
win() {
printf("Congratulations!");
}
setter(unsigned int i, int v, int * a) {
a[i] = v;
}
main() {
int i, v;
int a[50];
puts("i");
scanf("%d", i);
puts("v");
scanf("%d", v);
setter(i, v, a)
}
Reading on the Internet, I've found that when a conversion from an int to an unsigned int takes place, if the int is a negative number, it will be converted into a very high unsigned int. So, probably the vulnerabilty in this code is due to this conversion which takes place when setter is called in the main function. So, an attacker could give the following input: i=-1, v=40 and he will access to a part of the memory which isn't reserved to the buffer a and so, in the setter function, the attacker will be able to overwrite important values. For example, the attacker could overwrite the return address with the address of the win function in order to execute win when setter returns. Am I right?
Summary of some comments and some additions
Firstly, the code is wrong. The arguments to scanf needs to be pointers:
scanf("%d", &i); // Note the &
if the int is a negative number, it will be converted into a very high unsigned int.
Yes, this is technically true, and it's also true that this may lead to accessing the array out of bounds. However, even if you change to unsigned, there is nothing preventing the attacker from simply typing any number, including whatever the number (unsigned) -1 will be on the particular system.
The correct way of solving this security issue is to check that the inputted number are in the range [0,49]. If you use an unsigned number, you may skip checking if it's below zero for obvious reasons. But you still need to do a range check.
Related
c performance profiling time-limiting Details of the purpose of writing the program is given on the link : https://www.spoj.com/problems/CRCLE_UI/
And the error Time limit exceeded
#include<stdio.h>
const int mod=1000000007;
int cal(int a, int b){
long long x=1,y=a;
while(b){
if(b&1)x=x*y;
if(x>=mod)x=x-(x/mod)*mod;
y=y*y;
if(y>=mod)y=y-(y/mod)*mod;
b>>=1;
}
return x;
}
int main(){
int t, n, k;
long long ans,a1;
for(scanf("%d",&t);t--;){
scanf("%d %d", &n, &k);;t--;
k--;
if(k>=mod)k%=mod;
ans=(long long)k;
if(n&1)ans=ans*(-1);
a1=cal((int)k,n);
printf("%lld\n",(a1+ans+mod)%mod);
}
}
The problem is designed so that it is impossible to compute a result directly by exponentiating with n. Any such attempt will exceed the available resources. You must solve the problem using some number theory, particularly Fermat’s Little Theorem. Additionally, you cannot use scanf to process the input numerals but must read them yourself character by character and reduce them using number theory.
Why the second t-- on this line?
scanf("%d %d", &n, &k);;t--;
Getting rid of it allows the program to halt for any value of t (even and odd, so long as they're positive). Remember, the for loop's condition, t--, tests if t is 0. If it's any non-zero value, it'll evaluate to true.
What your code did was essentially make it so that any odd-number entered as t will never evaluate to 0. Take 1 for example: it's scanned in, t-- in the for condition decrements it, the above line decrements it, so the next time the loop is evaluated t == -1, which evaluates to true. Every iteration after that will just be a more negative number, never 0.
I have been asked to write a code that receives a type of data without being specific about what type (example, int, float, double ect..) and its certainly a number.
The code is simple, find a number in the array and return it's location in the array.
This is the code i wrote:
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int findselectnum(int num, int array[], int size)
{
int i = 0;
for (i = 0; i <= size; i++)
{
if (num == array[i])
return i;
}
return EOF;
}
int main()
{
int array[] = { 1, 3, 5, 10, 88, 21, 100, 77, 0, 11, 2 }, num = 0, result = 0, size = 0;
printf("Enter a number you wish to find\n");
scanf("%d", &num);
size = sizeof(array);
result = findselectnum(num, array, size);
if (result != EOF)
printf("The number %d is in array[%d]\n", num, result);
else
printf("The number does not exists on the array");
}
As you can see, i can only use the int type, so numbers that are float, or double, wont get the same result.
So how can i use all types of data? Is there some kind of a structure for that?
Thanks in advance.
You can use a void* type instead of the int[] type.
It is the type used by the memcpy() function so that it can copy any type of data.
Then you have to cast your void* argument to compare it with the variable of the type you want.
Personally, I wouldn't use C to perform this kind of task.
C++ is maybe a bit more appropriate since it natively handles such mechanisms (templates):
https://en.wikipedia.org/wiki/Template_(C%2B%2B)
I have been asked to write a code that receives a type of data without being specific about what type (example, int, float, double ect..) and its certainly a number.
So how can i use all types of data?
You can't. More specifically, the CPU itself can't. To compare 2 numbers, the CPU has to know what size the numbers are, if the numbers are integer or floating type, and (if it's not just comparing for equality) if the number is signed or not.
There are 3 ways around this:
a) Code duplication (including templates in C++ where the compiler automatically generates N versions of the code for N types, and using macros in C to do similar).
b) Only support the largest type (e.g. maybe double in C) and convert everything to the largest type so that you only need one function for one type.
c) Abuse variable arguments and have run-time branches based on a "what type is it" argument (and increased risk of programmer mistakes); like int findselectnum(char *data_type, int size, ...). This mostly ends up being code duplication in disguise (e.g. you'd duplicate the loop in each case of a switch(data_type)).
Depending on the actual situation; I'd use a mixture of the first 2 options - e.g. find out why the software has been so poorly designed that it needs to do the same work on multiple different types, then try to change the design so it only needs to care about a small number of different types; then have a small number of different functions for the types that are "unavoidably necessary" (e.g. maybe an int findselectnum_int(int num, int array[], int size) and a separate int findselectnum_double(double num, double array[], int size); with nothing for float or short or whatever because they were avoidable).
I recently had to create a program where the user enters a certain integer N. After that, my int main() had to call a seperate function, int getNextFibonacciNumber(void), which calculates the Nth term in the fibonacci sequence and then prints it. When I compile the code, Vode::Blocks says that there aren't any errors or warnings. This said, when I try to run the program, it automatically crashes. I have read it and re-read it but I am not able to see where it all went wrong. Would anyone be able to shed some light on this mysery? Thank you very much! When the program crashes, it says: filename.exe has stopped working. A problem caused the program to stop working correctly. Windows will close the program and notify you if a solutions is available. However, when the code is compiled in Code::Blocks, everything is fine.
#include <stdio.h>
#include <stdlib.h>
int getNextFibonacciNumber(void);
int main()
{
int N, fibonacci[N];
printf("Enter a positive integer:");
scanf("%d", &N);
printf("The %d th term in the Fibonacci sequence is: %d", N, getNextFibonacciNumber());
}
int getNextFibonacciNumber()
{
int N, i, fibonacci[N];
fibonacci[0] = 0;
fibonacci[1] = 1;
for(i = 2; i < N+1; i++)
{
fibonacci[i] = fibonacci[i-1] + fibonacci[i-2];
}
return(fibonacci[N-1]);
}
The problem is, that this
int main()
{
int N, fibonacci[N];
invokes undefined behavior. N is not initialized, but used as a C99 variable length array size specifier. Reading a value from a uninitialized variable invokes UB.
To fix this issue you have to write
int main()
{
int N;
printf("Enter a positive integer:");
scanf("%d", &N);
int fibonacci[N];
However there's another problem, namely that you have the same UB causing construct in getNextFibonacciNumber. You have to fix that to. Also the number entered into N is not "communicated" to getNextFibonacciNumber, so I highly doubt that this program worked at all, even if it didn't crash.
Code::Blocks (or rather the compiler Code::Blocks calls) only checks if you have written "legal" c code. It does not (and can not) check if your program does what you want, if your program will exit at any point (or simply run forever), if your program causes errors and crashs and stuff like this.
When you say
int N, fibonacci[N];
I guess you want to create an integer N and an array of the same size. However right now you create an integer N (that has some "random" value, presumably 0) and an array of the FIXED size N.
If you change N late on in your program this does not affect the size of your array "fibonacci" in any way. So if your N was by chance 0 at the beginning of your program than you have created an array of size 0. Even if you read a value (say 5) from the console input. Trying to read and write to this array causes problems.
Moving the part
int fibonacci[N];
below your "scanf" line will fix this problem. At this point N is initialized (and not some random number).
Also be aware that the variable N in the main function
int main()
has no connection at all to the N variable in your function
int getNextFibonacciNumber()
The second N is a newly created variable (again set to some "random" value). If you want to pass data from one function to another you should do it by passing it as an argument in brackets:
int getNextFibonacciNumber( int N)
So here's the code:
int create_mask(unsigned b, unsigned e)
{
unsigned int mask=1;
if(b<e || b<0 || e<0)
{
printf("Wrong values, starting bit can't be smaller than ending.\n");
printf("Both got to be >= 0.\n");
exit(EXIT_FAILURE);
}
while(b>0)
{
printf("%u\n", b);
mask<<=1;
if(b>e)
mask|=1;
b--;
}
return ~mask; /* negates mask for later purpose that is clearing corresponding bits */
}
Function creates mask for some bit operations, but should take two unsigned ints b and e, both non-negative. Question is how to prevent user input of negative numbers?
When function is called with (-1,0) it start the loop, and shoult exit with error.
You could just input a string, check if it contains a '-' character, and yield an error if it does. Else you convert it to an unsigned integer and proceed on. (Reading as a string then converting with strtoul() is preferred over using scanf() anyway, especially while you aren't aware of all of the quirks of scanf().)
char buf[LINE_MAX];
fgets(buf, sizeof buf, stdin);
if (strchr(buf, '-') != NULL) {
fprintf(stderr, "input must be non-negative!\n");
exit(-1);
}
unsigned int n = strtoul(buf, NULL, 0);
Edit:
you can take the long int input and then checks input is in between 0 to ending range of unsigned int .if so then assign to your variable else rise an exception to the user ,you should only give unsigned numbers as input.
long int input;
unsigned int valid_input;
scanf("%ld",&input);
if((0<= input) && (input <= 4294967295))
valid_input= (unsigned int)input ;
else
printf("Unvalid input\n");
As H2CO3 said.
reading input into string and checking for first literal if it is not minus then convert into unsigned integer would be preferable rather than the below method. because half of the part unsigned integers not covered.
you can get the input into int and then if it is non negative then proceed .if it is negative rise an exception to the user ,you should not give negative input.
Take a look at this: Stopping function implicit conversion
I was able to adapt it to your issue, and it stops the program from linking. The info in the above thread seems partially incorrect because the example compiled fine. It failed to link because there was not a template specialization defined. I'm actually a little surprised that the following worked for the int vs unsigned int.
template <class T>
void foo(const T& t);
template <>
void foo<unsigned int>(const unsigned int& t)
{
}
int main(){
foo((unsigned int) 9); // will compile and link
unsigned int value(5);
foo(value);// will compile and link
foo(9.0); // will not link
foo(-9); // will not link
return 0;
}
I think that you might be over thinking this though. Is it really a problem? Would it be better to make your id type an int to begin with? Is there a min/max id that avoids the large numbers that could be mistaken for a twos compliment? This seems like an unfortunate issue with the language that it doesn't provide any easy way to stop an implicit cast.
I tested the example with Visual Studio 2010. Additionally, I didn't have the time to write a test class so if it interests you then you'll have to adapt the example to a foo class to see if it works with a constructor of a class, or if there is another way to use templates to do this. Based on the other answers, and my experience I don't think that you are going to find an easy way to do what you want.
This small C script checks if a number is a prime... Unfortunately it doesn't fully work. I am aware of the inefficiency of the script (e.g. sqrt optimization), these are not the problem.
#include <stdio.h>
int main() {
int n, m;
printf("Enter an integer, that will be checked:\n"); // Set 'n' from commandline
scanf("%d", &n); // Set 'n' from commandline
//n = 5; // To specify 'n' inside code.
for (m = n-1; m >= 1; m--) {
if (m == 1) {
printf("The entered integer IS a prime.\n");
break;
}
if (n % m == 0) {
printf("The entered integer IS NOT a prime.\n");
break;
}
}
return 0;
}
I tested the programm with a lot of numbers and it worked... Then I tried a bigger number (1231231231231236) which is clearly not a prime...
BUT: the program told me it was!?
What am I missing...?
The number "1231231231231236" is too big to fit in an "int" data type. Add a printf statement to show what number your program thinks you gave it, and if that's prime, your program works fine; else, you might have a problem that merits checking. Adding support for integers of arbitary size requires considerable extra effort.
The reason you are having this problem is that intrinsic data types like int have a fixed size - probably 32 bits, or 4 bytes, for int. Given that, variables of type int can only represent 2^32 unique values - about 4 billion. Even if you were using unsigned int (you're not), the int type couldn't be used to store numbers bigger than around 4 billion. Your number is several orders of magnitude larger than that and, as such, when you try to put your input into the int variable, something happens, but I can tell you what doesn't happen: it doesn't get assigned the value 1231231231231236.
Hard to know without more details, but if your ints are 32-bit, then the value you've passed is outside the allowable range, which will no doubt be represented as something other than the value you've passed. You may want to consider using unsigned int instead.
The given number is too large for integer in C. Probably it only accepted a part of it. Try Printing the value of n.