diff options
author | pjd <pjd@FreeBSD.org> | 2011-02-08 23:08:20 +0000 |
---|---|---|
committer | pjd <pjd@FreeBSD.org> | 2011-02-08 23:08:20 +0000 |
commit | 4b7d2ad6a21bd90c918a821465d52c95c6559dc4 (patch) | |
tree | cf98c653076814bb559ebff32981c2ea043116b2 /sbin | |
parent | a614f3ba259b5d004357b3eeb861c2496e87ea1d (diff) | |
download | FreeBSD-src-4b7d2ad6a21bd90c918a821465d52c95c6559dc4.zip FreeBSD-src-4b7d2ad6a21bd90c918a821465d52c95c6559dc4.tar.gz |
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
Diffstat (limited to 'sbin')
-rw-r--r-- | sbin/hastd/proto_uds.c | 21 |
1 files changed, 16 insertions, 5 deletions
diff --git a/sbin/hastd/proto_uds.c b/sbin/hastd/proto_uds.c index a5fda7f..91c98ad 100644 --- a/sbin/hastd/proto_uds.c +++ b/sbin/hastd/proto_uds.c @@ -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); } |