From 88ce42f6944774788f610598fccdc6bab4283497 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 21 May 2010 17:06:40 +0200 Subject: [PATCH] sd-daemon: verify socket family, too --- fixme | 2 +- src/logger.c | 2 +- src/sd-daemon.c | 69 +++++++++++++++++++++++++++++++++++-------------- src/sd-daemon.h | 34 ++++++++++++------------ 4 files changed, 70 insertions(+), 37 deletions(-) diff --git a/fixme b/fixme index 22c5cc3a3..b8d0fca35 100644 --- a/fixme +++ b/fixme @@ -47,9 +47,9 @@ - uuidd DONE - nscd DONE - dbus DONE + - rsyslog DONE - rpcbind (/var/run/rpcbind.sock!) - avahi-daemon (/var/run/avahi-daemon/socket) - - rsyslog - cups - ssh CLASSIC - postfix, saslauthd diff --git a/src/logger.c b/src/logger.c index c486a8acd..2e036dd77 100644 --- a/src/logger.c +++ b/src/logger.c @@ -428,7 +428,7 @@ static int server_init(Server *s, unsigned n_sockets) { fd = SD_LISTEN_FDS_START+i; - if ((r = sd_is_socket(fd, SOCK_STREAM, 1)) < 0) { + if ((r = sd_is_socket(fd, AF_UNSPEC, SOCK_STREAM, 1)) < 0) { log_error("Failed to determine file descriptor type: %s", strerror(-r)); goto fail; } diff --git a/src/sd-daemon.c b/src/sd-daemon.c index ad2bfa82e..eec472270 100644 --- a/src/sd-daemon.c +++ b/src/sd-daemon.c @@ -133,7 +133,7 @@ int sd_is_fifo(int fd, const char *path) { return 1; } -int sd_is_socket(int fd, int type, int listening) { +static int sd_is_socket_internal(int fd, int type, int listening) { struct stat st_fd; if (fd < 0 || type < 0) @@ -176,18 +176,51 @@ int sd_is_socket(int fd, int type, int listening) { return 1; } -int sd_is_socket_inet(int fd, int type, int listening, uint16_t port) { - union { - struct sockaddr sa; - struct sockaddr_in in4; - struct sockaddr_in6 in6; - struct sockaddr_un un; - struct sockaddr_storage storage; - } sockaddr; +union sockaddr_union { + struct sockaddr sa; + struct sockaddr_in in4; + struct sockaddr_in6 in6; + struct sockaddr_un un; + struct sockaddr_storage storage; +}; + +int sd_is_socket(int fd, int family, int type, int listening) { + int r; + + if (family < 0) + return -EINVAL; + + if ((r = sd_is_socket_internal(fd, type, listening)) <= 0) + return r; + + if (family > 0) { + union sockaddr_union sockaddr; + socklen_t l; + + memset(&sockaddr, 0, sizeof(sockaddr)); + l = sizeof(sockaddr); + + if (getsockname(fd, &sockaddr.sa, &l) < 0) + return -errno; + + if (l < sizeof(sa_family_t)) + return -EINVAL; + + return sockaddr.sa.sa_family == family; + } + + return 1; +} + +int sd_is_socket_inet(int fd, int family, int type, int listening, uint16_t port) { + union sockaddr_union sockaddr; socklen_t l; int r; - if ((r = sd_is_socket(fd, type, listening)) <= 0) + if (family != 0 && family != AF_INET && family != AF_INET6) + return -EINVAL; + + if ((r = sd_is_socket_internal(fd, type, listening)) <= 0) return r; memset(&sockaddr, 0, sizeof(sockaddr)); @@ -196,13 +229,17 @@ int sd_is_socket_inet(int fd, int type, int listening, uint16_t port) { if (getsockname(fd, &sockaddr.sa, &l) < 0) return -errno; - if (l < sizeof(struct sockaddr)) + if (l < sizeof(sa_family_t)) return -EINVAL; if (sockaddr.sa.sa_family != AF_INET && sockaddr.sa.sa_family != AF_INET6) return 0; + if (family > 0) + if (sockaddr.sa.sa_family != family) + return 0; + if (port > 0) { if (sockaddr.sa.sa_family == AF_INET) { if (l < sizeof(struct sockaddr_in)) @@ -221,17 +258,11 @@ int sd_is_socket_inet(int fd, int type, int listening, uint16_t port) { } int sd_is_socket_unix(int fd, int type, int listening, const char *path, size_t length) { - union { - struct sockaddr sa; - struct sockaddr_in in4; - struct sockaddr_in6 in6; - struct sockaddr_un un; - struct sockaddr_storage storage; - } sockaddr; + union sockaddr_union sockaddr; socklen_t l; int r; - if ((r = sd_is_socket(fd, type, listening)) <= 0) + if ((r = sd_is_socket_internal(fd, type, listening)) <= 0) return r; memset(&sockaddr, 0, sizeof(sockaddr)); diff --git a/src/sd-daemon.h b/src/sd-daemon.h index ab69364c2..e209af648 100644 --- a/src/sd-daemon.h +++ b/src/sd-daemon.h @@ -73,24 +73,26 @@ int sd_listen_fds(int unset_environment); int sd_is_fifo(int fd, const char *path); /* Helper call for identifying a passed file descriptor. Returns 1 if - * the file descriptor is a socket of the specified type (SOCK_DGRAM, - * SOCK_STREAM, ...), 0 otherwise. If type is 0 a socket type check - * will not be done and the call only verifies if the file descriptor - * refers to a socket. If listening is > 0 it is verified that the - * socket is in listening mode. (i.e. listen() has been called) If - * listening is == 0 it is verified that the socket is not in - * listening mode. If listening is < 0 no listening mode check is - * done. Returns a negative errno style error code on failure. */ -int sd_is_socket(int fd, int type, int listening); + * the file descriptor is a socket of the specified family (AF_INET, + * ...) and type (SOCK_DGRAM, SOCK_STREAM, ...), 0 otherwise. If + * family is 0 a socket family check will not be done. If type is 0 a + * socket type check will not be done and the call only verifies if + * the file descriptor refers to a socket. If listening is > 0 it is + * verified that the socket is in listening mode. (i.e. listen() has + * been called) If listening is == 0 it is verified that the socket is + * not in listening mode. If listening is < 0 no listening mode check + * is done. Returns a negative errno style error code on failure. */ +int sd_is_socket(int fd, int family, int type, int listening); /* Helper call for identifying a passed file descriptor. Returns 1 if - * the file descriptor is an Internet socket (either AF_INET or - * AF_INET6) of the specified type (SOCK_DGRAM, SOCK_STREAM, ...), 0 - * otherwise. If type is 0 a socket type check will not be done. If - * port is 0 a socket port check will not be done. The listening flag - * is used the same way as in sd_is_socket(). Returns a negative errno - * style error code on failure. */ -int sd_is_socket_inet(int fd, int type, int listening, uint16_t port); + * the file descriptor is an Internet socket, of the specified family + * (either AF_INET or AF_INET6) of the specified type (SOCK_DGRAM, + * SOCK_STREAM, ...), 0 otherwise. If version is 0 a protocol version + * check is not done. If type is 0 a socket type check will not be + * done. If port is 0 a socket port check will not be done. The + * listening flag is used the same way as in sd_is_socket(). Returns a + * negative errno style error code on failure. */ +int sd_is_socket_inet(int fd, int family, int type, int listening, uint16_t port); /* Helper call for identifying a passed file descriptor. Returns 1 if * the file descriptor is an AF_UNIX socket of the specified type -- 2.30.2