From dd5145131e3b8f212fe8787dc095dfc31165613f Mon Sep 17 00:00:00 2001 From: Steve Beattie Date: Fri, 6 Sep 2013 13:39:41 -0700 Subject: [PATCH] Subject: parser - use DUP_STRING more widely and detect strdup errors This patch moves the DUP_STRING macro to parser.h and modifies it to accept a goto error target, that will be jumped to if the call to strdup(3) fails. It also uses it in additional locations where copying structures occurs, as well as detecting additional cases where a structure duplication might have failed but not been propagated outward. Signed-off-by: Steve Beattie Acked-by: Tyler Hicks --- parser/dbus.c | 19 ++++++++++--------- parser/mount.c | 16 ++++++++++++---- parser/parser.h | 7 +++++++ parser/parser_misc.c | 10 +++++++--- 4 files changed, 36 insertions(+), 16 deletions(-) diff --git a/parser/dbus.c b/parser/dbus.c index 26298fcda..ca5161df1 100644 --- a/parser/dbus.c +++ b/parser/dbus.c @@ -141,9 +141,6 @@ out: return ent; } -#define DUP_STRING(orig, new, field) \ - (new)->field = (orig)->field ? strdup((orig)->field) : NULL - struct dbus_entry *dup_dbus_entry(struct dbus_entry *orig) { struct dbus_entry *ent = NULL; @@ -151,12 +148,12 @@ struct dbus_entry *dup_dbus_entry(struct dbus_entry *orig) if (!ent) return NULL; - DUP_STRING(orig, ent, bus); - DUP_STRING(orig, ent, name); - DUP_STRING(orig, ent, peer_label); - DUP_STRING(orig, ent, path); - DUP_STRING(orig, ent, interface); - DUP_STRING(orig, ent, member); + DUP_STRING(orig, ent, bus, err); + DUP_STRING(orig, ent, name, err); + DUP_STRING(orig, ent, peer_label, err); + DUP_STRING(orig, ent, path, err); + DUP_STRING(orig, ent, interface, err); + DUP_STRING(orig, ent, member, err); ent->mode = orig->mode; ent->audit = orig->audit; ent->deny = orig->deny; @@ -164,6 +161,10 @@ struct dbus_entry *dup_dbus_entry(struct dbus_entry *orig) ent->next = orig->next; return ent; + +err: + free_dbus_entry(ent); + return NULL; } void print_dbus_entry(struct dbus_entry *ent) diff --git a/parser/mount.c b/parser/mount.c index d446d2941..ba58f4e3d 100644 --- a/parser/mount.c +++ b/parser/mount.c @@ -466,7 +466,6 @@ void free_mnt_entry(struct mnt_entry *ent) free(ent); } - struct mnt_entry *dup_mnt_entry(struct mnt_entry *orig) { struct mnt_entry *entry = NULL; @@ -475,12 +474,17 @@ struct mnt_entry *dup_mnt_entry(struct mnt_entry *orig) if (!entry) return NULL; - entry->mnt_point = orig->mnt_point ? strdup(orig->mnt_point) : NULL; - entry->device = orig->device ? strdup(orig->device) : NULL; - entry->trans = orig->trans ? strdup(orig->trans) : NULL; + DUP_STRING(orig, entry, mnt_point, err); + DUP_STRING(orig, entry, device, err); + DUP_STRING(orig, entry, trans, err); entry->dev_type = dup_value_list(orig->dev_type); + if (orig->dev_type && !(entry->dev_type)) + goto err; + entry->opts = dup_value_list(orig->opts); + if (orig->opts && !(entry->opts)) + goto err; entry->flags = orig->flags; entry->inv_flags = orig->inv_flags; @@ -492,6 +496,10 @@ struct mnt_entry *dup_mnt_entry(struct mnt_entry *orig) entry->next = orig->next; return entry; + +err: + free_mnt_entry(entry); + return NULL; } void print_mnt_entry(struct mnt_entry *entry) diff --git a/parser/parser.h b/parser/parser.h index 6d7e84b95..1101985cb 100644 --- a/parser/parser.h +++ b/parser/parser.h @@ -261,6 +261,13 @@ extern int preprocess_only; ___tmp->next = (LISTB); \ } while (0) +#define DUP_STRING(orig, new, field, fail_target) \ + do { \ + (new)->field = ((orig)->field) ? strdup((orig)->field) : NULL; \ + if (((orig)->field) && !((new)->field)) \ + goto fail_target; \ + } while (0) + /* from parser_common.c */ extern int regex_type; extern int perms_create; diff --git a/parser/parser_misc.c b/parser/parser_misc.c index d8647373c..67e6d6b85 100644 --- a/parser/parser_misc.c +++ b/parser/parser_misc.c @@ -840,9 +840,9 @@ struct cod_entry *copy_cod_entry(struct cod_entry *orig) if (!entry) return NULL; - entry->namespace = orig->namespace ? strdup(orig->namespace) : NULL; - entry->name = strdup(orig->name); - entry->link_name = orig->link_name ? strdup(orig->link_name) : NULL; + DUP_STRING(orig, entry, namespace, err); + DUP_STRING(orig, entry, name, err); + DUP_STRING(orig, entry, link_name, err); entry->mode = orig->mode; entry->audit = orig->audit; entry->deny = orig->deny; @@ -854,6 +854,10 @@ struct cod_entry *copy_cod_entry(struct cod_entry *orig) entry->next = orig->next; return entry; + +err: + free_cod_entries(entry); + return NULL; } void free_cod_entries(struct cod_entry *list)