Subject: veriexecgen: removing duplicate files
To: None <tech-userlevel@NetBSD.org>
From: M J Fleming <mjf@NetBSD.org>
List: tech-userlevel
Date: 10/29/2006 23:15:47
--SUOF0GtieIMvvwua
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
Hi, currently veriexecgen will create a seperate entry in a fingerprintdb file
for hard-links. The attached patch only adds one entry per inode/device number.
Is it safe to use inode/device pairs for this purpose? Comments?
Thanks,
Matt
--SUOF0GtieIMvvwua
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="veriexecgen.patch"
? usr.sbin/veriexecgen/.gdbinit
? usr.sbin/veriexecgen/veriexecgen
? usr.sbin/veriexecgen/veriexecgen.cat8
Index: usr.sbin/veriexecgen/veriexecgen.c
===================================================================
RCS file: /cvsroot/src/usr.sbin/veriexecgen/veriexecgen.c,v
retrieving revision 1.6
diff -u -r1.6 veriexecgen.c
--- usr.sbin/veriexecgen/veriexecgen.c 23 Sep 2006 19:08:48 -0000 1.6
+++ usr.sbin/veriexecgen/veriexecgen.c 7 Oct 2006 14:56:32 -0000
@@ -40,11 +40,13 @@
#include <sys/types.h>
#include <sys/queue.h>
#include <sys/stat.h>
+#include <sys/statvfs.h>
#include <sys/dirent.h>
#include <sys/verified_exec.h>
#include <err.h>
#include <errno.h>
+#include <fnmatch.h>
#include <fts.h>
#include <stdio.h>
#include <stdlib.h>
@@ -65,11 +67,21 @@
#define DEFAULT_SYSPATHS { "/bin", "/sbin", "/usr/bin", "/usr/sbin", \
"/lib", "/usr/lib", "/libexec", "/usr/libexec", \
NULL }
+#define DEFAULT_INTERPRETERS { "/bin/sh", "/bin/csh", "/bin/ksh", \
+ "/usr/pkg/bin/perl", "/usr/pkg/bin/python2.4", \
+ NULL }
+#define DEFAULT_LIBS { "/lib/*", "/usr/lib/*", "/usr/pkg/lib/*", NULL }
+#define DEFAULT_SCRIPT_SUFFIX { ".sh", ".py", ".pl", NULL }
+
+#define PROGRAM VERIEXEC_DIRECT
+#define INTERPRETER VERIEXEC_INDIRECT
+#define SCRIPT (VERIEXEC_DIRECT | VERIEXEC_FILE)
+#define LIBRARY 0x20
struct fentry {
char filename[MAXPATHLEN];
char *hash_val;
- int flags;
+ char *flags;
TAILQ_ENTRY(fentry) f;
};
TAILQ_HEAD(, fentry) fehead;
@@ -87,13 +99,26 @@
{ NULL, NULL },
};
-int Aflag, aflag, Dflag, Fflag, rflag, Sflag, vflag;
+struct flags {
+ int script;
+ int lib;
+ int intrprtr;
+ int exec;
+ int local;
+};
+
+int Aflag, aflag, Dflag, Fflag, Iflag, iflag, Lflag, lflag, rflag;
+int Sflag, sflag, vflag, Xflag;
+
+char **interpreter_patterns = NULL;
+char **lib_patterns = NULL;
+char **scripts = NULL;
static void
usage(void)
{
(void)fprintf(stderr,
- "usage: %s [-AaDrSv] [-d dir] [-o fingerprintdb]"
+ "usage: %s [-AaDFIiLlrSsvX] [-d dir] [-o fingerprintdb]"
" [-t algorithm]\n", getprogname());
}
@@ -130,20 +155,89 @@
return h->filefunc(filename, NULL);
}
+static char *
+weigh_flags(struct flags f)
+{
+ char *buf = "";
+
+ if (!(f.local))
+ easprintf(&buf, "%sUNTRUSTED", *buf ? ", " : "");
+
+ if (f.script)
+ easprintf(&buf, "%s%sSCRIPT", buf, *buf ? ", " : "");
+ else if (f.lib)
+ easprintf(&buf, "%s%sLIBRARY", buf, *buf ? ", " : "");
+ else if (f.intrprtr)
+ easprintf(&buf, "%s%sINTERPRETER", buf, *buf ? ", " : "");
+ else if (f.exec)
+ easprintf(&buf, "%s%sPROGRAM", buf, *buf ? ", " : "");
+ else
+ easprintf(&buf, "%s%sFILE", buf, *buf ? ", " : "");
+
+ return buf;
+}
+
static int
+wildcard(char **list, char *path)
+{
+ int i;
+ char **a = list;
+
+ for (i = 0; a[i] != NULL; i++) {
+ if (!fnmatch(a[i], path, 0))
+ return 1;
+ }
+ return 0;
+}
+
+static char *
figure_flags(char *path, mode_t mode)
{
-#ifdef notyet
+ char *p;
+ struct statvfs st;
+ struct flags f;
+
+ memset(&f, 0, sizeof(struct flags));
+
if (Fflag) {
/* Try to figure out right flag(s). */
- return VERIEXEC_DIRECT;
-}
-#endif /* notyet */
+ if (statvfs(path, &st) == -1)
+ err(1, "could not stat %s", path);
+
+ if ((st.f_flag & MNT_LOCAL))
+ f.local = 1;
- if (!IS_EXEC(mode))
- return VERIEXEC_FILE;
- else
- return 0;
+ if (IS_EXEC(mode))
+ f.exec = 1;
+
+ if (Lflag) {
+ char *a[] = DEFAULT_LIBS;
+ f.lib = wildcard(a, path);
+ }
+
+ if (lflag && *lib_patterns != NULL)
+ f.lib = wildcard(lib_patterns, path);
+
+ if (Iflag) {
+ char *a[] = DEFAULT_INTERPRETERS;
+ f.intrprtr = wildcard(a, path);
+ }
+
+ if (iflag && *interpreter_patterns != NULL)
+ f.intrprtr = wildcard(interpreter_patterns, path);
+
+ if (Sflag && ((p = strchr(path, '.')) != NULL)) {
+ char *a[] = DEFAULT_SCRIPT_SUFFIX;
+ f.script = wildcard(a, p);
+ }
+
+ if (sflag && *scripts != NULL)
+ f.script = wildcard(scripts, path);
+
+ } else if (IS_EXEC(mode))
+ f.exec = 1;
+
+ return weigh_flags(f);
}
static int
@@ -168,7 +262,7 @@
if (file->fts_info == FTS_SL) {
if (stat(file->fts_path, &sb) == -1)
- err(1, "Cannot stat symlink");
+ err(1, "Cannot stat symlink %s", file->fts_path);
} else
sb = *file->fts_statp;
@@ -225,15 +319,6 @@
fts_close(fh);
}
-static char *
-flags2str(int flags)
-{
- if (flags != 0)
- return "FILE";
- else
- return "";
-}
-
static void
store_entries(char *dbfile, struct hash *hash)
{
@@ -274,7 +359,7 @@
(void)printf("Adding %s.\n", e->filename);
(void)fprintf(fp, "%s %s %s %s\n", e->filename,
- hash->hashname, e->hash_val, flags2str(e->flags));
+ hash->hashname, e->hash_val, e->flags);
}
(void)fclose(fp);
@@ -293,14 +378,15 @@
int
main(int argc, char **argv)
{
- int ch, total = 0;
+ int ch, stotal = 0, itotal = 0, sutotal = 0, ltotal = 0;
char *dbfile = NULL;
char **search_path = NULL;
struct hash *hash = NULL;
- Aflag = aflag = Dflag = Fflag = rflag = Sflag = vflag = 0;
+ Aflag = aflag = Dflag = Fflag = Iflag = iflag = Lflag = lflag;
+ rflag = Sflag = sflag = vflag = Xflag = 0;
- while ((ch = getopt(argc, argv, "AaDd:ho:rSt:v")) != -1) {
+ while ((ch = getopt(argc, argv, "AaDd:FhIiLl::o:rSs:t:vX")) != -1) {
switch (ch) {
case 'A':
Aflag = 1;
@@ -313,18 +399,34 @@
break;
case 'd':
search_path = erealloc(search_path, sizeof(char *) *
- (total + 1));
- search_path[total] = optarg;
- search_path[++total] = NULL;
+ (stotal + 1));
+ search_path[stotal] = optarg;
+ search_path[++stotal] = NULL;
break;
-#ifdef notyet
case 'F':
Fflag = 1;
break;
-#endif /* notyet */
case 'h':
usage();
return 0;
+ case 'I':
+ Iflag = 1;
+ break;
+ case 'i':
+ iflag = 1;
+ interpreter_patterns = erealloc(interpreter_patterns,
+ sizeof(char *) * (itotal + 1));
+ interpreter_patterns[itotal++] = optarg;
+ break;
+ case 'L':
+ Lflag = 1;
+ break;
+ case 'l':
+ lflag = 1;
+ lib_patterns = erealloc(lib_patterns, sizeof(char *) *
+ (ltotal + 1));
+ lib_patterns[ltotal++] = optarg;
+ break;
case 'o':
dbfile = optarg;
break;
@@ -334,18 +436,31 @@
case 'S':
Sflag = 1;
break;
+ case 's':
+ sflag = 1;
+ scripts = erealloc(scripts,
+ sizeof(char *) * (sutotal + 1));
+ scripts[sutotal++] = optarg;
+ break;
case 't':
hash = find_hash(optarg);
break;
case 'v':
vflag = 1;
break;
+ case 'X':
+ Xflag = 1;
+ break;
default:
usage();
return 1;
}
}
+ /* -F implies -I and -S */
+ if (Fflag)
+ Iflag = Lflag = Sflag = 1;
+
if (dbfile == NULL)
dbfile = DEFAULT_DBFILE;
@@ -375,7 +490,7 @@
store_entries(dbfile, hash);
- if (Sflag && chflags(dbfile, SF_IMMUTABLE) != 0)
+ if (Xflag && chflags(dbfile, SF_IMMUTABLE) != 0)
err(1, "Can't set immutable flag");
return 0;
--SUOF0GtieIMvvwua--