[libvirt] PATCH: better error checking for LOCAL_PEERCRED

I was debugging libvirt with OSX today, and got as far as finding the problem with LOCAL_PEERCRED, then googled this only to find that Ryota Ozaki had fixed the problems a few days ago! However you still may find the following patch useful. It tightens up the checking in the LOCAL_PEERCRED block, and in particular fixes the unlocking of the socket in the error return path for invalid groups, by using the same logic from SO_PEERCRED - have a 'goto cleanup' in all return paths. (Detail: I found that when getsockopt was being called with SOL_SOCKET, cr_ngroups was typically <0, probably because it was uninitialised. However once the check for this was tightened, it hung because the socket wasn't being unlocked on return. So better to (a) initialise it to a negative value anyway, and (b) fix the return path) However I have not checked that NGROUPS is defined on other BSD-like systems. Regards, Brian Candler. --- src/rpc/virnetsocket.c.orig 2013-10-10 22:37:49.000000000 +0100 +++ src/rpc/virnetsocket.c 2013-10-12 22:51:57.000000000 +0100 @@ -1157,8 +1157,10 @@ { struct xucred cr; socklen_t cr_len = sizeof(cr); + int ret = -1; virObjectLock(sock); + cr.cr_ngroups = -1; # if defined(__APPLE__) if (getsockopt(sock->fd, SOL_LOCAL, LOCAL_PEERCRED, &cr, &cr_len) < 0) { # else @@ -1166,20 +1168,19 @@ # endif virReportSystemError(errno, "%s", _("Failed to get client socket identity")); - virObjectUnlock(sock); - return -1; + goto cleanup; } if (cr.cr_version != XUCRED_VERSION) { virReportError(VIR_ERR_SYSTEM_ERROR, "%s", _("Failed to get valid client socket identity")); - return -1; + goto cleanup; } - if (cr.cr_ngroups == 0) { + if (cr.cr_ngroups <= 0 || cr.cr_ngroups > NGROUPS) { virReportError(VIR_ERR_SYSTEM_ERROR, "%s", _("Failed to get valid client socket identity groups")); - return -1; + goto cleanup; } /* PID and process creation time are not supported on BSDs */ @@ -1188,8 +1189,11 @@ *uid = cr.cr_uid; *gid = cr.cr_gid; + ret = 0; + +cleanup: virObjectUnlock(sock); - return 0; + return ret; } #else int virNetSocketGetUNIXIdentity(virNetSocketPtr sock ATTRIBUTE_UNUSED,
participants (1)
-
Brian Candler