Hi,
I found a strange behavior in pfctl(8) which looks like a bug.
When given a directory as input (either with the `-f` flag, or with the
`include` directive in a config file), pfctl(8) does not emit any
warning and silently accepts the given input.
I suppose this is not the intended behavior so here is a patch that
fixes the issue.
Regards,
--
Stephane A. Sezer
Index: sbin/pfctl/parse.y
===================================================================
RCS file: /cvs/src/sbin/pfctl/parse.y,v
retrieving revision 1.613
diff -u -r1.613 parse.y
--- sbin/pfctl/parse.y 19 Dec 2011 23:26:16 -0000 1.613
+++ sbin/pfctl/parse.y 2 Jan 2012 08:04:12 -0000
@@ -5614,37 +5614,52 @@
pushfile(const char *name, int secret)
{
struct file *nfile;
+ struct stat sb;
- if ((nfile = calloc(1, sizeof(struct file))) == NULL ||
- (nfile->name = strdup(name)) == NULL) {
- if (nfile)
- free(nfile);
- warn("malloc");
- return (NULL);
+ if ((nfile = calloc(1, sizeof(struct file))) == NULL) {
+ warn("calloc");
+ goto err;
}
- if (TAILQ_FIRST(&files) == NULL && strcmp(nfile->name, "-") == 0) {
+
+ if (TAILQ_FIRST(&files) == NULL && strcmp(name, "-") == 0) {
nfile->stream = stdin;
- free(nfile->name);
if ((nfile->name = strdup("stdin")) == NULL) {
warn("strdup");
- free(nfile);
- return (NULL);
+ goto err;
+ }
+ } else {
+ if ((nfile->name = strdup(name)) == NULL) {
+ warn("strdup");
+ goto err;
+ }
+ if ((nfile->stream = fopen(nfile->name, "r")) == NULL) {
+ warn("%s", nfile->name);
+ goto err;
+ }
+ if (secret &&
+ check_file_secrecy(fileno(nfile->stream), nfile->name))
+ goto file_err;
+ if (fstat(fileno(nfile->stream), &sb) == -1) {
+ warn("fstat");
+ goto file_err;
+ }
+ if (S_ISDIR(sb.st_mode)) {
+ errno = EISDIR;
+ warn("%s", nfile->name);
+ goto file_err;
}
- } else if ((nfile->stream = fopen(nfile->name, "r")) == NULL) {
- warn("%s", nfile->name);
- free(nfile->name);
- free(nfile);
- return (NULL);
- } else if (secret &&
- check_file_secrecy(fileno(nfile->stream), nfile->name)) {
- fclose(nfile->stream);
- free(nfile->name);
- free(nfile);
- return (NULL);
}
+
nfile->lineno = 1;
TAILQ_INSERT_TAIL(&files, nfile, entry);
return (nfile);
+
+file_err:
+ fclose(nfile->stream);
+err:
+ free(nfile->name);
+ free(nfile);
+ return (NULL);
}
int