If msg_control is not present in struct msghdr use msg_accrights instead.
Fixes building on Solaris and probably others. It is possible to expose msg_control on Solaris but this requires a specific set of feature flag defines which can cause other complications.
This commit is contained in:
@@ -824,6 +824,9 @@
|
|||||||
/* Define to 1 if the system has the type `struct in6_addr'. */
|
/* Define to 1 if the system has the type `struct in6_addr'. */
|
||||||
#undef HAVE_STRUCT_IN6_ADDR
|
#undef HAVE_STRUCT_IN6_ADDR
|
||||||
|
|
||||||
|
/* Define to 1 if `msg_control' is a member of `struct msghdr'. */
|
||||||
|
#undef HAVE_STRUCT_MSGHDR_MSG_CONTROL
|
||||||
|
|
||||||
/* Define to 1 if `pr_ttydev' is a member of `struct psinfo'. */
|
/* Define to 1 if `pr_ttydev' is a member of `struct psinfo'. */
|
||||||
#undef HAVE_STRUCT_PSINFO_PR_TTYDEV
|
#undef HAVE_STRUCT_PSINFO_PR_TTYDEV
|
||||||
|
|
||||||
|
13
configure
vendored
13
configure
vendored
@@ -21970,6 +21970,19 @@ then :
|
|||||||
printf "%s\n" "#define HAVE_STRUCT_DIRENT_D_NAMLEN 1" >>confdefs.h
|
printf "%s\n" "#define HAVE_STRUCT_DIRENT_D_NAMLEN 1" >>confdefs.h
|
||||||
|
|
||||||
|
|
||||||
|
fi
|
||||||
|
|
||||||
|
ac_fn_c_check_member "$LINENO" "struct msghdr" "msg_control" "ac_cv_member_struct_msghdr_msg_control" "
|
||||||
|
$ac_includes_default
|
||||||
|
#include <sys/socket.h>
|
||||||
|
|
||||||
|
"
|
||||||
|
if test "x$ac_cv_member_struct_msghdr_msg_control" = xyes
|
||||||
|
then :
|
||||||
|
|
||||||
|
printf "%s\n" "#define HAVE_STRUCT_MSGHDR_MSG_CONTROL 1" >>confdefs.h
|
||||||
|
|
||||||
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
openssl_missing=no
|
openssl_missing=no
|
||||||
|
@@ -2913,6 +2913,13 @@ AC_INCLUDES_DEFAULT
|
|||||||
#include <$ac_header_dirent>
|
#include <$ac_header_dirent>
|
||||||
])
|
])
|
||||||
dnl
|
dnl
|
||||||
|
dnl Check for POSIX sendmsg() ancillary data support.
|
||||||
|
dnl
|
||||||
|
AC_CHECK_MEMBERS(struct msghdr.msg_control, [], [], [
|
||||||
|
AC_INCLUDES_DEFAULT
|
||||||
|
#include <sys/socket.h>
|
||||||
|
])
|
||||||
|
dnl
|
||||||
dnl Check for functions only present in OpenSSL 1.1 and above
|
dnl Check for functions only present in OpenSSL 1.1 and above
|
||||||
dnl
|
dnl
|
||||||
openssl_missing=no
|
openssl_missing=no
|
||||||
|
18
src/exec.c
18
src/exec.c
@@ -978,11 +978,13 @@ intercept_fd_cb(int fd, int what, void *v)
|
|||||||
struct intercept_closure *closure = NULL;
|
struct intercept_closure *closure = NULL;
|
||||||
struct intercept_fd_closure *fdc = v;
|
struct intercept_fd_closure *fdc = v;
|
||||||
struct msghdr msg;
|
struct msghdr msg;
|
||||||
|
#if defined(HAVE_STRUCT_MSGHDR_MSG_CONTROL) && HAVE_STRUCT_MSGHDR_MSG_CONTROL == 1
|
||||||
union {
|
union {
|
||||||
struct cmsghdr hdr;
|
struct cmsghdr hdr;
|
||||||
char buf[CMSG_SPACE(sizeof(int))];
|
char buf[CMSG_SPACE(sizeof(int))];
|
||||||
} cmsgbuf;
|
} cmsgbuf;
|
||||||
struct cmsghdr *cmsg;
|
struct cmsghdr *cmsg;
|
||||||
|
#endif
|
||||||
struct iovec iov[1];
|
struct iovec iov[1];
|
||||||
int newfd = -1;
|
int newfd = -1;
|
||||||
char ch;
|
char ch;
|
||||||
@@ -1003,11 +1005,16 @@ intercept_fd_cb(int fd, int what, void *v)
|
|||||||
iov[0].iov_base = &ch;
|
iov[0].iov_base = &ch;
|
||||||
iov[0].iov_len = 1;
|
iov[0].iov_len = 1;
|
||||||
memset(&msg, 0, sizeof(msg));
|
memset(&msg, 0, sizeof(msg));
|
||||||
memset(&cmsgbuf, 0, sizeof(cmsgbuf));
|
|
||||||
msg.msg_iov = iov;
|
msg.msg_iov = iov;
|
||||||
msg.msg_iovlen = 1;
|
msg.msg_iovlen = 1;
|
||||||
|
#if defined(HAVE_STRUCT_MSGHDR_MSG_CONTROL) && HAVE_STRUCT_MSGHDR_MSG_CONTROL == 1
|
||||||
|
memset(&cmsgbuf, 0, sizeof(cmsgbuf));
|
||||||
msg.msg_control = &cmsgbuf.buf;
|
msg.msg_control = &cmsgbuf.buf;
|
||||||
msg.msg_controllen = sizeof(cmsgbuf.buf);
|
msg.msg_controllen = sizeof(cmsgbuf.buf);
|
||||||
|
#else
|
||||||
|
msg.msg_accrights = (caddr_t)&fd;
|
||||||
|
msg.msg_accrightslen = sizeof(fd);
|
||||||
|
#endif /* HAVE_STRUCT_MSGHDR_MSG_CONTROL */
|
||||||
|
|
||||||
switch (recvmsg(fd, &msg, 0)) {
|
switch (recvmsg(fd, &msg, 0)) {
|
||||||
case -1:
|
case -1:
|
||||||
@@ -1021,6 +1028,7 @@ intercept_fd_cb(int fd, int what, void *v)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(HAVE_STRUCT_MSGHDR_MSG_CONTROL) && HAVE_STRUCT_MSGHDR_MSG_CONTROL == 1
|
||||||
cmsg = CMSG_FIRSTHDR(&msg);
|
cmsg = CMSG_FIRSTHDR(&msg);
|
||||||
if (cmsg == NULL) {
|
if (cmsg == NULL) {
|
||||||
sudo_warnx(U_("%s: missing message header"), __func__);
|
sudo_warnx(U_("%s: missing message header"), __func__);
|
||||||
@@ -1032,8 +1040,14 @@ intercept_fd_cb(int fd, int what, void *v)
|
|||||||
SCM_RIGHTS, cmsg->cmsg_type);
|
SCM_RIGHTS, cmsg->cmsg_type);
|
||||||
goto bad;
|
goto bad;
|
||||||
}
|
}
|
||||||
|
memcpy(&newfd, CMSG_DATA(cmsg), sizeof(newfd));
|
||||||
|
#else
|
||||||
|
if (msg.msg_accrightslen != sizeof(fd)) {
|
||||||
|
sudo_warnx(U_("%s: missing message header"), __func__);
|
||||||
|
goto bad;
|
||||||
|
}
|
||||||
|
#endif /* HAVE_STRUCT_MSGHDR_MSG_CONTROL */
|
||||||
|
|
||||||
newfd = (*(int *)CMSG_DATA(cmsg));
|
|
||||||
if (sudo_ev_set(&closure->ev, newfd, SUDO_EV_READ, intercept_cb, closure) == -1) {
|
if (sudo_ev_set(&closure->ev, newfd, SUDO_EV_READ, intercept_cb, closure) == -1) {
|
||||||
sudo_warn("%s", U_("unable to add event to queue"));
|
sudo_warn("%s", U_("unable to add event to queue"));
|
||||||
goto bad;
|
goto bad;
|
||||||
|
@@ -153,11 +153,13 @@ static bool
|
|||||||
intercept_send_fd(int sock, int fd)
|
intercept_send_fd(int sock, int fd)
|
||||||
{
|
{
|
||||||
struct msghdr msg;
|
struct msghdr msg;
|
||||||
|
#if defined(HAVE_STRUCT_MSGHDR_MSG_CONTROL) && HAVE_STRUCT_MSGHDR_MSG_CONTROL == 1
|
||||||
union {
|
union {
|
||||||
struct cmsghdr hdr;
|
struct cmsghdr hdr;
|
||||||
char buf[CMSG_SPACE(sizeof(int))];
|
char buf[CMSG_SPACE(sizeof(int))];
|
||||||
} cmsgbuf;
|
} cmsgbuf;
|
||||||
struct cmsghdr *cmsg;
|
struct cmsghdr *cmsg;
|
||||||
|
#endif
|
||||||
struct iovec iov[1];
|
struct iovec iov[1];
|
||||||
char ch = '\0';
|
char ch = '\0';
|
||||||
ssize_t nsent;
|
ssize_t nsent;
|
||||||
@@ -171,17 +173,21 @@ intercept_send_fd(int sock, int fd)
|
|||||||
iov[0].iov_base = &ch;
|
iov[0].iov_base = &ch;
|
||||||
iov[0].iov_len = 1;
|
iov[0].iov_len = 1;
|
||||||
memset(&msg, 0, sizeof(msg));
|
memset(&msg, 0, sizeof(msg));
|
||||||
memset(&cmsgbuf, 0, sizeof(cmsgbuf));
|
|
||||||
msg.msg_iov = iov;
|
msg.msg_iov = iov;
|
||||||
msg.msg_iovlen = 1;
|
msg.msg_iovlen = 1;
|
||||||
|
#if defined(HAVE_STRUCT_MSGHDR_MSG_CONTROL) && HAVE_STRUCT_MSGHDR_MSG_CONTROL == 1
|
||||||
|
memset(&cmsgbuf, 0, sizeof(cmsgbuf));
|
||||||
msg.msg_control = &cmsgbuf.buf;
|
msg.msg_control = &cmsgbuf.buf;
|
||||||
msg.msg_controllen = sizeof(cmsgbuf.buf);
|
msg.msg_controllen = sizeof(cmsgbuf.buf);
|
||||||
|
|
||||||
cmsg = CMSG_FIRSTHDR(&msg);
|
cmsg = CMSG_FIRSTHDR(&msg);
|
||||||
cmsg->cmsg_len = CMSG_LEN(sizeof(int));
|
cmsg->cmsg_len = CMSG_LEN(sizeof(int));
|
||||||
cmsg->cmsg_level = SOL_SOCKET;
|
cmsg->cmsg_level = SOL_SOCKET;
|
||||||
cmsg->cmsg_type = SCM_RIGHTS;
|
cmsg->cmsg_type = SCM_RIGHTS;
|
||||||
*(int *)CMSG_DATA(cmsg) = fd;
|
memcpy(CMSG_DATA(cmsg), &fd, sizeof(fd));
|
||||||
|
#else
|
||||||
|
msg.msg_accrights = (caddr_t)&fd;
|
||||||
|
msg.msg_accrightslen = sizeof(fd);
|
||||||
|
#endif /* HAVE_STRUCT_MSGHDR_MSG_CONTROL */
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
nsent = sendmsg(sock, &msg, 0);
|
nsent = sendmsg(sock, &msg, 0);
|
||||||
|
Reference in New Issue
Block a user