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

This commit is contained in:
Gerhard Rieger 2012-07-21 20:53:23 +02:00
parent 529b9ece6b
commit 2040d8300c
4 changed files with 149 additions and 3 deletions

View file

@ -1,5 +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)
corrected the "fixed possible SIGSEGV" fix because SIGSEGV still might
occur under those conditions. Thanks to Toni Mattila for first
reporting this problem.

68
test.sh
View file

@ -10747,6 +10747,74 @@ N=$((N+1))
fi # false
###############################################################################
# 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=$!
waitfile $tl
(echo "$da"; usleep $MICROS; echo -e "\x1a") |$CMD1 >"${tf}1" 2>"${te}1" >"$tf"
rc1=$?
usleep $((2*MICROS))
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

@ -1,5 +1,5 @@
/* source: xio-pty.c */
/* Copyright Gerhard Rieger 2002-2009 */
/* Copyright Gerhard Rieger 2002-2012 */
/* Published under the GNU General Public License V.2, see file COPYING */
/* this file contains the source for creating pty addresses */
@ -183,6 +183,32 @@ static int xioopen_pty(const char *linkname, struct opt *opts, int xioflags, xio
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));
}
}
}
if (XIOWITHRD(rw)) xfd->stream.rfd = ptyfd;
if (XIOWITHWR(rw)) xfd->stream.wfd = ptyfd;
applyopts(ptyfd, opts, PH_LATE);

View file

@ -1,5 +1,5 @@
/* source: xioopts.h */
/* Copyright Gerhard Rieger 2001-2009 */
/* Copyright Gerhard Rieger 2001-2012 */
/* Published under the GNU General Public License V.2, see file COPYING */
#ifndef __xioopts_h_included
@ -944,4 +944,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) */