Date: Tue, 05 Jun 2012 13:46:20 +0000 From: gpf@FreeBSD.org To: svn-soc-all@FreeBSD.org Subject: socsvn commit: r237137 - soc2012/gpf/pefs_kmod/sbin/pefs Message-ID: <20120605134620.44F9E106564A@hub.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: gpf Date: Tue Jun 5 13:46:19 2012 New Revision: 237137 URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=237137 Log: - check if our input file list is empty - check if some file entry corresponds to an empty file - check if pefs_next_file_entry encounters an error - handle symlinks: If file in input list is symlink, get the absolute path of the file that it's pointing to. Perform sanity checks on target file. If everything's ok, target file is used throughout the codebase. Which means that .pefs.checksum will have an entry for that target file, not for the symlink. - check for numeric overflows in a few parts 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 12:34:08 2012 (r237136) +++ soc2012/gpf/pefs_kmod/sbin/pefs/pefs_checksum.c Tue Jun 5 13:46:19 2012 (r237137) @@ -54,7 +54,7 @@ #include "pefs_ctl.h" -#define PEFS_INTEGRITY_DEBUG +//#define PEFS_INTEGRITY_DEBUG #if defined (PEFS_INTEGRITY_DEBUG) #define dprintf(a) printf a #else @@ -71,6 +71,8 @@ #define PEFS_CFH_SIZE 16 #define PEFS_FH_SIZE 16 +/* XXXgpf: [TODO] check pathname string lengths. Some are MAXPATHLEN + 1, some MAXPATHLEN */ + /* XXXgpf: unions for on disk structs and move to a different header? */ struct checksum_file_header { uint8_t version; @@ -169,8 +171,11 @@ return (PEFS_ERR_SYS); } - /* XXXgpf: shouldn't we also check for empty files? */ resid = sb.st_size; + if (resid == 0) { + pefs_warn("empty files are not allowed: %s", fhp->path); + return (PEFS_ERR_INVALID); + } fd = open(fhp->path, O_RDONLY); if (fd < 0) { @@ -244,7 +249,10 @@ nfiles = 0; while (fgets(buf, sizeof(buf), fpin) != NULL) { - /* XXXgpf: [TODO] check for numeric overflow */ + if (nfiles + 1 < nfiles) { + pefs_warn("numeric overflow while counting file entries"); + return (PEFS_ERR_GENERIC); + } nfiles++; } @@ -253,6 +261,11 @@ return (PEFS_ERR_IO); } + if (nfiles == 0) { + pefs_warn("input file has no entries"); + return (PEFS_ERR_INVALID); + } + fseek(fpin, 0, SEEK_SET); *nelementsp = nfiles; @@ -287,6 +300,10 @@ } else { chtp->size = pefs_next_prime(chtp->size + 1); + if (chtp->size < chtp->nelements) { + pefs_warn("numeric overflow while computing new hash table size"); + return (PEFS_ERR_GENERIC); + } free(chtp->buckets1); free(chtp->buckets2); } @@ -533,10 +550,14 @@ static int pefs_file_semantic_checks(struct file_header *fhp, struct statfs *fsp) { + char parent_dir[MAXPATHLEN]; + char sbuf[MAXPATHLEN]; struct stat sb; struct statfs this_fs; + char *pch; + int nchars; - if (stat(fhp->path, &sb) != 0) { + if (lstat(fhp->path, &sb) != 0) { warn("cannot stat file %s", fhp->path); return (PEFS_ERR_SYS); } @@ -549,6 +570,35 @@ /* * XXXgpf: [TODO] deal with other types of files */ + if (S_ISLNK(sb.st_mode) != 0) { + nchars = readlink(fhp->path, sbuf, sizeof(sbuf)); + if (nchars == -1) { + warn("readlink failed: %s", fhp->path); + return (PEFS_ERR_SYS); + } + + if (nchars > sizeof(sbuf) - 1) + nchars = sizeof(sbuf) - 1; + sbuf[nchars] = '\0'; + /* turn relative paths to absolute paths which are needed for pefs_get_file_id() */ + if (sbuf[0] != '/') { + strlcpy(parent_dir, fhp->path, sizeof(parent_dir)); + pch = strrchr(parent_dir, '/'); + if (pch == NULL) { + pefs_warn("error retrieving parent dir of %s", fhp->path); + return (PEFS_ERR_NOENT); + } + *pch = '\0'; + snprintf(fhp->path, sizeof(fhp->path), "%s/%s", parent_dir, sbuf); + } + else + strlcpy(fhp->path, sbuf, sizeof(fhp->path)); + + if (lstat(fhp->path, &sb) != 0) { + warn("cannot stat file %s", fhp->path); + return (PEFS_ERR_SYS); + } + } if (S_ISREG(sb.st_mode) == 0) { pefs_warn("filename: %s is not a regular file", fhp->path); @@ -652,6 +702,10 @@ TAILQ_INSERT_TAIL(&fh_head, fhp, file_header_entries); } + /* checking I/O error with pefs_next_file()*/ + if (error != 0) + return (error); + cuckoo_insert: TAILQ_FOREACH(fhp, &fh_head, file_header_entries) { error = pefs_add_to_hash_table(chtp, fhp); @@ -667,7 +721,7 @@ return (error); goto cuckoo_insert; } - } + } pefs_print_hash_table(chtp, hash_len); return (error);
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20120605134620.44F9E106564A>
