mirror of
https://github.com/systemd/systemd.git
synced 2024-10-27 01:55:22 +03:00
sd-daemon: verify socket family, too
This commit is contained in:
parent
dde770cfc6
commit
88ce42f694
2
fixme
2
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
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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));
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user