summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Haller <thaller@redhat.com>2018-12-23 14:39:22 +0100
committerThomas Haller <thaller@redhat.com>2019-01-09 16:46:41 +0100
commit2e48f6419ffaff960548f40e0a54303e35b9a7bb (patch)
treeeb541636b01a7247a9b981f74ebe21983ecae204
parente5fb1dd6e7fff3827eca0ec79e890b21ed96284d (diff)
netlink: don't heap allocate struct ucred during nla_recv()
Instead, fill a preallocated output buffer provided by the caller.
-rw-r--r--src/platform/nm-linux-platform.c16
-rw-r--r--src/platform/nm-netlink.c31
-rw-r--r--src/platform/nm-netlink.h7
3 files changed, 32 insertions, 22 deletions
diff --git a/src/platform/nm-linux-platform.c b/src/platform/nm-linux-platform.c
index d9af54c2c3..45016ea50b 100644
--- a/src/platform/nm-linux-platform.c
+++ b/src/platform/nm-linux-platform.c
@@ -7367,13 +7367,13 @@ event_handler_recvmsgs (NMPlatform *platform, gboolean handle_events)
struct nlmsghdr *hdr;
WaitForNlResponseResult seq_result;
struct sockaddr_nl nla = {0};
- nm_auto_free struct ucred *creds = NULL;
+ struct ucred creds;
+ gboolean creds_has;
nm_auto_free unsigned char *buf = NULL;
continue_reading:
g_clear_pointer (&buf, free);
- g_clear_pointer (&creds, free);
- n = nl_recv (sk, &nla, &buf, &creds);
+ n = nl_recv (sk, &nla, &buf, &creds, &creds_has);
if (n <= 0) {
@@ -7410,11 +7410,11 @@ continue_reading:
nlmsg_set_proto (msg, NETLINK_ROUTE);
nlmsg_set_src (msg, &nla);
- if (!creds || creds->pid) {
- if (creds)
- _LOGT ("netlink: recvmsg: received non-kernel message (pid %d)", creds->pid);
- else
+ if (!creds_has || creds.pid) {
+ if (!creds_has)
_LOGT ("netlink: recvmsg: received message without credentials");
+ else
+ _LOGT ("netlink: recvmsg: received non-kernel message (pid %d)", creds.pid);
err = 0;
goto stop;
}
@@ -7422,7 +7422,7 @@ continue_reading:
_LOGt ("netlink: recvmsg: new message %s",
nl_nlmsghdr_to_str (hdr, buf_nlmsghdr, sizeof (buf_nlmsghdr)));
- nlmsg_set_creds (msg, creds);
+ nlmsg_set_creds (msg, &creds);
if (hdr->nlmsg_flags & NLM_F_MULTI)
multipart = TRUE;
diff --git a/src/platform/nm-netlink.c b/src/platform/nm-netlink.c
index a4feee0564..72f7c73495 100644
--- a/src/platform/nm-netlink.c
+++ b/src/platform/nm-netlink.c
@@ -1084,10 +1084,11 @@ nl_recvmsgs (struct nl_sock *sk, const struct nl_cb *cb)
gs_free unsigned char *buf = NULL;
struct nlmsghdr *hdr;
struct sockaddr_nl nla = { 0 };
- gs_free struct ucred *creds = NULL;
+ struct ucred creds;
+ gboolean creds_has;
continue_reading:
- n = nl_recv (sk, &nla, &buf, &creds);
+ n = nl_recv (sk, &nla, &buf, &creds, &creds_has);
if (n <= 0)
return n;
@@ -1099,7 +1100,7 @@ continue_reading:
nlmsg_set_proto (msg, sk->s_proto);
nlmsg_set_src (msg, &nla);
- nlmsg_set_creds (msg, creds);
+ nlmsg_set_creds (msg, creds_has ? &creds : NULL);
nrecv++;
@@ -1203,7 +1204,6 @@ skip:
if (multipart) {
/* Multipart message not yet complete, continue reading */
- nm_clear_g_free (&creds);
nm_clear_g_free (&buf);
goto continue_reading;
@@ -1315,8 +1315,11 @@ int nl_send_auto (struct nl_sock *sk, struct nl_msg *msg)
}
int
-nl_recv (struct nl_sock *sk, struct sockaddr_nl *nla,
- unsigned char **buf, struct ucred **creds)
+nl_recv (struct nl_sock *sk,
+ struct sockaddr_nl *nla,
+ unsigned char **buf,
+ struct ucred *out_creds,
+ gboolean *out_creds_has)
{
ssize_t n;
int flags = 0;
@@ -1327,12 +1330,13 @@ nl_recv (struct nl_sock *sk, struct sockaddr_nl *nla,
.msg_iov = &iov,
.msg_iovlen = 1,
};
- gs_free struct ucred* tmpcreds = NULL;
+ struct ucred tmpcreds;
+ gboolean tmpcreds_has = FALSE;
int retval;
nm_assert (nla);
nm_assert (buf && !*buf);
- nm_assert (!creds || !*creds);
+ nm_assert (!out_creds_has == !out_creds);
if ( (sk->s_flags & NL_MSG_PEEK)
|| ( !(sk->s_flags & NL_MSG_PEEK_EXPLICIT)
@@ -1343,7 +1347,7 @@ nl_recv (struct nl_sock *sk, struct sockaddr_nl *nla,
?: (((size_t) nm_utils_getpagesize ()) * 4u);
iov.iov_base = g_malloc (iov.iov_len);
- if ( creds
+ if ( out_creds
&& (sk->s_flags & NL_SOCK_PASSCRED)) {
msg.msg_controllen = CMSG_SPACE (sizeof (struct ucred));
msg.msg_control = g_malloc (msg.msg_controllen);
@@ -1403,7 +1407,7 @@ retry:
goto abort;
}
- if (creds && (sk->s_flags & NL_SOCK_PASSCRED)) {
+ if (out_creds && (sk->s_flags & NL_SOCK_PASSCRED)) {
struct cmsghdr *cmsg;
for (cmsg = CMSG_FIRSTHDR (&msg); cmsg; cmsg = CMSG_NXTHDR (&msg, cmsg)) {
@@ -1411,7 +1415,8 @@ retry:
continue;
if (cmsg->cmsg_type != SCM_CREDENTIALS)
continue;
- tmpcreds = nm_memdup (CMSG_DATA (cmsg), sizeof (*tmpcreds));
+ memcpy (&tmpcreds, CMSG_DATA (cmsg), sizeof (tmpcreds));
+ tmpcreds_has = TRUE;
break;
}
}
@@ -1427,6 +1432,8 @@ abort:
}
*buf = iov.iov_base;
- NM_SET_OUT (creds, g_steal_pointer (&tmpcreds));
+ if (out_creds && tmpcreds_has)
+ *out_creds = tmpcreds;
+ NM_SET_OUT (out_creds_has, tmpcreds_has);
return retval;
}
diff --git a/src/platform/nm-netlink.h b/src/platform/nm-netlink.h
index 2fbddff4cf..f1f8394052 100644
--- a/src/platform/nm-netlink.h
+++ b/src/platform/nm-netlink.h
@@ -416,8 +416,11 @@ int nl_socket_add_memberships (struct nl_sock *sk, int group, ...);
int nl_connect (struct nl_sock *sk, int protocol);
-int nl_recv (struct nl_sock *sk, struct sockaddr_nl *nla,
- unsigned char **buf, struct ucred **creds);
+int nl_recv (struct nl_sock *sk,
+ struct sockaddr_nl *nla,
+ unsigned char **buf,
+ struct ucred *out_creds,
+ gboolean *out_creds_has);
int nl_send (struct nl_sock *sk, struct nl_msg *msg);