Substituted ISPEED_OFFSET mechanism for cfsetispeed() calls

This commit is contained in:
Gerhard Rieger 2019-03-03 10:12:44 +01:00
parent 1301cacad3
commit ea42d022c6
9 changed files with 112 additions and 84 deletions

View file

@ -41,6 +41,8 @@ corrections:
Termios options TAB0,TAB1,TAB2,TAB3, and XTABS did not have an effect.
Thanks to Alan Walters for reporting this bug.
Substituted cumbersom ISPEED_OFFSET mechanism for cfsetispeed() calls
testing:
test.sh: Show a warning when phase-1 (insecure phase) of a security
test fails

View file

@ -1 +1 @@
"1.7.3.2"
"1.7.3.2+termios"

View file

@ -350,6 +350,35 @@ typedef int sig_atomic_t;
# endif
#endif
#if _WITH_TERMIOS
#if !defined(HAVE_BASIC_SPEED_T) || !HAVE_BASIC_SPEED_T
# undef HAVE_BASIC_SPEED_T
# define HAVE_BASIC_SPEED_T 4
#endif
#ifndef F_speed
# if HAVE_BASIC_SPEED_T==1
#define F_speed "%hd"
# elif HAVE_BASIC_SPEED_T==2
#define F_speed "%hu"
# elif HAVE_BASIC_SPEED_T==3
#define F_speed "%""d"
# elif HAVE_BASIC_SPEED_T==4
#define F_speed "%u"
# elif HAVE_BASIC_SPEED_T==5
#define F_speed "%ld"
# elif HAVE_BASIC_SPEED_T==6
#define F_speed "%lu"
# elif HAVE_BASIC_SPEED_T==7
#define F_speed "%Ld"
# elif HAVE_BASIC_SPEED_T==8
#define F_speed "%Lu"
# else
#error "HAVE_BASIC_SPEED_T is out of range:" HAVE_BASIC_SPEED_T
# endif
#endif
#endif /* _WITH_TERMIOS */
/* all unsigned; default; unsigned long */
#if !defined(HAVE_TYPEOF_ST_INO) || !HAVE_TYPEOF_ST_INO
# undef HAVE_TYPEOF_ST_INO

View file

@ -321,6 +321,10 @@
/* fdset may have component fds_bits or __fds_bits */
#undef HAVE_FDS_BITS
/* struct termios may have components c_ispeed,c_ospeed */
#undef HAVE_STRUCT_TERMIOS_C_ISPEED
#undef HAVE_STRUCT_TERMIOS_C_OSPEED
/* Define if you have the sa_family_t */
#undef HAVE_TYPE_SA_FAMILY_T
@ -330,20 +334,6 @@
/* define if you have struct sock_extended_err */
#undef HAVE_STRUCT_SOCK_EXTENDED_ERR
/* Define if your struct termios has component c_ispeed */
#undef HAVE_TERMIOS_ISPEED
/* the offset of c_ispeed in struct termios - usable in an speed_t array.
Applies only when HAVE_TERMIOS_ISPEED is set */
#undef ISPEED_OFFSET
/* the offset of c_ospeed in struct termios - see ISPEED_OFFSET */
#ifdef ISPEED_OFFSET
# define OSPEED_OFFSET (ISPEED_OFFSET+1)
#else
# undef OSPEED_OFFSET
#endif
/* Define if your termios.h likes _SVID3 defined */
#undef _SVID3
@ -422,6 +412,20 @@
/* Define if you have the unsetenv function. not on HP-UX */
#undef HAVE_UNSETENV
/* Define if you have the cfsetispeed,cfgetispeed,cfsetspeed,cfgetospeed function */
#undef HAVE_CFSETISPEED
#undef HAVE_CFSETOSPEED
#if HAVE_CFSETISPEED
# define HAVE_TERMIOS_ISPEED 1
#endif
#if HAVE_CFSETOSPEED
# define HAVE_TERMIOS_OSPEED 1
#endif
#if defined(HAVE_TERMIOS_ISPEED) && defined(HAVE_TERMIOS_OSPEED)
# define HAVE_TERMIOS_SPEED 1
#endif
/* Define if you have the SSLv2 client and server method functions. not in new openssl */
#undef HAVE_SSLv2_client_method
#undef HAVE_SSLv2_server_method
@ -558,6 +562,7 @@
#undef HAVE_BASIC_OFF_T
#undef HAVE_BASIC_OFF64_T
#undef HAVE_BASIC_DEV_T
#undef HAVE_BASIC_SPEED_T
#undef HAVE_BASIC_SOCKLEN_T

View file

@ -749,6 +749,9 @@ AC_CHECK_FUNCS(grantpt unlockpt)
# GR AC_CHECK_FUNCS only checks linking, not prototype. This may lead to implicit
# function declarations and to SIGSEGV on systems with 32bit int and 64bit pointer
dnl Search for cfsetispeed(),cfgetispeed(),cfsetspeed(),cfgetospeed() functions
AC_CHECK_FUNCS(cfsetispeed cfgetispeed cfsetospeed cfgetospeed)
###################################
# check for prototype and existence of functions that return a pointer
# defines in config.h: HAVE_PROTOTYPE_LIB_$1
@ -915,7 +918,6 @@ AC_MSG_RESULT($sc_cv_type_uint64)
### fds_bits
AC_MSG_CHECKING(for fdset->fds_bits)
AC_TRY_COMPILE([#include <sys/types.h>
#if HAVE_SYS_SELECT_H
@ -925,6 +927,24 @@ AC_TRY_COMPILE([#include <sys/types.h>
[AC_MSG_RESULT(yes); AC_DEFINE(HAVE_FDS_BITS)],
[AC_MSG_RESULT(no);])
AC_MSG_CHECKING(for struct termios . c_ispeed)
AC_TRY_COMPILE([#include <unistd.h>
#if HAVE_TERMIOS_H
#include <termios.h>
#endif],
[struct termios s; s.c_ispeed=0;],
[AC_MSG_RESULT(yes); AC_DEFINE(HAVE_STRUCT_TERMIOS_C_ISPEED)],
[AC_MSG_RESULT(no);])
AC_MSG_CHECKING(for struct termios . c_ospeed)
AC_TRY_COMPILE([#include <unistd.h>
#if HAVE_TERMIOS_H
#include <termios.h>
#endif],
[struct termios s; s.c_ospeed=0;],
[AC_MSG_RESULT(yes); AC_DEFINE(HAVE_STRUCT_TERMIOS_C_OSPEED)],
[AC_MSG_RESULT(no);])
AC_MSG_CHECKING(for sa_family_t)
AC_CACHE_VAL(sc_cv_type_sa_family_t,
[AC_TRY_COMPILE([#include <sys/types.h>
@ -963,50 +983,6 @@ if test $sc_cv_struct_sigaction_sa_sigaction = yes; then
fi
AC_MSG_RESULT($sc_cv_struct_sigaction_sa_sigaction)
### struct termios .c_ispeed
AC_MSG_CHECKING(for termios.c_ispeed)
AC_CACHE_VAL(sc_cv_termios_ispeed,
[AC_TRY_COMPILE([#include <termios.h>],
[struct termios t; t.c_ispeed=0;],
[sc_cv_termios_ispeed=yes],
[sc_cv_termios_ispeed=no])])
if test $sc_cv_termios_ispeed = yes; then
AC_DEFINE(HAVE_TERMIOS_ISPEED)
fi
AC_MSG_RESULT($sc_cv_termios_ispeed)
if test $sc_cv_termios_ispeed = yes; then
AC_MSG_CHECKING(for offset of c_ispeed in struct termios)
LIBS1="$LIBS"; LIBS="" # avoid libwrap allow_severity undefined
AC_CACHE_VAL(ac_cv_ispeed_offset,
[conftestspeedoff="conftestspeedoff.out"
AC_TRY_RUN([
#include <errno.h>
#include <stdlib.h>
#include <stdio.h>
#include <termios.h>
#include <string.h>
int main(){
struct termios t;
FILE *f;
if ((f=fopen("$conftestspeedoff","w"))==NULL){
fprintf(stderr,"\\"$conftestspeedoff\\": %s\n",strerror(errno)); exit(-1);
}
fprintf(f, "%d", ((char*)&t.c_ispeed-(char*)&t)/sizeof(speed_t));
exit(0);
}
],
[ac_cv_ispeed_offset=`cat $conftestspeedoff`],
[ac_cv_ispeed_offset=-1],
[ac_cv_ispeed_offset="((unsigned long)&((struct termios *)0)->c_ispeed / sizeof(speed_t))"]
)])
LIBS="$LIBS1"
AC_MSG_RESULT($ac_cv_ispeed_offset)
if test "$ac_cv_ispeed_offset" != -1; then
AC_DEFINE_UNQUOTED(ISPEED_OFFSET, $ac_cv_ispeed_offset)
fi
fi
# there is another issue with termios: OSR requires "#define _SVID3 ..."
# for reasonable termios support. We check this situation using IMAXBEL
AC_MSG_CHECKING(if _SVID3 is helpful)
@ -1817,6 +1793,9 @@ AC_BASIC_TYPE([#include <sys/types.h>
# oh god, __dev_t in Linux 2.4 is struct{int[2];}, not handled here yet.
AC_BASIC_TYPE([#include <sys/stat.h>], dev_t, HAVE_BASIC_DEV_T, sc_cv_type_dev_basic)
AC_BASIC_TYPE([#include <unistd.h>
#include <termios.h>], speed_t, HAVE_BASIC_SPEED_T, sc_cv_type_spee_t)
AC_TYPEOF_COMPONENT([#include <sys/stat.h>], struct stat, st_ino, HAVE_TYPEOF_ST_INO, sc_cv_type_stat_stino_basic)
AC_TYPEOF_COMPONENT([#include <sys/stat.h>], struct stat, st_nlink, HAVE_TYPEOF_ST_NLINK, sc_cv_type_stat_stnlink_basic)
AC_TYPEOF_COMPONENT([#include <sys/stat.h>], struct stat, st_size, HAVE_TYPEOF_ST_SIZE, sc_cv_type_stat_stsize_basic)

17
sycls.c
View file

@ -1472,10 +1472,18 @@ int Tcgetattr(int fd, struct termios *termios_p) {
cp += sprintf(cp, "%02x,", termios_p->c_cc[i]);
}
sprintf(cp, "%02x", termios_p->c_cc[i]);
#if HAVE_STRUCT_TERMIOS_C_ISPEED && HAVE_STRUCT_TERMIOS_C_OSPEED
Debug8("tcgetattr(, {%08x,%08x,%08x,%08x, "F_speed","F_speed", %s}) -> %d",
termios_p->c_iflag, termios_p->c_oflag,
termios_p->c_cflag, termios_p->c_lflag,
termios_p->c_ispeed, termios_p->c_ospeed,
chars, result);
#else
Debug6("tcgetattr(, {%08x,%08x,%08x,%08x,%s}) -> %d",
termios_p->c_iflag, termios_p->c_oflag,
termios_p->c_cflag, termios_p->c_lflag,
chars, result);
#endif
errno = _errno;
return result;
}
@ -1490,9 +1498,18 @@ int Tcsetattr(int fd, int optional_actions, struct termios *termios_p) {
cp += sprintf(cp, "%02x,", termios_p->c_cc[i]);
}
sprintf(cp, "%02x", termios_p->c_cc[i]);
#if HAVE_STRUCT_TERMIOS_C_ISPEED && HAVE_STRUCT_TERMIOS_C_OSPEED
Debug9("tcsetattr(%d, %d, {%08x,%08x,%08x,%08x, "F_speed","F_speed", %s})",
fd, optional_actions,
termios_p->c_iflag, termios_p->c_oflag,
termios_p->c_cflag, termios_p->c_lflag,
termios_p->c_ispeed, termios_p->c_ospeed,
chars);
#else
Debug7("tcsetattr(%d, %d, {%08x,%08x,%08x,%08x,%s})", fd, optional_actions,
termios_p->c_iflag, termios_p->c_oflag,
termios_p->c_cflag, termios_p->c_lflag, chars);
#endif
result = tcsetattr(fd, optional_actions, termios_p);
_errno = errno;
Debug1("tcsetattr() -> %d", result);

View file

@ -272,14 +272,12 @@ const struct optdesc opt_sane = { "sane", NULL, OPT_SANE, GROUP_TER
const struct optdesc opt_termios_cfmakeraw = { "termios-cfmakeraw", "cfmakeraw", OPT_TERMIOS_CFMAKERAW, GROUP_TERMIOS, PH_FD, TYPE_CONST, OFUNC_TERMIOS_SPEC };
const struct optdesc opt_termios_rawer = { "termios-rawer", "rawer", OPT_TERMIOS_RAWER, GROUP_TERMIOS, PH_FD, TYPE_CONST, OFUNC_TERMIOS_SPEC };
#ifdef HAVE_TERMIOS_ISPEED
#if defined(ISPEED_OFFSET) && (ISPEED_OFFSET != -1)
#if defined(OSPEED_OFFSET) && (OSPEED_OFFSET != -1)
const struct optdesc opt_ispeed = { "ispeed", NULL, OPT_ISPEED, GROUP_TERMIOS, PH_FD, TYPE_UINT, OFUNC_TERMIOS_SPEED, ISPEED_OFFSET };
const struct optdesc opt_ospeed = { "ospeed", NULL, OPT_OSPEED, GROUP_TERMIOS, PH_FD, TYPE_UINT, OFUNC_TERMIOS_SPEED, OSPEED_OFFSET };
#if HAVE_TERMIOS_ISPEED
const struct optdesc opt_ispeed = { "ispeed", NULL, OPT_ISPEED, GROUP_TERMIOS, PH_FD, TYPE_UINT, OFUNC_TERMIOS_SPEED, 0/*in*/ };
#endif
#if HAVE_TERMIOS_OSPEED
const struct optdesc opt_ospeed = { "ospeed", NULL, OPT_OSPEED, GROUP_TERMIOS, PH_FD, TYPE_UINT, OFUNC_TERMIOS_SPEED, 1/*out*/ };
#endif
#endif /* HAVE_TERMIOS_ISPEED */
int xiotermiosflag_applyopt(int fd, struct opt *opt) {
@ -302,9 +300,6 @@ bool _xiotermios_doit = false; /* _data has been retrieved and manipulated, set
union {
struct termios termarg;
tcflag_t flags[4];
#ifdef HAVE_TERMIOS_ISPEED
speed_t speeds[sizeof(struct termios)/sizeof(speed_t)];
#endif
} _xiotermios_data;
int xiotermios_setflag(int fd, int word, tcflag_t mask) {
@ -360,8 +355,8 @@ int xiotermios_char(int fd, int n, unsigned char c) {
return 0;
}
#ifdef HAVE_TERMIOS_ISPEED
int xiotermios_speed(int fd, int n, unsigned int speed) {
#if HAVE_TERMIOS_ISPEED || HAVE_TERMIOS_OSPEED
int xiotermios_speed(int fd, int n, speed_t speed) {
if (!_xiotermios_doit) {
if (Tcgetattr(fd, &_xiotermios_data.termarg) < 0) {
Error3("tcgetattr(%d, %p): %s",
@ -370,7 +365,18 @@ int xiotermios_speed(int fd, int n, unsigned int speed) {
}
_xiotermios_doit = true;
}
_xiotermios_data.speeds[n] = speed;
if (n == 0) {
if (cfsetispeed(&_xiotermios_data.termarg, speed) < 0) {
Error3("cfsetispeed(%p, "F_speed"): %s",
&_xiotermios_data.termarg, speed, strerror(errno));
}
} else {
if (cfsetospeed(&_xiotermios_data.termarg, speed) < 0) {
Error3("cfsetospeed(%p, "F_speed"): %s",
&_xiotermios_data.termarg, speed, strerror(errno));
}
}
// Tcgetattr(fd, &_xiotermios_data.termarg);
return 0;
}
#endif /* HAVE_TERMIOS_ISPEED */

View file

@ -62,16 +62,6 @@ int xioinitialize(void) {
assert(tdata.termarg.c_oflag == tdata.flags[1]);
assert(tdata.termarg.c_cflag == tdata.flags[2]);
assert(tdata.termarg.c_lflag == tdata.flags[3]);
#if HAVE_TERMIOS_ISPEED && (ISPEED_OFFSET != -1) && (OSPEED_OFFSET != -1)
#if defined(ISPEED_OFFSET) && (ISPEED_OFFSET != -1)
#if defined(OSPEED_OFFSET) && (OSPEED_OFFSET != -1)
tdata.termarg.c_ispeed = 0x56789abc;
tdata.termarg.c_ospeed = 0x6789abcd;
assert(tdata.termarg.c_ispeed == tdata.speeds[ISPEED_OFFSET]);
assert(tdata.termarg.c_ospeed == tdata.speeds[OSPEED_OFFSET]);
#endif
#endif
#endif
}
#endif

View file

@ -790,7 +790,7 @@ const struct optname optionnames[] = {
IF_IP6 ("ipv6only", &opt_ipv6_v6only)
#endif
IF_TERMIOS("isig", &opt_isig)
#if defined(HAVE_TERMIOS_ISPEED) && defined(ISPEED_OFFSET) && (ISPEED_OFFSET != -1)
#if HAVE_TERMIOS_ISPEED
IF_TERMIOS("ispeed", &opt_ispeed)
#endif
IF_TERMIOS("istrip", &opt_istrip)
@ -1113,7 +1113,7 @@ const struct optname optionnames[] = {
IF_OPENSSL("openssl-pseudo", &opt_openssl_pseudo)
IF_OPENSSL("openssl-verify", &opt_openssl_verify)
IF_TERMIOS("opost", &opt_opost)
#if defined(HAVE_TERMIOS_ISPEED) && defined(OSPEED_OFFSET) && (OSPEED_OFFSET != -1)
#if HAVE_TERMIOS_OSPEED
IF_TERMIOS("ospeed", &opt_ospeed)
#endif
IF_ANY ("owner", &opt_user)