summaryrefslogtreecommitdiffstats
path: root/lib/session.c
diff options
context:
space:
mode:
authorJozsef Kadlecsik <kadlec@blackhole.kfki.hu>2010-12-23 15:28:28 +0100
committerJozsef Kadlecsik <kadlec@blackhole.kfki.hu>2010-12-23 15:28:28 +0100
commitad4d802717b4fa60a65a6f4a6d64f007fcb82cf9 (patch)
treec83a96a8debd23cdfba7d4b26bc106cc37b234cd /lib/session.c
parent7c80f67c0c16620e8b0425a129b3dfe72a72aaed (diff)
Handle internal printing errors
Internal printing errors were not reported, handle them by setjmp/longjmp.
Diffstat (limited to 'lib/session.c')
-rw-r--r--lib/session.c35
1 files changed, 25 insertions, 10 deletions
diff --git a/lib/session.c b/lib/session.c
index 2a57378..311e5df 100644
--- a/lib/session.c
+++ b/lib/session.c
@@ -6,6 +6,7 @@
*/
#include <assert.h> /* assert */
#include <errno.h> /* errno */
+#include <setjmp.h> /* setjmp, longjmp */
#include <stdio.h> /* snprintf */
#include <stdarg.h> /* va_* */
#include <stdlib.h> /* free */
@@ -629,6 +630,9 @@ call_outfn(struct ipset_session *session)
return ret < 0 ? ret : 0;
}
+/* Handle printing failures */
+static jmp_buf printf_failure;
+
static int __attribute__((format(printf,2,3)))
safe_snprintf(struct ipset_session *session, const char *fmt, ...)
{
@@ -643,16 +647,20 @@ retry:
fmt, args);
va_end(args);
- if (ret < 0)
- return ipset_err(session,
- "Internal error at printing to output buffer");
+ if (ret < 0) {
+ ipset_err(session,
+ "Internal error at printing to output buffer");
+ longjmp(printf_failure, 1);
+ }
if (ret >= IPSET_OUTBUFLEN - len) {
/* Buffer was too small, push it out and retry */
D("print buffer and try again: %u", len);
- if (loop++)
- return ipset_err(session,
+ if (loop++) {
+ ipset_err(session,
"Internal error at printing, loop detected!");
+ longjmp(printf_failure, 1);
+ }
session->outbuf[len] = '\0';
if (!call_outfn(session))
@@ -673,16 +681,20 @@ retry:
ret = fn(session->outbuf + len, IPSET_OUTBUFLEN - len,
session->data, opt, session->envopts);
- if (ret < 0)
- return ipset_err(session,
+ if (ret < 0) {
+ ipset_err(session,
"Internal error at printing to output buffer");
+ longjmp(printf_failure, 1);
+ }
if (ret >= IPSET_OUTBUFLEN - len) {
/* Buffer was too small, push it out and retry */
D("print buffer and try again: %u", len);
- if (loop++)
- return ipset_err(session,
- "Internal error at printing, loop detected!");
+ if (loop++) {
+ ipset_err(session,
+ "Internal error at printing, loop detected!");
+ longjmp(printf_failure, 1);
+ }
session->outbuf[len] = '\0';
if (!call_outfn(session))
@@ -904,6 +916,9 @@ callback_list(struct ipset_session *session, struct nlattr *nla[],
{
struct ipset_data *data = session->data;
+ if (setjmp(printf_failure))
+ return MNL_CB_ERROR;
+
if (!nla[IPSET_ATTR_SETNAME])
FAILURE("Broken %s kernel message: missing setname!",
cmd2name[cmd]);