All of lore.kernel.org
 help / color / mirror / Atom feed
From: Colin Walters <walters@verbum.org>
To: SELinux@tycho.nsa.gov
Cc: albert@users.sourceforge.net
Subject: port of procps patch to acahalan procps
Date: 09 Jul 2003 14:55:06 -0400	[thread overview]
Message-ID: <1057776906.28674.262.camel@columbia> (raw)

[-- Attachment #1: Type: text/plain, Size: 372 bytes --]

Hi,

I've ported the SELinux 2.5 procps patch to the acahalan procps; this
may be useful for other systems like Debian which also use acalahan's
procps (I think Gentoo does).

It's been lightly tested.

Albert: this is an update to the new SELinux API for Linux 2.5; the old
API is deprecated now, and will likely be obsoleted once the new API is
backported to Linux 2.4.

[-- Attachment #2: acalahan-procps.patch --]
[-- Type: text/plain, Size: 16430 bytes --]

--- procps-3.1.9.orig/Makefile
+++ procps-3.1.9/Makefile
@@ -63,9 +63,9 @@
 
 CURSES := -I/usr/include/ncurses -lncurses
 
-LDFLAGS := -Wl,-warn-common
+LDFLAGS := -Wl,-warn-common -lselinux -lattr
 
-CFLAGS := -D_GNU_SOURCE -O2 -g3 -fno-common -ffast-math -I proc \
+CFLAGS := -D_GNU_SOURCE -DWITH_SELINUX -g -fno-common -ffast-math -I proc \
   -W -Wall -Wshadow -Wcast-align -Wredundant-decls \
   -Wbad-function-cast -Wcast-qual -Wwrite-strings -Waggregate-return \
 #  -Wpadded -Wunreachable-code -Wdisabled-optimization \
@@ -128,7 +128,7 @@
 ###### install
 
 $(BINFILES) : all
-	$(install) --mode a=rx --strip $(notdir $@) $@
+	$(install) --mode a=rx $(notdir $@) $@
 
 $(MANFILES) : all
 	$(install) --mode a=r $(notdir $@) $@
--- procps-3.1.9.orig/proc/readproc.c
+++ procps-3.1.9/proc/readproc.c
@@ -27,8 +27,8 @@
 #include <sys/types.h>
 #include <sys/stat.h>
 
-#ifdef FLASK_LINUX
-#include <fs_secure.h>
+#ifdef WITH_SELINUX
+#include <selinux/selinux.h>
 #endif
 
 #ifdef PROF
@@ -82,6 +82,10 @@
 	free((void*)*p->cmdline);
     if (p->environ)
 	free((void*)*p->environ);
+#ifdef WITH_SELINUX
+    if (p->scontext)
+        freecon(p->scontext);
+#endif
     free(p);
 }
 
@@ -519,10 +523,10 @@
     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 secsid;
-#endif
     pid_t pid;  // saved until we have a proc_t allocated for sure
+#ifdef WITH_SELINUX
+    int selinux_enabled = is_selinux_enabled();
+#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 ;-) */
@@ -546,23 +550,18 @@
 	strcpy(path+6, ent->d_name);  // trust /proc to not contain evil top-level entries
 //	snprintf(path, sizeof path, "/proc/%s", ent->d_name);
     }
-#ifdef FLASK_LINUX
-    if ( stat_secure(path, &sb, &secsid) == -1 ) /* no such dirent (anymore) */
-#else
     if (unlikely(stat(path, &sb) == -1))	/* no such dirent (anymore) */
-#endif
 	goto next_proc;
 
     if ((flags & PROC_UID) && !XinLN(uid_t, sb.st_uid, PT->uids, PT->nuid))
 	goto next_proc;			/* not one of the requested uids */
 
-    if (!p)
+    if (!p) {
 	p = xcalloc(p, sizeof *p); /* passed buf or alloced mem */
+	memset(p, 0, sizeof(p));
+    }
 
     p->euid = sb.st_uid;			/* need a way to get real uid */
-#ifdef FLASK_LINUX
-    p->secsid = secsid;
-#endif
     p->pid  = pid;
 
     if (flags & PROC_FILLSTAT) {         /* read, parse /proc/#/stat */
@@ -571,6 +570,30 @@
 	stat2proc(sbuf, p);				/* parse /proc/#/stat */
     }
 
+#ifdef WITH_SELINUX
+    if (selinux_enabled) {
+	if (p->scontext) {
+	    freecon(p->scontext);
+	    p->scontext=NULL;
+	}
+	if (getpidcon(p->pid, &p->scontext) < 0 )
+	    goto next_proc;
+	
+	if (unlikely(flags & PROC_CONTEXT)) {
+	    int found=0;
+	    int i=0;
+	    for (i=0; PT->scontexts[i]; i++) {
+		if (strcmp(p->scontext, PT->scontexts[i]) ==0) {
+		    found=1;
+		    break;
+		}
+	    }
+	    if (! found)
+		goto next_proc;			/* not one of the requested CONTEXTS */
+	}
+    }
+#endif
+
     if (unlikely(flags & PROC_FILLMEM)) {				/* read, parse /proc/#/statm */
 	if (likely( file2str(path, "statm", sbuf, sizeof sbuf) != -1 ))
 	    statm2proc(sbuf, p);		/* ignore statm errors here */
@@ -630,10 +653,10 @@
     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 secsid;
-#endif
     pid_t pid;  // saved until we have a proc_t allocated for sure
+#ifdef WITH_SELINUX
+    int selinux_enabled = is_selinux_enabled();
+#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 ;-) */
@@ -652,26 +675,30 @@
     strcpy(path+6, ent->d_name);  // trust /proc to not contain evil top-level entries
 //  snprintf(path, sizeof path, "/proc/%s", ent->d_name);
 
-#ifdef FLASK_LINUX
-    if (stat_secure(path, &sb, &secsid) == -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->secsid = secsid;
-#endif
     p->pid  = pid;
 
     if ((file2str(path, "stat", sbuf, sizeof sbuf)) == -1)
 	goto next_proc;			/* error reading /proc/#/stat */
     stat2proc(sbuf, p);				/* parse /proc/#/stat */
 
+#ifdef WITH_SELINUX
+    if (selinux_enabled) {
+	if (p->scontext) {
+	    freecon(p->scontext);
+	    p->scontext=NULL;
+	}
+	if (getpidcon(p->pid, &p->scontext) < 0 )
+	    goto next_proc;
+    }
+#endif
+
     if (flags & PROC_FILLMEM) {				/* read, parse /proc/#/statm */
 	if ((file2str(path, "statm", sbuf, sizeof sbuf)) != -1 )
 	    statm2proc(sbuf, p);		/* ignore statm errors here */
@@ -755,9 +782,15 @@
     }
     else if (flags & PROC_PID)
 	PT = openproc(flags, va_arg(ap, void*)); /* assume ptr sizes same */
+#ifdef WITH_SELINUX
+    else if (flags & PROC_CONTEXT)
+	PT = openproc(flags, va_arg(ap, security_context_t*));
+#endif
     else
 	PT = openproc(flags);
     va_end(ap);
+    if (!PT)
+      return 0;
     do {					/* read table: */
 	tab = xrealloc(tab, (n+1)*sizeof(proc_t*));/* realloc as we go, using */
 	tab[n] = readproc_direct(PT, NULL);     /* final null to terminate */
--- procps-3.1.9.orig/proc/readproc.h
+++ procps-3.1.9/proc/readproc.h
@@ -14,8 +14,8 @@
 
 #define SIGNAL_STRING
 
-#ifdef FLASK_LINUX
-#include <fs_secure.h>
+#ifdef WITH_SELINUX
+#include <selinux/selinux.h>
 #endif
 
 EXTERN_C_BEGIN
@@ -136,8 +136,8 @@
 	tgid,		/* thread group ID */
 	exit_signal,	/* might not be SIGCHLD */
 	processor;      /* current (or most recent?) CPU */
-#ifdef FLASK_LINUX
-	security_id_t secsid;
+#ifdef WITH_SELINUX
+	security_context_t scontext;
 #endif
 } proc_t;
 
@@ -154,8 +154,8 @@
     pid_t*	pids;	/* pids of the procs */
     uid_t*	uids;	/* uids of procs */
     int		nuid;	/* cannot really sentinel-terminate unsigned short[] */
-#ifdef FLASK_LINUX
-    security_id_t* sids; /* SIDs of the procs */
+#ifdef WITH_SELINUX
+    security_context_t* scontexts; /* security contexts of the procs */
 #endif
 } PROCTAB;
 
@@ -218,6 +218,9 @@
 /* Obsolete, consider only processes with one of the passed: */
 #define PROC_PID     0x1000  /* process id numbers ( 0   terminated) */
 #define PROC_UID     0x4000  /* user id numbers    ( length needed ) */
+#ifdef WITH_SELINUX
+#define PROC_CONTEXT 0x8000 
+#endif
 
 // it helps to give app code a few spare bits
 #define PROC_SPARE_1 0x01000000
--- procps-3.1.9.orig/ps/display.c
+++ procps-3.1.9/ps/display.c
@@ -246,7 +246,7 @@
     fprintf(stderr, "Error: can not access /proc.\n");
     exit(1);
   }
-  memset(&buf, '#', sizeof(proc_t));
+  memset(&buf, 0, sizeof(proc_t));
   while(ps_readproc(ptp,&buf)){
     if(want_this_proc(&buf)) show_one_proc(&buf);
     if(buf.cmdline) free((void*)*buf.cmdline); // ought to reuse
--- procps-3.1.9.orig/ps/help.c
+++ procps-3.1.9/ps/help.c
@@ -35,8 +35,8 @@
 "-O,O preloaded -o  v  virtual memory  --cumulative --format --deselect\n"
 "-l,l long          u  user-oriented   --sort --tty --forest --version\n"
 "-F   extra full    X  registers       --heading --no-heading\n"
-#ifdef FLASK_LINUX
-"                                      --context --SID   (Flask only)\n"
+#ifdef WITH_SELINUX
+"                                      --context (SELinux only)\n"
 #endif
 "                    ********* misc options *********\n"
 "-V,V show version       L  list format codes  f  ASCII art forest\n"
--- procps-3.1.9.orig/ps/output.c
+++ procps-3.1.9/ps/output.c
@@ -68,11 +68,9 @@
 #include "../proc/escape.h"
 #include "common.h"
 
-#ifdef FLASK_LINUX
+#ifdef WITH_SELINUX
 #include <errno.h>
-#include <fs_secure.h>
-#include <ss.h>
-#define DEF_CTXTLEN 255
+#include <selinux/selinux.h>
 #endif
 
 
@@ -208,6 +206,9 @@
 CMP_SMALL(pcpu)
 
 CMP_SMALL(state)
+#ifdef WITH_SELINUX
+CMP_STR(scontext)
+#endif
 
 /* approximation to: kB of address space that could end up in swap */
 static int sr_swapable(const proc_t* P, const proc_t* Q) {
@@ -957,7 +958,7 @@
 
 
 /****************** FLASK security stuff **********************/
-#ifdef FLASK_LINUX
+#ifdef WITH_SELINUX
 
 /*
  * The sr_fn() calls -- for sorting -- don't return errors because
@@ -965,128 +966,26 @@
  * is called, at which point the error goes onscreen.
  */
 
-/* as above, creates sr_secsid function */
-CMP_INT(secsid)  /* FLASK security ID, **NOT** a session ID -- ugh */
-
-static int pr_secsid(char *restrict const outbuf, const proc_t *restrict const pp){
-  return sprintf(outbuf, "%d", (int) pp->secsid);
-}
-
 static int pr_context(char *restrict const outbuf, const proc_t *restrict const pp){
-  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->secsid, (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->secsid, (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, "-");
-      }
-    }
+  if (pp->scontext) {
+    sprintf(outbuf, pp->scontext);
   } else {
-    rv = sprintf(outbuf, "%s", ctxt);
-    free(ctxt);
-    return rv;
+    sprintf(outbuf, "-");
   }
 }
 
-
 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->secsid, (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->secsid, (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->secsid, (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->secsid, (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 );
+  if ((P->scontext==NULL) && (Q->scontext==NULL))
+    return 0;
+  if ((P->scontext==NULL) || (Q->scontext==NULL))
+    return 1;
+  return strcmp(P->scontext, Q->scontext);
 }
 
 #else
 
 /****** dummy functions ******/
 
-#define pr_secsid pr_nop
-#define sr_secsid sr_nop
 #define pr_context pr_nop
 #define sr_context sr_nop
 
@@ -1274,7 +1173,7 @@
 {"sched",     "SCH",     pr_sched,    sr_sched,   3,   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 */
-{"secsid",    "SID",     pr_secsid,   sr_secsid,  6,   0,    LNX, RIGHT}, /* Flask Linux */
+{"context",   "CONTEXT", pr_context,  sr_context,40,   0,    LNX, RIGHT}, /* SE Linux */
 {"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 */
@@ -1384,9 +1283,6 @@
 
 {"FL5FMT",   "f,state,uid,pid,ppid,pcpu,pri,nice,rss,wchan,start,time,command"},  /* Digital -fl */
 
-{"FLASK_context",   "pid,secsid,context,command"},  /* Flask Linux context, --context */
-{"FLASK_sid",       "pid,secsid,command"},          /* Flask Linux SID,     --SID */
-
 {"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 */
@@ -1414,6 +1310,9 @@
 
 {"RUSAGE",   "minflt,majflt,nswap,inblock,oublock,msgsnd,msgrcv,nsigs,nvcsw,nivcsw"}, /* Digital -o "RUSAGE" */
 {"SCHED",    "user,pcpu,pri,usrpri,nice,psxpri,psr,policy,pset"},                /* Digital -o "SCHED" */
+#ifdef WITH_SELINUX
+{"SELINUX_context",   "pid,context,command"},  /* SELinux Linux context, --context */
+#endif
 {"SFMT",     "uid,pid,cursig,sig,sigmask,sigignore,sigcatch,stat,tname,command"},  /* Digital s */
 
 {"Std_f",    "uid_hack,pid,ppid,c,stime,tname,time,cmd"},                     /* new -f */
--- procps-3.1.9.orig/ps/parser.c
+++ procps-3.1.9/ps/parser.c
@@ -727,7 +727,6 @@
   gnu_table_struct *found;
   static const gnu_table_struct gnu_table[] = {
   {"Group",         &&case_Group},       /* rgid */
-  {"SID",           &&case_secsid},
   {"User",          &&case_User},        /* ruid */
   {"cols",          &&case_cols},
   {"columns",       &&case_columns},
@@ -755,7 +754,6 @@
   {"pid",           &&case_pid},
   {"ppid",          &&case_ppid},
   {"rows",          &&case_rows},
-  {"secsid",        &&case_secsid},
   {"sid",           &&case_sid},
   {"sort",          &&case_sort},
   {"tty",           &&case_tty},
@@ -941,13 +939,14 @@
     exit(0);
     return NULL;
   case_context:
-    trace("--context\n");
-    format_flags |= FF_Fc;
+    if (is_selinux_enabled()) {
+	trace("--context\n");
+	format_flags |= FF_Fc;
+    } else {
+	  fprintf(stderr,
+		  "Warning: --context ignored. Requires a SELinux enabled kernel\n");
+    }
     return NULL;
-  case_secsid:
-     trace("--secsid\n");
-     format_flags |= FF_Fs;
-     return NULL;
 }
 
 /*************** process trailing PIDs  **********************/
--- procps-3.1.9.orig/ps/sortformat.c
+++ procps-3.1.9/ps/sortformat.c
@@ -803,9 +803,8 @@
     case FF_LX:          spec="OL_X";         break;
     case FF_Lm:          spec="OL_m";         break;
 
-    /* These are FLASK security options. */
-    case FF_Fc:          spec="FLASK_context"; break;
-    case FF_Fs:          spec="FLASK_sid";     break;
+    /* These are SELinux security options. */
+    case FF_Fc:          spec="SELINUX_context"; break;
 
     }  /* end switch(format_flags) */
 
--- procps-3.1.9.orig/ps/common.h
+++ procps-3.1.9/ps/common.h
@@ -103,7 +103,6 @@
 #define FF_LX 0x0100 /* X */
 #define FF_Lm 0x0200 /* m */  /* overloaded: threads, sort, format */
 #define FF_Fc 0x0400 /* --context */  /* Flask security context format */
-#define FF_Fs 0x0800 /* --SID */      /* Flask SID format */
 
 /* predefined format modifier flags such as:  -l -f l u s -j */
 #define FM_c 0x0001 /* -c */

             reply	other threads:[~2003-07-09 18:55 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2003-07-09 18:55 Colin Walters [this message]
     [not found] ` <1057805552.751.1243.camel@cube>
2003-07-11 19:14   ` port of procps patch to acahalan procps Colin Walters

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1057776906.28674.262.camel@columbia \
    --to=walters@verbum.org \
    --cc=SELinux@tycho.nsa.gov \
    --cc=albert@users.sourceforge.net \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.