summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Haller <thaller@redhat.com>2023-11-27 21:15:06 +0100
committerThomas Haller <thaller@redhat.com>2023-11-29 16:03:41 +0100
commit2f485cc7e4ff0d15f203ddf54702f65aed0a427a (patch)
treeb7cbe44047ecb862c7b1f0f868d61a20db1873e2
parent01bd8fb01fb0fe4a0132fad6edbe2ab62a57ae8d (diff)
downloadlibnl-2f485cc7e4ff0d15f203ddf54702f65aed0a427a.tar.gz
xfrm: refactor error handling in XFRM parsing
Use cleanup attribute and return-early.
-rw-r--r--lib/xfrm/ae.c38
-rw-r--r--lib/xfrm/sa.c110
-rw-r--r--lib/xfrm/sp.c62
3 files changed, 70 insertions, 140 deletions
diff --git a/lib/xfrm/ae.c b/lib/xfrm/ae.c
index 6369f32f..9af73a87 100644
--- a/lib/xfrm/ae.c
+++ b/lib/xfrm/ae.c
@@ -134,6 +134,7 @@
#include "nl-priv-dynamic-core/nl-core.h"
#include "nl-priv-dynamic-core/cache-api.h"
#include "nl-aux-core/nl-core.h"
+#include "nl-aux-xfrm/nl-xfrm.h"
/** @cond SKIP */
@@ -523,36 +524,30 @@ static struct nla_policy xfrm_ae_policy[XFRMA_MAX+1] = {
int xfrmnl_ae_parse(struct nlmsghdr *n, struct xfrmnl_ae **result)
{
- struct xfrmnl_ae* ae;
+ _nl_auto_xfrmnl_ae struct xfrmnl_ae *ae = NULL;
struct nlattr *tb[XFRMA_MAX + 1];
struct xfrm_aevent_id* ae_id;
int err;
ae = xfrmnl_ae_alloc();
- if (!ae) {
- err = -NLE_NOMEM;
- goto errout;
- }
+ if (!ae)
+ return -NLE_NOMEM;
ae->ce_msgtype = n->nlmsg_type;
ae_id = nlmsg_data(n);
err = nlmsg_parse(n, sizeof(struct xfrm_aevent_id), tb, XFRMA_MAX, xfrm_ae_policy);
if (err < 0)
- goto errout;
+ return err;
- if (!(ae->sa_id.daddr = _nl_addr_build(ae_id->sa_id.family,
- &ae_id->sa_id.daddr))) {
- err = -NLE_NOMEM;
- goto errout;
- }
+ if (!(ae->sa_id.daddr =
+ _nl_addr_build(ae_id->sa_id.family, &ae_id->sa_id.daddr)))
+ return -NLE_NOMEM;
ae->sa_id.family= ae_id->sa_id.family;
ae->sa_id.spi = ntohl(ae_id->sa_id.spi);
ae->sa_id.proto = ae_id->sa_id.proto;
- if (!(ae->saddr = _nl_addr_build(ae_id->sa_id.family, &ae_id->saddr))) {
- err = -NLE_NOMEM;
- goto errout;
- }
+ if (!(ae->saddr = _nl_addr_build(ae_id->sa_id.family, &ae_id->saddr)))
+ return -NLE_NOMEM;
ae->reqid = ae_id->reqid;
ae->flags = ae_id->flags;
ae->ce_mask |= (XFRM_AE_ATTR_DADDR | XFRM_AE_ATTR_FAMILY | XFRM_AE_ATTR_SPI |
@@ -568,6 +563,7 @@ int xfrmnl_ae_parse(struct nlmsghdr *n, struct xfrmnl_ae **result)
if (tb[XFRMA_LTIME_VAL]) {
struct xfrm_lifetime_cur* cur = nla_data(tb[XFRMA_LTIME_VAL]);
+
ae->lifetime_cur.bytes = cur->bytes;
ae->lifetime_cur.packets = cur->packets;
ae->lifetime_cur.add_time = cur->add_time;
@@ -589,10 +585,8 @@ int xfrmnl_ae_parse(struct nlmsghdr *n, struct xfrmnl_ae **result)
struct xfrm_replay_state_esn* esn = nla_data (tb[XFRMA_REPLAY_ESN_VAL]);
uint32_t len = sizeof (struct xfrmnl_replay_state_esn) + (sizeof (uint32_t) * esn->bmp_len);
- if ((ae->replay_state_esn = calloc (1, len)) == NULL) {
- err = -NLE_ENOMEM;
- goto errout;
- }
+ if ((ae->replay_state_esn = calloc (1, len)) == NULL)
+ return -NLE_NOMEM;
ae->replay_state_esn->oseq = esn->oseq;
ae->replay_state_esn->seq = esn->seq;
ae->replay_state_esn->oseq_hi = esn->oseq_hi;
@@ -613,12 +607,8 @@ int xfrmnl_ae_parse(struct nlmsghdr *n, struct xfrmnl_ae **result)
ae->replay_state_esn = NULL;
}
- *result = ae;
+ *result = _nl_steal_pointer(&ae);
return 0;
-
-errout:
- xfrmnl_ae_put(ae);
- return err;
}
static int xfrm_ae_msg_parser(struct nl_cache_ops *ops, struct sockaddr_nl *who,
diff --git a/lib/xfrm/sa.c b/lib/xfrm/sa.c
index 96ee754f..0970b441 100644
--- a/lib/xfrm/sa.c
+++ b/lib/xfrm/sa.c
@@ -55,6 +55,7 @@
#include "nl-priv-dynamic-core/nl-core.h"
#include "nl-priv-dynamic-core/cache-api.h"
#include "nl-aux-core/nl-core.h"
+#include "nl-aux-xfrm/nl-xfrm.h"
/** @cond SKIP */
@@ -773,17 +774,15 @@ int xfrmnl_sa_parse(struct nlmsghdr *n, struct xfrmnl_sa **result)
{
_nl_auto_nl_addr struct nl_addr *addr1 = NULL;
_nl_auto_nl_addr struct nl_addr *addr2 = NULL;
- struct xfrmnl_sa* sa;
+ _nl_auto_xfrmnl_sa struct xfrmnl_sa *sa = NULL;
struct nlattr *tb[XFRMA_MAX + 1];
struct xfrm_usersa_info* sa_info;
struct xfrm_user_expire* ue;
int len, err;
sa = xfrmnl_sa_alloc();
- if (!sa) {
- err = -NLE_NOMEM;
- goto errout;
- }
+ if (!sa)
+ return -NLE_NOMEM;
sa->ce_msgtype = n->nlmsg_type;
if (n->nlmsg_type == XFRM_MSG_EXPIRE)
@@ -804,20 +803,16 @@ int xfrmnl_sa_parse(struct nlmsghdr *n, struct xfrmnl_sa **result)
err = nlmsg_parse(n, sizeof(struct xfrm_usersa_info), tb, XFRMA_MAX, xfrm_sa_policy);
if (err < 0)
- goto errout;
+ return err;
- if (!(addr1 = _nl_addr_build(sa_info->sel.family, &sa_info->sel.daddr))) {
- err = -NLE_NOMEM;
- goto errout;
- }
+ if (!(addr1 = _nl_addr_build(sa_info->sel.family, &sa_info->sel.daddr)))
+ return -NLE_NOMEM;
nl_addr_set_prefixlen (addr1, sa_info->sel.prefixlen_d);
xfrmnl_sel_set_daddr (sa->sel, addr1);
xfrmnl_sel_set_prefixlen_d (sa->sel, sa_info->sel.prefixlen_d);
- if (!(addr2 = _nl_addr_build(sa_info->sel.family, &sa_info->sel.saddr))) {
- err = -NLE_NOMEM;
- goto errout;
- }
+ if (!(addr2 = _nl_addr_build(sa_info->sel.family, &sa_info->sel.saddr)))
+ return -NLE_NOMEM;
nl_addr_set_prefixlen (addr2, sa_info->sel.prefixlen_s);
xfrmnl_sel_set_saddr (sa->sel, addr2);
xfrmnl_sel_set_prefixlen_s (sa->sel, sa_info->sel.prefixlen_s);
@@ -832,18 +827,14 @@ int xfrmnl_sa_parse(struct nlmsghdr *n, struct xfrmnl_sa **result)
xfrmnl_sel_set_userid (sa->sel, sa_info->sel.user);
sa->ce_mask |= XFRM_SA_ATTR_SEL;
- if (!(sa->id.daddr = _nl_addr_build(sa_info->family, &sa_info->id.daddr))) {
- err = -NLE_NOMEM;
- goto errout;
- }
+ if (!(sa->id.daddr = _nl_addr_build(sa_info->family, &sa_info->id.daddr)))
+ return -NLE_NOMEM;
sa->id.spi = ntohl(sa_info->id.spi);
sa->id.proto = sa_info->id.proto;
sa->ce_mask |= (XFRM_SA_ATTR_DADDR | XFRM_SA_ATTR_SPI | XFRM_SA_ATTR_PROTO);
- if (!(sa->saddr = _nl_addr_build(sa_info->family, &sa_info->saddr))) {
- err = -NLE_NOMEM;
- goto errout;
- }
+ if (!(sa->saddr = _nl_addr_build(sa_info->family, &sa_info->saddr)))
+ return -NLE_NOMEM;
sa->ce_mask |= XFRM_SA_ATTR_SADDR;
sa->lft->soft_byte_limit = sa_info->lft.soft_byte_limit;
@@ -879,36 +870,30 @@ int xfrmnl_sa_parse(struct nlmsghdr *n, struct xfrmnl_sa **result)
if (tb[XFRMA_ALG_AEAD]) {
struct xfrm_algo_aead* aead = nla_data(tb[XFRMA_ALG_AEAD]);
+
len = sizeof (struct xfrmnl_algo_aead) + ((aead->alg_key_len + 7) / 8);
if ((sa->aead = calloc (1, len)) == NULL)
- {
- err = -NLE_NOMEM;
- goto errout;
- }
+ return -NLE_NOMEM;
memcpy ((void *)sa->aead, (void *)aead, len);
sa->ce_mask |= XFRM_SA_ATTR_ALG_AEAD;
}
if (tb[XFRMA_ALG_AUTH_TRUNC]) {
struct xfrm_algo_auth* auth = nla_data(tb[XFRMA_ALG_AUTH_TRUNC]);
+
len = sizeof (struct xfrmnl_algo_auth) + ((auth->alg_key_len + 7) / 8);
if ((sa->auth = calloc (1, len)) == NULL)
- {
- err = -NLE_NOMEM;
- goto errout;
- }
+ return -NLE_NOMEM;
memcpy ((void *)sa->auth, (void *)auth, len);
sa->ce_mask |= XFRM_SA_ATTR_ALG_AUTH;
}
if (tb[XFRMA_ALG_AUTH] && !sa->auth) {
struct xfrm_algo* auth = nla_data(tb[XFRMA_ALG_AUTH]);
+
len = sizeof (struct xfrmnl_algo_auth) + ((auth->alg_key_len + 7) / 8);
if ((sa->auth = calloc (1, len)) == NULL)
- {
- err = -NLE_NOMEM;
- goto errout;
- }
+ return -NLE_NOMEM;
strcpy(sa->auth->alg_name, auth->alg_name);
memcpy(sa->auth->alg_key, auth->alg_key, (auth->alg_key_len + 7) / 8);
sa->auth->alg_key_len = auth->alg_key_len;
@@ -917,44 +902,36 @@ int xfrmnl_sa_parse(struct nlmsghdr *n, struct xfrmnl_sa **result)
if (tb[XFRMA_ALG_CRYPT]) {
struct xfrm_algo* crypt = nla_data(tb[XFRMA_ALG_CRYPT]);
+
len = sizeof (struct xfrmnl_algo) + ((crypt->alg_key_len + 7) / 8);
if ((sa->crypt = calloc (1, len)) == NULL)
- {
- err = -NLE_NOMEM;
- goto errout;
- }
+ return -NLE_NOMEM;
memcpy ((void *)sa->crypt, (void *)crypt, len);
sa->ce_mask |= XFRM_SA_ATTR_ALG_CRYPT;
}
if (tb[XFRMA_ALG_COMP]) {
struct xfrm_algo* comp = nla_data(tb[XFRMA_ALG_COMP]);
+
len = sizeof (struct xfrmnl_algo) + ((comp->alg_key_len + 7) / 8);
if ((sa->comp = calloc (1, len)) == NULL)
- {
- err = -NLE_NOMEM;
- goto errout;
- }
+ return -NLE_NOMEM;
memcpy ((void *)sa->comp, (void *)comp, len);
sa->ce_mask |= XFRM_SA_ATTR_ALG_COMP;
}
if (tb[XFRMA_ENCAP]) {
struct xfrm_encap_tmpl* encap = nla_data(tb[XFRMA_ENCAP]);
+
len = sizeof (struct xfrmnl_encap_tmpl);
if ((sa->encap = calloc (1, len)) == NULL)
- {
- err = -NLE_NOMEM;
- goto errout;
- }
+ return -NLE_NOMEM;
sa->encap->encap_type = encap->encap_type;
sa->encap->encap_sport = ntohs(encap->encap_sport);
sa->encap->encap_dport = ntohs(encap->encap_dport);
if (!(sa->encap->encap_oa = _nl_addr_build(sa_info->family,
- &encap->encap_oa))) {
- err = -NLE_NOMEM;
- goto errout;
- }
+ &encap->encap_oa)))
+ return -NLE_NOMEM;
sa->ce_mask |= XFRM_SA_ATTR_ENCAP;
}
@@ -965,15 +942,14 @@ int xfrmnl_sa_parse(struct nlmsghdr *n, struct xfrmnl_sa **result)
if (tb[XFRMA_COADDR]) {
if (!(sa->coaddr = _nl_addr_build(
- sa_info->family, nla_data(tb[XFRMA_COADDR])))) {
- err = -NLE_NOMEM;
- goto errout;
- }
+ sa_info->family, nla_data(tb[XFRMA_COADDR]))))
+ return -NLE_NOMEM;
sa->ce_mask |= XFRM_SA_ATTR_COADDR;
}
if (tb[XFRMA_MARK]) {
struct xfrm_mark* m = nla_data(tb[XFRMA_MARK]);
+
sa->mark.m = m->m;
sa->mark.v = m->v;
sa->ce_mask |= XFRM_SA_ATTR_MARK;
@@ -981,12 +957,10 @@ int xfrmnl_sa_parse(struct nlmsghdr *n, struct xfrmnl_sa **result)
if (tb[XFRMA_SEC_CTX]) {
struct xfrm_user_sec_ctx* sec_ctx = nla_data(tb[XFRMA_SEC_CTX]);
+
len = sizeof (struct xfrmnl_user_sec_ctx) + sec_ctx->ctx_len;
if ((sa->sec_ctx = calloc (1, len)) == NULL)
- {
- err = -NLE_NOMEM;
- goto errout;
- }
+ return -NLE_NOMEM;
memcpy (sa->sec_ctx, sec_ctx, len);
sa->ce_mask |= XFRM_SA_ATTR_SECCTX;
}
@@ -1003,12 +977,10 @@ int xfrmnl_sa_parse(struct nlmsghdr *n, struct xfrmnl_sa **result)
if (tb[XFRMA_REPLAY_ESN_VAL]) {
struct xfrm_replay_state_esn* esn = nla_data (tb[XFRMA_REPLAY_ESN_VAL]);
+
len = sizeof (struct xfrmnl_replay_state_esn) + (sizeof (uint32_t) * esn->bmp_len);
if ((sa->replay_state_esn = calloc (1, len)) == NULL)
- {
- err = -NLE_NOMEM;
- goto errout;
- }
+ return -NLE_NOMEM;
memcpy ((void *)sa->replay_state_esn, (void *)esn, len);
sa->ce_mask |= XFRM_SA_ATTR_REPLAY_STATE;
}
@@ -1026,24 +998,16 @@ int xfrmnl_sa_parse(struct nlmsghdr *n, struct xfrmnl_sa **result)
struct xfrm_user_offload *offload;
len = sizeof(struct xfrmnl_user_offload);
-
- if ((sa->user_offload = calloc(1, len)) == NULL) {
- err = -NLE_NOMEM;
- goto errout;
- }
-
+ if ((sa->user_offload = calloc(1, len)) == NULL)
+ return -NLE_NOMEM;
offload = nla_data(tb[XFRMA_OFFLOAD_DEV]);
sa->user_offload->ifindex = offload->ifindex;
sa->user_offload->flags = offload->flags;
sa->ce_mask |= XFRM_SA_ATTR_OFFLOAD_DEV;
}
- *result = sa;
+ *result = _nl_steal_pointer(&sa);
return 0;
-
-errout:
- xfrmnl_sa_put(sa);
- return err;
}
static int xfrm_sa_update_cache (struct nl_cache *cache, struct nl_object *obj,
diff --git a/lib/xfrm/sp.c b/lib/xfrm/sp.c
index 0e17f4ba..e98339c0 100644
--- a/lib/xfrm/sp.c
+++ b/lib/xfrm/sp.c
@@ -54,6 +54,7 @@
#include "nl-priv-dynamic-core/nl-core.h"
#include "nl-priv-dynamic-core/cache-api.h"
#include "nl-aux-core/nl-core.h"
+#include "nl-aux-xfrm/nl-xfrm.h"
struct xfrmnl_userpolicy_type {
uint8_t type;
@@ -564,46 +565,33 @@ int xfrmnl_sp_parse(struct nlmsghdr *n, struct xfrmnl_sp **result)
{
_nl_auto_nl_addr struct nl_addr *addr1 = NULL;
_nl_auto_nl_addr struct nl_addr *addr2 = NULL;
- struct xfrmnl_sp *sp;
+ _nl_auto_xfrmnl_sp struct xfrmnl_sp *sp = NULL;
struct nlattr *tb[XFRMA_MAX + 1];
struct xfrm_userpolicy_info *sp_info;
int len, err;
sp = xfrmnl_sp_alloc();
- if (!sp) {
- err = -NLE_NOMEM;
- goto errout;
- }
+ if (!sp)
+ return -NLE_NOMEM;
sp->ce_msgtype = n->nlmsg_type;
if (n->nlmsg_type == XFRM_MSG_DELPOLICY)
- {
sp_info = (struct xfrm_userpolicy_info*)((char *)nlmsg_data(n) + sizeof (struct xfrm_userpolicy_id) + NLA_HDRLEN);
- }
else
- {
sp_info = nlmsg_data(n);
- }
err = nlmsg_parse(n, sizeof(struct xfrm_userpolicy_info), tb, XFRMA_MAX, xfrm_sp_policy);
if (err < 0)
- {
- printf ("parse error: %d \n", err);
- goto errout;
- }
+ return err;
- if (!(addr1 = _nl_addr_build(sp_info->sel.family, &sp_info->sel.daddr))) {
- err = -NLE_NOMEM;
- goto errout;
- }
+ if (!(addr1 = _nl_addr_build(sp_info->sel.family, &sp_info->sel.daddr)))
+ return -NLE_NOMEM;
nl_addr_set_prefixlen (addr1, sp_info->sel.prefixlen_d);
xfrmnl_sel_set_daddr (sp->sel, addr1);
xfrmnl_sel_set_prefixlen_d (sp->sel, sp_info->sel.prefixlen_d);
- if (!(addr2 = _nl_addr_build(sp_info->sel.family, &sp_info->sel.saddr))) {
- err = -NLE_NOMEM;
- goto errout;
- }
+ if (!(addr2 = _nl_addr_build(sp_info->sel.family, &sp_info->sel.saddr)))
+ return -NLE_NOMEM;
nl_addr_set_prefixlen (addr2, sp_info->sel.prefixlen_s);
xfrmnl_sel_set_saddr (sp->sel, addr2);
xfrmnl_sel_set_prefixlen_s (sp->sel, sp_info->sel.prefixlen_s);
@@ -646,18 +634,17 @@ int xfrmnl_sp_parse(struct nlmsghdr *n, struct xfrmnl_sp **result)
if (tb[XFRMA_SEC_CTX]) {
struct xfrm_user_sec_ctx* ctx = nla_data(tb[XFRMA_SEC_CTX]);
+
len = sizeof (struct xfrmnl_user_sec_ctx) + ctx->ctx_len;
if ((sp->sec_ctx = calloc (1, len)) == NULL)
- {
- err = -NLE_NOMEM;
- goto errout;
- }
+ return -NLE_NOMEM;
memcpy ((void *)sp->sec_ctx, (void *)ctx, len);
sp->ce_mask |= XFRM_SP_ATTR_SECCTX;
}
if (tb[XFRMA_POLICY_TYPE]) {
struct xfrm_userpolicy_type* up = nla_data(tb[XFRMA_POLICY_TYPE]);
+
memcpy ((void *)&sp->uptype, (void *)up, sizeof (struct xfrm_userpolicy_type));
sp->ce_mask |= XFRM_SP_ATTR_POLTYPE;
}
@@ -674,24 +661,17 @@ int xfrmnl_sp_parse(struct nlmsghdr *n, struct xfrmnl_sp **result)
_nl_auto_nl_addr struct nl_addr *addr2 = NULL;
if ((sputmpl = xfrmnl_user_tmpl_alloc ()) == NULL)
- {
- err = -NLE_NOMEM;
- goto errout;
- }
-
- if (!(addr1 = _nl_addr_build(tmpl->family, &tmpl->id.daddr))) {
- err = -NLE_NOMEM;
- goto errout;
- }
+ return -NLE_NOMEM;
+
+ if (!(addr1 = _nl_addr_build(tmpl->family, &tmpl->id.daddr)))
+ return -NLE_NOMEM;
xfrmnl_user_tmpl_set_daddr (sputmpl, addr1);
xfrmnl_user_tmpl_set_spi (sputmpl, ntohl(tmpl->id.spi));
xfrmnl_user_tmpl_set_proto (sputmpl, tmpl->id.proto);
xfrmnl_user_tmpl_set_family (sputmpl, tmpl->family);
- if (!(addr2 = _nl_addr_build(tmpl->family, &tmpl->saddr))) {
- err = -NLE_NOMEM;
- goto errout;
- }
+ if (!(addr2 = _nl_addr_build(tmpl->family, &tmpl->saddr)))
+ return -NLE_NOMEM;
xfrmnl_user_tmpl_set_saddr (sputmpl, addr2);
xfrmnl_user_tmpl_set_reqid (sputmpl, tmpl->reqid);
@@ -714,12 +694,8 @@ int xfrmnl_sp_parse(struct nlmsghdr *n, struct xfrmnl_sp **result)
sp->ce_mask |= XFRM_SP_ATTR_MARK;
}
- *result = sp;
+ *result = _nl_steal_pointer(&sp);
return 0;
-
-errout:
- xfrmnl_sp_put(sp);
- return err;
}
static int xfrm_sp_msg_parser(struct nl_cache_ops *ops, struct sockaddr_nl *who,