[10847] in bugtraq
Testing for bugs at configure time
daemon@ATHENA.MIT.EDU (Duncan Simpson)
Thu Jun 17 11:39:53 1999
Mime-Version: 1.0
Content-Type: multipart/mixed ; boundary="==_Exmh_3068928820"
Message-Id: <199906171323.OAA02893@io.stargate.co.uk>
Date: Thu, 17 Jun 1999 14:23:47 +0100
Reply-To: Duncan Simpson <dps@IO.STARGATE.CO.UK>
From: Duncan Simpson <dps@IO.STARGATE.CO.UK>
To: BUGTRAQ@NETSPACE.ORG
This is a multipart MIME message.
--==_Exmh_3068928820
Content-Type: text/plain; charset=us-ascii
Various people have expressed concern about old systems emulating secure
function but no providing the security, for example simulations of snprintf
that ignore n (and therefore could introduce buffer overrun potential). I have
written GNU autoconf test macros to determine this and the presence or absence
of other bugs, for example the bugs that allow symlink to .rhosts potential
(not sure how to defeat this particular bug outside the kernel if O_EXCL does
not work).
In particular I have included a test for RLIMIT_PROC not actually having any
effect.
If vendors do such versions of snprintf then use the SIO stdio replacement
functions for inetd instead. Stealing these checks is of course encouraged :-)
--==_Exmh_3068928820
Content-Type: text/plain ; name="acl.m4"; charset=us-ascii
Content-Description: acl.m4
Content-Disposition: attachment; filename="acl.m4"
dnl Check snprintf for overrun potential
AC_DEFUN(dps_snprintf_oflow,
[AC_MSG_CHECKING(whether snprintf ignores n)
AC_CACHE_VAL(dps_cv_snprintf_bug,
[AC_TRY_RUN(
changequote(<<, >>)dnl
<<#include <stdio.h>
#ifndef HAVE_SNPRINTF
#ifdef HAVE_VSNPRINTF
#include "vsnprintf.h"
#else /* not HAVE_VSNPRINTF */
#include "vsnprintf.c"
#endif /* HAVE_VSNPRINTF */
#endif /* HAVE_SNPRINTF */
int main(void)
{
char ovbuf[7];
int i;
for (i=0; i<7; i++) ovbuf[i]='x';
snprintf(ovbuf, 4,"foo%s", "bar");
if (ovbuf[5]!='x') exit(1);
snprintf(ovbuf, 4,"foo%d", 666);
if (ovbuf[5]!='x') exit(1);
exit(0);
} >>
changequote([, ]), dps_cv_snprintf_bug=0, dps_cv_snprintf_bug=1,
dps_cv_snprintf_bug=2)])
if test $dps_cv_snprintf_bug -eq 0; then
AC_MSG_RESULT([no, snprintf is ok])
else if test $dps_cv_snprint_bug -eq 1; then
AC_MSG_RESULT([yes, snprintf is broken])
AC_DEFINE(HAVE_SNPRINTF_BUG,1)
else
AC_MSG_RESULT([unknown, assuming yes])
AC_DEFINE(HAVE_SNPRINTF_BUG,1)
fi; fi])
dnl Check vsnprintf for overrun potential
AC_DEFUN(dps_vsnprintf_oflow,
[AC_MSG_CHECKING(whether vsnprintf ignores n)
AC_CACHE_VAL(dps_cv_vsnprintf_bug,
[AC_TRY_RUN(
changequote(<<, >>)dnl
<<#include <stdio.h>
#include <stdarg.h>
#ifndef HAVE_VSNPRINTF
#include "vsnprintf.c"
#endif /* HAVE_VSNPRINTF */
int prnt(char *s, const char *fmt, ...)
{
va_list argp;
va_start(argp, fmt);
vsnprintf(s, 4, fmt, argp);
va_end(argp);
}
int main(void)
{
char ovbuf[7];
int i;
for (i=0; i<7; i++) ovbuf[i]='x';
prnt(ovbuf, "foo%s", "bar");
if (ovbuf[5]!='x') exit(1);
prnt(ovbuf, "foo%d", 666);
if (ovbuf[5]!='x') exit(1);
exit(0);
} >>
changequote([, ]), dps_cv_vsnprintf_bug=0, dps_cv_vsnprintf_bug=1,
dps_cv_vsnprintf_bug=2)])
if test $dps_cv_vsnprintf_bug -eq 0; then
AC_MSG_RESULT([no, vsnprintf is ok])
else if test $dps_cv_vsnprint_bug -eq 1; then
AC_MSG_RESULT([yes, vsnprintf is broken])
AC_DEFINE(HAVE_VSNPRINTF_BUG,1)
else
AC_MSG_RESULT([unknown, assuming yes])
AC_DEFINE(HAVE_VSNPRINTF_BUG,1)
fi; fi])
dnl open and symlink interaction bug test
AC_DEFUN(dps_symlink_open_bug,
[AC_MSG_CHECKING(security of interaction between symlink and open)
AC_CACHE_VAL(dps_cv_symlink_open_bug,
[mkdir conftest.d
AC_TRY_RUN(
changequote(<<, >>)dnl
<<#include <stdio.h>
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif
#ifdef HAVE_SYS_TYPES_H
#include <sys/types.h>
#endif
#ifdef HAVE_SYS_STAT_H
#include <sys/stat.h>
#endif
#ifdef HAVE_FCNTL_H
#include <fcntl.h>
#endif
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#ifdef HAVE_ERRNO_H
#include <errno.h>
#else
extern int errno;
#endif
int main(void)
{
int fd;
if (chdir("conftest.d")!=0)
exit(1);
if (symlink("foo","bar")!=0)
exit(1);
if ((fd=open("bar", O_CREAT | O_EXCL | O_WRONLY, 0700))==0)
{
write(fd, "If the symlink was to .rhosts you would be unhappy", 50);
close(fd);
exit(1);
}
if (errno!=EEXIST)
exit(1);
exit(0);
} >>
changequote([, ]), cps_cv_symlink_open_bug=0,
[if test -r conftest.d/foo; then
cps_cv_symlink_open_bug=2
else
cps_cv_symlink_open_bug=1
fi], cps_cv_symlink_open_buf=3)
rm -rf conftest.d])
case "$cps_cv_symlink_open_bug" in
0) AC_MSG_RESULT(secure) ;;
1) AC_MSG_RESULT(errno wrong but ok)
AC_DEFINE(HAVE_SYMLINK_OPEN_ERRNO_BUG) ;;
2) AC_MSG_RESULT(insecure)
AC_DEFINE(HAVE_SYMLINK_OPEN_SECURITY_HOLE)
AC_DEFINE(HAVE_SYMLINK_OPEN_ERRNO_BUG) ;;
3) AC_MSG_RESULT(assuming insecure)
AC_DEFINE(HAVE_SYMLINK_OPEN_SECURITY_HOLE)
AC_DEFINE(HAVE_SYMLINK_OPEN_ERRNO_BUG) ;;
*) AC_MSG_RESULT($cps_cv_symlink_open_bug)
AC_MSG_ERROR(Impossible value of cps_cv_symlink_open_bug) ;;
esac])
dnl Check to RLIMIT_NPROC resource limit
AC_DEFUN(dps_rlimit_nproc,
[AC_MSG_CHECKING(for working RLIMIT_NPROC resource limit)
AC_CACHE_VAL(dps_cv_rlimit_nproc,
[AC_TRY_RUN(
changequote(<<, >>)dnl
<<
#ifndef HAVE_STDLIB_H
#include <stdlib.h>
#endif /* HAVE_STDLIB_H */
#ifndef HAVE_SIGNAL_H
#include <signal.h>
#endif /* HAVE_SIGNAL_H */
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif /* HAVE_UNISTD_H */
#ifdef HAVE_SYS_RESOURCE_H
#include <sys/resource.h>
#endif /* HAVE_SYS_RESOURCE_H */
int main(void)
{
#ifdef RLIMIT_NPROC
static const struct rlimit pid_lim={RLIMIT_NPROC, 1};
pid_t f;
signal(SIGCHLD, SIG_IGN);
setrlimit(RLIMIT_NPROC, (struct rlimit *) &pid_lim);
if ((f=fork())==0)
exit(0);
if (f==-1)
exit(0); /* The fork() failed (the right thing) */
#endif
exit(1);
} >>
changequote([, ]), cps_cv_rlimit_nproc=0, cps_cv_rlimit_nproc=1,
cps_cv_rlimit_nproc=2)])
if test $cps_cv_rlimit_nproc -eq 0; then
AC_MSG_RESULT([yes])
AC_DEFINE(HAVE_RLIMIT_NPROC,1)
else if test $cps_cv_rlimit_nproc -eq 1; then
AC_MSG_RESULT([no])
else
AC_MSG_RESULT([unknown, assuming none])
fi; fi])
dnl Check to RLIMIT_MEMLOCK resource limit
AC_DEFUN(cps_rlimit_memlock,
[AC_MSG_CHECKING(for RLIMIT_MEMLOCK resource limit)
AC_CACHE_VAL(cps_cv_rlimit_memlock,
[AC_TRY_RUN(
changequote(<<, >>)dnl
<<
#ifndef HAVE_STDLIB_H
#include <stdlib.h>
#endif /* HAVE_STDLIB_H */
#ifndef HAVE_SIGNAL_H
#include <signal.h>
#endif /* HAVE_SIGNAL_H */
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif /* HAVE_UNISTD_H */
#ifdef HAVE_SYS_RESOURCE_H
#include <sys/resource.h>
#endif /* HAVE_SYS_RESOURCE_H */
#ifdef HAVE_SYS_MMAN
#include <sys/mman.h>
#endif /* HAVE_SYS_MMAN */
#ifdef HAVE_ERRNO_H
#include <errno.h>
#endif /* HAVE_ERRNO_H */
int main(void)
{
#ifdef RLIMIT_MEMLOCK
static const struct rlimit mlock_lim={RLIMIT_MEMLOCK, 0};
void *memory;
if (setrlimit(RLIMIT_MEMLOCK, (struct rlimit *) &mlock_lim)!=-1)
exit(0);
#endif
exit(1);
} >>
changequote([, ]), cps_cv_rlimit_memlock=0, cps_cv_rlimit_memlock=1,
cps_cv_rlimit_memlock=2)])
if test $cps_cv_rlimit_memlock -eq 0; then
AC_MSG_RESULT([yes])
AC_DEFINE(HAVE_RLIMIT_MEMLOCK,1)
else if test $cps_cv_rlimit_memlock -eq 1; then
AC_MSG_RESULT([no])
else
AC_MSG_RESULT([unknown, assuming none])
fi; fi])
--==_Exmh_3068928820
Content-Type: text/plain; charset=us-ascii
Duncan (-:
"software industry, the: unique industry where selling substandard goods is
legal and you can charge extra for fixing the problems."
--==_Exmh_3068928820--