summaryrefslogtreecommitdiffstats
path: root/freebsd/sys/netpfil/ipfw/ip_fw_sockopt.c
diff options
context:
space:
mode:
Diffstat (limited to 'freebsd/sys/netpfil/ipfw/ip_fw_sockopt.c')
-rw-r--r--freebsd/sys/netpfil/ipfw/ip_fw_sockopt.c27
1 files changed, 21 insertions, 6 deletions
diff --git a/freebsd/sys/netpfil/ipfw/ip_fw_sockopt.c b/freebsd/sys/netpfil/ipfw/ip_fw_sockopt.c
index 468e4ad4..d9d37758 100644
--- a/freebsd/sys/netpfil/ipfw/ip_fw_sockopt.c
+++ b/freebsd/sys/netpfil/ipfw/ip_fw_sockopt.c
@@ -60,6 +60,7 @@ __FBSDID("$FreeBSD$");
#include <sys/syslog.h>
#include <sys/fnv_hash.h>
#include <net/if.h>
+#include <net/pfil.h>
#include <net/route.h>
#include <net/vnet.h>
#include <vm/vm.h>
@@ -1738,11 +1739,16 @@ check_ipfw_rule_body(ipfw_insn *cmd, int cmd_len, struct rule_check_info *ci)
return (EINVAL);
}
ci->object_opcodes++;
- /* Do we have O_EXTERNAL_INSTANCE opcode? */
+ /*
+ * Do we have O_EXTERNAL_INSTANCE or O_EXTERNAL_DATA
+ * opcode?
+ */
if (l != cmdlen) {
l -= cmdlen;
cmd += cmdlen;
cmdlen = F_LEN(cmd);
+ if (cmd->opcode == O_EXTERNAL_DATA)
+ goto check_action;
if (cmd->opcode != O_EXTERNAL_INSTANCE) {
printf("ipfw: invalid opcode "
"next to external action %u\n",
@@ -1828,6 +1834,8 @@ check_ipfw_rule_body(ipfw_insn *cmd, int cmd_len, struct rule_check_info *ci)
break;
case O_IP_SRC_LOOKUP:
+ if (cmdlen > F_INSN_SIZE(ipfw_insn_u32))
+ goto bad_size;
case O_IP_DST_LOOKUP:
if (cmd->arg1 >= V_fw_tables_max) {
printf("ipfw: invalid table number %d\n",
@@ -2618,11 +2626,11 @@ unref_rule_objects(struct ip_fw_chain *ch, struct ip_fw *rule)
continue;
no = rw->find_bykidx(ch, kidx);
- KASSERT(no != NULL, ("table id %d not found", kidx));
+ KASSERT(no != NULL, ("object id %d not found", kidx));
KASSERT(no->subtype == subtype,
- ("wrong type %d (%d) for table id %d",
+ ("wrong type %d (%d) for object id %d",
no->subtype, subtype, kidx));
- KASSERT(no->refcnt > 0, ("refcount for table %d is %d",
+ KASSERT(no->refcnt > 0, ("refcount for object %d is %d",
kidx, no->refcnt));
if (no->refcnt == 1 && rw->destroy_object != NULL)
@@ -2671,7 +2679,14 @@ ref_opcode_object(struct ip_fw_chain *ch, ipfw_insn *cmd, struct tid_info *ti,
return (0);
}
- /* Found. Bump refcount and update kidx. */
+ /*
+ * Object is already exist.
+ * Its subtype should match with expected value.
+ */
+ if (ti->type != no->subtype)
+ return (EINVAL);
+
+ /* Bump refcount and update kidx. */
no->refcnt++;
rw->update(cmd, no->kidx);
return (0);
@@ -3137,7 +3152,7 @@ int
classify_opcode_kidx(ipfw_insn *cmd, uint16_t *puidx)
{
- if (find_op_rw(cmd, puidx, NULL) == 0)
+ if (find_op_rw(cmd, puidx, NULL) == NULL)
return (1);
return (0);
}