Random seeding seg fault - c

I am asked to put a random seeding into a program that is called when a user types in -r. It is shown to look like
-r1234567
So as a global variable I set Random = 1234567.
I added this to the top of my function as well:
printf("Seed: %d\n", Random);
srand48(Random);
Every time I use -r1234567 My program segfaults and says this:
Program received signal SIGSEGV, Segmentation fault.
____strtol_l_internal (nptr=0x0, endptr=0x0, base=10, group=<optimized out>,
loc=0x7ffff7ad8020) at ../stdlib/strtol_l.c:298
298 ../stdlib/strtol_l.c: No such file or directory.
(gdb) bt
#0 ____strtol_l_internal (nptr=0x0, endptr=0x0, base=10, group=<optimized out>,
loc=0x7ffff7ad8020) at ../stdlib/strtol_l.c:298
#1 0x00007ffff77589e0 in atoi (nptr=<optimized out>) at atoi.c:28
#2 0x0000000000401d8c in getCommandLine (argc=6, argv=0x7fffffffe238)
at prog.c:171
#3 0x0000000000401514 in main (argc=6, argv=0x7fffffffe238) at prog.c:35
(gdb) up
#1 0x00007ffff77589e0 in atoi (nptr=<optimized out>) at atoi.c:28
28 atoi.c: No such file or directory.
(gdb) up
#2 0x0000000000401d8c in getCommandLine (argc=6, argv=0x7fffffffe238)
at prog.c:171
warning: Source file is more recent than executable.
In my command like: the case looks like this:
while ((c = getopt(argc, argv, "g:n:a:h:s:d:v:r")) != -1)
case 'r': Random = atoi(optarg); break;
So a user wants to to randomize using a seed. They do ./program -r1234567. This then goes into the two lines of code that I put above and should randomize.
Any suggestions?

Your problem is the getopt call, in that you forgot to tell getopt that the -r argument takes a value:
getopt(argc, argv, "g:n:a:h:s:d:v:r:")
/* ^ */
/* | */
/* Add colon here */
Because of that, the optarg pointer is NULL when you call atoi.

you are giving -r1234567 from the command line , How you are parsing it and giving ito atoi ?
if atoi get "1234567" as its argument then there should not be any problem .. Can you paste the logic which parses the argv[1] ?

Are declaring Random as an int?. srand48 takes a long as an argument so you should be usuing atol instead of atoi:
long Random = 42;
printf("Seed: %d\n", Random);
srand48(Random);

The problem is .. you are missing ":" at the end of argument r ...because of this NULL is being passed to atoi .. try adding ":" at the end of r in the getopt !!

Related

gdb debugging segmentation fault, arguments count showing false

I am trying to debug the segmentation fault of a menu program written in 'C' and the main function is shown in the below screen shot.
int main( int ac, char **av ) {
/* TDT,II - 02 May 2006 - Added this check to see if there is a Debug level passed in */
if ( ac > 0 ) {
iDebug = atoi( av[1] );
sprintf( cLogText, "Setting Debug Level to ~%d~", iDebug );
WriteTrace( cLogText );
};
initscr();
clear();
t1=time(NULL);
local =localtime(&t1);
Svc_Login();
for ( ; ; ) {
cases_on_pc=FALSE;
if ( !Process_security() ) break;
menu1();
};
wrap_up(0);
endwin( );
exit(0);
}
when i try to debug (run using gdb), without any arguments, getting halted at 0x00007ffff34c323a in ____strtoll_l_internal () from /lib64/libc.so.6 as shown below. if(ac>0) becomes true, only when i pass any arguments. but i haven't passed any runtime arguments. still that 'f block is being executed and function atoi(av[1]) is called and resulted in segmentation fault. I am unable to figure it out. how to proceed further to identify and correct the issue so that i could run the menu program successfully. could somebody give any suggestions on this?
-rw-rw-r--. 1 MaheshRedhat MaheshRedhat 2275270 Jan 10 03:09 caomenu.c
-rw-rw-r--. 1 MaheshRedhat MaheshRedhat 0 Jan 10 03:09 caomenu.lis
-rwxr-xr-x. 1 root root 796104 Jan 10 03:10 scrmenu
[MaheshRedhat#azureRHEL MenuPrograms]$
[MaheshRedhat#azureRHEL MenuPrograms]$ gdb ./scrmenu
(gdb) run
Starting program: /home/MaheshRedhat/MenuPrograms/scrmenu
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib64/libthread_db.so.1".
Program received signal SIGSEGV, Segmentation fault.
0x00007ffff34c323a in ____strtoll_l_internal () from /lib64/libc.so.6
Missing separate debuginfos, use: yum debuginfo-install glibc-2.28-189.5.0.1.el8_6.x86_64 libnsl-2.28-189.5.0.1.el8_6.x86_64 ncurses-libs-6.1-9.20180224.el8.x86_64
(gdb)
(gdb) bt
#0 0x00007ffff34c323a in ____strtoll_l_internal () from /lib64/libc.so.6
#1 0x00007ffff34bfce4 in atoi () from /lib64/libc.so.6
#2 0x0000000000401674 in main (ac=1, av=0x7fffffffe228) at caomenu.pc:541
(gdb)
Update
The above issue has been resolved. Here is another encounter of segmentation fault.
from this backtrace of system calls, in WriteTrace (cEntryText=0x6f4d20 <cLogText> in my main function lead to call fputs() from library file /lib64/libc.so.6
Starting program: /home/MaheshRedhat/MenuPrograms/scrmenu 1
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib64/libthread_db.so.1".
Program received signal SIGSEGV, Segmentation fault.
0x00007ffff34f7f5c in fputs () from /lib64/libc.so.6
(gdb)
(gdb) bt
#0 0x00007ffff34f7f5c in fputs () from /lib64/libc.so.6
#1 0x0000000000472efc in WriteTrace (cEntryText=0x6f4d20 <cLogText> "Setting Debug Level to ~1~") at caomenu.pc:18394
#2 0x00000000004016a0 in main (ac=2, av=0x7fffffffe208) at caomenu.pc:543
(gdb)
The below is the declaration of cLogText
char cLogText[250];
The below is code for WriteTrace:
/**************************************************************************
routine to write an entry in the trace file
**************************************************************************/
void WriteTrace( char *cEntryText ) {
char cTimeStamp[40]; /* time stamp variable */
char cTimeFormat[]="%H:%M:%S: "; /* time stamp format */
GetTimeStamp( &cTimeStamp[0], sizeof(cTimeStamp), &cTimeFormat[0] );
TrcFile = fopen( cTraceFile, cTrcOpenFlag ); /* open the file */
cTrcOpenFlag[0] = 'a'; /* after first, always app} */
fprintf(TrcFile, "%s", cTimeStamp); /* write the time stamp */
fprintf(TrcFile, "%s\n", cEntryText); /* write the entry */
fclose(TrcFile); /* close the trace file */
return; /* return to caller */
}
From C11:
The value of argc shall be nonnegative. argv[argc] shall be a null
pointer. If the value of argc is greater than zero, the array members
argv[0] through argv[argc-1] inclusive shall contain pointers to
strings, which are given implementation-defined values by the host
environment prior to program startup. The intent is to supply to the
program information determined prior to program startup from elsewhere
in the hosted environment. If the host environment is not capable of
supplying strings with letters in both uppercase and lowercase, the
implementation shall ensure that the strings are received in
lowercase.
If the value of argc is greater than zero, the string
pointed to by argv[0] represents the program name; argv[0][0] shall be
the null character if the program name is not available from the host
environment. If the value of argc is greater than one, the strings
pointed to by argv[1] through argv[argc-1] represent the program
parameters.
The condition
( ac > 0 )
would be true even if you provided 0 program arguments, with argv[0] pointing to the program name (if it was available).
This statement:
atoi( av[1] );
tries to access av[1] which the Standard defines to be NULL when no program arguments were provided. Hence the segmentation violation signal.
fopen returns NULL to indicate failure.
TrcFile = fopen( cTraceFile, cTrcOpenFlag );
You do not check its return value here, before passing it to fprintf.
Perhaps:
TrcFile = fopen( cTraceFile, cTrcOpenFlag );
if (!TrcFile) {
deal with error here..
}
if (ac > 0) {
iDebug = atoi(av[1]); // out of bounds here, when you run `./scrmenu`
}
when you run ./scrmenu, you will have ac=1 and av[0]=./scrmenu
You may misunderstand ac and av mean in the main function.
how to fix:
if (ac == 2) {
iDebug = atoi(av[1]); // parse the second argument
}
then you can run: ./scrmenu or ./scrmenu 1 something like this.
you can check this post about command line argument

How to find which function from program reads from stdin?

I am currently working on fuzzing a program, and the code base is huge. To improve the performance, I am using persistent mode by creating a loop around the necessary function or code that reads from stdin. Right now using gdb, I am able to enumerate all the functions being used by the program like this:
set logging on
set confirm off
rbreak ^[^#]*$
run the binary
continue
This gives me all the functions that the program uses, but I think an easier way than reading hundreds of lines is by finding the function that reads from stdin. How would I be able to find the function that reads from stdin?
Since you're running Linux, virtually every function that reads from a stream (such as stdin) will ultimately do a read system call. (Less often, they will call readv.)
The C prototype for the read function is
ssize_t read(int fd, void *buf, size_t count);
and like most Linux system calls, this is pretty much the prototype for the actual system call (all the integer and pointer types are put into registers.)
On x86_64, the first argument to a system call will be in register rdi. (See Calling conventions.) A value of 0 means stdin.
So first we will tell GDB to stop the process upon entering the read system call, adding a condition to stop only when its first argument is 0:
(gdb) catch syscall read
Catchpoint 1 (syscall 'read' [0])
(gdb) condition 1 $rdi == 0
(gdb) run
Starting program: cat
Catchpoint 1 (call to syscall read), 0x00007fffff13b910 in __read_nocancel () at ../sysdeps/unix/syscall-template.S:84
84 ../sysdeps/unix/syscall-template.S: No such file or directory.
Now do a backtrace to see all the functions in the call stack:
(gdb) bt
#0 0x00007fffff13b910 in __read_nocancel () at ../sysdeps/unix/syscall-template.S:84
#1 0x00007fffff0d2a84 in __GI__IO_file_xsgetn (fp=0x7fffff3f98c0 <_IO_2_1_stdin_>, data=<optimized out>, n=4096)
at fileops.c:1442
#2 0x00007fffff0c7ad9 in __GI__IO_fread (buf=<optimized out>, size=1, count=4096, fp=0x7fffff3f98c0 <_IO_2_1_stdin_>)
at iofread.c:38
#3 0x00000000080007c2 in copy () at cat.c:6
#4 0x00000000080007de in main () at cat.c:12
(gdb) fr 3
#3 0x00000000080007c2 in copy () at cat.c:6
6 while ((n=fread(buf, 1, sizeof buf, stdin)) > 0)
(gdb) fr 4
#4 0x00000000080007de in main () at cat.c:12
12 copy();
How would I be able to find the function that reads from stdin?
In general, your question is equivalent to the halting problem. Consider this function:
ssize_t foo(int fd, void *buf, size_t count) { return read(fd, buf, count); }
Does this function read from stdin? It may or may not (depending on inputs), and therein lies the problem.
P.S. Your method of enumerating all functions that are called is exceedingly inefficient. You should look into building your program with -finstrument-functions instead. Example.

GDB doesn't let me read argv memory segment

I have this simple script written in C:
#include <stdio.h>
void usage(char *program_name) {
printf("Usage: %s <message> <# of times to repeat>\n", program_name);
exit(1);
}
int main(int argc, char *argv[]) {
int i, count;
// if(argc < 3) // If less than 3 arguments are used,
// usage(argv[0]); // display usage message and exit.
count = atoi(argv[2]); // convert the 2nd arg into an integer
printf("Repeating %d times..\n", count);
for(i=0; i < count; i++)
printf("%3d - %s\n", i, argv[1]); // print the 1st arg
}
And I'm making some test with GDB.
I did this:
(gdb) run test
Starting program: /home/user/Desktop/booksrc/convert2 test
Program received signal SIGSEGV, Segmentation fault.
0x00007ffff7a56e56 in ____strtoll_l_internal () from /usr/lib/libc.so.6
Obviusly it goes in segmentation fault because to work the program needs three argv. And I commented the lines that do the control. So it goes in error.
(gdb) where
#0 0x00007ffff7a56e56 in ____strtoll_l_internal () from /usr/lib/libc.so.6
#1 0x00007ffff7a53a80 in atoi () from /usr/lib/libc.so.6
#2 0x00005555555546ea in main (argc=2, argv=0x7fffffffe958) at convert2.c:14
(gdb) break main
Breakpoint 1 at 0x5555555546d2: file convert2.c, line 14.
(gdb) run test
The program being debugged has been started already.
Start it from the beginning? (y or n) y
Starting program: /home/user/Desktop/booksrc/convert2 test
Breakpoint 1, main (argc=2, argv=0x7fffffffe958) at convert2.c:14
14 count = atoi(argv[2]); // convert the 2nd arg into an integer
(gdb) cont
Continuing.
Program received signal SIGSEGV, Segmentation fault.
0x00007ffff7a56e56 in ____strtoll_l_internal () from /usr/lib/libc.so.6
(gdb) x/3xw 0x7fffffffe958 // this is memory of the "argv" some line before
0x7fffffffe958: 0xffffebfe 0x00007fff 0xffffec22
(gdb) x/s 0xffffebfe
0xffffebfe: <error: Cannot access memory at address 0xffffebfe>
(gdb) x/s 0x00007fff
0x7fff: <error: Cannot access memory at address 0x7fff>
(gdb) x/s 0xffffec22
0xffffec22: <error: Cannot access memory at address 0xffffec22>
In theory, with "x/s" I should have seen the commandline in the first address and "test" in the second address and the null in the third. But nothing. If I copy paste that address to a ascii to string converter, it gives me data without any sense. What am I doing wrong?
Your platform uses 64bit pointers, so try :
(gdb) x/3xg 0x7fffffffe958
to display the 64bit pointers in the argv array, and then :
(gdb) x/s 0x00007fffffffebfe
or just :
(gdb) p argv[0]
First of all always check if the command line is correct
Uncomment the check from your code.
Then in the gdb set the arguments (before running it)
(gdb) set args "hello world" 12

GCC based SIGSEGV error?

So I have been writing a handful of C libraries for my own personal use and I have been doing swell until my latest library, which just contains a bunch of string functions. As you can probably tell by the question title, I am getting a SIGSEGV signal. The problem is this: my research indicates that about 99% of all SIGSEGV errors are due to stack overflow, itself due to bad recursion, but as you will see, I am not using any recursion. Furthermore, there are a few odd problems that occur. For one, printf is exhibiting a lot of funky behavior. GDB encounters printf calls but does not actually seem to execute them until a few lines of code later. Likewise, one of my printf statements is being broken up somehow, and only a part is being called, with another part being chopped off apparently.
Here are the key code snippets, some stuff is named funny because I suspected name clashing may be the cause at one point and may have gone a little overboard...
"firstIndexOf" function (finds the first index of a character in a string, if that character is in said string), found at line 31:
int firstIndexOfFUNCTION(char thisChar, char* inThisString)
{
int lengthABC = strlen(inThisString);
printf("\nLength of %s is %d",inThisString,lengthABC);
int thisFunctionsIndex;
for (thisFunctionsIndex=0;thisFunctionsIndex<lengthABC;thisFunctionsIndex++)
{
printf("\n%dth iteration:\n-char 1 is %c\n-char2 is %c",thisFunctionsIndex,inThisString[thisFunctionsIndex],thisChar);
if (inThisString[thisFunctionsIndex] == thisChar)
{
printf("\nMatch found on iteration %d!",thisFunctionsIndex);
return thisFunctionsIndex;
}
}
printf("\nNo matches detected...");
return -3;
}
The "string_functions_test" function (a function just meant to test the other functions) at line 62:
int string_functions_test()
{
printf("PROGRAM INITIALIZED!\n\n");
char* sft_string;
int sft_index;
sft_string = malloc(sizeof(char)*100);
sft_string = "B um sbm. Sbm B bm.";
printf("2nd BREAKPOINT");
sft_index = firstIndexOfFUNCTION('B',sft_string);
sft_string[sft_index] = 'I';
return 0;
}
and last but not least, good ol' main, at line 107:
int main(int argc, char* argv[])
{
string_functions_test();
return 0;
}
Here is the gdb output for a step-through of my code:
(gdb) b 105
Breakpoint 1 at 0x400970: file string_functions.c, line 105.
(gdb) run
Starting program: /home/user/Development/projects/c/string_functions/source/c/a.out
Breakpoint 1, main (argc=1, argv=0x7fffffffde98) at string_functions.c:109
109 string_functions_test();
(gdb) step
string_functions_test () at string_functions.c:64
64 printf("PROGRAM INITIALIZED!\n\n");
(gdb) next
PROGRAM INITIALIZED!
68 sft_string = malloc(sizeof(char)*100);
(gdb) next
69 sft_string = "B um sbm. Sbm B bm.";
(gdb) next
71 printf("2nd BREAKPOINT");
(gdb) next
73 sft_index = firstIndexOfFUNCTION('B',sft_string);
(gdb) step
firstIndexOfFUNCTION (thisChar=66 'B', inThisString=0x400ab9 "B um sbm. Sbm B bm.") at string_functions.c:33
33 int lengthABC = strlen(inThisString);
(gdb) next
34 printf("\nLength of %s is %d",inThisString,lengthABC);
(gdb) next
2nd BREAKPOINT
36 for (thisFunctionsIndex=0;thisFunctionsIndex<lengthABC;thisFunctionsIndex++)
(gdb) next
38 printf("\n%dth iteration:\n-char 1 is %c\n-char2 is %c",thisFunctionsIndex,inThisString[thisFunctionsIndex],thisChar);
(gdb) next
Length of B um sbm. Sbm B bm. is 19
0th iteration:
-char 1 is B
39 if (inThisString[thisFunctionsIndex] == thisChar)
(gdb) next
41 printf("\nMatch found on iteration %d!",thisFunctionsIndex);
(gdb) next
-char2 is B
42 return thisFunctionsIndex;
(gdb) next
47 }
(gdb) next
string_functions_test () at string_functions.c:75
75 sft_string[sft_index] = 'I';
(gdb) next
Program received signal SIGSEGV, Segmentation fault.
0x0000000000400883 in string_functions_test () at string_functions.c:75
75 sft_string[sft_index] = 'I';
(gdb) next
Program terminated with signal SIGSEGV, Segmentation fault.
The program no longer exists.
(gdb) quit
You may notice that the printf which prints "2nd Breakpoint" is called, and then the program steps into a different function before the results are seen. I am assuming this is some whacky behavior on the part of the gcc compiler meant to serve as a cpu optimization, but it is sort of messing me up right now obviously. Likewise, the printf in my for loop is being broken up after the first formatted char. These two things are making it super hard to detect what exactly is happening. Has anyone experienced similar behavior?
In case it matters, I am including:
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
You are first pointing the pointer sft_string to what is returned from malloc. In the next line you make it point to a literal string. You need to copy it. A literal is built into the source code and cannot be changed during execution. Otherwise it raises a segment fault, which means that an area of memory that has code is being changed. Use strcpy.

Regexc - Segmentation Fault

I'm relatively new to C and I have a problem with the following:
regex_t re;
regmatch_t matches[2];
int start;
int end;
int count = 0;
int reti = regcomp(&re, "^(?:[a-zA-Z]|[a-zA-Z](?:[a-zA-Z0-9\\-])*[a-zA-Z0-9])(?:\\.(?:[a-zA-Z]|[a-zA-Z](?:[a-zA-Z0-9\\-])*[a-zA-Z0-9]))*$", REG_EXTENDED);
while (1) {
printf("Local = %s\n", local);
reti = regexec(&re, local, 2, matches, 0);
// More code here
}
When I run this, I get a segmentation fault.
local was defined as char *local and is being printed out correctly.
I ran the code using GDB and it turns out the issue is arising at the line:
reti = regexec(&re, local, 2, matches, 0);
I can't seem to figure out why.
This is the output from gdb:
Program received signal SIGSEGV, Segmentation fault.
0x00007ffff7af8d42 in regexec () from /lib/x86_64-linux-gnu/libc.so.6
(gdb) backtrace
#0 0x00007ffff7af8d42 in regexec () from /lib/x86_64-linux-gnu/libc.so.6
#1 0x000000000040092d in email_in (str=0x400aa8 "giri#gmail.com") attestdriver.c:70
#2 0x0000000000400780 in main () at testdriver.c:15
Would anyone have any ideas as to what might be the issue?
Thanks for your help.
The problem is actually here:
int reti = regcomp(&re, "^(?:[a............
From here:
You need to check the return of regcomp, it will tell you that your regex is invalid.
You will get Invalid preceding regular expression
(?: is not supported by POSIX regexes.
It's throwing this error because:
A common way to get a segfault is to dereference a null pointer
(From here)
The regex cannot initialize because of the illegal (?:
The original error is shown in the return of regcomp, and does not halt execution.

Resources