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>