From ad4d802717b4fa60a65a6f4a6d64f007fcb82cf9 Mon Sep 17 00:00:00 2001 From: Jozsef Kadlecsik Date: Thu, 23 Dec 2010 15:28:28 +0100 Subject: Handle internal printing errors Internal printing errors were not reported, handle them by setjmp/longjmp. --- lib/session.c | 35 +++++++++++++++++++++++++---------- 1 file 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 */ #include /* errno */ +#include /* setjmp, longjmp */ #include /* snprintf */ #include /* va_* */ #include /* 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]); -- cgit v1.2.3