Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 9 Mar 2003 20:27:45 +1100 (EST)
From:      Peter Jeremy <peterjeremy@optushome.com.au>
To:        FreeBSD-gnats-submit@FreeBSD.org
Cc:        Peter Jeremy <jeremyp@cirb503493.alcatel.com.au>
Subject:   bin/49048: [patch] ctm(1) does not check parent directory of objects
Message-ID:  <200303090927.h299RjX0001974@cirb503493.alcatel.com.au>

next in thread | raw e-mail | index | archive | help

>Number:         49048
>Category:       bin
>Synopsis:       [patch] ctm(1) does not check parent directory of objects
>Confidential:   no
>Severity:       serious
>Priority:       high
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Sun Mar 09 01:30:10 PST 2003
>Closed-Date:
>Last-Modified:
>Originator:     Peter Jeremy
>Release:        FreeBSD 4.6-STABLE i386
>Organization:
n/a
>Environment:
System: FreeBSD cirb503493.alcatel.com.au 4.6-STABLE FreeBSD 4.6-STABLE #0: Mon Jul 22 21:45:58 EST 2002 root@cirb503493.alcatel.com.au:/usr/obj/usr/src/sys/pj1592 i386

>Description:
	When ctm(1) executes FM or DM operations, it verifies that the
	specified object doesn't exist but it fails to verify that the
	parent directory does exist during pass2.  If the parent directory
	doesn't exist then pass2 will succeed and ctm will die during pass3
	leaving the repository in an inconsistent state.

	Likewise ctm does not verify that the parent directory can be
	modified by the user running ctm.
>How-To-Repeat:
	Remove (or rename) the parent directory associated with a CTMFM
	or CTMDM operation in a ctm delta.  Run "ctm -c" on the delta
	and repository.  This will report "All checks out ok."  Actually
	running CTM will report "Fatal error: Assert failed." during
	pass3.  For further details or sample deltas, contact me.

>Fix:
	The following is against -CURRENT but will also apply to -STABLE.
Index: ctm_pass2.c
===================================================================
RCS file: /usr/ncvs/src/usr.sbin/ctm/ctm/ctm_pass2.c,v
retrieving revision 1.20
diff -u -r1.20 ctm_pass2.c
--- ctm_pass2.c	25 Mar 2002 13:53:29 -0000	1.20
+++ ctm_pass2.c	9 Mar 2003 08:57:50 -0000
@@ -21,6 +21,7 @@
 Pass2(FILE *fd)
 {
     u_char *p,*q,*md5=0;
+    const u_char *parent;
     MD5_CTX ctx;
     int i,j,sep,cnt,fdesc;
     u_char *trash=0,*name=0;
@@ -96,7 +97,41 @@
 		    if (CTM_FILTER_DISABLE == match)
 			    break;	/* should ignore this file */
 
-		    /* XXX Check DR DM rec's for parent-dir */
+		    /* Check parent directory exists */
+		    q = strrchr(name,'/');
+		    if(NULL != q) {
+			*q = '\0';
+			parent = name;
+		    } else
+			parent = ".";
+		    if(-1 == stat(parent,&st)) {
+			if (NULL != q)
+			    *q = '/';
+			fprintf(stderr,"  %s: %s parent doesn't exist.\n",
+			    sp->Key,name);
+			ret |= Exit_NotOK;
+			break;
+		    }
+		    /* Check we can write to parent */
+		    if (0 != access(parent, W_OK)) {
+			if (NULL != q)
+			    *q = '/';
+			fprintf(stderr, "  %s: %s can't alter parent.\n",
+			    sp->Key,name);
+			ret |= Exit_NotOK;
+			break;
+		    }
+		    if (NULL != q)
+			*q = '/';
+		    /* Check parent is directory */
+		    if((st.st_mode & S_IFMT) != S_IFDIR) {
+			fprintf(stderr,
+			    "  %s: %s parent exists, but isn't dir.\n",
+			    sp->Key,name);
+			ret |= Exit_NotOK;
+			break;
+		    }
+
 		    if(j & CTM_Q_Name_New) {
 			/* XXX Check DR FR rec's for item */
 			if(-1 != stat(name,&st)) {
>Release-Note:
>Audit-Trail:
>Unformatted:

To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-bugs" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200303090927.h299RjX0001974>