socket-util: add more careful parsers for AF_VSOCK cid/port
Let's handle the magic CIDs, and filter out invalid ports.
This commit is contained in:
+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,
|
||||
|
||||
Reference in New Issue
Block a user