Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 28 May 2012 17:02:32 +0000
From:      gpf@FreeBSD.org
To:        svn-soc-all@FreeBSD.org
Subject:   socsvn commit: r236605 - in soc2012/gpf/pefs_kmod: sbin/pefs sys/fs/pefs
Message-ID:  <20120528170232.1390C106564A@hub.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: gpf
Date: Mon May 28 17:02:31 2012
New Revision: 236605
URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=236605

Log:
  add ioctl() to retrieve ciphertext for specific 4k sector.
  

Modified:
  soc2012/gpf/pefs_kmod/sbin/pefs/pefs_checksum.c
  soc2012/gpf/pefs_kmod/sbin/pefs/pefs_ctl.c
  soc2012/gpf/pefs_kmod/sys/fs/pefs/pefs.h
  soc2012/gpf/pefs_kmod/sys/fs/pefs/pefs_vnops.c

Modified: soc2012/gpf/pefs_kmod/sbin/pefs/pefs_checksum.c
==============================================================================
--- soc2012/gpf/pefs_kmod/sbin/pefs/pefs_checksum.c	Mon May 28 16:37:42 2012	(r236604)
+++ soc2012/gpf/pefs_kmod/sbin/pefs/pefs_checksum.c	Mon May 28 17:02:31 2012	(r236605)
@@ -69,6 +69,7 @@
 #define PEFS_FH_SIZE 16
 #define PEFS_BUCKET_SIZE 8
 
+/* XXXgpf: unions for on disk structs and move to a different header? */
 struct checksum_file_header {
         uint8_t version;
         uint8_t reserved;
@@ -83,6 +84,7 @@
 	TAILQ_ENTRY(checksum) checksum_entries;
 };
 
+/* XXXgpf: [TODO] turns offsets to 64bits uints (or off_t?) */
 struct file_header {
 	uint32_t nhashes;
 	uint64_t file_id;
@@ -108,13 +110,25 @@
 pefs_compute_file_checksums(struct file_header *fhp, const EVP_MD *md,
 	uint8_t hash_len)
 {
-	char buf[PEFS_SECTOR_SIZE];
+
+	struct pefs_xsector_ctext xsct;
 	EVP_MD_CTX mdctx;
-	int md_len, i, fd, bytes_read;
+	struct stat sb;
+	off_t resid;
+	uint32_t bytes_to_read;
+	int error, i, fd, md_len;
 	struct checksum *csp;
 
 	TAILQ_INIT(&(fhp->checksums));
 
+	/* XXXgpf: what happens if file size > 2^64? */
+	if (stat(fhp->path, &sb) != 0) {
+		warn("cannot stat file %s", fhp->path);
+		return (PEFS_ERR_SYS);
+	}
+
+	resid = sb.st_size;
+
 	fd = open(fhp->path, O_RDONLY);
 	if (fd < 0) {
 		warn("failed to open file: %s", fhp->path);
@@ -122,13 +136,31 @@
 	}
 
 	fhp->nhashes = 0;
-	while ((bytes_read = read(fd, buf, sizeof(buf))) > 0) {
+	xsct.pxsct_offset = 0;
+	while (resid > 0) {
+		if (resid > PEFS_SECTOR_SIZE)
+			bytes_to_read = PEFS_SECTOR_SIZE;
+		else
+			bytes_to_read = resid;
+
+		resid-=bytes_to_read;
+		xsct.pxsct_ctext_len = bytes_to_read;
+		error = ioctl(fd, PEFS_GETSECTORCTEXT, &xsct);
+		if (error != 0) {
+			pefs_warn("error retrieving ciphertext of %s", fhp->path);
+			close(fd);
+			return (PEFS_ERR_IO);
+		}
+		xsct.pxsct_offset+= xsct.pxsct_ctext_len;
+
 		EVP_MD_CTX_init(&mdctx);
 		EVP_DigestInit_ex(&mdctx, md, NULL);
-		EVP_DigestUpdate(&mdctx, buf, bytes_read);
+		EVP_DigestUpdate(&mdctx, xsct.pxsct_ctext, xsct.pxsct_ctext_len);
 
-		dprintf(("read %d bytes\n", bytes_read));
-		//for (i=0; i<bytes_read; i++) dprintf(("%c", buf[i]));
+		dprintf(("read %d bytes from kernel\n\n", bytes_to_read));
+		dprintf(("printing contents of buffer:"));
+		for (i=0; i < (int)bytes_to_read; i++) dprintf(("%c", xsct.pxsct_ctext[i]));
+		dprintf(("!\n"));
 
 		csp = malloc(sizeof(struct checksum));
 		if (csp == NULL) {
@@ -304,7 +336,7 @@
 		dprintf(("\nbucket %d with elements: %u\n", i, checksum_hash_tablep->buckets[i].nelements));
 		LIST_FOREACH(fhp, &(checksum_hash_tablep->buckets[i].file_headers), bucket_entries) {
 			//printf(("\tpath=%s!\t id = %d!\tnhashes = %d\n", fhp->path, (int)fhp->file_id, fhp->nhashes));
-			dprintf(("\tid = %d!\tnhashes = %d\n", (int)fhp->file_id, fhp->nhashes));
+			dprintf(("\tid = %llu!\tnhashes = %d\n", fhp->file_id, fhp->nhashes));
 			TAILQ_FOREACH(csp, &(fhp->checksums), checksum_entries) {
 				dprintf(("\t\tdigest="));
 				for (j = 0; j < hash_len; j++)
@@ -613,7 +645,7 @@
  * All data member writes are done separately so as to avoid alignment problems.
  * Writes are always in little endian byte order.
  *
- * TODO more comments about internal structure of file
+ * XXXgpf: [TODO] more comments about internal structure of file.
  */
 static int
 pefs_write_checksum_file(int fdout, struct checksum_file_header *cfhp, struct hash_table *chtp)

Modified: soc2012/gpf/pefs_kmod/sbin/pefs/pefs_ctl.c
==============================================================================
--- soc2012/gpf/pefs_kmod/sbin/pefs/pefs_ctl.c	Mon May 28 16:37:42 2012	(r236604)
+++ soc2012/gpf/pefs_kmod/sbin/pefs/pefs_ctl.c	Mon May 28 17:02:31 2012	(r236605)
@@ -108,6 +108,8 @@
 	{ NULL, NULL },
 };
 
+
+/* XXXgpf: [TODO] should probably add more at a later point */
 const char *supported_digests[] = {"sha256","sha512"};
 
 void
@@ -1048,7 +1050,6 @@
 	/* by default create checksum file under $PWD */
 	snprintf(csm_path, sizeof(csm_path), "./%s", PEFS_FILE_CHECKSUM);
 
-	/* XXXgpf: [TODO] add argument for user to specify path for .pefs. checksum */
 	while ((i = getopt(argc, argv, "a:i:p:")) != -1)
 		switch(i) {
 		case 'a':

Modified: soc2012/gpf/pefs_kmod/sys/fs/pefs/pefs.h
==============================================================================
--- soc2012/gpf/pefs_kmod/sys/fs/pefs/pefs.h	Mon May 28 16:37:42 2012	(r236604)
+++ soc2012/gpf/pefs_kmod/sys/fs/pefs/pefs.h	Mon May 28 17:02:31 2012	(r236605)
@@ -61,6 +61,12 @@
 	char			pnm_filename[MAXPATHLEN];
 };
 
+struct pefs_xsector_ctext {
+	off_t			pxsct_offset;
+	uint32_t		pxsct_ctext_len;
+	char			pxsct_ctext[PEFS_SECTOR_SIZE];
+};
+
 #ifdef _IO
 #define	PEFS_GETKEY			_IOWR('p', 0, struct pefs_xkey)
 #define	PEFS_ADDKEY			_IOWR('p', 1, struct pefs_xkey)
@@ -69,6 +75,7 @@
 #define	PEFS_FLUSHKEYS			_IO('p', 4)
 #define	PEFS_GETNODEKEY			_IOWR('p', 5, struct pefs_xkey)
 #define PEFS_GETNAMEMAC			_IOWR('p', 6, struct pefs_namemac)
+#define PEFS_GETSECTORCTEXT		_IOWR('p', 7, struct pefs_xsector_ctext)
 #endif
 
 #ifdef _KERNEL

Modified: soc2012/gpf/pefs_kmod/sys/fs/pefs/pefs_vnops.c
==============================================================================
--- soc2012/gpf/pefs_kmod/sys/fs/pefs/pefs_vnops.c	Mon May 28 16:37:42 2012	(r236604)
+++ soc2012/gpf/pefs_kmod/sys/fs/pefs/pefs_vnops.c	Mon May 28 17:02:31 2012	(r236605)
@@ -2357,15 +2357,20 @@
 {
 	struct pefs_enccn enccn;
 	struct componentname cn;
+	struct pefs_chunk pc;
+	u_quad_t fsize;
 	struct vnode *vp = ap->a_vp;
+	struct vnode *lvp = PEFS_LOWERVP(vp);
 	struct pefs_xkey *xk = ap->a_data;
 	struct pefs_namemac *namemac = ap->a_data;
+	struct pefs_xsector_ctext *xsct = ap->a_data;
 	struct ucred *cred = ap->a_cred;
 	struct thread *td = ap->a_td;
 	struct mount *mp = vp->v_mount;
 	struct pefs_mount *pm = VFS_TO_PEFS(mp);
 	struct pefs_node *pn;
 	struct pefs_key *pk;
+	struct uio *puio;
 	char *enc, *buf;
 	size_t enc_len, buf_len;
 	int error = 0, i, r;
@@ -2470,28 +2475,73 @@
 		if (pefs_key_remove_all(pm))
 			pefs_flushkey(mp, td, PEFS_FLUSHKEY_ALL, NULL);
 		break;
+	case PEFS_GETSECTORCTEXT:
+		vn_lock(vp, LK_EXCLUSIVE);
+
+		if (vp->v_type != VREG) {
+			printf("pefs_ioctl: PEFS_GETSECTORCTEXT vp is not a reg file\n");
+			VOP_UNLOCK(vp, 0);
+			return (EOPNOTSUPP);
+		}
+
+		error = pefs_getsize(vp, &fsize, cred);
+		if (error != 0) {
+			VOP_UNLOCK(vp, 0);
+			return (error);
+		}
+
+		if (xsct->pxsct_ctext_len > PEFS_SECTOR_SIZE || xsct->pxsct_ctext_len == 0
+			|| xsct->pxsct_ctext_len > fsize) {
+			printf("pefs_ioctl: PEFS_GETSECTORCTEXT invalid len: %d\n",
+						xsct->pxsct_ctext_len);
+			VOP_UNLOCK(vp, 0);
+			return (EINVAL);
+		}
+
+		if (xsct->pxsct_offset > (fsize - xsct->pxsct_ctext_len)) {
+			printf("pefs_ioctl: PEFS_GETSECTORCTEXT invalid offset: %llu\n",
+						xsct->pxsct_offset);
+			VOP_UNLOCK(vp, 0);
+			return (EINVAL);
+		}
+
+		pn = VP_TO_PN(vp);
+		pefs_chunk_create(&pc, pn, xsct->pxsct_ctext_len);
+		puio = pefs_chunk_uio(&pc, xsct->pxsct_offset, UIO_READ);
+
+		/* XXXgpf: is this lock really necessary? */
+		vn_lock(lvp, LK_EXCLUSIVE);
+		error = VOP_READ(lvp, puio, IO_UNIT | IO_NODELOCKED, cred);
+		VOP_UNLOCK(lvp, 0);
+
+		if (error == 0)
+			memcpy(xsct->pxsct_ctext, pc.pc_base, xsct->pxsct_ctext_len);
+
+		pefs_chunk_free(&pc, pn);
+		VOP_UNLOCK(vp, 0);
+		break;
 	case PEFS_GETNAMEMAC:
-		/* XXXgpf: should I change printf to PEFSDEBUG or something else? */
+		vn_lock(vp, LK_EXCLUSIVE);
+		/* XXXgpf: should I change printf to something else? e.g. PEFSDEBUG */
 		if (vp->v_type != VDIR) {
 			printf("pefs_ioctl: PEFS_GETNAMEMAC vp is not a directory\n");
-			error = EINVAL;
-			break;
+			VOP_UNLOCK(vp, 0);
+			return (EINVAL);
 		}
 
 		if (strnlen(namemac->pnm_filename, sizeof(namemac->pnm_filename)) !=
 			namemac->pnm_namelen) {
 			printf("pefs_ioctl: PEFS_GETNAMEMAC incorrect pnm_namelen %d\n", namemac->pnm_namelen);
-			error = EINVAL;
-			break;
+			VOP_UNLOCK(vp, 0);
+			return (EINVAL);
 		}
 
 		if (strchr(namemac->pnm_filename, '/') != NULL) {
 			printf("pefs_ioctl: PEFS_GETNAMEMAC pnm_filename contains '/'\n");
-			error = EINVAL;
-			break;
+			VOP_UNLOCK(vp, 0);
+			return (EINVAL);
 		}
 
-		vn_lock(vp, LK_EXCLUSIVE);
 		pefs_enccn_init(&enccn);
 
 		cn.cn_nameiop = LOOKUP;
@@ -2522,6 +2572,10 @@
 			r = pefs_name_pton(enc, enc_len, buf, buf_len);
 			if (r <= 0)
 				error = EINVAL;
+			/*
+			 * XXXgpf: [TODO] endianess!! Change int64_t to char[8]
+			 * and deal with endianess at user-space
+			 */
 			else
 				memcpy(&(namemac->pnm_csum), buf, PEFS_NAME_CSUM_SIZE);
 



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