diff --git a/Makefile.in b/Makefile.in index 3e48ec12..6cbef2fc 100644 --- a/Makefile.in +++ b/Makefile.in @@ -65,6 +65,7 @@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ ECHO = @ECHO@ EXEEXT = @EXEEXT@ +FLASK_LINUX = @FLASK_LINUX@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LIBTOOL = @LIBTOOL@ LN_S = @LN_S@ diff --git a/autom4te.cache/output.0 b/autom4te.cache/output.0 index 3be1d92a..45e50147 100644 --- a/autom4te.cache/output.0 +++ b/autom4te.cache/output.0 @@ -992,6 +992,7 @@ Optional Features: --enable-FEATURE[=ARG] include FEATURE [ARG=yes] --disable-dependency-tracking Speeds up one-time builds --enable-dependency-tracking Do not reject slow dependency extractors + --enable-flask Enable Security-Enhanced Linux features --enable-shared=PKGS build shared libraries default=yes --enable-static=PKGS build static libraries default=yes --enable-fast-install=PKGS optimize for fast installation default=yes @@ -1704,6 +1705,17 @@ INSTALL_STRIP_PROGRAM="\${SHELL} \$(install_sh) -c -s" # some platforms. + +# Check whether --enable-flask or --disable-flask was given. +if test "${enable_flask+set}" = set; then + enableval="$enable_flask" + +cat >>confdefs.h <<\_ACEOF +@%:@define FLASK_LINUX 1 +_ACEOF + +fi; + ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' @@ -8103,6 +8115,7 @@ s,@AMDEP_TRUE@,$AMDEP_TRUE,;t t s,@AMDEP_FALSE@,$AMDEP_FALSE,;t t s,@AMDEPBACKSLASH@,$AMDEPBACKSLASH,;t t s,@DEPDIR@,$DEPDIR,;t t +s,@FLASK_LINUX@,$FLASK_LINUX,;t t s,@CC@,$CC,;t t s,@CFLAGS@,$CFLAGS,;t t s,@LDFLAGS@,$LDFLAGS,;t t diff --git a/autom4te.cache/traces.0 b/autom4te.cache/traces.0 index 1553fec0..5ffa9315 100644 --- a/autom4te.cache/traces.0 +++ b/autom4te.cache/traces.0 @@ -84,45 +84,49 @@ m4trace:configure.in:6: -1- AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_t m4trace:configure.in:6: -1- AC_SUBST([AMDEP_TRUE]) m4trace:configure.in:6: -1- AC_SUBST([AMDEP_FALSE]) m4trace:configure.in:6: -1- AC_SUBST([DEPDIR]) -m4trace:configure.in:9: -1- AC_PROG_CC -m4trace:configure.in:9: -1- AC_SUBST([CC]) -m4trace:configure.in:9: -1- AC_SUBST([CFLAGS]) -m4trace:configure.in:9: -1- AC_SUBST([LDFLAGS]) -m4trace:configure.in:9: -1- AC_SUBST([CPPFLAGS]) -m4trace:configure.in:9: -1- AC_SUBST([CC]) -m4trace:configure.in:9: -1- AC_SUBST([ac_ct_CC]) -m4trace:configure.in:9: -1- AC_SUBST([CC]) -m4trace:configure.in:9: -1- AC_SUBST([ac_ct_CC]) -m4trace:configure.in:9: -1- AC_SUBST([CC]) -m4trace:configure.in:9: -1- AC_SUBST([CC]) -m4trace:configure.in:9: -1- AC_SUBST([ac_ct_CC]) -m4trace:configure.in:9: -1- AC_SUBST([EXEEXT], [$ac_cv_exeext]) -m4trace:configure.in:9: -1- AC_SUBST([OBJEXT], [$ac_cv_objext]) -m4trace:configure.in:9: -1- AC_SUBST([am__include]) -m4trace:configure.in:9: -1- AC_SUBST([am__quote]) -m4trace:configure.in:9: -1- AC_SUBST([CCDEPMODE]) -m4trace:configure.in:10: -1- AC_PROG_INSTALL -m4trace:configure.in:10: -1- AC_SUBST([INSTALL_PROGRAM]) -m4trace:configure.in:10: -1- AC_SUBST([INSTALL_SCRIPT]) -m4trace:configure.in:10: -1- AC_SUBST([INSTALL_DATA]) -m4trace:configure.in:11: -1- AC_PROG_LN_S -m4trace:configure.in:11: -1- AC_SUBST([LN_S], [$as_ln_s]) -m4trace:configure.in:12: -1- AM_PROG_LIBTOOL -m4trace:configure.in:12: -1- AC_PROG_LIBTOOL -m4trace:configure.in:12: -1- AC_SUBST([build], [$ac_cv_build]) -m4trace:configure.in:12: -1- AC_SUBST([build_cpu], [`echo $ac_cv_build | sed 's/^\([[^-]]*\)-\([[^-]]*\)-\(.*\)$/\1/'`]) -m4trace:configure.in:12: -1- AC_SUBST([build_vendor], [`echo $ac_cv_build | sed 's/^\([[^-]]*\)-\([[^-]]*\)-\(.*\)$/\2/'`]) -m4trace:configure.in:12: -1- AC_SUBST([build_os], [`echo $ac_cv_build | sed 's/^\([[^-]]*\)-\([[^-]]*\)-\(.*\)$/\3/'`]) -m4trace:configure.in:12: -1- AC_SUBST([host], [$ac_cv_host]) -m4trace:configure.in:12: -1- AC_SUBST([host_cpu], [`echo $ac_cv_host | sed 's/^\([[^-]]*\)-\([[^-]]*\)-\(.*\)$/\1/'`]) -m4trace:configure.in:12: -1- AC_SUBST([host_vendor], [`echo $ac_cv_host | sed 's/^\([[^-]]*\)-\([[^-]]*\)-\(.*\)$/\2/'`]) -m4trace:configure.in:12: -1- AC_SUBST([host_os], [`echo $ac_cv_host | sed 's/^\([[^-]]*\)-\([[^-]]*\)-\(.*\)$/\3/'`]) -m4trace:configure.in:12: -1- AC_SUBST([ECHO]) -m4trace:configure.in:12: -1- AC_SUBST([RANLIB]) -m4trace:configure.in:12: -1- AC_SUBST([ac_ct_RANLIB]) -m4trace:configure.in:12: -1- AC_SUBST([STRIP]) -m4trace:configure.in:12: -1- AC_SUBST([ac_ct_STRIP]) -m4trace:configure.in:12: -1- AC_CHECK_LIB([dld], [shl_load], [lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-dld"], [AC_CHECK_FUNC([dlopen], +m4trace:configure.in:8: -1- AC_SUBST([FLASK_LINUX]) +m4trace:configure.in:9: -2- AC_DEFINE_TRACE_LITERAL([FLASK_LINUX]) +m4trace:configure.in:9: -2- AH_OUTPUT([FLASK_LINUX], [/* Use Security-Enhanced Linux features */ +#undef FLASK_LINUX]) +m4trace:configure.in:12: -1- AC_PROG_CC +m4trace:configure.in:12: -1- AC_SUBST([CC]) +m4trace:configure.in:12: -1- AC_SUBST([CFLAGS]) +m4trace:configure.in:12: -1- AC_SUBST([LDFLAGS]) +m4trace:configure.in:12: -1- AC_SUBST([CPPFLAGS]) +m4trace:configure.in:12: -1- AC_SUBST([CC]) +m4trace:configure.in:12: -1- AC_SUBST([ac_ct_CC]) +m4trace:configure.in:12: -1- AC_SUBST([CC]) +m4trace:configure.in:12: -1- AC_SUBST([ac_ct_CC]) +m4trace:configure.in:12: -1- AC_SUBST([CC]) +m4trace:configure.in:12: -1- AC_SUBST([CC]) +m4trace:configure.in:12: -1- AC_SUBST([ac_ct_CC]) +m4trace:configure.in:12: -1- AC_SUBST([EXEEXT], [$ac_cv_exeext]) +m4trace:configure.in:12: -1- AC_SUBST([OBJEXT], [$ac_cv_objext]) +m4trace:configure.in:12: -1- AC_SUBST([am__include]) +m4trace:configure.in:12: -1- AC_SUBST([am__quote]) +m4trace:configure.in:12: -1- AC_SUBST([CCDEPMODE]) +m4trace:configure.in:13: -1- AC_PROG_INSTALL +m4trace:configure.in:13: -1- AC_SUBST([INSTALL_PROGRAM]) +m4trace:configure.in:13: -1- AC_SUBST([INSTALL_SCRIPT]) +m4trace:configure.in:13: -1- AC_SUBST([INSTALL_DATA]) +m4trace:configure.in:14: -1- AC_PROG_LN_S +m4trace:configure.in:14: -1- AC_SUBST([LN_S], [$as_ln_s]) +m4trace:configure.in:15: -1- AM_PROG_LIBTOOL +m4trace:configure.in:15: -1- AC_PROG_LIBTOOL +m4trace:configure.in:15: -1- AC_SUBST([build], [$ac_cv_build]) +m4trace:configure.in:15: -1- AC_SUBST([build_cpu], [`echo $ac_cv_build | sed 's/^\([[^-]]*\)-\([[^-]]*\)-\(.*\)$/\1/'`]) +m4trace:configure.in:15: -1- AC_SUBST([build_vendor], [`echo $ac_cv_build | sed 's/^\([[^-]]*\)-\([[^-]]*\)-\(.*\)$/\2/'`]) +m4trace:configure.in:15: -1- AC_SUBST([build_os], [`echo $ac_cv_build | sed 's/^\([[^-]]*\)-\([[^-]]*\)-\(.*\)$/\3/'`]) +m4trace:configure.in:15: -1- AC_SUBST([host], [$ac_cv_host]) +m4trace:configure.in:15: -1- AC_SUBST([host_cpu], [`echo $ac_cv_host | sed 's/^\([[^-]]*\)-\([[^-]]*\)-\(.*\)$/\1/'`]) +m4trace:configure.in:15: -1- AC_SUBST([host_vendor], [`echo $ac_cv_host | sed 's/^\([[^-]]*\)-\([[^-]]*\)-\(.*\)$/\2/'`]) +m4trace:configure.in:15: -1- AC_SUBST([host_os], [`echo $ac_cv_host | sed 's/^\([[^-]]*\)-\([[^-]]*\)-\(.*\)$/\3/'`]) +m4trace:configure.in:15: -1- AC_SUBST([ECHO]) +m4trace:configure.in:15: -1- AC_SUBST([RANLIB]) +m4trace:configure.in:15: -1- AC_SUBST([ac_ct_RANLIB]) +m4trace:configure.in:15: -1- AC_SUBST([STRIP]) +m4trace:configure.in:15: -1- AC_SUBST([ac_ct_STRIP]) +m4trace:configure.in:15: -1- AC_CHECK_LIB([dld], [shl_load], [lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-dld"], [AC_CHECK_FUNC([dlopen], [lt_cv_dlopen="dlopen"], [AC_CHECK_LIB([dl], [dlopen], [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"], @@ -134,50 +138,50 @@ m4trace:configure.in:12: -1- AC_CHECK_LIB([dld], [shl_load], [lt_cv_dlopen="shl_ ]) ]) ]) -m4trace:configure.in:12: -1- AC_CHECK_LIB([dl], [dlopen], [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"], [AC_CHECK_LIB([svld], [dlopen], +m4trace:configure.in:15: -1- AC_CHECK_LIB([dl], [dlopen], [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"], [AC_CHECK_LIB([svld], [dlopen], [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld"], [AC_CHECK_LIB([dld], [dld_link], [lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-dld"]) ]) ]) -m4trace:configure.in:12: -1- AC_CHECK_LIB([svld], [dlopen], [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld"], [AC_CHECK_LIB([dld], [dld_link], +m4trace:configure.in:15: -1- AC_CHECK_LIB([svld], [dlopen], [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld"], [AC_CHECK_LIB([dld], [dld_link], [lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-dld"]) ]) -m4trace:configure.in:12: -1- AC_CHECK_LIB([dld], [dld_link], [lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-dld"]) -m4trace:configure.in:12: -1- AC_CHECK_HEADERS([dlfcn.h]) -m4trace:configure.in:12: -1- AH_OUTPUT([HAVE_DLFCN_H], [/* Define to 1 if you have the header file. */ +m4trace:configure.in:15: -1- AC_CHECK_LIB([dld], [dld_link], [lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-dld"]) +m4trace:configure.in:15: -1- AC_CHECK_HEADERS([dlfcn.h]) +m4trace:configure.in:15: -1- AH_OUTPUT([HAVE_DLFCN_H], [/* Define to 1 if you have the header file. */ #undef HAVE_DLFCN_H]) -m4trace:configure.in:12: -1- AC_HEADER_STDC -m4trace:configure.in:12: -1- AC_PROG_CPP -m4trace:configure.in:12: -1- AC_SUBST([CPP]) -m4trace:configure.in:12: -1- AC_SUBST([CPPFLAGS]) -m4trace:configure.in:12: -1- AC_SUBST([CPP]) -m4trace:configure.in:12: -1- AC_DEFINE_TRACE_LITERAL([STDC_HEADERS]) -m4trace:configure.in:12: -1- AH_OUTPUT([STDC_HEADERS], [/* Define to 1 if you have the ANSI C header files. */ +m4trace:configure.in:15: -1- AC_HEADER_STDC +m4trace:configure.in:15: -1- AC_PROG_CPP +m4trace:configure.in:15: -1- AC_SUBST([CPP]) +m4trace:configure.in:15: -1- AC_SUBST([CPPFLAGS]) +m4trace:configure.in:15: -1- AC_SUBST([CPP]) +m4trace:configure.in:15: -1- AC_DEFINE_TRACE_LITERAL([STDC_HEADERS]) +m4trace:configure.in:15: -1- AH_OUTPUT([STDC_HEADERS], [/* Define to 1 if you have the ANSI C header files. */ #undef STDC_HEADERS]) -m4trace:configure.in:12: -1- AC_CHECK_HEADERS([sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \ +m4trace:configure.in:15: -1- AC_CHECK_HEADERS([sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \ inttypes.h stdint.h unistd.h], [], [], [$ac_includes_default]) -m4trace:configure.in:12: -1- AH_OUTPUT([HAVE_SYS_TYPES_H], [/* Define to 1 if you have the header file. */ +m4trace:configure.in:15: -1- AH_OUTPUT([HAVE_SYS_TYPES_H], [/* Define to 1 if you have the header file. */ #undef HAVE_SYS_TYPES_H]) -m4trace:configure.in:12: -1- AH_OUTPUT([HAVE_SYS_STAT_H], [/* Define to 1 if you have the header file. */ +m4trace:configure.in:15: -1- AH_OUTPUT([HAVE_SYS_STAT_H], [/* Define to 1 if you have the header file. */ #undef HAVE_SYS_STAT_H]) -m4trace:configure.in:12: -1- AH_OUTPUT([HAVE_STDLIB_H], [/* Define to 1 if you have the header file. */ +m4trace:configure.in:15: -1- AH_OUTPUT([HAVE_STDLIB_H], [/* Define to 1 if you have the header file. */ #undef HAVE_STDLIB_H]) -m4trace:configure.in:12: -1- AH_OUTPUT([HAVE_STRING_H], [/* Define to 1 if you have the header file. */ +m4trace:configure.in:15: -1- AH_OUTPUT([HAVE_STRING_H], [/* Define to 1 if you have the header file. */ #undef HAVE_STRING_H]) -m4trace:configure.in:12: -1- AH_OUTPUT([HAVE_MEMORY_H], [/* Define to 1 if you have the header file. */ +m4trace:configure.in:15: -1- AH_OUTPUT([HAVE_MEMORY_H], [/* Define to 1 if you have the header file. */ #undef HAVE_MEMORY_H]) -m4trace:configure.in:12: -1- AH_OUTPUT([HAVE_STRINGS_H], [/* Define to 1 if you have the header file. */ +m4trace:configure.in:15: -1- AH_OUTPUT([HAVE_STRINGS_H], [/* Define to 1 if you have the header file. */ #undef HAVE_STRINGS_H]) -m4trace:configure.in:12: -1- AH_OUTPUT([HAVE_INTTYPES_H], [/* Define to 1 if you have the header file. */ +m4trace:configure.in:15: -1- AH_OUTPUT([HAVE_INTTYPES_H], [/* Define to 1 if you have the header file. */ #undef HAVE_INTTYPES_H]) -m4trace:configure.in:12: -1- AH_OUTPUT([HAVE_STDINT_H], [/* Define to 1 if you have the header file. */ +m4trace:configure.in:15: -1- AH_OUTPUT([HAVE_STDINT_H], [/* Define to 1 if you have the header file. */ #undef HAVE_STDINT_H]) -m4trace:configure.in:12: -1- AH_OUTPUT([HAVE_UNISTD_H], [/* Define to 1 if you have the header file. */ +m4trace:configure.in:15: -1- AH_OUTPUT([HAVE_UNISTD_H], [/* Define to 1 if you have the header file. */ #undef HAVE_UNISTD_H]) -m4trace:configure.in:12: -1- AC_SUBST([LIBTOOL]) -m4trace:configure.in:48: -1- AC_SUBST([NCURSES_LIB]) -m4trace:configure.in:49: -1- AC_CHECK_LIB([ncurses], [initscr], [NCURSES_LIB="-lncurses"], [{ { echo "$as_me:$LINENO: error: Need ncurses to compile this program" >&5 +m4trace:configure.in:15: -1- AC_SUBST([LIBTOOL]) +m4trace:configure.in:51: -1- AC_SUBST([NCURSES_LIB]) +m4trace:configure.in:52: -1- AC_CHECK_LIB([ncurses], [initscr], [NCURSES_LIB="-lncurses"], [{ { echo "$as_me:$LINENO: error: Need ncurses to compile this program" >&5 echo "$as_me: error: Need ncurses to compile this program" >&2;} { (exit 1); exit 1; }; }]) -m4trace:configure.in:52: -1- AC_CONFIG_FILES([Makefile ps/Makefile proc/Makefile]) +m4trace:configure.in:55: -1- AC_CONFIG_FILES([Makefile ps/Makefile proc/Makefile]) diff --git a/config.h.in b/config.h.in index 5a1898ac..3ae786e1 100644 --- a/config.h.in +++ b/config.h.in @@ -1,5 +1,8 @@ /* config.h.in. Generated from configure.in by autoheader. */ +/* Use Security-Enhanced Linux features */ +#undef FLASK_LINUX + /* Define to 1 if you have the header file. */ #undef HAVE_DLFCN_H diff --git a/configure b/configure index 14c9f615..88602b03 100755 --- a/configure +++ b/configure @@ -992,6 +992,7 @@ Optional Features: --enable-FEATURE[=ARG] include FEATURE [ARG=yes] --disable-dependency-tracking Speeds up one-time builds --enable-dependency-tracking Do not reject slow dependency extractors + --enable-flask Enable Security-Enhanced Linux features --enable-shared=PKGS build shared libraries default=yes --enable-static=PKGS build static libraries default=yes --enable-fast-install=PKGS optimize for fast installation default=yes @@ -1704,6 +1705,17 @@ INSTALL_STRIP_PROGRAM="\${SHELL} \$(install_sh) -c -s" # some platforms. + +# Check whether --enable-flask or --disable-flask was given. +if test "${enable_flask+set}" = set; then + enableval="$enable_flask" + +cat >>confdefs.h <<\_ACEOF +#define FLASK_LINUX 1 +_ACEOF + +fi; + ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' @@ -4247,7 +4259,7 @@ test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes case $host in *-*-irix6*) # Find out which ABI we are using. - echo '#line 4250 "configure"' > conftest.$ac_ext + echo '#line 4262 "configure"' > conftest.$ac_ext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? @@ -4779,7 +4791,7 @@ chmod -w . save_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS -o out/conftest2.$ac_objext" compiler_c_o=no -if { (eval echo configure:4782: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>out/conftest.err; } && test -s out/conftest2.$ac_objext; then +if { (eval echo configure:4794: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>out/conftest.err; } && test -s out/conftest2.$ac_objext; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings if test -s out/conftest.err; then @@ -6593,7 +6605,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext < conftest.$ac_ext < #include +#ifdef FLASK_LINUX +#include +#endif + #define Do(x) (flags & PROC_ ## x) /* convenient shorthand */ /* initiate a process table scan @@ -43,6 +50,10 @@ PROCTAB* openproc(int flags, ...) { PT->nuid = va_arg(ap, int); } else if (Do(STAT)) PT->stats = va_arg(ap, char*); +#ifdef FLASK_LINUX + else if ( Do(SID) || Do(CONTEXT) ) + PT->sids = va_arg(ap, security_id_t*); +#endif va_end(ap); /* Clean up args list */ if (Do(ANYTTY) && Do(TTY)) PT->flags = PT->flags & ~PROC_TTY; /* turn off TTY flag */ @@ -306,6 +317,9 @@ proc_t* readproc(PROCTAB* PT, proc_t* p) { static struct stat sb; /* stat buffer */ static char path[32], sbuf[1024]; /* bufs for stat,statm */ int matched = 0; /* flags */ +#ifdef FLASK_LINUX + security_id_t sid; +#endif /* loop until a proc matching restrictions is found or no more processes */ /* I know this could be a while loop -- this way is easier to indent ;-) */ @@ -327,8 +341,13 @@ next_proc: /* get next PID for consideration */ return NULL; sprintf(path, "/proc/%s", ent->d_name); } +#ifdef FLASK_LINUX + if ( stat_secure(path, &sb, &sid) == -1 ) /* no such dirent (anymore) */ +#else if (stat(path, &sb) == -1) /* no such dirent (anymore) */ +#endif goto next_proc; + if (Do(UID) && !XinLN(uid_t, sb.st_uid, PT->uids, PT->nuid)) goto next_proc; /* not one of the requested uids */ @@ -336,10 +355,19 @@ next_proc: /* get next PID for consideration */ p = xcalloc(p, sizeof *p); /* passed buf or alloced mem */ p->euid = sb.st_uid; /* need a way to get real uid */ +#ifdef FLASK_LINUX + p->sid = sid; +#endif + if ((file2str(path, "stat", sbuf, sizeof sbuf)) == -1) goto next_proc; /* error reading /proc/#/stat */ stat2proc(sbuf, p); /* parse /proc/#/stat */ +#ifdef FLASK_LINUX + if (!matched && (Do(SID) || Do(CONTEXT)) && !XinL(security_id_t, p->sid, PT->sids)) + goto next_proc; /* not one of the requested SIDs */ +#endif + if (!matched && Do(TTY) && !XinL(dev_t, p->tty, PT->ttys)) goto next_proc; /* not one of the requested ttys */ @@ -402,6 +430,9 @@ proc_t* ps_readproc(PROCTAB* PT, proc_t* p) { static struct direct *ent; /* dirent handle */ static struct stat sb; /* stat buffer */ static char path[32], sbuf[1024]; /* bufs for stat,statm */ +#ifdef FLASK_LINUX + security_id_t sid; +#endif /* loop until a proc matching restrictions is found or no more processes */ /* I know this could be a while loop -- this way is easier to indent ;-) */ @@ -417,12 +448,19 @@ next_proc: /* get next PID for consideration */ return NULL; sprintf(path, "/proc/%s", ent->d_name); +#ifdef FLASK_LINUX + if (stat_secure(path, &sb, &sid) == -1) /* no such dirent (anymore) */ +#else if (stat(path, &sb) == -1) /* no such dirent (anymore) */ +#endif goto next_proc; if (!p) p = xcalloc(p, sizeof *p); /* passed buf or alloced mem */ p->euid = sb.st_uid; /* need a way to get real uid */ +#ifdef FLASK_LINUX + p->sid = sid; +#endif if ((file2str(path, "stat", sbuf, sizeof sbuf)) == -1) goto next_proc; /* error reading /proc/#/stat */ @@ -528,6 +566,10 @@ proc_t** readproctab(int flags, ...) { } else if (Do(PID) || Do(TTY) || Do(STAT)) PT = openproc(flags, va_arg(ap, void*)); /* assume ptr sizes same */ +#ifdef FLASK_LINUX + else if ( Do(SID) || Do(CONTEXT) ) + PT = openproc(flags, va_arg(ap, security_id_t*)); +#endif else PT = openproc(flags); va_end(ap); diff --git a/proc/readproc.h b/proc/readproc.h index 8739fd5a..1ec2b1f9 100644 --- a/proc/readproc.h +++ b/proc/readproc.h @@ -12,6 +12,9 @@ #define SIGNAL_STRING +#ifdef FLASK_LINUX +#include +#endif /* ld cutime, cstime, priority, nice, timeout, it_real_value, rss, @@ -121,6 +124,9 @@ typedef struct proc_t { pcpu; /* %CPU usage (is not filled in by readproc!!!) */ char state; /* single-char code for process state (S=sleeping) */ +#ifdef FLASK_LINUX + security_id_t sid; +#endif } proc_t; /* PROCTAB: data structure holding the persistent information readproc needs @@ -138,6 +144,9 @@ typedef struct PROCTAB { uid_t* uids; /* uids of procs */ int nuid; /* cannot really sentinel-terminate unsigned short[] */ char* stats; /* status chars (actually output into /proc//stat) */ +#ifdef FLASK_LINUX +security_id_t* sids; /* SIDs of the procs */ +#endif } PROCTAB; /* initialize a PROCTAB structure holding needed call-to-call persistent data @@ -197,5 +206,9 @@ extern void freeproc(proc_t* p); #define PROC_UID 0x0400 /* user id numbers ( length needed ) */ #define PROC_STAT 0x0800 /* status fields ('\0' terminated) */ #define PROC_ANYTTY 0x1000 /* proc must have a controlling terminal */ +#ifdef FLASK_LINUX +#define PROC_SID 0x2000 +#define PROC_CONTEXT 0x2000 /* synonym: SID gets converted to string if PROC_CONTEXT */ +#endif #endif diff --git a/ps/Makefile.in b/ps/Makefile.in index 83cb2884..a0fb4634 100644 --- a/ps/Makefile.in +++ b/ps/Makefile.in @@ -65,6 +65,7 @@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ ECHO = @ECHO@ EXEEXT = @EXEEXT@ +FLASK_LINUX = @FLASK_LINUX@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LIBTOOL = @LIBTOOL@ LN_S = @LN_S@ diff --git a/ps/common.h b/ps/common.h index d2bf76f5..1282264b 100644 --- a/ps/common.h +++ b/ps/common.h @@ -105,6 +105,10 @@ #define FF_Bv 0x0080 /* v */ #define FF_LX 0x0100 /* X */ #define FF_Lm 0x0200 /* m */ /* overloaded: threads, sort, format */ +#ifdef FLASK_LINUX +#define FF_Fc 0x0400 /* --context */ /* Flask security context format */ +#define FF_Fs 0x0800 /* --SID */ /* Flask SID format */ +#endif /* predefined format modifier flags such as: -l -f l u s -j */ #define FM_c 0x0001 /* -c */ diff --git a/ps/help.c b/ps/help.c index 8e6bc0d5..70e6d299 100644 --- a/ps/help.c +++ b/ps/help.c @@ -13,7 +13,9 @@ * The help message must not become longer, because it must fit * on an 80x24 screen _with_ the error message and command prompt. */ - +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif const char *help_message = "********* simple selection ********* ********* selection by list *********\n" @@ -33,6 +35,9 @@ const char *help_message = "-O,O preloaded -o v virtual memory --cumulative --format --deselect\n" "-l,l long u user-oriented --sort --tty --forest --version\n" " X registers --heading --no-heading\n" +#ifdef FLASK_LINUX +" --context --SID (Flask only)\n" +#endif " ********* misc options *********\n" "-V,V show version L list format codes f ASCII art forest\n" "-m,m show threads S children in sum -y change -l format\n" diff --git a/ps/output.c b/ps/output.c index 2fb7b6db..257ee6bd 100644 --- a/ps/output.c +++ b/ps/output.c @@ -38,7 +38,9 @@ * * Table 5 could go in a file with the output functions. */ - +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif /* proc_t offset macro */ #define PO(q) ((unsigned long)(&(((proc_t*)0)->q))) @@ -64,6 +66,13 @@ #include "../proc/devname.h" #include "common.h" +#ifdef FLASK_LINUX +#include +#include +#include +#define DEF_CTXTLEN 255 +#endif + /* TODO: * Stop assuming system time is local time. @@ -192,6 +201,10 @@ CMP_INT(pcpu) CMP_INT(state) +#ifdef FLASK_LINUX +CMP_INT(sid) +#endif + /***************************************************************************/ /************ Lots of format functions, starting with the NOP **************/ @@ -911,6 +924,134 @@ static int pr_sgi_p(void){ /* FIXME */ +#ifdef FLASK_LINUX + +/* + * The sr_fn() calls -- for sorting -- don't return errors because the same errors + * should show up when the printing function pr_fn() is called, at which point the + * error goes onscreen. + */ + +static int pr_sid ( void ) { + return sprintf(outbuf, "%d", (int) pp->sid); +} + +static int pr_context ( void ) { + char *ctxt; /* should be security_context_t */ + unsigned int len; + int rv; + + + len = DEF_CTXTLEN; + ctxt = (char *) calloc(1, len); + if ( ctxt != NULL ) + rv = security_sid_to_context(pp->sid, (security_context_t) ctxt, &len); + else + return sprintf(outbuf, "-"); + + if ( rv ) { + if ( errno != ENOSPC ) { + free(ctxt); + return sprintf(outbuf, "-"); + } + else { + free(ctxt); + ctxt = (char *) calloc(1, len); + if ( ctxt != NULL ) { + rv = security_sid_to_context(pp->sid, (security_context_t) ctxt, &len); + if ( rv ) { + free(ctxt); + return sprintf(outbuf, "-"); + } + else { + rv = sprintf(outbuf, "%s", ctxt); + free(ctxt); + return rv; + } + } + else /* calloc() failed */ + return sprintf(outbuf, "-"); + } + } + else { + rv = sprintf(outbuf, "%s", ctxt); + free(ctxt); + return rv; + } +} + + +static int sr_context ( const proc_t* P, const proc_t* Q ) { + char *ctxt_P, *ctxt_Q; /* type should be security_context_t */ + unsigned int len; + int rv; + + len = DEF_CTXTLEN; + ctxt_P = (char *) calloc(1, len); + ctxt_Q = (char *) calloc(1, len); + + rv = security_sid_to_context(P->sid, (security_context_t) ctxt_P, &len); + if ( rv ) { + if ( errno != ENOSPC ) { + free(ctxt_P); + /* error should resurface during printing */ + return( 0 ); + } + else { + free(ctxt_P); + ctxt_P = (char *) calloc(1, len); + if ( ctxt_P != NULL ) { + rv = security_sid_to_context(P->sid, (security_context_t) ctxt_P, &len); + if ( rv ) { + free(ctxt_P); + /* error should resurface during printing */ + return( 0 ); + } + } + else /* calloc() failed */ + /* error should resurface during printing */ + return( 0 ); + } + } + + len = DEF_CTXTLEN; + + rv = security_sid_to_context(Q->sid, (security_context_t) ctxt_Q, &len); + if ( rv ) { + if ( errno != ENOSPC ) { + free(ctxt_P); + free(ctxt_Q); + /* error should resurface during printing */ + return( 0 ); + } + else { + free(ctxt_Q); + ctxt_Q = (char *) calloc(1, len); + if ( ctxt_Q != NULL ) { + rv = security_sid_to_context(Q->sid, (security_context_t) ctxt_Q, &len); + if ( rv ) { + free(ctxt_P); + free(ctxt_Q); + /* error should resurface during printing */ + return( 0 ); + } + } + else /* calloc() failed */ + /* error should resurface during printing */ + free(ctxt_P); + return( 0 ); + } + } + + rv = strcmp(ctxt_P, ctxt_Q); + + free(ctxt_P); + free(ctxt_Q); + + return( rv ); +} +#endif + /***************************************************************************/ /*************************** other stuff ***********************************/ @@ -981,6 +1122,9 @@ static const format_struct format_array[] = { {"cnswap", "-", pr_nop, sr_cnswap, 1, 0, LNX, RIGHT}, {"comm", "COMMAND", pr_comm, sr_nop, 16, 0, U98, UNLIMITED}, /*ucomm*/ {"command", "COMMAND", pr_args, sr_nop, 16, 0, XXX, UNLIMITED}, /*args*/ +#ifdef FLASK_LINUX +{"context", "CONTEXT", pr_context, sr_context,40, 0, LNX, LEFT}, +#endif {"cp", "CP", pr_cp, sr_pcpu, 3, 0, DEC, RIGHT}, /*cpu*/ {"cpu", "CPU", pr_nop, sr_nop, 3, 0, BSD, RIGHT}, /* FIXME ... HP-UX wants this as the CPU number for SMP? */ {"cputime", "TIME", pr_time, sr_nop, 8, 0, DEC, RIGHT}, /*time*/ @@ -1090,6 +1234,9 @@ static const format_struct format_array[] = { {"sched", "SCH", pr_nop, sr_nop, 1, 0, AIX, RIGHT}, {"scnt", "SCNT", pr_nop, sr_nop, 4, 0, DEC, RIGHT}, /* man page misspelling of scount? */ {"scount", "SC", pr_nop, sr_nop, 4, 0, AIX, RIGHT}, /* scnt==scount, DEC claims both */ +#ifdef FLASK_LINUX +{"secsid", "SID", pr_sid, sr_sid, 6, 0, LNX, RIGHT}, /* Flask Linux */ +#endif {"sess", "SESS", pr_sess, sr_session, 5, 0, XXX, RIGHT}, {"session", "SESS", pr_sess, sr_session, 5, 0, LNX, RIGHT}, {"sgi_p", "P", pr_sgi_p, sr_nop, 1, 0, LNX, RIGHT}, /* "cpu" number */ @@ -1199,6 +1346,11 @@ static const macro_struct macro_array[] = { {"FL5FMT", "f,state,uid,pid,ppid,pcpu,pri,nice,rss,wchan,start,time,command"}, /* Digital -fl */ +#ifdef FLASK_LINUX +{"FLASK_context", "pid,secsid,context,command"}, /* Flask Linux context, --context */ +{"FLASK_sid", "pid,secsid,command"}, /* Flask Linux SID, --SID */ +#endif + {"HP_", "pid,tty,time,comm"}, /* HP default */ {"HP_f", "user,pid,ppid,cpu,stime,tty,time,args"}, /* HP -f */ {"HP_fl", "flags,state,user,pid,ppid,cpu,intpri,nice,addr,sz,wchan,stime,tty,time,args"}, /* HP -fl */ diff --git a/ps/parser.c b/ps/parser.c index 4ecf0e8b..8f00896f 100644 --- a/ps/parser.c +++ b/ps/parser.c @@ -12,7 +12,9 @@ /* Ought to have debug print stuff like this: * #define Print(fmt, args...) printf("Debug: " fmt, ## args) */ - +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif #include #include @@ -724,9 +726,15 @@ static const char *parse_gnu_option(void){ gnu_table_struct *found; static const gnu_table_struct gnu_table[] = { {"Group", &&case_Group}, /* rgid */ +#ifdef FLASK_LINUX + {"SID", &&case_secsid}, +#endif {"User", &&case_User}, /* ruid */ {"cols", &&case_cols}, {"columns", &&case_columns}, +#ifdef FLASK_LINUX + {"context", &&case_context}, +#endif {"cumulative", &&case_cumulative}, {"deselect", &&case_deselect}, /* -N */ {"forest", &&case_forest}, /* f -H */ @@ -749,6 +757,9 @@ static const char *parse_gnu_option(void){ {"noheadings", &&case_noheadings}, {"pid", &&case_pid}, {"rows", &&case_rows}, +#ifdef FLASK_LINUX + {"secsid", &&case_secsid}, +#endif {"sid", &&case_sid}, {"sort", &&case_sort}, {"tty", &&case_tty}, @@ -925,6 +936,16 @@ static const char *parse_gnu_option(void){ display_version(); exit(0); return NULL; +#ifdef FLASK_LINUX + case_context: + trace("--context\n"); + format_flags |= FF_Fc; + return NULL; + case_secsid: + trace("--secsid\n"); + format_flags |= FF_Fs; + return NULL; +#endif } /*************** process trailing PIDs **********************/ diff --git a/ps/ps.1 b/ps/ps.1 index 1cae9c84..a01a0e90 100644 --- a/ps/ps.1 +++ b/ps/ps.1 @@ -95,6 +95,9 @@ s display signal format u display user-oriented format v display virtual memory format --format user-defined format +--context (SELinux only) Display security context format; implies --SID +--secsid (SELinux only) Display Security ID (SID) +--SID (SELinux only) Display Security ID (SID) OUTPUT MODIFIERS -H show process hierarchy (forest) @@ -323,6 +326,7 @@ caught CAUGHT cmd CMD comm COMMAND command COMMAND +context CONTEXT cputime TIME drs DRS dsiz DSIZ @@ -380,6 +384,7 @@ rsz RSZ ruid RUID ruser RUSER s S +secsid SECSID sess SESS session SESS sgi_p P diff --git a/ps/sortformat.c b/ps/sortformat.c index 9c08d9a1..21b5bb5f 100644 --- a/ps/sortformat.c +++ b/ps/sortformat.c @@ -8,6 +8,9 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Library General Public License for more details. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif #include #include @@ -797,6 +800,10 @@ const char *process_sf_options(int localbroken){ /* These are old Linux options. Option m is overloaded. */ case FF_LX: spec="OL_X"; break; case FF_Lm: spec="OL_m"; break; +#ifdef FLASK_LINUX + case FF_Fc: spec="FLASK_context"; break; + case FF_Fs: spec="FLASK_sid"; break; +#endif } /* end switch(format_flags) */