summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAnoop C S <anoopcs@redhat.com>2019-05-22 10:45:37 +0530
committerAndreas Schneider <asn@samba.org>2021-02-02 10:23:33 +0100
commit00650ffb0b913010aab7a004fa2d3eadf2f2f007 (patch)
treed1f27088f61e80a6a864e9ae387a68b29c18ff84
parent5b2a98203bbb0230785a65429338b52bd377971b (diff)
downloadsocket_wrapper-00650ffb0b913010aab7a004fa2d3eadf2f2f007.tar.gz
socket_wrapper-00650ffb0b913010aab7a004fa2d3eadf2f2f007.tar.xz
socket_wrapper-00650ffb0b913010aab7a004fa2d3eadf2f2f007.zip
swrap: Fix MSGHDR check in sendmsg()
Check for msg_controllen and msg_control data members from msghdr structure needs to be validated on the received omsg pointer rather than on newly created msghdr struture inside the wrapper. Signed-off-by: Anoop C S <anoopcs@redhat.com> Reviewed-by: Anoop C S <anoopcs@samba.org> Reviewed-by: Andreas Schneider <asn@samba.org>
-rw-r--r--src/socket_wrapper.c86
1 files changed, 48 insertions, 38 deletions
diff --git a/src/socket_wrapper.c b/src/socket_wrapper.c
index 0507481..8a0e80d 100644
--- a/src/socket_wrapper.c
+++ b/src/socket_wrapper.c
@@ -4991,16 +4991,18 @@ static int swrap_msghdr_add_socket_info(struct socket_info *si,
return rc;
}
-static int swrap_sendmsg_copy_cmsg(struct cmsghdr *cmsg,
+static int swrap_sendmsg_copy_cmsg(const struct cmsghdr *cmsg,
uint8_t **cm_data,
size_t *cm_data_space);
-static int swrap_sendmsg_filter_cmsg_socket(struct cmsghdr *cmsg,
+static int swrap_sendmsg_filter_cmsg_socket(const struct cmsghdr *cmsg,
uint8_t **cm_data,
size_t *cm_data_space);
-static int swrap_sendmsg_filter_cmsghdr(struct msghdr *msg,
+static int swrap_sendmsg_filter_cmsghdr(const struct msghdr *_msg,
uint8_t **cm_data,
- size_t *cm_data_space) {
+ size_t *cm_data_space)
+{
+ struct msghdr *msg = discard_const_p(struct msghdr, _msg);
struct cmsghdr *cmsg;
int rc = -1;
@@ -5029,7 +5031,7 @@ static int swrap_sendmsg_filter_cmsghdr(struct msghdr *msg,
return rc;
}
-static int swrap_sendmsg_copy_cmsg(struct cmsghdr *cmsg,
+static int swrap_sendmsg_copy_cmsg(const struct cmsghdr *cmsg,
uint8_t **cm_data,
size_t *cm_data_space)
{
@@ -5052,12 +5054,12 @@ static int swrap_sendmsg_copy_cmsg(struct cmsghdr *cmsg,
return 0;
}
-static int swrap_sendmsg_filter_cmsg_pktinfo(struct cmsghdr *cmsg,
+static int swrap_sendmsg_filter_cmsg_pktinfo(const struct cmsghdr *cmsg,
uint8_t **cm_data,
size_t *cm_data_space);
-static int swrap_sendmsg_filter_cmsg_socket(struct cmsghdr *cmsg,
+static int swrap_sendmsg_filter_cmsg_socket(const struct cmsghdr *cmsg,
uint8_t **cm_data,
size_t *cm_data_space)
{
@@ -5085,7 +5087,7 @@ static int swrap_sendmsg_filter_cmsg_socket(struct cmsghdr *cmsg,
return rc;
}
-static int swrap_sendmsg_filter_cmsg_pktinfo(struct cmsghdr *cmsg,
+static int swrap_sendmsg_filter_cmsg_pktinfo(const struct cmsghdr *cmsg,
uint8_t **cm_data,
size_t *cm_data_space)
{
@@ -5247,28 +5249,6 @@ static ssize_t swrap_sendmsg_before(int fd,
goto out;
}
-#ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
- if (msg->msg_controllen > 0 && msg->msg_control != NULL) {
- uint8_t *cmbuf = NULL;
- size_t cmlen = 0;
-
- ret = swrap_sendmsg_filter_cmsghdr(msg, &cmbuf, &cmlen);
- if (ret < 0) {
- free(cmbuf);
- goto out;
- }
-
- if (cmlen == 0) {
- msg->msg_controllen = 0;
- msg->msg_control = NULL;
- } else if (cmlen < msg->msg_controllen && cmbuf != NULL) {
- memcpy(msg->msg_control, cmbuf, cmlen);
- msg->msg_controllen = cmlen;
- }
- free(cmbuf);
- }
-#endif
-
ret = 0;
out:
SWRAP_UNLOCK_SI(si);
@@ -6180,20 +6160,32 @@ static ssize_t swrap_sendmsg(int s, const struct msghdr *omsg, int flags)
SWRAP_UNLOCK_SI(si);
#ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
- if (msg.msg_controllen > 0 && msg.msg_control != NULL) {
- /* omsg is a const so use a local buffer for modifications */
- uint8_t cmbuf[omsg->msg_controllen];
+ if (omsg != NULL && omsg->msg_controllen > 0 && omsg->msg_control != NULL) {
+ uint8_t *cmbuf = NULL;
+ size_t cmlen = 0;
- memcpy(cmbuf, omsg->msg_control, omsg->msg_controllen);
+ rc = swrap_sendmsg_filter_cmsghdr(omsg, &cmbuf, &cmlen);
+ if (rc < 0) {
+ return rc;
+ }
- msg.msg_control = cmbuf; /* ancillary data, see below */
- msg.msg_controllen = omsg->msg_controllen; /* ancillary data buffer len */
+ if (cmlen == 0) {
+ msg.msg_controllen = 0;
+ msg.msg_control = NULL;
+ } else {
+ msg.msg_control = cmbuf;
+ msg.msg_controllen = cmlen;
+ }
}
msg.msg_flags = omsg->msg_flags; /* flags on received message */
#endif
-
rc = swrap_sendmsg_before(s, si, &msg, &tmp, &un_addr, &to_un, &to, &bcast);
if (rc < 0) {
+ int saved_errno = errno;
+#ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
+ SAFE_FREE(msg.msg_control);
+#endif
+ errno = saved_errno;
return -1;
}
@@ -6219,6 +6211,11 @@ static ssize_t swrap_sendmsg(int s, const struct msghdr *omsg, int flags)
/* we capture it as one single packet */
buf = (uint8_t *)malloc(remain);
if (!buf) {
+ int saved_errno = errno;
+#ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
+ SAFE_FREE(msg.msg_control);
+#endif
+ errno = saved_errno;
return -1;
}
@@ -6235,7 +6232,12 @@ static ssize_t swrap_sendmsg(int s, const struct msghdr *omsg, int flags)
swrap_dir = socket_wrapper_dir();
if (swrap_dir == NULL) {
- free(buf);
+ int saved_errno = errno;
+#ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
+ SAFE_FREE(msg.msg_control);
+#endif
+ SAFE_FREE(buf);
+ errno = saved_errno;
return -1;
}
@@ -6266,6 +6268,14 @@ static ssize_t swrap_sendmsg(int s, const struct msghdr *omsg, int flags)
swrap_sendmsg_after(s, si, &msg, to, ret);
+#ifdef HAVE_STRUCT_MSGHDR_MSG_CONTROL
+ {
+ int saved_errno = errno;
+ SAFE_FREE(msg.msg_control);
+ errno = saved_errno;
+ }
+#endif
+
return ret;
}