sd-daemon: verify socket family, too

This commit is contained in:
Lennart Poettering 2010-05-21 17:06:40 +02:00
parent dde770cfc6
commit 88ce42f694
4 changed files with 70 additions and 37 deletions

2
fixme
View File

@ -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

View File

@ -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;
}

View File

@ -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));

View File

@ -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