Latest Tweets

molly: SEGMENTATION FAULT whenever pressing CTRL+D on the CLI

The issue

Pressing <CTRL+D> during a Molly session fires a segmentation fault, as shown below:

molly> <CTRL+D>
Program received signal SIGSEGV: Segmentation fault – invalid memory reference.

Backtrace for this error:
#0 0x7F68CC17A667
#1 0x7F68CC17AC34
#2 0x7F68CA38E1DF
#3 0x7F68CA476D12
#4 0x4FA46E in fgetlin_
#5 0x43227C in control_
#6 0x40456F in MAIN__ at molly.f:0
Segmentation fault

Debugging molly

In order to investigate this issue, we need to recompile molly with its debugging symbols. We add the “-g -O0” flags to the Makefile variables CFLAGS and FFLAGS to do so; finally we execute the make command to obtain the new binary. Once we have a new molly binary, we execute it inside a gdb session so that we can have a proper look at the back trace:

molly> <CTRL+D>
Program received signal SIGSEGV: Segmentation fault – invalid memory reference.

Backtrace for this error:
#0 0x7F4D3BF08667
#1 0x7F4D3BF08C34
#2 0x7F4D3A11C1DF
#3 0x7F4D3A204D12
#4 0x54895E in fgetlin_ at fgetlin.c:68
#5 0x43C073 in control_ at control.f:154
#6 0x4045E5 in molly at molly.f:687
Segmentation fault

As clearly seen above, the fgetlin_ function could be a good candidate to start looking for bugs. So, we set a breakpoint at fgetlin.c:68  to analyse this function properly:

(gdb) b fgetlin.c:68
Breakpoint 1 at 0x54894c: file src/fgetlin.c, line 68.
molly>
Breakpoint 1, fgetlin_ (g95_result=0x1d5ca000 “H\025\274\360\377\177”, g95_result_length=512,
prompt=0x77ade0 “molly> “, g95_prompt_length=7) at src/fgetlin.c:68
68 strcpy(g95_result, comm);

We are dealing with a classic invalid pointer de-reference issue here. The strcpy function is trying to copy from the address pointed to by comm to the address pointed to by g95_result. Let’s have a look at these particular addresses:

(gdb) p g95_result
$1 = “H\025\274\360\377\177”
(gdb) p comm
$2 = 0x0

Crystal clear; comm is pointing to NULL: 0x0. Therefore, the strcpy function is de-referencing the NULL PAGE &0x0. And so, the program crashes.

 Patching molly

CTRL+D equals EOF. And, according to the readline manpage:

If EOF is encountered while reading a line, and the line is empty, NULL is returned

So it would seem fair enough to infer that comm is holding the value returned by a call to readline, this being NULL because we have typed <CTRL+D>. Let’s have a look inside the fgetlin_ function:

 /* Get the prompt */
    char *comm = readline (cprompt);
    if (comm && *comm) add_history(comm);
 
    strcpy(g95_result, comm);
    int lok = strlen(g95_result);
    for(i=lok; i<g95_result_length; i++){
        *(g95_result+i) = ' ';
    }

Well, the value returned by readline is only checked whenever trying to add this command to the history. A BUG that needs to be amended. We can rewrite the rpevious code this way:

if (comm && *comm) {
 add_history(comm);
 strcpy(g95_result, comm);
}
int lok = strlen(g95_result);
for(i=((comm && *comm)?lok:0); i<g95_result_length; i++){
*(g95_result+i) = ' ';
}
if(comm==NULL) *g95_result='\n';

We have to do exactly the same to the fgetlinnh_ function. This function has the same behaviour as fgetlin_ but it does not add the typed command to the history. Finally, we recompile molly and try it out once again:

molly> <CTRL+D>
molly> Command not recognised

molly>

So far so good; now it does not fires a segmentation fault and it reports that <CTRL+D> is not a valid command, which is not. Problem fixed.