socsvn commit: r237140 - soc2012/gpf/pefs_kmod/sbin/pefs

gpf at FreeBSD.org gpf at FreeBSD.org
Tue Jun 5 14:26:33 UTC 2012


Author: gpf
Date: Tue Jun  5 14:26:30 2012
New Revision: 237140
URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=237140

Log:
  change how symlinks are handled. user may want to check integrity for symlink
  file itself, and not just for the target file that the symlink points to.
  Therefore, if user wants integrity checking for both symlink & target file, he
  should provide two separate entries in input file list. one for symlink file,
  one for target file. However, if symlink is given, normal sanity checks are
  performed as usual.
  
  Todo: print warning if target file of a sylmink does not reside in input
  file list.
  

Modified:
  soc2012/gpf/pefs_kmod/sbin/pefs/pefs_checksum.c

Modified: soc2012/gpf/pefs_kmod/sbin/pefs/pefs_checksum.c
==============================================================================
--- soc2012/gpf/pefs_kmod/sbin/pefs/pefs_checksum.c	Tue Jun  5 13:57:02 2012	(r237139)
+++ soc2012/gpf/pefs_kmod/sbin/pefs/pefs_checksum.c	Tue Jun  5 14:26:30 2012	(r237140)
@@ -93,6 +93,7 @@
 	uint32_t nhashes;
 	uint64_t file_id;
 	char path[MAXPATHLEN];
+	char *target_path;
 	uint32_t offset_to_checksums;
 	struct checksum_head checksums;
 	TAILQ_ENTRY(file_header) file_header_entries;
@@ -380,7 +381,7 @@
 	uint32_t nbucket;
 
 	nbucket = fhp->file_id % chtp->size;
-	printf("hash1: goto bucket %d\n", nbucket);
+	dprintf(("hash1: goto bucket %d\n", nbucket));
 	return (nbucket);
 }
 
@@ -390,7 +391,7 @@
 	uint32_t nbucket;
 
 	nbucket = fnv_64_buf(&(fhp->file_id), sizeof(fhp->file_id), FNV1_64_INIT) % chtp->size;
-	printf("hash2: goto bucket %d\n", nbucket);
+	dprintf(("hash2: goto bucket %d\n", nbucket));
 
 	return (nbucket);
 }
@@ -562,11 +563,6 @@
 		return (PEFS_ERR_SYS);
 	}
 
-	if (statfs(fhp->path, &this_fs) == -1) {
-		pefs_warn("statfs failed: %s: %s", fhp->path, strerror(errno));
-		return (PEFS_ERR_SYS);
-	}
-
 	/*
 	 * XXXgpf: [TODO] deal with other types of files
 	 */
@@ -577,10 +573,22 @@
 			return (PEFS_ERR_SYS);
 		}
 
-		if (nchars > sizeof(sbuf) - 1)
-			nchars = sizeof(sbuf) - 1;
+		/*
+		 * XXXgpf: target_path can be used to tell if user has supplied target_file
+		 * in input file-list, since symlinks are not traversed. User will have to
+		 * provide fullpaths for both symlink & target file if he wants integrity
+		 * checking for both.
+		 * [TODO] make sure they are properly free()d and print warning errors
+		 * in case user does not supply separate entry for target_file.
+		 */
+		fhp->target_path = malloc(MAXPATHLEN);
+		if (fhp->target_path == NULL) {
+			warn("memory allocation error");
+			return (PEFS_ERR_SYS);
+		}
+
 		sbuf[nchars] = '\0';
-		/* turn relative paths to absolute paths which are needed for pefs_get_file_id() */
+		/* turn relative paths to absolute paths */
 		if (sbuf[0] != '/') {
 			strlcpy(parent_dir, fhp->path, sizeof(parent_dir));
 			pch = strrchr(parent_dir, '/');
@@ -589,15 +597,38 @@
 				return (PEFS_ERR_NOENT);
 			}
 			*pch = '\0';
-			snprintf(fhp->path, sizeof(fhp->path), "%s/%s", parent_dir, sbuf);
+			snprintf(fhp->target_path, MAXPATHLEN, "%s/%s", parent_dir, sbuf);
 		}
 		else
-			strlcpy(fhp->path, sbuf, sizeof(fhp->path));
+			strlcpy(fhp->target_path, sbuf, sizeof(fhp->target_path));
 
-		if (lstat(fhp->path, &sb) != 0) {
-			warn("cannot stat file %s", fhp->path);
+		/* target file should be in pefs filesystem */
+		if (statfs(fhp->target_path, &this_fs) == -1) {
+			pefs_warn("statfs failed: %s: %s", fhp->target_path, strerror(errno));
 			return (PEFS_ERR_SYS);
 		}
+
+		if ((fsp->f_fsid.val[0] != this_fs.f_fsid.val[0]) ||
+			(fsp->f_fsid.val[1] != this_fs.f_fsid.val[1])) {
+			pefs_warn("symlink target filename: %s does not reside in filesystem %s",
+				fhp->target_path, fsp->f_mntonname);
+			return (PEFS_ERR_INVALID);
+		}
+
+		/* symlink file should be in pefs filesystem */
+		if (statfs(fhp->path, &this_fs) == -1) {
+			pefs_warn("statfs failed: %s: %s", fhp->path, strerror(errno));
+			return (PEFS_ERR_SYS);
+		}
+
+		if ((fsp->f_fsid.val[0] != this_fs.f_fsid.val[0]) ||
+			(fsp->f_fsid.val[1] != this_fs.f_fsid.val[1])) {
+			pefs_warn("filename: %s does not reside in filesystem %s",
+				fhp->path, fsp->f_mntonname);
+			return (PEFS_ERR_INVALID);
+		}
+
+		return (0);
 	}
 
 	if (S_ISREG(sb.st_mode) == 0) {
@@ -605,6 +636,11 @@
 		return (PEFS_ERR_INVALID);
 	}
 
+	if (statfs(fhp->path, &this_fs) == -1) {
+		pefs_warn("statfs failed: %s: %s", fhp->path, strerror(errno));
+		return (PEFS_ERR_SYS);
+	}
+
 	if ((fsp->f_fsid.val[0] != this_fs.f_fsid.val[0]) ||
 		(fsp->f_fsid.val[1] != this_fs.f_fsid.val[1])) {
 		pefs_warn("filename: %s does not reside in filesystem %s",


More information about the svn-soc-all mailing list