[comp.bugs.4bsd] Serious bug in 43bsd Reno make

mwm@hslrswi.hasler.ascom.ch (Mike McGann) (04/12/91)

Subject: Make unlinks directories if run as su
Index: folder 4.3BSD-reno

Description:
	When make is interrupted it removes the current target. If you are running 
        as root and the target is a directory, it will unlink the directory.	
Repeat-By:
Create a make file with a directory as a target, as below. It runs a nmake in subdir
etc. Run as root. Then interrupt it. It will say ****** etc removed and mean it.
	
SUBDIR= etc src


all:	${SUBDIR}

${SUBDIR}: FRC
	cd $@; make all

	to occur.
Fix:
Make sure its a regular file before it's unlinked.	
*** job.c.dist	Fri Apr 12 09:13:44 1991
--- job.c	Fri Apr 12 09:23:06 1991
***************
*** 85,90 ****
--- 85,91 ----
  #include "make.h"
  #include <sys/signal.h>
  #include <sys/stat.h>
+ #include <sys/types.h>
  #include <sys/file.h>
  #include <sys/time.h>
  #include <sys/wait.h>
***************
*** 2441,2446 ****
--- 2442,2448 ----
      LstNode 	  ln;		/* element in job table */
      Job           *job;	    	/* job descriptor in that element */
      GNode         *interrupt;	/* the node describing the .INTERRUPT target */
+     struct stat   fileStatus;
      
      aborting = ABORT_INTERRUPT;
  
***************
*** 2452,2457 ****
--- 2454,2461 ----
  	    char  	*file = (job->node->path == (char *)NULL ?
  				 job->node->name :
  				 job->node->path);
+             stat(file,&fileStatus);
+             if((fileStatus.st_mode & S_IFMT) == S_IFREG)
  	    if (unlink (file) == 0) {
  		Error ("*** %s removed", file);
  	    }
*** compat.c.dist	Fri Apr 12 09:13:57 1991
--- compat.c	Fri Apr 12 09:23:45 1991
***************
*** 41,46 ****
--- 41,47 ----
  
  #include    <stdio.h>
  #include    <sys/types.h>
+ #include    <sys/stat.h>
  #include    <sys/signal.h>
  #include    <sys/wait.h>
  #include    <sys/errno.h>
***************
*** 81,90 ****
      int	    signo;
  {
      GNode   *gn;
      
      if ((curTarg != NILGNODE) && !Targ_Precious (curTarg)) {
  	char 	  *file = Var_Value (TARGET, curTarg);
! 
  	if (unlink (file) == SUCCESS) {
  	    printf ("*** %s removed\n", file);
  	}
--- 82,94 ----
      int	    signo;
  {
      GNode   *gn;
+     struct stat fileStatus;
      
      if ((curTarg != NILGNODE) && !Targ_Precious (curTarg)) {
  	char 	  *file = Var_Value (TARGET, curTarg);
!         
!         stat(file, &fileStatus);
!         if((fileStatus.st_mode & S_IFMT) == S_IFREG)
  	if (unlink (file) == SUCCESS) {
  	    printf ("*** %s removed\n", file);
  	}