Latest Tweets

MODEST: avoiding SEGFAULTS during FDT altered state and the eXCHG command

The issue

As long as a certain process p with its FDT altered closes a file previously redirected via kmodest, in the “do_restore_task()” function the module crashes, generating  a SEGFAULT error, causing the process to crash, also.

The cause

It was a trivial error but with an important awful effect. Basically, the function do_restore_task() did not check for a valid fd while it was restoring fd <-> fd’. In short:

t1{p[fd0,…,fdN]}
t2 -> Ins(fdS) -||- t2{p[fd0,..,fdN,..,fdS]}
t3 -> XCHG(fdN,fdS) -||- t3{p[fd0,..,fdS,..fdN]}
t4 -> Close(fdS) -||- t4{p[fd0,..,NULL,..,fdN]}
t5 -> RST(fdS,fdN) -||- t5{p[fd0,..,fdN,..,NULL]}

Thus, on quantum t5 the module crashes as the affected process p. In order to avoid this issue, all I needed to do was checking for NULL pointers just before trying to restore fd <-> fd’. In case of finding a NULL pointer in the slot fdS , it is clear it is not an opened one, so we can conclude that the process p has closed it some quantum of time before t5, that is, on t4.

At this time, MODEST prints out via printk() a message concerning this behaviour, as shown in the new video uploaded to the CVS repository, on SourceForge.net. Watch it here.

All the code changes involved are shown below:

...
521         if(tmp!=NULL){
522             do_fsync(tmp,0);                                /* Sync data buffers ! (1) */
523             fTable-&gt;fd[clean_up_user_args-&gt;oldfd] = fTable-&gt;fd[krn_fd]; /* Restore original fd pos. */
524             /* This code is for sanity reasons: */
525             fTable-&gt;fd[krn_fd] = tmp;
526         } else
527             /* It seems the process closed the file "oldfd". So, tmp is NULL. The "newfd" slot inside
528             * its FDT must be cleared, also. It is done if we do not do anything now, just call
529             * fd_deinstall_by_task.
530             */
531             printk("WARNING: The process has closed the file %d... n", clean_up_user_args-&gt;oldfd);
...