diff -up net-tools-1.60/config.in.selinux net-tools-1.60/config.in --- net-tools-1.60/config.in.selinux 2011-11-21 02:31:57.000000000 +0100 +++ net-tools-1.60/config.in 2011-12-07 12:24:21.922245784 +0100 @@ -91,3 +91,4 @@ bool 'InfiniBand hardware support' HAVE_ bool 'IP Masquerading support' HAVE_FW_MASQUERADE y bool 'Build iptunnel and ipmaddr' HAVE_IP_TOOLS y bool 'Build mii-tool' HAVE_MII y +bool 'SELinux support' HAVE_SELINUX n diff -up net-tools-1.60/Makefile.selinux net-tools-1.60/Makefile --- net-tools-1.60/Makefile.selinux 2011-11-21 02:31:57.000000000 +0100 +++ net-tools-1.60/Makefile 2011-12-07 12:23:00.078268978 +0100 @@ -114,6 +114,12 @@ endif NET_LIB = $(NET_LIB_PATH)/lib$(NET_LIB_NAME).a +ifeq ($(HAVE_SELINUX),1) +LDFLAGS += -lselinux +CFLAGS += -DHAVE_SELINUX +else +endif + CPPFLAGS += -I. -I$(TOPDIR)/include -I$(NET_LIB_PATH) LDFLAGS += -L$(NET_LIB_PATH) diff -up net-tools-1.60/netstat.c.selinux net-tools-1.60/netstat.c --- net-tools-1.60/netstat.c.selinux 2011-12-07 12:23:00.040269453 +0100 +++ net-tools-1.60/netstat.c 2011-12-07 12:23:00.079268965 +0100 @@ -89,6 +89,11 @@ #include #include +#if HAVE_SELINUX +#include +#else +#define security_context_t char* +#endif #include "net-support.h" #include "pathnames.h" #include "version.h" @@ -100,6 +105,7 @@ #include "proc.h" #define PROGNAME_WIDTH 20 +#define SELINUX_WIDTH 50 #if !defined(s6_addr32) && defined(in6a_words) #define s6_addr32 in6a_words /* libinet6 */ @@ -159,6 +165,7 @@ int flag_wide= 0; int flag_prg = 0; int flag_arg = 0; int flag_ver = 0; +int flag_selinux = 0; FILE *procinfo; @@ -222,12 +229,17 @@ FILE *procinfo; #define PROGNAME_WIDTH1(s) PROGNAME_WIDTH2(s) #define PROGNAME_WIDTH2(s) #s +#define SELINUX_WIDTHs SELINUX_WIDTH1(SELINUX_WIDTH) +#define SELINUX_WIDTH1(s) SELINUX_WIDTH2(s) +#define SELINUX_WIDTH2(s) #s + #define PRG_HASH_SIZE 211 static struct prg_node { struct prg_node *next; unsigned long inode; char name[PROGNAME_WIDTH]; + char scon[SELINUX_WIDTH]; } *prg_hash[PRG_HASH_SIZE]; static char prg_cache_loaded = 0; @@ -235,9 +247,12 @@ static char prg_cache_loaded = 0; #define PRG_HASHIT(x) ((x) % PRG_HASH_SIZE) #define PROGNAME_BANNER "PID/Program name" +#define SELINUX_BANNER "Security Context" #define print_progname_banner() do { if (flag_prg) printf(" %-" PROGNAME_WIDTHs "s",PROGNAME_BANNER); } while (0) +#define print_selinux_banner() do { if (flag_selinux) printf("%-" SELINUX_WIDTHs "s"," " SELINUX_BANNER); } while (0) + #define PRG_LOCAL_ADDRESS "local_address" #define PRG_INODE "inode" #define PRG_SOCKET_PFX "socket:[" @@ -257,7 +272,7 @@ static char prg_cache_loaded = 0; #define PATH_CMDLINE "cmdline" #define PATH_CMDLINEl strlen(PATH_CMDLINE) -static void prg_cache_add(unsigned long inode, char *name) +static void prg_cache_add(unsigned long inode, char *name, char *scon) { unsigned hi = PRG_HASHIT(inode); struct prg_node **pnp,*pn; @@ -278,6 +293,14 @@ static void prg_cache_add(unsigned long if (strlen(name)>sizeof(pn->name)-1) name[sizeof(pn->name)-1]='\0'; strcpy(pn->name,name); + + { + int len=(strlen(scon)-sizeof(pn->scon))+1; + if (len > 0) + strcpy(pn->scon,&scon[len+1]); + else + strcpy(pn->scon,scon); + } } static const char *prg_cache_get(unsigned long inode) @@ -290,6 +313,16 @@ static const char *prg_cache_get(unsigne return("-"); } +static const char *prg_cache_get_con(unsigned long inode) +{ + unsigned hi=PRG_HASHIT(inode); + struct prg_node *pn; + + for (pn=prg_hash[hi];pn;pn=pn->next) + if (pn->inode==inode) return(pn->scon); + return("-"); +} + static void prg_cache_clear(void) { struct prg_node **pnp,*pn; @@ -367,6 +400,7 @@ static void prg_cache_load(void) const char *cs,*cmdlp; DIR *dirproc=NULL,*dirfd=NULL; struct dirent *direproc,*direfd; + security_context_t scon=NULL; if (prg_cache_loaded || !flag_prg) return; prg_cache_loaded=1; @@ -428,7 +462,15 @@ static void prg_cache_load(void) } snprintf(finbuf, sizeof(finbuf), "%s/%s", direproc->d_name, cmdlp); - prg_cache_add(inode, finbuf); +#if HAVE_SELINUX + if (getpidcon(atoi(direproc->d_name), &scon) == -1) { + scon=strdup("-"); + } + prg_cache_add(inode, finbuf, scon); + freecon(scon); +#else + prg_cache_add(inode, finbuf, "-"); +#endif } closedir(dirfd); dirfd = NULL; @@ -662,6 +704,9 @@ static void finish_this_one(int uid, uns } if (flag_prg) printf(" %-" PROGNAME_WIDTHs "s",prg_cache_get(inode)); + if (flag_selinux) + printf(" %-" SELINUX_WIDTHs "s",prg_cache_get_con(inode)); + if (flag_opt) printf(" %s", timers); putchar('\n'); @@ -1484,7 +1529,9 @@ static void unix_do_one(int nr, const ch printf("- "); if (flag_prg) printf(" %-" PROGNAME_WIDTHs "s",(has & HAS_INODE?prg_cache_get(inode):"-")); - + if (flag_selinux) + printf(" %-" SELINUX_WIDTHs "s",(has & HAS_INODE?prg_cache_get_con(inode):"-")); + printf(" %s\n", path); } @@ -1503,6 +1550,7 @@ static int unix_info(void) printf(_("\nProto RefCnt Flags Type State I-Node ")); print_progname_banner(); + print_selinux_banner(); printf(_(" Path\n")); /* xxx */ { @@ -1802,6 +1850,7 @@ static void usage(void) fprintf(stderr, _(" -o, --timers display timers\n")); fprintf(stderr, _(" -F, --fib display Forwarding Information Base (default)\n")); fprintf(stderr, _(" -C, --cache display routing cache instead of FIB\n\n")); + fprintf(stderr, _(" -Z, --context display SELinux security context for sockets\n\n")); fprintf(stderr, _(" ={-t|--tcp} {-u|--udp} {-U|--udplite} {-w|--raw} {-x|--unix} --ax25 --ipx --netrom\n")); fprintf(stderr, _(" =Use '-6|-4' or '-A ' or '--'; default: %s\n"), DFLT_AF); @@ -1850,6 +1899,7 @@ int main {"cache", 0, 0, 'C'}, {"fib", 0, 0, 'F'}, {"groups", 0, 0, 'g'}, + {"context", 0, 0, 'Z'}, {NULL, 0, 0, 0} }; @@ -1861,7 +1911,7 @@ int main getroute_init(); /* Set up AF routing support */ afname[0] = '\0'; - while ((i = getopt_long(argc, argv, "A:CFMacdeghiI::lnNoprsStuUvVWwx64?", longopts, &lop)) != EOF) + while ((i = getopt_long(argc, argv, "A:CFMacdeghiI::lnNoprsStuUvVWwx64?Z", longopts, &lop)) != EOF) switch (i) { case -1: break; @@ -1975,6 +2025,20 @@ int main if (aftrans_opt("unix")) exit(1); break; + case 'Z': +#if HAVE_SELINUX + if (is_selinux_enabled() <= 0) { + fprintf(stderr, _("SELinux is not enabled on this machine.\n")); + exit(1); + } + flag_prg++; + flag_selinux++; +#else + fprintf(stderr, _("SELinux is not enabled for this application.\n")); + exit(1); +#endif + + break; case '?': case 'h': usage(); @@ -2101,6 +2165,7 @@ int main if (flag_exp > 1) printf(_(" User Inode ")); print_progname_banner(); + print_selinux_banner(); if (flag_opt) printf(_(" Timer")); /* xxx */ printf("\n");