Unlink UNIX domain socket file only if:

1. The descriptor is the one we are listening on (not the one when we connect
   as a client and not the one which is created on accept(2)).
2. Descriptor was created by us (PID matches with the PID stored on bind(2)).

Reported by:	Mikolaj Golub <to.my.trociny@gmail.com>
MFC after:	1 week
This commit is contained in:
Pawel Jakub Dawidek 2011-02-08 23:08:20 +00:00
parent 6a9f4949fb
commit f431ab182a

View File

@ -54,6 +54,7 @@ struct uds_ctx {
#define UDS_SIDE_CLIENT 0
#define UDS_SIDE_SERVER_LISTEN 1
#define UDS_SIDE_SERVER_WORK 2
pid_t uc_owner;
};
static void uds_close(void *ctx);
@ -109,6 +110,7 @@ uds_common_setup(const char *addr, void **ctxp, int side)
}
uctx->uc_side = side;
uctx->uc_owner = 0;
uctx->uc_magic = UDS_CTX_MAGIC;
*ctxp = uctx;
@ -167,13 +169,14 @@ uds_server(const char *addr, void **ctxp)
uctx = *ctxp;
unlink(uctx->uc_sun.sun_path);
(void)unlink(uctx->uc_sun.sun_path);
if (bind(uctx->uc_fd, (struct sockaddr *)&uctx->uc_sun,
sizeof(uctx->uc_sun)) < 0) {
ret = errno;
uds_close(uctx);
return (ret);
}
uctx->uc_owner = getpid();
if (listen(uctx->uc_fd, 8) < 0) {
ret = errno;
uds_close(uctx);
@ -200,9 +203,9 @@ uds_accept(void *ctx, void **newctxp)
if (newuctx == NULL)
return (errno);
fromlen = sizeof(uctx->uc_sun);
newuctx->uc_fd = accept(uctx->uc_fd, (struct sockaddr *)&uctx->uc_sun,
&fromlen);
fromlen = sizeof(newuctx->uc_sun);
newuctx->uc_fd = accept(uctx->uc_fd,
(struct sockaddr *)&newuctx->uc_sun, &fromlen);
if (newuctx->uc_fd < 0) {
ret = errno;
free(newuctx);
@ -309,7 +312,15 @@ uds_close(void *ctx)
if (uctx->uc_fd >= 0)
close(uctx->uc_fd);
unlink(uctx->uc_sun.sun_path);
/*
* Unlink the socket only if we are the owner and this is descriptor
* we listen on.
*/
if (uctx->uc_side == UDS_SIDE_SERVER_LISTEN &&
uctx->uc_owner == getpid()) {
(void)unlink(uctx->uc_sun.sun_path);
}
uctx->uc_owner = 0;
uctx->uc_magic = 0;
free(uctx);
}