summaryrefslogtreecommitdiff
path: root/src/libsystemd
diff options
context:
space:
mode:
authorZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>2018-05-14 11:08:59 +0200
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>2018-05-15 12:25:44 +0200
commitf6ddae40ab7790910b1f454c4a838ba624898900 (patch)
treee21f1ff4b768f37c6234069a9da369a5f9887357 /src/libsystemd
parent0b45ff5278f0aa5770f661969fcb850e12f9ecf9 (diff)
downloadsystemd-f6ddae40ab7790910b1f454c4a838ba624898900.tar.gz
sd-resolve: do not assert on packet size received over a socket
This is external data, even if trusted. We should not assert on it, but verify and return proper error instead, which assert_return does. In particular, write(2) says that a partial write could occur when interupted by a signal. When compiled with asserts disabled, we could access memory outside of the allocated buffer. CID #1237671. Follow-up for 1a96c8e1ccb06f87b6bfaff4639390ecd00af588.
Diffstat (limited to 'src/libsystemd')
-rw-r--r--src/libsystemd/sd-resolve/sd-resolve.c28
1 files changed, 14 insertions, 14 deletions
diff --git a/src/libsystemd/sd-resolve/sd-resolve.c b/src/libsystemd/sd-resolve/sd-resolve.c
index 9fabfcec6a..b5e9c01313 100644
--- a/src/libsystemd/sd-resolve/sd-resolve.c
+++ b/src/libsystemd/sd-resolve/sd-resolve.c
@@ -321,8 +321,8 @@ static int handle_request(int out_fd, const Packet *packet, size_t length) {
req = &packet->rheader;
- assert(length >= sizeof(RHeader));
- assert(length == req->length);
+ assert_return(length >= sizeof(RHeader), -EIO);
+ assert_return(length == req->length, -EIO);
switch (req->type) {
@@ -332,8 +332,8 @@ static int handle_request(int out_fd, const Packet *packet, size_t length) {
const char *node, *service;
int ret;
- assert(length >= sizeof(AddrInfoRequest));
- assert(length == sizeof(AddrInfoRequest) + ai_req->node_len + ai_req->service_len);
+ assert_return(length >= sizeof(AddrInfoRequest), -EBADMSG);
+ assert_return(length == sizeof(AddrInfoRequest) + ai_req->node_len + ai_req->service_len, -EBADMSG);
hints.ai_flags = ai_req->ai_flags;
hints.ai_family = ai_req->ai_family;
@@ -358,9 +358,9 @@ static int handle_request(int out_fd, const Packet *packet, size_t length) {
union sockaddr_union sa;
int ret;
- assert(length >= sizeof(NameInfoRequest));
- assert(length == sizeof(NameInfoRequest) + ni_req->sockaddr_len);
- assert(sizeof(sa) >= ni_req->sockaddr_len);
+ assert_return(length >= sizeof(NameInfoRequest), -EBADMSG);
+ assert_return(length == sizeof(NameInfoRequest) + ni_req->sockaddr_len, -EBADMSG);
+ assert_return(ni_req->sockaddr_len <= sizeof(sa), -EBADMSG);
memcpy(&sa, (const uint8_t *) ni_req + sizeof(NameInfoRequest), ni_req->sockaddr_len);
@@ -754,11 +754,11 @@ static int handle_response(sd_resolve *resolve, const Packet *packet, size_t len
int r;
assert(resolve);
+ assert(packet);
resp = &packet->rheader;
- assert(resp);
- assert(length >= sizeof(RHeader));
- assert(length == resp->length);
+ assert_return(length >= sizeof(RHeader), -EIO);
+ assert_return(length == resp->length, -EIO);
if (resp->type == RESPONSE_DIED) {
resolve->dead = true;
@@ -780,8 +780,8 @@ static int handle_response(sd_resolve *resolve, const Packet *packet, size_t len
size_t l;
struct addrinfo *prev = NULL;
- assert(length >= sizeof(AddrInfoResponse));
- assert(q->type == REQUEST_ADDRINFO);
+ assert_return(length >= sizeof(AddrInfoResponse), -EBADMSG);
+ assert_return(q->type == REQUEST_ADDRINFO, -EBADMSG);
ASSIGN_ERRNO(q, ai_resp->ret, ai_resp->_errno, ai_resp->_h_errno);
@@ -813,8 +813,8 @@ static int handle_response(sd_resolve *resolve, const Packet *packet, size_t len
case RESPONSE_NAMEINFO: {
const NameInfoResponse *ni_resp = &packet->nameinfo_response;
- assert(length >= sizeof(NameInfoResponse));
- assert(q->type == REQUEST_NAMEINFO);
+ assert_return(length >= sizeof(NameInfoResponse), -EBADMSG);
+ assert_return(q->type == REQUEST_NAMEINFO, -EBADMSG);
if (ni_resp->hostlen > DNS_HOSTNAME_MAX ||
ni_resp->servlen > DNS_HOSTNAME_MAX ||