This question already has answers here:
Why is the gets function so dangerous that it should not be used?
(13 answers)
Closed 2 years ago.
I am learning C and decided to play around with the code, but not being able to find out where is the vulnerabity in this code.
I have pasted my code here:
#include <stdio.h>
char getPasswd() {
int trigger = 'K';
char data[100];
gets(data);
return (char) trigger;
}
void login() {
printf("inside!\n");
exit(0);
}
void main() {
printf("enter ");
if (getdata() == 'G') {
login();
} else {
printf("wrong.\n");
exit(1);
}
}
If any more info is required please let me know. What I think is vulnerbility is in gets() line 6 since its not safe to use that. I am new so not sure any help is appreciated.
The vulnerability is indeed in the gets function. you do:
char passwd[100];
gets(passwd);
The buffer is in this case 100 bytes long, so if someone inputs a string longer then 100 characters, your passwd buffer will overflow and possibly overwrite some important data that is stored after that password. to stop this from happening, you could use (fgets(buffer, sizeof(buffer), stdin);
So your piece of code would change into:
char passwd[100];
fgets(passwd, 100, stdin);
gets() has no bounds checking. So technically you can enter a password larger than 100 bytes and corrupt the stack.
For example on my machine, I could enter a password of
TTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT
(108 characters), overwriting the (possibly) adjacent variable trigger from 'F' to 'T', thereby making your code print the "logged in" message.
But this heavily depends on which platform you are running and your compiler, etc..
Related
This question already has an answer here:
What are null-terminated strings?
(1 answer)
Closed 7 months ago.
I have this simple program in which I initialize a string with "HELLO". I need the output to be printed as HLOEL, i.e) all the even indexes (0,2,4) followed by the odd ones (1,2). I could not infer what's wrong with my code, but it yields "HLOELHLO" instead of "HLOEL". Could someone explain what is happening here?
#include <stdio.h>
int main() {
int i,loPos=0,hiPos=0;
char *str="HELLO";
char lo[2];
char hi[3];
for(i=0;i<5;i++)
{
if(i%2==0)
{
hi[hiPos++]=str[i];
}
else
{
lo[loPos++]=str[i];
}
}
printf("%s%s",hi,lo);
return 0;
}
Thanks in Advance!
After the for loop, you need to put string terminating 0 bytes to the new strings, and also make sure they habe room for it:
char lo[2+1];
char hi[3+1];
for(...) {
}
hi[hiPos] = '\0';
Lo[loPos] = '\0';
Otherwise any string functions will have buffer overflow, causing undefined behavior. Generally they will keep reading bytes until by chance they encounter byte with value 0. But as always with undefined behavior, even this can cause your program to do anything.
because C style string need extra one char '\0' as its end. With your code,
the memory layout around two arrays maybe looks like:
lo[0], lo[1], hi[0], hi[1], hi[2], something else equal 0,
printf stops when it meets a '\0'
you should declare arrays as:
char lo[3];
char hi[4];
lo[2] = '\0';
hi[3] = '\0';
int main(int argc, char* argv[]) {
char* string; //local variable for a character
string = (char*)malloc(sizeof(char));
char* yes = "yes";
printf("Do you want to play (y/n)?");
scanf_s("%s", string);
if (strcmp(yes, string) == 0) {
printf("Hello welcome...");
}
Above is my code. Essentially, I want to make a loop asking for the user to input yes, y to continue; n, no to discontinue. But I simplify it for the sake of simple codes. The program just output the question, I press enter yes and enter then it stops.
I cant figure out a way to do it using array syntax( char string[] way, although array and malloc are basically the same) so I use pointer and malloc instead.
I'm going mad because this is bugging me so much. The practice assignment only asks to input character 'y' 'n' using %c but i want to do it the %s.
Really appreciate any help, im really stuck now. Thank you so much
Your code has two significant problems. First, if you want to input a string of characters, your malloc call needs to allocate space for more than one character; you should allocate the maximum number of characters you think the user's input will contain plus one - strings in C have a zero (nul) character at the end, to mark the end of the string).
Second, when you use the scanf_s function to read in a string (using the %s format specifier, as you have done), then you need to add additional parameters (the size of the target string buffer) after each string argument.
Here's a modified version of your code with these (and a few other) corrections:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main(int argc, char* argv[])
{
char* string = malloc(5); //local variable for a character string (up to 5 chars)
char* yes = "yes";
printf("Do you want to play (y/n)?");
scanf_s("%s", string, 5);
if (strcmp(yes, string) == 0) {
printf("Hello welcome...");
}
free(string); // Don't forget to release the memory!
return 0; // Conventionally, return 0 for success or non-zero on error
}
Note 1: Each and every call to malloc (or calloc) should be paired with a call to free to release the allocated memory, or you will end up with memory leaks.
Note 2: Please read this post: Do I cast the result of malloc?
Note 3: Although most (all?) C compilers will not insist on it, it is good practice to explicitly add a return 0; (for success) statement at the end of the main function.
Please feel free to ask for any further clarification and/or explanation.
This question already has answers here:
How do I properly compare strings in C?
(10 answers)
Closed 5 years ago.
char str[6];
do
{
printf("Enter the string you wanna check:");
scanf("%s", str);
}
while(str != "exit");
Why does this not work?
str will never equal "exit", because you're comparing the addresses of two different sections of memory. You probably want to compare the contents of the strings, for which there is a function strcmp().
"exit" is a char[5] generated by the compiler at some address in the data segment. This address is definitely different from the address of str, as two different objects cannot occupy the same location in memory.
The != operator between expressions of type char[] compares two pointers. These two pointers are the address of "exit" and the address of str, which, as I have already explained, will never be equal.
So, the expression str != "exit" will never evaluate to true. Which brings us to another point: your compiler should have issued a warning about this condition being always false. Which means that you are trying to program without -Wall. Don't do this, you are never going to get very far. Always use the highest warning level, and when you see warnings, always fix them.
To correct the problem, do as user3121023 suggested in a comment, and use strcmp() to compare strings.
The short answer is: it does not work because you must use strcmp(str, "exit") to compare the strings and loop for as long as the return value of strcmp() is not 0.
The long answer is: there are more problems in this little code fragment:
The array into which you read a word is very short and you do not limit the number of characters scanf() is likely to store there. Any user input longer than 5 non space characters will cause undefined behavior.
You do not check the return value of scanf(). A premature end of file, such as redirecting input from an empty file, will cause an infinite loop.
Here is how the code can be written in a safer way:
#include <stdio.h>
int main(void) {
char str[80];
for (;;) {
printf("Enter the string you wanna check:");
if (scanf("%79s", str) != 1 || strcmp(str, "exit") == 0)
break;
}
return 0;
}
As suggested above, use strcmp from the <string.h> header file.
char str[6];
do {
printf("Enter the string you wanna check:");
scanf("%s", str);
} while(!strcmp(str, "exit"));
Try :
#include <stdio.h>
#include <string.h>
int main() {
char str[6];
do
{
printf("Enter the string you wanna check:");
scanf("%s", str);
}
while(strcmp(str, "exit") != 0);
return 0;
}
This question already has answers here:
Why does printf not flush after the call unless a newline is in the format string?
(10 answers)
printf not printing on console
(7 answers)
Closed 5 years ago.
I'm trying to print out a character array (carefully choosing my words here) as if it were being typed by someone to the console. For some reason, printf does not immediately print the character to the console. As-is, the program will have nothing printed to the console for the exact amount of time taken to print the entire character array. However, when I uncomment the line //printf("\n"); , the console will actually show the contents being "typed", although vertically. In other words, using a newline seems to force the console to immediately print the character.
Why is this, and what would be an ideal way to fix this? I ask because I'm trying to think generally: what if I were writing a text-engine for a graphical video game?
#include <stdio.h>
#include <unistd.h>
void milliDelay(unsigned int milliseconds)
{
usleep(milliseconds * 1000);
}
void printConsole(char* txt)
{
//Define local variables such as the iterator and timers
unsigned int i;
unsigned const int keyDelay = 75, puncDelay = 1000;
//Print each character to the screen until we reach the null character
for(i = 0; txt[i] != '\0'; i++)
{
if(txt[i] == '.' || txt[i] == '!' || txt[i] == '?')
{
printf("%c", txt[i]);
milliDelay(puncDelay);
}
else
{
printf("%c", txt[i]);
milliDelay(keyDelay);
}
//printf("\n");
}
//Newline for much more appealing text formatting
printf("\n");
}
int main(int argc, char** argv) {
printConsole("Hello. This is a test using punctuation! Does this pause correctly?");
return 0;
}
For what it's worth, I'm using an Ubuntu system. I have not been able to see if the code works as intended on other platforms. I have also researched this question. I have written the code as I thought of it. Others have used putchar(), but this is something I never saw in my C programming class--hence I don't use that here. Is there anything bad about using printf() over putchar() in such a case?
Shouldn't I get an error if my string goes over 9 characters long in this program?
// CString.c
// 2.22.11
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
main()
{
char *aString = calloc(10, sizeof(char));
if (aString == NULL)
{
return 1;
}
printf("PLEASE ENTER A WORD: ");
scanf("%s", aString);
printf("YOU TYPED IN: %s\n", aString);
//printf("STRING LENGTH: %i\n", strlen(aString));
}
Thanks
blargman
You don't get a compiler error because the syntax is correct. What is incorrect is the logic and, what you get is undefined behavior because you are writing into memory past the end of the buffer.
Why is it undefined behavior? Well, you didn't allocate that memory which means it doesn't belong to you -- you are intruding into an area that is closed off with caution tape. Consider if your program is using the memory directly after the buffer. You have now overwritten that memory because you overran your buffer.
Consider using a size specifier like this:
scanf("%9s", aString);
so you dont overrun your buffer.
Yes, you got an error. And the most unfortunate part is that you don't know about it. You might know about it later on in the program when something mysteriously crashes (if you're lucky), or when your client's lawyers come to sue you (if you're not).