diff options
author | Ben Pfaff <blp@nicira.com> | 2010-05-20 15:57:36 -0700 |
---|---|---|
committer | Ben Pfaff <blp@nicira.com> | 2010-06-17 10:30:18 -0700 |
commit | a35fbea5bb1b49bcdad696a62c3814e02c4df6e2 (patch) | |
tree | 3e585767ebc3b365dfed82a373b3bac4727be12c /lib/netlink.c | |
parent | b4d73e97bae62b5eb18bcd216b603b69ce63297b (diff) |
netlink: Make nl_sock_transact() always return a reply on success.
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.
Diffstat (limited to 'lib/netlink.c')
-rw-r--r-- | lib/netlink.c | 9 |
1 files changed, 8 insertions, 1 deletions
diff --git a/lib/netlink.c b/lib/netlink.c index de88a81e..334e45af 100644 --- a/lib/netlink.c +++ b/lib/netlink.c @@ -421,7 +421,14 @@ recv: 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)", |