checkpoint

This commit is contained in:
albert
2002-12-21 06:22:00 +00:00
parent b8c8125f63
commit 1158fdd1b1
7 changed files with 40 additions and 31 deletions

108
proc/escape.c Normal file
View File

@@ -0,0 +1,108 @@
/*
* Copyright 1998-2002 by Albert Cahalan; all rights resered.
* This file may be used subject to the terms and conditions of the
* GNU Library General Public License Version 2, or any later version
* at your option, as published by the Free Software Foundation.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Library General Public License for more details.
*/
#include <sys/types.h>
#include "../proc/procps.h"
#include "common.h"
/* sanitize a string, without the nice BSD library function: */
/* strvis(vis_args, k->ki_args, VIS_TAB | VIS_NL | VIS_NOSLASH) */
int octal_escape_str(char *restrict dst, const char *restrict src, size_t n){
unsigned char c;
char d;
size_t i;
const char codes[] =
"Z------abtnvfr-------------e----"
" *******************************" /* better: do not print any space */
"****************************\\***"
"*******************************-"
"--------------------------------"
"********************************"
"********************************"
"********************************";
for(i=0; i<n;){
c = (unsigned char) *(src++);
d = codes[c];
switch(d){
case 'Z':
goto leave;
case '*':
i++;
*(dst++) = c;
break;
case '-':
if(i+4 > n) goto leave;
i += 4;
*(dst++) = '\\';
*(dst++) = "01234567"[c>>6];
*(dst++) = "01234567"[(c>>3)&07];
*(dst++) = "01234567"[c&07];
break;
default:
if(i+2 > n) goto leave;
i += 2;
*(dst++) = '\\';
*(dst++) = d;
break;
}
}
leave:
*(dst++) = '\0';
return i;
}
/* sanitize a string via one-way mangle */
int simple_escape_str(char *restrict dst, const char *restrict src, size_t n){
unsigned char c;
size_t i;
const char codes[] =
"Z-------------------------------"
"********************************"
"********************************"
"*******************************-"
"--------------------------------"
"********************************"
"********************************"
"********************************";
for(i=0; i<n;){
c = (unsigned char) *(src++);
switch(codes[c]){
case 'Z':
goto leave;
case '*':
i++;
*(dst++) = c;
break;
case '-':
i++;
*(dst++) = '?';
break;
}
}
leave:
*(dst++) = '\0';
return i;
}
/* escape a string as desired */
int escape_str(char *restrict dst, const char *restrict src, size_t n){
return simple_escape_str(dst, src, n);
}
/* escape an argv or environment string array */
int escape_strlist(char *restrict dst, const char *restrict const *restrict src, size_t n){
size_t i = 0;
while(*src){
i += simple_escape_str(dst+i, *src, n-i);
if((n-i > 1) && src[1]) dst[i++] = ' ';
src++;
}
return i;
}

View File

@@ -77,6 +77,13 @@ void freeproc(proc_t* p) {
}
// 2.5.xx looks like:
//
// "State:\t%s\n"
// "Tgid:\t%d\n"
// "Pid:\t%d\n"
// "PPid:\t%d\n"
// "TracerPid:\t%d\n"
static void status2proc(const char *S, proc_t *restrict P){
char* tmp;
@@ -105,11 +112,9 @@ static void status2proc(const char *S, proc_t *restrict P){
if(likely(tmp)) P->state = tmp[7];
else fprintf(stderr, "Internal error!\n");
tmp = strstr (S,"Pid:");
tmp = strstr (S,"PPid:");
if(likely(tmp)) sscanf (tmp,
"Pid:\t%d\n"
"PPid:\t%d\n",
&P->pid,
&P->ppid
);
else fprintf(stderr, "Internal error!\n");
@@ -166,10 +171,8 @@ static void status2proc(const char *S, proc_t *restrict P){
/* stat2proc() makes sure it can handle arbitrary executable file basenames
* for `cmd', i.e. those with embedded whitespace or embedded ')'s.
* Such names confuse %s (see scanf(3)), so the string is split and %39c
* is used instead. (except for embedded ')' "(%[^)]c)" would work.
/* Reads /proc/*/stat files, being careful not to trip over processes with
* names like ":-) 1 2 3 4 5 6".
*/
static void stat2proc(const char* S, proc_t *restrict P) {
unsigned num;
@@ -181,9 +184,8 @@ static void stat2proc(const char* S, proc_t *restrict P) {
P->rtprio = -1;
P->sched = -1;
P->pid = strtol(S, &tmp, 10);
S = tmp + 2;
tmp = strrchr(S, ')'); // split into "PID (cmd" and "<rest>"
S = strchr(S, '(') + 1;
tmp = strrchr(S, ')');
num = tmp - S;
if(unlikely(num >= sizeof P->cmd)) num = sizeof P->cmd - 1;
memcpy(P->cmd, S, num);
@@ -376,16 +378,20 @@ next_proc: /* get next PID for consideration */
#define flags (PT->flags)
if (flags & PROC_PID) {
if (unlikely(!*PT->pids)) /* set to next item in pids */
return NULL;
sprintf(path, "/proc/%d", *(PT->pids)++);
pid_t pid = *(PT->pids)++;
if (unlikely(!pid)) return NULL;
p->pid = pid;
snprintf(path, sizeof path, "/proc/%d", pid);
} else { /* get next numeric /proc ent */
for (;;) {
ent = readdir(PT->procfs);
if(unlikely(unlikely(!ent) || unlikely(!ent->d_name))) return NULL;
if(likely( likely(*ent->d_name > '0') && likely(*ent->d_name < '9') )) break;
if(likely( likely(*ent->d_name > '0') && likely(*ent->d_name <= '9') )) break;
}
sprintf(path, "/proc/%s", ent->d_name);
p->pid = strtoul(ent->d_name, NULL, 10);
memcpy(path, "/proc/", 6);
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) */
@@ -452,9 +458,6 @@ next_proc: /* get next PID for consideration */
else
p->environ = NULL;
if (unlikely(p->state == 'Z')) /* fixup cmd for zombies */
strncat(p->cmd," <defunct>", sizeof p->cmd);
return p;
}
#undef flags
@@ -484,12 +487,15 @@ next_proc: /* get next PID for consideration */
/*printf("PT->flags is 0x%08x\n", PT->flags);*/
#define flags (PT->flags)
while ((ent = readdir(PT->procfs)) &&
(*ent->d_name < '0' || *ent->d_name > '9'))
;
if (!ent || !ent->d_name)
return NULL;
sprintf(path, "/proc/%s", ent->d_name);
for (;;) {
ent = readdir(PT->procfs);
if(unlikely(unlikely(!ent) || unlikely(!ent->d_name))) return NULL;
if(likely( likely(*ent->d_name > '0') && likely(*ent->d_name <= '9') )) break;
}
p->pid = strtoul(ent->d_name, NULL, 10);
memcpy(path, "/proc/", 6);
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) */
@@ -550,9 +556,6 @@ next_proc: /* get next PID for consideration */
else
p->environ = NULL;
if (p->state == 'Z') /* fixup cmd for zombies */
strncat(p->cmd," <defunct>", sizeof p->cmd);
return p;
}
#undef flags