PERFORCE change 20860 for review

Brian Feldman green at freebsd.org
Fri Nov 8 18:50:25 GMT 2002


http://perforce.freebsd.org/chv.cgi?CH=20860

Change 20860 by green at green_laptop_2 on 2002/11/08 10:49:58

	Make fsck_ffs(8)'s extended attribute checks do something
	useful: actually perform sanity checks on the extent and
	offer to dump the entire extent for debugging.

Affected files ...

.. //depot/projects/trustedbsd/mac/sbin/fsck_ffs/ea.c#2 edit

Differences ...

==== //depot/projects/trustedbsd/mac/sbin/fsck_ffs/ea.c#2 (text+ko) ====

@@ -47,42 +47,84 @@
 #include <ufs/ffs/fs.h>
 
 #include <err.h>
+#include <errno.h>
 #include <string.h>
+#include <unistd.h>
 
 #include "fsck.h"
 
+static int chkextattr(u_char *, int32_t);
+
 /*
- * Scan each entry in an ea block.
+ * Scan each entry in an ea block and do basic sanity checks as per
+ * those in src/sys/ufs/ffs/ffs_vnops.c:ffs_findextattr().
  */
 int
 eascan(struct inodesc *idesc, struct ufs2_dinode *dp)
 {
-#if 1
-	return (0);
-#else
 	struct bufarea *bp;
-	u_int dsize, n;
+	char tmpf[sizeof("/tmp/fsck_ffs-extent.XXXXXX")];
 	u_char *cp;
 	long blksiz;
-	char dbuf[DIRBLKSIZ];
+	int fd;
 
-	printf("Inode %ju extsize %ju\n",
-	   (intmax_t)idesc->id_number, (intmax_t)dp->di_extsize);
 	if (dp->di_extsize == 0)
 		return 0;
 	if (dp->di_extsize <= sblock.fs_fsize)
 		blksiz = sblock.fs_fsize;
 	else
-		blksiz = sblock.fs_bsize;
-	printf("blksiz = %ju\n", (intmax_t)blksiz);
+		blksiz = dp->di_extsize;
 	bp = getdatablk(dp->di_extb[0], blksiz);
 	cp = (u_char *)bp->b_un.b_buf;
-	for (n = 0; n < blksiz; n++) {
-		printf("%02x", cp[n]);
-		if ((n & 31) == 31)
-			printf("\n");
+	if (chkextattr(cp, dp->di_extsize)) {
+		pfatal("CORRUPT EXTENDED ATTRIBUTES I=%lu",
+		    (u_long)idesc->id_number);
+		if (reply("DUMP EXTENT") == 1) {
+			strcpy(tmpf, "/tmp/fsck_ffs-extent.XXXXXX");
+			fd = mkstemp(tmpf);
+			if (fd == -1) {
+				pwarn("temp file for dump: %s\n",
+				    strerror(errno));
+			} else {
+				pwarn("dump file at %s\n", tmpf);
+				(void)write(fd, cp, dp->di_extsize);
+				(void)close(fd);
+			}
+		}
 	}
-	return (STOP);
-#endif
+	bp->b_flags &= ~B_INUSE;
+	return (0);
 }
 
+static int
+chkextattr(u_char *ptr, int32_t length)
+{
+	u_char *p, *pe, *pn;
+	int nlen;
+	uint32_t ul, eapad2;
+
+	pe = ptr + length;
+
+	for (p = ptr; p < pe; p = pn) {
+		bcopy(p, &ul, sizeof(ul));
+		pn = p + ul;
+		/* make sure this entry is complete */
+		if (pn > pe)
+			return (EIO);
+		/* don't loop forever on a corrupt entry */
+		if (pn <= p)
+			return (EIO);
+		p += sizeof(uint32_t);
+		p++;
+		eapad2 = *p++;
+		/* padding is at most 7 bytes */
+		if (eapad2 >= 8)
+			return (EIO);
+		nlen = *p;
+		p++;
+		/* compare only up to the end of this attribute */
+		if (p + nlen > pn)
+			return (EIO);
+	}
+	return (0);
+}
To Unsubscribe: send mail to majordomo at trustedbsd.org
with "unsubscribe trustedbsd-cvs" in the body of the message



More information about the trustedbsd-cvs mailing list