> Your fix reads ok, but:
>
> please write null-pointer checks explicitly, i.e. != NULL or == NULL.
Sure.
> and a suggestion: how about putting a
>
> if (head == NULL)
> return;
>
> at the top of iaw_free(), so it works like free()?
>
> Then you can skip the if (...) infront of all the calls.
Thanks, makes sense. Not sure how I didn't think of this.
Here is a cleaned up version:
Index: parse.y
===================================================================
RCS file: /cvs/src/sbin/iked/parse.y,v
retrieving revision 1.83
diff -u -p -u -r1.83 parse.y
--- parse.y 26 Aug 2019 16:41:08 -0000 1.83
+++ parse.y 25 Sep 2019 20:28:31 -0000
@@ -354,10 +354,13 @@ int get_id_type(char *);
uint8_t x2i(unsigned char *);
int parsekey(unsigned char *, size_t, struct iked_auth *);
int parsekeyfile(char *, struct iked_auth *);
+void iaw_free(struct ipsec_addr_wrap *);
struct ipsec_transforms *ipsec_transforms;
struct ipsec_filters *ipsec_filters;
struct ipsec_mode *ipsec_mode;
+/* interface lookup routintes */
+struct ipsec_addr_wrap *iftab;
typedef struct {
union {
@@ -1630,6 +1633,9 @@ parse_config(const char *filename, struc
free(sym);
}
+ iaw_free(iftab);
+ iftab = NULL;
+
return (errors ? -1 : 0);
}
@@ -2184,10 +2190,6 @@ host_any(void)
return (ipa);
}
-/* interface lookup routintes */
-
-struct ipsec_addr_wrap *iftab;
-
void
ifa_load(void)
{
@@ -3040,7 +3042,17 @@ done:
free(p->prop_xforms);
free(p);
}
-
+ if (peers != NULL) {
+ iaw_free(peers->src);
+ iaw_free(peers->dst);
+ /* peers is static, cannot be freed */
+ }
+ if (hosts != NULL) {
+ iaw_free(hosts->src);
+ iaw_free(hosts->dst);
+ free(hosts);
+ }
+ iaw_free(ikecfg);
return (ret);
}
@@ -3066,4 +3078,24 @@ create_user(const char *user, const char
rules++;
return (0);
+}
+
+void
+iaw_free(struct ipsec_addr_wrap *head)
+{
+ struct ipsec_addr_wrap *n, *cur;
+
+ if (head == NULL)
+ return;
+
+ for (n = head; n != NULL; ) {
+ cur = n;
+ n = n->next;
+ if (cur->srcnat != NULL) {
+ free(cur->srcnat->name);
+ free(cur->srcnat);
+ }
+ free(cur->name);
+ free(cur);
+ }
}