Path: katsu From: katsu@sra.co.jp (WATANABE Katsuhiro) Message-ID: Date: 24 Oct 1994 14:39:56 GMT Organization: Software Research Associates, Inc.,Japan Distribution: Newsgroups: gnu.utils.bug Subject: CVS 1.3 tries to free NULL pointer, and causes SIGSEGV. CVS 1.3 can call free(3) with NULL pointer. On my machine (OMRON LUNA UniOS-Sigma 1.3) that causes SIGSEGV. You can observe the situation as follows: 1. Add "cvsbug" module entry into your modules file. 2. cd /tmp 3. mkdir cvsbug; cd cvsbug; touch file0 4. cvs import -m "start" cvsbug KATSU start 5. cd /tmp; rm -rf cvsbug 6. cd /tmp; mkdir base; cd base; cvs checkout cvsbug 7. cd /tmp; mkdir head; cd head; cvs checkout cvsbug 8. cd cvsbug; touch file1; cvs add file1; cvs commit -m "add file1" 9. cd /tmp/base/cvsbug; cvs -n -t update Invoking step 9 will produce output like followings: cvs update: Updating . -> unlink(CVS/,,file1) -> system(co -q -r1.1 /usr/mmb/katsu/CVS/cvsbug/file1,v file1) -> Register(file1, 1.1, , , ) U file1 -> unlink(CVS/,,file1) Segmentation fault (core dumped) (If "free(NULL)" returns peacefully on your OS, the segmentation fault might not be caused and "update" end successfully.) The reason why is a little bit complicated. But I'll try to explain. The 4th line "Register(file1, 1.1, , , )" shows that the 4th argument (char *ts --- that must contain the time stamp string of the RCS file of "file1") was NULL when it was called. That means a fact that a Entnode structure (we name it p) has been created with its timestamp field being NULL. When p will be free-ed by Entries_delproc() later, free(p->timestamp) will be called and p->timestamp must be NULL. In turn, why is Register(...) called with 4th argument NULL, to say why is the time stamp of "file1" specified illegally? Its caller is update.c:checkout_file(), which figures out the 4th argument (the time stamp of "file1") by calling Version_TS(). Version_TS() searches "file1" in "entries" table, which was prepared in Find_Names(), to try to take the time stamp out. But Version_TS never find "file1" entry because Find_Names() did not register it. Find_Names() registers only entries in ./CVS/Entries into "entries" table (by calling ParseEntries()). I believe that ./CVS/Entries keeps filenames only in "base" revision, to say, it does not keep "file1" entry, which is added at "head" revision. That's the story. To fix this problem, I think Entries_delproc() should check if p->timestamp is NULL or not, but I'm not sure it's right. -- WATANABE Katsuhiro Software Research Associates, Inc. (Tokyo JAPAN)