summaryrefslogtreecommitdiff
path: root/sys/net
diff options
context:
space:
mode:
authorReyk Floeter <reyk@cvs.openbsd.org>2017-08-11 13:55:10 +0000
committerReyk Floeter <reyk@cvs.openbsd.org>2017-08-11 13:55:10 +0000
commitc866e474a36777a21e01a563648ca4c22e0775e5 (patch)
treea53e211f111cdc60d68f5e222403b51243e32650 /sys/net
parente1e5afd4d2e05619c8d5df9ca3e6e325cbce32b6 (diff)
Set free'd tables to NULL in swofp_flow_entry_instruction_free().
swofp_flow_entry_instruction_free is used to "reset" the tables. It called free on each table but didn't set them to NULL, causing potential double-frees in swofp_flow_entry_put_instructions(). Instead of complicating the code and adding a X = NULL for each table, restructure it by introducing a generic function to free tables as they're all derived from struct ofp_instruction. Reported by Coverity as various "Read from pointer after free" errors: Coverity CIDs 1452955 1453345 1452858 1453031 1453179 1453216 1453093 OK millert@ goda@
Diffstat (limited to 'sys/net')
-rw-r--r--sys/net/switchofp.c47
1 files changed, 25 insertions, 22 deletions
diff --git a/sys/net/switchofp.c b/sys/net/switchofp.c
index dc37307b49a..e6321a517b2 100644
--- a/sys/net/switchofp.c
+++ b/sys/net/switchofp.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: switchofp.c,v 1.67 2017/08/11 13:54:14 reyk Exp $ */
+/* $OpenBSD: switchofp.c,v 1.68 2017/08/11 13:55:09 reyk Exp $ */
/*
* Copyright (c) 2016 Kazuya GODA <goda@openbsd.org>
@@ -212,6 +212,7 @@ int swofp_validate_buckets(struct switch_softc *, struct mbuf *, uint8_t,
*/
int swofp_flow_entry_put_instructions(struct switch_softc *,
struct mbuf *, struct swofp_flow_entry *, uint16_t *, uint16_t *);
+void swofp_flow_entry_table_free(struct ofp_instruction **);
void swofp_flow_entry_instruction_free(struct swofp_flow_entry *);
void swofp_flow_entry_free(struct swofp_flow_entry **);
void swofp_flow_entry_add(struct switch_softc *, struct swofp_flow_table *,
@@ -1523,29 +1524,31 @@ swofp_validate_buckets(struct switch_softc *sc, struct mbuf *m, uint8_t type,
}
void
+swofp_flow_entry_table_free(struct ofp_instruction **table)
+{
+ if (*table) {
+ free(*table, M_DEVBUF, ntohs((*table)->i_len));
+ *table = NULL;
+ }
+}
+
+void
swofp_flow_entry_instruction_free(struct swofp_flow_entry *swfe)
{
- if (swfe->swfe_goto_table)
- free(swfe->swfe_goto_table, M_DEVBUF,
- ntohs(swfe->swfe_goto_table->igt_len));
- if (swfe->swfe_write_metadata)
- free(swfe->swfe_write_metadata, M_DEVBUF,
- ntohs(swfe->swfe_write_metadata->iwm_len));
- if (swfe->swfe_apply_actions)
- free(swfe->swfe_apply_actions, M_DEVBUF,
- ntohs(swfe->swfe_apply_actions->ia_len));
- if (swfe->swfe_write_actions)
- free(swfe->swfe_write_actions, M_DEVBUF,
- ntohs(swfe->swfe_write_actions->ia_len));
- if (swfe->swfe_clear_actions)
- free(swfe->swfe_clear_actions, M_DEVBUF,
- ntohs(swfe->swfe_clear_actions->ia_len));
- if (swfe->swfe_experimenter)
- free(swfe->swfe_experimenter, M_DEVBUF,
- ntohs(swfe->swfe_experimenter->ie_len));
- if (swfe->swfe_meter)
- free(swfe->swfe_meter, M_DEVBUF,
- ntohs(swfe->swfe_meter->im_len));
+ swofp_flow_entry_table_free((struct ofp_instruction **)
+ &swfe->swfe_goto_table);
+ swofp_flow_entry_table_free((struct ofp_instruction **)
+ &swfe->swfe_write_metadata);
+ swofp_flow_entry_table_free((struct ofp_instruction **)
+ &swfe->swfe_apply_actions);
+ swofp_flow_entry_table_free((struct ofp_instruction **)
+ &swfe->swfe_write_actions);
+ swofp_flow_entry_table_free((struct ofp_instruction **)
+ &swfe->swfe_clear_actions);
+ swofp_flow_entry_table_free((struct ofp_instruction **)
+ &swfe->swfe_experimenter);
+ swofp_flow_entry_table_free((struct ofp_instruction **)
+ &swfe->swfe_meter);
}
void