Until now, if nl_sock_transact() received a reply that merely acknowledged
success, without providing any other payload, it would return success but
not provide the reply to its caller. This is inconsistent and could easily
cause a segfault in a caller that expects to see the reply on success, if
kernel behavior changed, for whatever reason, so that a request that
previously returned data now just returns an acknowledgment. In practice
this kind of change should never happen, but it is still better to handle
it properly.
ofpbuf_delete(reply);
goto recv;
}
- if (nl_msg_nlmsgerr(reply, &retval)) {
+
+ /* If the reply is an error, discard the reply and return the error code.
+ *
+ * Except: if the reply is just an acknowledgement (error code of 0), and
+ * the caller is interested in the reply (replyp != NULL), pass the reply
+ * up to the caller. Otherwise the caller will get a return value of 0
+ * and null '*replyp', which makes unwary callers likely to segfault. */
+ if (nl_msg_nlmsgerr(reply, &retval) && (retval || !replyp)) {
ofpbuf_delete(reply);
if (retval) {
VLOG_DBG_RL(&rl, "received NAK error=%d (%s)",