summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/afb-api-so-v3.c2
-rw-r--r--src/afb-api-v3.c31
-rw-r--r--src/afb-api-v3.h4
3 files changed, 35 insertions, 2 deletions
diff --git a/src/afb-api-so-v3.c b/src/afb-api-so-v3.c
index 415c13d9..b02f3c88 100644
--- a/src/afb-api-so-v3.c
+++ b/src/afb-api-so-v3.c
@@ -59,7 +59,7 @@ static int init(void *closure, struct afb_api_x3 *api)
}
if (rc >= 0 && a->entry)
- rc = a->entry(api);
+ rc = afb_api_v3_safe_preinit(api, a->entry);
if (rc >= 0)
afb_api_x3_seal(api);
diff --git a/src/afb-api-v3.c b/src/afb-api-v3.c
index 8c755f94..39f627a9 100644
--- a/src/afb-api-v3.c
+++ b/src/afb-api-v3.c
@@ -35,6 +35,7 @@
#include "afb-export.h"
#include "afb-xreq.h"
#include "verbose.h"
+#include "sig-monitor.h"
/*
* Description of a binding
@@ -342,12 +343,40 @@ int afb_api_v3_set_binding_fields(const struct afb_binding_v3 *desc, struct afb_
return rc;
}
+struct safe_preinit_data
+{
+ int (*preinit)(struct afb_api_x3 *);
+ struct afb_api_x3 *api;
+ int result;
+};
+
+static void safe_preinit(int sig, void *closure)
+{
+ struct safe_preinit_data *spd = closure;
+ if (!sig)
+ spd->result = spd->preinit(spd->api);
+ else {
+ spd->result = -1;
+ errno = EFAULT;
+ }
+}
+
+int afb_api_v3_safe_preinit(struct afb_api_x3 *api, int (*preinit)(struct afb_api_x3 *))
+{
+ struct safe_preinit_data spd;
+
+ spd.preinit = preinit;
+ spd.api = api;
+ sig_monitor(60, safe_preinit, &spd);
+ return spd.result;
+}
+
static int init_binding(void *closure, struct afb_api_x3 *api)
{
const struct afb_binding_v3 *desc = closure;
int rc = afb_api_v3_set_binding_fields(desc, api);
if (!rc && desc->preinit)
- rc = desc->preinit(api);
+ rc = afb_api_v3_safe_preinit(api, desc->preinit);
return rc;
}
diff --git a/src/afb-api-v3.h b/src/afb-api-v3.h
index 33649f35..04d9124a 100644
--- a/src/afb-api-v3.h
+++ b/src/afb-api-v3.h
@@ -46,6 +46,10 @@ extern struct afb_api_v3 *afb_api_v3_from_binding(
struct afb_apiset *declare_set,
struct afb_apiset * call_set);
+extern int afb_api_v3_safe_preinit(
+ struct afb_api_x3 *api,
+ int (*preinit)(struct afb_api_x3 *));
+
extern int afb_api_v3_set_binding_fields(const struct afb_binding_v3 *desc, struct afb_api_x3 *api);
extern struct afb_api_v3 *afb_api_v3_addref(struct afb_api_v3 *api);