user-late and group-late, when applied to a pty, affected the system device /dev/ptmx

This commit is contained in:
Gerhard Rieger 2010-01-09 10:10:48 +01:00
parent 30a3ec3baa
commit 80286cdeb5
5 changed files with 146 additions and 3 deletions

View file

@ -1,4 +1,9 @@
corrections:
user-late and group-late, when applied to a pty, affected the system
device /dev/ptmx instead of the pty (thanks to Matthew Cloke for
pointing me to this bug)
####################### V 1.7.1.1:
corrections:

View file

@ -1 +1 @@
"1.7.1.1"
"1.7.1.1-userlate"

66
test.sh
View file

@ -1,6 +1,6 @@
#! /bin/bash
# source: test.sh
# Copyright Gerhard Rieger 2001-2009
# Copyright Gerhard Rieger 2001-2010
# Published under the GNU General Public License V.2, see file COPYING
# perform lots of tests on socat
@ -10048,6 +10048,70 @@ PORT=$((PORT+1))
N=$((N+1))
# here come tests that might affect your systems integrity. Put normal tests
# before this paragraph.
# tests must be explicitely selected by roottough or name (not number)
NAME=PTYGROUPLATE
case "$TESTS" in
*%roottough%*|*%$NAME%*)
TEST="$NAME: pty with group-late works on pty"
# up to socat 1.7.1.1 address pty changed the ownership of /dev/ptmx instead of
# the pty with options user-late, group-late, or perm-late.
# here we check for correct behaviour.
# ATTENTION: in case of failure of this test the
# group of /dev/ptmx might be changed!
if ! eval $NUMCOND; then :; else
# save current /dev/ptmx properties
F=
for f in /dev/ptmx /dev/ptc; do
if [ -e $f ]; then
F=$(echo "$f" |tr / ..)
ls -l $f >"$td/test$N.$F.ls-l"
break
fi
done
printf "test $F_n $TEST... " $N
if [ -z "$F" ]; then
echo -e "${YELLOW}no /dev/ptmx or /dev/ptc${NORMAL}"
else
GROUP=daemon
tf="$td/test$N.stdout"
te="$td/test$N.stderr"
tl="$td/test$N.pty"
tdiff="$td/test$N.diff"
da="test$N $(date) $RANDOM"
CMD0="$SOCAT $opts pty,link=$tl,group-late=$GROUP,escape=0x1a PIPE"
CMD1="$SOCAT $opts - $tl,raw,echo=0"
$CMD0 >/dev/null 2>"${te}0" &
pid0=$!
(echo "$da"; usleep $MICROS; echo -e "\x1a") |$CMD1 >"${tf}1" 2>"${te}1" >"$tf"
rc1=$?
kill $pid0 2>/dev/null; wait
if [ $rc1 -ne 0 ]; then
$PRINTF "$FAILED\n"
echo "$CMD0 &"
echo "$CMD1"
cat "${te}0"
cat "${te}1"
numFAIL=$((numFAIL+1))
elif echo "$da" |diff - "$tf" >$tdiff; then
$PRINTF "$OK\n"
numOK=$((numOK+1))
else
$PRINTF "$FAILED\n"
cat "$tdiff"
numFAIL=$((numFAIL+1))
fi
if ! ls -l $f |diff "$td/test$N.$F.ls-l" -; then
$PRINTF "${RED}this test changed properties of $f!${NORMAL}\n"
fi
fi # no /dev/ptmx
fi # NUMCOND
;;
esac
N=$((N+1))
echo "summary: $((N-1)) tests; $numOK ok, $numFAIL failed, $numCANT could not be performed"
if [ "$numFAIL" -gt 0 ]; then

View file

@ -165,7 +165,33 @@ static int xioopen_pty(int argc, const char *argv[], struct opt *opts, int xiofl
xfd->stream.dtype = XIODATA_PTY;
applyopts(ptyfd, opts, PH_FD);
{
/* special handling of user-late etc.; with standard behaviour (up to
1.7.1.1) they affected /dev/ptmx instead of /dev/pts/N */
uid_t uid = -1, gid = -1;
mode_t perm;
bool dont;
dont = retropt_uid(opts, OPT_USER_LATE, &uid);
dont &= retropt_gid(opts, OPT_GROUP_LATE, &gid);
if (!dont) {
if (Chown(ptyname, uid, gid) < 0) {
Error4("chown(\"%s\", %d, %d): %s",
ptyname, uid, gid, strerror(errno));
}
}
if (retropt_mode(opts, OPT_PERM_LATE, &perm) == 0) {
if (Chmod(ptyname, perm) < 0) {
Error3("chmod(\"%s\", %03o): %s",
ptyname, perm, strerror(errno));
}
}
}
xfd->stream.fd = ptyfd;
applyopts(ptyfd, opts, PH_LATE);
if (applyopts_single(&xfd->stream, opts, PH_LATE) < 0) return -1;

View file

@ -935,4 +935,52 @@ extern int _groupbits(mode_t mode);
extern int dropopts(struct opt *opts, unsigned int phase);
extern int dropopts2(struct opt *opts, unsigned int from, unsigned int to);
#if HAVE_BASIC_UID_T==1
# define retropt_uid(o,c,r) retropt_short(o,c,r)
#elif HAVE_BASIC_UID_T==2
# define retropt_uid(o,c,r) retropt_ushort(o,c,r)
#elif HAVE_BASIC_UID_T==3
# define retropt_uid(o,c,r) retropt_int(o,c,r)
#elif HAVE_BASIC_UID_T==4
# define retropt_uid(o,c,r) retropt_uint(o,c,r)
#elif HAVE_BASIC_UID_T==5
# define retropt_uid(o,c,r) retropt_long(o,c,r)
#elif HAVE_BASIC_UID_T==6
# define retropt_uid(o,c,r) retropt_ulong(o,c,r)
#else
# error "HAVE_BASIC_UID_T is out of range: " HAVE_BASIC_UID_T
#endif
#if HAVE_BASIC_GID_T==1
# define retropt_gid(o,c,r) retropt_short(o,c,r)
#elif HAVE_BASIC_GID_T==2
# define retropt_gid(o,c,r) retropt_ushort(o,c,r)
#elif HAVE_BASIC_GID_T==3
# define retropt_gid(o,c,r) retropt_int(o,c,r)
#elif HAVE_BASIC_GID_T==4
# define retropt_gid(o,c,r) retropt_uint(o,c,r)
#elif HAVE_BASIC_GID_T==5
# define retropt_gid(o,c,r) retropt_long(o,c,r)
#elif HAVE_BASIC_GID_T==6
# define retropt_gid(o,c,r) retropt_ulong(o,c,r)
#else
# error "HAVE_BASIC_GID_T is out of range: " HAVE_BASIC_GID_T
#endif
#if HAVE_BASIC_MODE_T==1
# define retropt_mode(o,c,r) retropt_short(o,c,r)
#elif HAVE_BASIC_MODE_T==2
# define retropt_mode(o,c,r) retropt_ushort(o,c,r)
#elif HAVE_BASIC_MODE_T==3
# define retropt_mode(o,c,r) retropt_int(o,c,r)
#elif HAVE_BASIC_MODE_T==4
# define retropt_mode(o,c,r) retropt_uint(o,c,r)
#elif HAVE_BASIC_MODE_T==5
# define retropt_mode(o,c,r) retropt_long(o,c,r)
#elif HAVE_BASIC_MODE_T==6
# define retropt_mode(o,c,r) retropt_ulong(o,c,r)
#else
# error "HAVE_BASIC_MODE_T is out of range: " HAVE_BASIC_MODE_T
#endif
#endif /* !defined(__xioopts_h_included) */