From owner-svn-soc-all@FreeBSD.ORG Tue Jun 5 14:26:32 2012 Return-Path: Delivered-To: svn-soc-all@FreeBSD.org Received: from socsvn.FreeBSD.org (unknown [IPv6:2001:4f8:fff6::2f]) by hub.freebsd.org (Postfix) with SMTP id E2A5C1065674 for ; Tue, 5 Jun 2012 14:26:31 +0000 (UTC) (envelope-from gpf@FreeBSD.org) Received: by socsvn.FreeBSD.org (sSMTP sendmail emulation); Tue, 05 Jun 2012 14:26:31 +0000 Date: Tue, 05 Jun 2012 14:26:31 +0000 From: gpf@FreeBSD.org To: svn-soc-all@FreeBSD.org MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Message-Id: <20120605142631.E2A5C1065674@hub.freebsd.org> Cc: Subject: socsvn commit: r237140 - soc2012/gpf/pefs_kmod/sbin/pefs X-BeenThere: svn-soc-all@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: SVN commit messages for the entire Summer of Code repository List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 05 Jun 2012 14:26:33 -0000 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",