From 80286cdeb584d35b666535ddbf9c31ee3e942cc1 Mon Sep 17 00:00:00 2001 From: Gerhard Rieger Date: Sat, 9 Jan 2010 10:10:48 +0100 Subject: [PATCH] user-late and group-late, when applied to a pty, affected the system device /dev/ptmx --- CHANGES | 5 +++++ VERSION | 2 +- test.sh | 66 ++++++++++++++++++++++++++++++++++++++++++++++++++++++- xio-pty.c | 28 ++++++++++++++++++++++- xioopts.h | 48 ++++++++++++++++++++++++++++++++++++++++ 5 files changed, 146 insertions(+), 3 deletions(-) diff --git a/CHANGES b/CHANGES index 8ce1617..3a40e84 100644 --- a/CHANGES +++ b/CHANGES @@ -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: diff --git a/VERSION b/VERSION index 4026ae1..7f4ccf8 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -"1.7.1.1" +"1.7.1.1-userlate" diff --git a/test.sh b/test.sh index 6233520..eee8233 100755 --- a/test.sh +++ b/test.sh @@ -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 diff --git a/xio-pty.c b/xio-pty.c index 1f7d7d3..c478d7c 100644 --- a/xio-pty.c +++ b/xio-pty.c @@ -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; diff --git a/xioopts.h b/xioopts.h index 25b3bcf..ab1b4d7 100644 --- a/xioopts.h +++ b/xioopts.h @@ -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) */