Merge pull request #30794 from poettering/parse-vsock-better
socket-util: add more careful parsers for AF_VSOCK cid/port
This commit is contained in:
@@ -6,7 +6,6 @@
|
||||
#if HAVE_LINUX_VM_SOCKETS_H
|
||||
#include <linux/vm_sockets.h>
|
||||
#else
|
||||
#define VMADDR_CID_ANY -1U
|
||||
struct sockaddr_vm {
|
||||
unsigned short svm_family;
|
||||
unsigned short svm_reserved1;
|
||||
@@ -20,6 +19,26 @@ struct sockaddr_vm {
|
||||
};
|
||||
#endif /* !HAVE_LINUX_VM_SOCKETS_H */
|
||||
|
||||
#ifndef VMADDR_CID_ANY
|
||||
#define VMADDR_CID_ANY -1U
|
||||
#endif
|
||||
|
||||
#ifndef VMADDR_CID_HYPERVISOR
|
||||
#define VMADDR_CID_HYPERVISOR 0U
|
||||
#endif
|
||||
|
||||
#ifndef VMADDR_CID_LOCAL
|
||||
#define VMADDR_CID_LOCAL 1U
|
||||
#endif
|
||||
|
||||
#ifndef VMADDR_CID_HOST
|
||||
#define VMADDR_CID_HOST 2U
|
||||
#endif
|
||||
|
||||
#ifndef VMADDR_PORT_ANY
|
||||
#define VMADDR_PORT_ANY -1U
|
||||
#endif
|
||||
|
||||
#ifndef AF_VSOCK
|
||||
#define AF_VSOCK 40
|
||||
#endif
|
||||
|
||||
+47
-3
@@ -1656,6 +1656,50 @@ int socket_address_parse_unix(SocketAddress *ret_address, const char *s) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int vsock_parse_port(const char *s, unsigned *ret) {
|
||||
int r;
|
||||
|
||||
assert(ret);
|
||||
|
||||
if (!s)
|
||||
return -EINVAL;
|
||||
|
||||
unsigned u;
|
||||
r = safe_atou(s, &u);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
/* Port 0 is apparently valid and not special in AF_VSOCK (unlike on IP). But VMADDR_PORT_ANY
|
||||
* (UINT32_MAX) is. Hence refuse that. */
|
||||
|
||||
if (u == VMADDR_PORT_ANY)
|
||||
return -EINVAL;
|
||||
|
||||
*ret = u;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int vsock_parse_cid(const char *s, unsigned *ret) {
|
||||
assert(ret);
|
||||
|
||||
if (!s)
|
||||
return -EINVAL;
|
||||
|
||||
/* Parsed an AF_VSOCK "CID". This is a 32bit entity, and the usual type is "unsigned". We recognize
|
||||
* the three special CIDs as strings, and otherwise parse the numeric CIDs. */
|
||||
|
||||
if (streq(s, "hypervisor"))
|
||||
*ret = VMADDR_CID_HYPERVISOR;
|
||||
else if (streq(s, "local"))
|
||||
*ret = VMADDR_CID_LOCAL;
|
||||
else if (streq(s, "host"))
|
||||
*ret = VMADDR_CID_HOST;
|
||||
else
|
||||
return safe_atou(s, ret);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int socket_address_parse_vsock(SocketAddress *ret_address, const char *s) {
|
||||
/* AF_VSOCK socket in vsock:cid:port notation */
|
||||
_cleanup_free_ char *n = NULL;
|
||||
@@ -1681,7 +1725,7 @@ int socket_address_parse_vsock(SocketAddress *ret_address, const char *s) {
|
||||
if (!e)
|
||||
return -EINVAL;
|
||||
|
||||
r = safe_atou(e+1, &port);
|
||||
r = vsock_parse_port(e+1, &port);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
@@ -1692,15 +1736,15 @@ int socket_address_parse_vsock(SocketAddress *ret_address, const char *s) {
|
||||
if (isempty(n))
|
||||
cid = VMADDR_CID_ANY;
|
||||
else {
|
||||
r = safe_atou(n, &cid);
|
||||
r = vsock_parse_cid(n, &cid);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
*ret_address = (SocketAddress) {
|
||||
.sockaddr.vm = {
|
||||
.svm_cid = cid,
|
||||
.svm_family = AF_VSOCK,
|
||||
.svm_cid = cid,
|
||||
.svm_port = port,
|
||||
},
|
||||
.type = type,
|
||||
|
||||
@@ -374,6 +374,9 @@ int socket_get_mtu(int fd, int af, size_t *ret);
|
||||
|
||||
int connect_unix_path(int fd, int dir_fd, const char *path);
|
||||
|
||||
int vsock_parse_port(const char *s, unsigned *ret);
|
||||
int vsock_parse_cid(const char *s, unsigned *ret);
|
||||
|
||||
/* Parses AF_UNIX and AF_VSOCK addresses. AF_INET[6] require some netlink calls, so it cannot be in
|
||||
* src/basic/ and is done from 'socket_local_address from src/shared/. Return -EPROTO in case of
|
||||
* protocol mismatch. */
|
||||
|
||||
Reference in New Issue
Block a user