mirror of
https://repo.or.cz/socat.git
synced 2024-12-22 15:32:35 +00:00
The async-signal-safe fix used internally FD 3 and FD 4 which could conflict with options fdin,fdout
This commit is contained in:
parent
a3c688210f
commit
9f5abda361
5 changed files with 86 additions and 1 deletions
5
CHANGES
5
CHANGES
|
@ -16,6 +16,11 @@ corrections:
|
|||
compiling with MUSL libc failed.
|
||||
Problem reported by Kennedy33.
|
||||
|
||||
The async signal safe diagnostic system used FDs 3 and 4 internally, so
|
||||
use of appropriate fdin or fdout led to failures.
|
||||
Test: DIAG_FDIN
|
||||
Problem reported by Onur Sentürk.
|
||||
|
||||
testing:
|
||||
test.sh: Show a warning when phase-1 (insecure phase) of a security
|
||||
test fails
|
||||
|
|
13
error.c
13
error.c
|
@ -210,6 +210,19 @@ const char *diag_get_string(char what) {
|
|||
return NULL;
|
||||
}
|
||||
|
||||
/* make sure that the diag_sock fds do not have this num */
|
||||
int diag_reserve_fd(int fd) {
|
||||
DIAG_INIT;
|
||||
if (diag_sock_send == fd) {
|
||||
diag_sock_send = Dup(fd);
|
||||
Close(fd);
|
||||
}
|
||||
if (diag_sock_recv == fd) {
|
||||
diag_sock_recv = Dup(fd);
|
||||
Close(fd);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Linux and AIX syslog format:
|
||||
Oct 4 17:10:37 hostname socat[52798]: D signal(13, 1)
|
||||
|
|
1
error.h
1
error.h
|
@ -236,6 +236,7 @@ extern void diag_set(char what, const char *arg);
|
|||
extern void diag_set_int(char what, int arg);
|
||||
extern int diag_get_int(char what);
|
||||
extern const char *diag_get_string(char what);
|
||||
extern int diag_reserve_fd(int fd);
|
||||
extern int diag_dup(void);
|
||||
extern int diag_dup2(int newfd);
|
||||
extern void msg(int level, const char *format, ...);
|
||||
|
|
42
test.sh
42
test.sh
|
@ -12799,6 +12799,48 @@ esac
|
|||
PORT=$((PORT+1))
|
||||
N=$((N+1))
|
||||
|
||||
|
||||
# The fix to "Make code async-signal-safe" used internally FD 3 and FD 4.
|
||||
# Using option fdin=3 did not pass data to executed program.
|
||||
NAME=DIAG_FDIN
|
||||
case "$TESTS" in
|
||||
*%$N%*|*%functions%*|*%bugs%*|*%exec%*|*%$NAME%*)
|
||||
TEST="$NAME: test use of fdin=3"
|
||||
# Use FD 3 explicitely with fdin and test if Socat passes data to executed
|
||||
# program
|
||||
if ! eval $NUMCOND; then :; else
|
||||
tf="$td/test$N.stdout"
|
||||
te="$td/test$N.stderr"
|
||||
tdiff="$td/test$N.diff"
|
||||
da="test$N $(date) $RANDOM"
|
||||
CMD0="$TRACE $SOCAT $opts - SYSTEM:\"cat >&3 <&4\",fdin=4,fdout=3"
|
||||
printf "test $F_n $TEST... " $N
|
||||
echo "$da" |$TRACE $SOCAT $opts - SYSTEM:"cat <&3 >&4",fdin=3,fdout=4 >${tf}0 2>"${te}0"
|
||||
rc0=$?
|
||||
if [ $rc0 -ne 0 ]; then
|
||||
$PRINTF "$FAILED\n"
|
||||
echo "$CMD0"
|
||||
cat "${te}0"
|
||||
numFAIL=$((numFAIL+1))
|
||||
listFAIL="$listFAIL $N"
|
||||
elif echo "$da" |diff - ${tf}0 >$tdiff; then
|
||||
$PRINTF "$OK\n"
|
||||
numOK=$((numOK+1))
|
||||
else
|
||||
$PRINTF "$FAILED\n"
|
||||
echo "$CMD0"
|
||||
cat "${te}0"
|
||||
cat "$tdiff"
|
||||
numFAIL=$((numFAIL+1))
|
||||
listFAIL="$listFAIL $N"
|
||||
fi
|
||||
fi # NUMCOND
|
||||
;;
|
||||
esac
|
||||
PORT=$((PORT+1))
|
||||
N=$((N+1))
|
||||
|
||||
|
||||
##################################################################################
|
||||
#=================================================================================
|
||||
# here come tests that might affect your systems integrity. Put normal tests
|
||||
|
|
|
@ -168,7 +168,7 @@ int _xioopen_foxec(int xioflags, /* XIO_RDONLY etc. */
|
|||
}
|
||||
#endif
|
||||
|
||||
/* remember: fdin is the fs where the sub program reads from, thus it is
|
||||
/* remember: fdin is the fd where the sub program reads from, thus it is
|
||||
sock0[]'s read fd */
|
||||
/*! problem: when fdi==WRFD(sock[0]) or fdo==RDFD(sock[0]) */
|
||||
if (rw != XIO_WRONLY) {
|
||||
|
@ -177,6 +177,9 @@ int _xioopen_foxec(int xioflags, /* XIO_RDONLY etc. */
|
|||
Warn2("fcntl(%d, F_SETFD, 0): %s", fdo, strerror(errno));
|
||||
}
|
||||
} else {
|
||||
/* make sure that the internal diagnostic socket pair fds do not conflict
|
||||
with our choices */
|
||||
diag_reserve_fd(fdo);
|
||||
if (Dup2(XIO_GETWRFD(sock[0]), fdo) < 0) {
|
||||
Error3("dup2(%d, %d): %s",
|
||||
XIO_GETWRFD(sock[0]), fdo, strerror(errno));
|
||||
|
@ -190,6 +193,9 @@ int _xioopen_foxec(int xioflags, /* XIO_RDONLY etc. */
|
|||
Warn2("fcntl(%d, F_SETFD, 0): %s", fdi, strerror(errno));
|
||||
}
|
||||
} else {
|
||||
/* make sure that the internal diagnostic socket pair fds do not conflict
|
||||
with our choices */
|
||||
diag_reserve_fd(fdi);
|
||||
if (Dup2(XIO_GETRDFD(sock[0]), fdi) < 0) {
|
||||
Error3("dup2(%d, %d): %s)",
|
||||
XIO_GETRDFD(sock[0]), fdi, strerror(errno));
|
||||
|
@ -425,12 +431,18 @@ int _xioopen_foxec(int xioflags, /* XIO_RDONLY etc. */
|
|||
if (usepty) {
|
||||
Close(ptyfd);
|
||||
if (rw != XIO_RDONLY && fdi != ttyfd) {
|
||||
/* make sure that the internal diagnostic socket pair fds do not conflict
|
||||
with our choices */
|
||||
diag_reserve_fd(fdi);
|
||||
if (Dup2(ttyfd, fdi) < 0) {
|
||||
Error3("dup2(%d, %d): %s", ttyfd, fdi, strerror(errno));
|
||||
return -1; }
|
||||
/*0 Info2("dup2(%d, %d)", ttyfd, fdi);*/
|
||||
}
|
||||
if (rw != XIO_WRONLY && fdo != ttyfd) {
|
||||
/* make sure that the internal diagnostic socket pair fds do not conflict
|
||||
with our choices */
|
||||
diag_reserve_fd(fdo);
|
||||
if (Dup2(ttyfd, fdo) < 0) {
|
||||
Error3("dup2(%d, %d): %s", ttyfd, fdo, strerror(errno));
|
||||
return -1; }
|
||||
|
@ -472,6 +484,9 @@ int _xioopen_foxec(int xioflags, /* XIO_RDONLY etc. */
|
|||
}
|
||||
|
||||
if (rw != XIO_WRONLY && rdpip[1] != fdo) {
|
||||
/* make sure that the internal diagnostic socket pair fds do not conflict
|
||||
with our choices */
|
||||
diag_reserve_fd(fdo);
|
||||
if (Dup2(rdpip[1], fdo) < 0) {
|
||||
Error3("dup2(%d, %d): %s", rdpip[1], fdo, strerror(errno));
|
||||
return -1;
|
||||
|
@ -481,6 +496,9 @@ int _xioopen_foxec(int xioflags, /* XIO_RDONLY etc. */
|
|||
/*0 applyopts_cloexec(fdo, *copts);*/
|
||||
}
|
||||
if (rw != XIO_RDONLY && wrpip[0] != fdi) {
|
||||
/* make sure that the internal diagnostic socket pair fds do not conflict
|
||||
with our choices */
|
||||
diag_reserve_fd(fdi);
|
||||
if (Dup2(wrpip[0], fdi) < 0) {
|
||||
Error3("dup2(%d, %d): %s", wrpip[0], fdi, strerror(errno));
|
||||
return -1;
|
||||
|
@ -499,12 +517,18 @@ int _xioopen_foxec(int xioflags, /* XIO_RDONLY etc. */
|
|||
} else { /* socketpair */
|
||||
Close(sv[0]);
|
||||
if (rw != XIO_RDONLY && fdi != sv[1]) {
|
||||
/* make sure that the internal diagnostic socket pair fds do not conflict
|
||||
with our choices */
|
||||
diag_reserve_fd(fdi);
|
||||
if (Dup2(sv[1], fdi) < 0) {
|
||||
Error3("dup2(%d, %d): %s", sv[1], fdi, strerror(errno));
|
||||
return -1; }
|
||||
/*0 Info2("dup2(%d, %d)", sv[1], fdi);*/
|
||||
}
|
||||
if (rw != XIO_WRONLY && fdo != sv[1]) {
|
||||
/* make sure that the internal diagnostic socket pair fds do not conflict
|
||||
with our choices */
|
||||
diag_reserve_fd(fdo);
|
||||
if (Dup2(sv[1], fdo) < 0) {
|
||||
Error3("dup2(%d, %d): %s", sv[1], fdo, strerror(errno));
|
||||
return -1; }
|
||||
|
|
Loading…
Reference in a new issue