~ubuntu-branches/ubuntu/intrepid/procps/intrepid-security

« back to all changes in this revision

Viewing changes to minimal.c

  • Committer: Bazaar Package Importer
  • Author(s): Colin Watson
  • Date: 2004-12-08 10:45:17 UTC
  • mfrom: (1.1.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20041208104517-dddigjyt093j9ql6
Tags: 1:3.2.4-1ubuntu1
Resynchronise with Debian.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*
2
 
 * Copyright 1998 by Albert Cahalan; all rights reserved.
 
2
 * Copyright 1998,2004 by Albert Cahalan; all rights reserved.
3
3
 * This file may be used subject to the terms and conditions of the
4
4
 * GNU Library General Public License Version 2, or any later version
5
5
 * at your option, as published by the Free Software Foundation.
27
27
#include <unistd.h>
28
28
#include <sys/stat.h>
29
29
#include <fcntl.h>
30
 
#include <sys/dir.h>
31
 
 
 
30
#include <dirent.h>
 
31
 
 
32
 
 
33
#define DEV_ENCODE(M,m) ( \
 
34
  ( (M&0xfff) << 8)   |   ( (m&0xfff00) << 12)   |   (m&0xff)   \
 
35
)
 
36
 
 
37
///////////////////////////////////////////////////////
 
38
#ifdef __sun__
 
39
#include <sys/mkdev.h>
 
40
#define _STRUCTURED_PROC 1
 
41
#include <sys/procfs.h>
 
42
#define NO_TTY_VALUE DEV_ENCODE(-1,-1)
 
43
#define HZ 1    // only bother with seconds
 
44
#endif
 
45
 
 
46
///////////////////////////////////////////////////////
 
47
#ifdef __FreeBSD__
 
48
#include <sys/param.h>
 
49
#include <sys/sysctl.h>
 
50
#include <sys/stat.h>
 
51
#include <sys/proc.h>
 
52
#include <sys/user.h>
 
53
#define NO_TTY_VALUE DEV_ENCODE(-1,-1)
 
54
#define HZ 1    // only bother with seconds
 
55
#endif
 
56
 
 
57
///////////////////////////////////////////////////////
 
58
#ifdef __linux__
32
59
#include <asm/param.h>  /* HZ */
33
60
#include <asm/page.h>   /* PAGE_SIZE */
34
 
 
 
61
#define NO_TTY_VALUE DEV_ENCODE(0,0)
 
62
#ifndef HZ
 
63
#warning HZ not defined, assuming it is 100
 
64
#define HZ 100
 
65
#endif
 
66
#endif
 
67
 
 
68
///////////////////////////////////////////////////////////
 
69
 
 
70
#ifndef PAGE_SIZE
 
71
#warning PAGE_SIZE not defined, assuming it is 4096
 
72
#define PAGE_SIZE 4096
 
73
#endif
 
74
 
 
75
 
 
76
 
 
77
static char P_tty_text[16];
 
78
static char P_cmd[16];
 
79
static char P_state;
35
80
static int P_euid;
36
81
static int P_pid;
37
 
static char P_cmd[16];
38
 
static char P_state;
39
 
static int P_ppid, P_pgrp, P_session, P_tty, P_tpgid;
 
82
static int P_ppid, P_pgrp, P_session, P_tty_num, P_tpgid;
40
83
static unsigned long P_flags, P_min_flt, P_cmin_flt, P_maj_flt, P_cmaj_flt, P_utime, P_stime;
41
 
static long P_cutime, P_cstime, P_priority, P_nice, P_timeout, P_it_real_value;
 
84
static long P_cutime, P_cstime, P_priority, P_nice, P_timeout, P_alarm;
42
85
static unsigned long P_start_time, P_vsize;
43
86
static long P_rss;
44
87
static unsigned long P_rss_rlim, P_start_code, P_end_code, P_start_stack, P_kstk_esp, P_kstk_eip;
46
89
static unsigned long P_wchan, P_nswap, P_cnswap;
47
90
 
48
91
 
 
92
 
49
93
#if 0
50
94
static int screen_cols = 80;
51
95
static int w_count;
69
113
static char *flagptr;  /* current location in ps_argv[thisarg] */
70
114
 
71
115
 
72
 
#ifndef PAGE_SIZE
73
 
#warning PAGE_SIZE not defined, assuming it is 4096
74
 
#define PAGE_SIZE 4096
75
 
#endif
76
 
 
77
 
#ifndef HZ
78
 
#warning HZ not defined, assuming it is 100
79
 
#define HZ 100
80
 
#endif
81
 
 
82
116
 
83
117
 
84
118
static void usage(void){
273
307
  if(bsd_c_option) show_args = 0;
274
308
}
275
309
 
 
310
#ifdef __sun__
 
311
/* return 1 if it works, or 0 for failure */
 
312
static int stat2proc(int pid) {
 
313
    struct psinfo p;  //   /proc/*/psinfo, struct psinfo, psinfo_t
 
314
    char buf[32];
 
315
    int num;
 
316
    int fd;
 
317
    int tty_maj, tty_min;
 
318
    snprintf(buf, sizeof buf, "/proc/%d/psinfo", pid);
 
319
    if ( (fd = open(buf, O_RDONLY, 0) ) == -1 ) return 0;
 
320
    num = read(fd, &p, sizeof p);
 
321
    close(fd);
 
322
    if(num != sizeof p) return 0;
 
323
 
 
324
    num = PRFNSZ;
 
325
    if (num >= sizeof P_cmd) num = sizeof P_cmd - 1;
 
326
    memcpy(P_cmd, p.pr_fname, num);  // p.pr_fname or p.pr_lwp.pr_name
 
327
    P_cmd[num] = '\0';
 
328
 
 
329
    P_pid     = p.pr_pid;
 
330
    P_ppid    = p.pr_ppid;
 
331
    P_pgrp    = p.pr_pgid;
 
332
    P_session = p.pr_sid;
 
333
    P_euid    = p.pr_euid;
 
334
    P_rss     = p.pr_rssize;
 
335
    P_vsize   = p.pr_size;
 
336
    P_start_time = p.pr_start.tv_sec;
 
337
    P_wchan   = p.pr_lwp.pr_wchan;
 
338
    P_state   = p.pr_lwp.pr_sname;
 
339
    P_nice    = p.pr_lwp.pr_nice;
 
340
    P_priority = p.pr_lwp.pr_pri;  // or pr_oldpri
 
341
//    P_ruid    = p.pr_uid;
 
342
//    P_rgid    = p.pr_gid;
 
343
//    P_egid    = p.pr_egid;
 
344
 
 
345
#if 0
 
346
    // don't support these
 
347
    P_tpgid; P_flags,
 
348
    P_min_flt, P_cmin_flt, P_maj_flt, P_cmaj_flt, P_utime, P_stime;
 
349
    P_cutime, P_cstime, P_timeout, P_alarm;
 
350
    P_rss_rlim, P_start_code, P_end_code, P_start_stack, P_kstk_esp, P_kstk_eip;
 
351
    P_signal, P_blocked, P_sigignore, P_sigcatch;
 
352
    P_nswap, P_cnswap;
 
353
#endif
 
354
 
 
355
    // we like it Linux-encoded :-)
 
356
    tty_maj = major(p.pr_ttydev);
 
357
    tty_min = minor(p.pr_ttydev);
 
358
    P_tty_num = DEV_ENCODE(tty_maj,tty_min);
 
359
 
 
360
    snprintf(P_tty_text, sizeof P_tty_text, "%3d,%-3d", tty_maj, tty_min);
 
361
#if 1
 
362
    if (tty_maj == 24) snprintf(P_tty_text, sizeof P_tty_text, "pts/%-3u", tty_min);
 
363
    if (P_tty_num == NO_TTY_VALUE)    memcpy(P_tty_text, "   ?   ", 8);
 
364
    if (P_tty_num == DEV_ENCODE(0,0)) memcpy(P_tty_text, "console", 8);
 
365
#endif
 
366
 
 
367
    if(P_pid != pid) return 0;
 
368
    return 1;
 
369
}
 
370
#endif
 
371
 
 
372
#ifdef __FreeBSD__
 
373
/* return 1 if it works, or 0 for failure */
 
374
static int stat2proc(int pid) {
 
375
    char buf[400];
 
376
    int num;
 
377
    int fd;
 
378
    char* tmp;
 
379
    int tty_maj, tty_min;
 
380
    snprintf(buf, 32, "/proc/%d/status", pid);
 
381
    if ( (fd = open(buf, O_RDONLY, 0) ) == -1 ) return 0;
 
382
    num = read(fd, buf, sizeof buf - 1);
 
383
    close(fd);
 
384
    if(num<43) return 0;
 
385
    buf[num] = '\0';
 
386
 
 
387
    P_state = '-';
 
388
 
 
389
    // FreeBSD /proc/*/status is seriously fucked. Unlike the Linux
 
390
    // files, we can't use strrchr to find the end of a command name.
 
391
    // Spaces in command names do not get escaped. To avoid spoofing,
 
392
    // one may skip 20 characters and then look _forward_ only to
 
393
    // find a pattern of entries that are {with,with,without} a comma.
 
394
    // The entry without a comma is wchan. Then count backwards!
 
395
    //
 
396
    // Don't bother for now. FreeBSD isn't worth the trouble.
 
397
 
 
398
    tmp = strchr(buf,' ');
 
399
    num = tmp - buf;
 
400
    if (num >= sizeof P_cmd) num = sizeof P_cmd - 1;
 
401
    memcpy(P_cmd,buf,num);
 
402
    P_cmd[num] = '\0';
 
403
 
 
404
    num = sscanf(tmp+1,
 
405
       "%d %d %d %d "
 
406
       "%d,%d "
 
407
       "%*s "
 
408
       "%ld,%*d "
 
409
       "%ld,%*d "
 
410
       "%ld,%*d "
 
411
       "%*s "
 
412
       "%d %d ",
 
413
       &P_pid, &P_ppid, &P_pgrp, &P_session,
 
414
       &tty_maj, &tty_min,
 
415
       /* SKIP funny flags thing */
 
416
       &P_start_time, /* SKIP microseconds */
 
417
       &P_utime, /* SKIP microseconds */
 
418
       &P_stime, /* SKIP microseconds */
 
419
       /* SKIP &P_wchan, for now -- it is a string */
 
420
       &P_euid, &P_euid   // don't know which is which
 
421
    );
 
422
/*    fprintf(stderr, "stat2proc converted %d fields.\n",num); */
 
423
 
 
424
    snprintf(P_tty_text, sizeof P_tty_text, "%3d,%-3d", tty_maj, tty_min);
 
425
    P_tty_num = DEV_ENCODE(tty_maj,tty_min);
 
426
// tty decode is 224 to 256 bytes on i386
 
427
#if 1
 
428
    tmp = NULL;
 
429
    if (tty_maj ==  5) tmp = " ttyp%c ";
 
430
    if (tty_maj == 12) tmp = " ttyv%c ";
 
431
    if (tty_maj == 28) tmp = " ttyd%c ";
 
432
    if (P_tty_num == NO_TTY_VALUE) tmp = "   ?   ";
 
433
    if (P_tty_num == DEV_ENCODE(0,0)) tmp = "console";
 
434
    if (P_tty_num == DEV_ENCODE(12,255)) tmp = "consolectl";
 
435
    if (tmp) {
 
436
      snprintf(
 
437
        P_tty_text,
 
438
        sizeof P_tty_text,
 
439
        tmp,
 
440
        "0123456789abcdefghijklmnopqrstuvwxyz"[tty_min&31]
 
441
      );
 
442
    }
 
443
#endif
 
444
 
 
445
    if(num < 9) return 0;
 
446
    if(P_pid != pid) return 0;
 
447
    return 1;
 
448
}
 
449
#endif
 
450
 
 
451
#ifdef __linux__
276
452
/* return 1 if it works, or 0 for failure */
277
453
static int stat2proc(int pid) {
278
454
    char buf[800]; /* about 40 fields, 64-bit decimal is about 20 chars */
304
480
       "%u %u %u %u " /* no use for RT signals */
305
481
       "%lu %lu %lu",
306
482
       &P_state,
307
 
       &P_ppid, &P_pgrp, &P_session, &P_tty, &P_tpgid,
 
483
       &P_ppid, &P_pgrp, &P_session, &P_tty_num, &P_tpgid,
308
484
       &P_flags, &P_min_flt, &P_cmin_flt, &P_maj_flt, &P_cmaj_flt, &P_utime, &P_stime,
309
 
       &P_cutime, &P_cstime, &P_priority, &P_nice, &P_timeout, &P_it_real_value,
 
485
       &P_cutime, &P_cstime, &P_priority, &P_nice, &P_timeout, &P_alarm,
310
486
       &P_start_time, &P_vsize,
311
487
       &P_rss,
312
488
       &P_rss_rlim, &P_start_code, &P_end_code, &P_start_stack, &P_kstk_esp, &P_kstk_eip,
316
492
/*    fprintf(stderr, "stat2proc converted %d fields.\n",num); */
317
493
    P_vsize /= 1024;
318
494
    P_rss *= (PAGE_SIZE/1024);
 
495
 
 
496
    memcpy(P_tty_text, "   ?   ", 8);
 
497
    if (P_tty_num != NO_TTY_VALUE) {
 
498
      int tty_maj = (P_tty_num>>8)&0xfff;
 
499
      int tty_min = (P_tty_num&0xff) | ((P_tty_num>>12)&0xfff00);
 
500
      snprintf(P_tty_text, sizeof P_tty_text, "%3d,%-3d", tty_maj, tty_min);
 
501
    }
 
502
 
319
503
    if(num < 30) return 0;
320
504
    if(P_pid != pid) return 0;
321
505
    return 1;
322
506
}
 
507
#endif
323
508
 
324
509
static const char *do_time(unsigned long t){
325
510
  int hh,mm,ss;
370
555
}
371
556
 
372
557
static void print_proc(void){
373
 
  char tty[16];
374
 
  snprintf(tty, sizeof tty, "%3d,%-3d", (P_tty>>8)&0xff, P_tty&0xff);
375
558
  switch(ps_format){
376
559
  case 0:
377
 
    printf("%5d %s %s", P_pid, tty, do_time(P_utime+P_stime));
 
560
    printf("%5d %s %s", P_pid, P_tty_text, do_time(P_utime+P_stime));
378
561
    break;
379
562
  case 'o':
380
563
    printf("%d\n", P_pid);
381
564
    return; /* don't want the command */
382
565
  case 'l':
383
566
    printf(
384
 
      "%03x %c %5d %5d %5d %s %3d %3d - "
 
567
      "0 %c %5d %5d %5d %s %3d %3d - "
385
568
      "%5ld %06x %s %s",
386
 
      (unsigned)P_flags&0x777, P_state, P_euid, P_pid, P_ppid, do_cpu(0),
 
569
      P_state, P_euid, P_pid, P_ppid, do_cpu(0),
387
570
      (int)P_priority, (int)P_nice, P_vsize/(PAGE_SIZE/1024),
388
 
      (unsigned)(P_wchan&0xffffff), tty, do_time(P_utime+P_stime)
 
571
      (unsigned)(P_wchan&0xffffff), P_tty_text, do_time(P_utime+P_stime)
389
572
    );
390
573
    break;
391
574
  case 'f':
392
575
    printf(
393
576
      "%8s %5d %5d %s %s %s %s",
394
 
      do_user(), P_pid, P_ppid, do_cpu(0), do_stime(), tty, do_time(P_utime+P_stime)
 
577
      do_user(), P_pid, P_ppid, do_cpu(0), do_stime(), P_tty_text, do_time(P_utime+P_stime)
395
578
    );
396
579
    break;
397
580
  case 'j':
398
581
    printf(
399
582
      "%5d %5d %5d %s %s",
400
 
      P_pid, P_pgrp, P_session, tty, do_time(P_utime+P_stime)
 
583
      P_pid, P_pgrp, P_session, P_tty_text, do_time(P_utime+P_stime)
401
584
    );
402
585
    break;
403
586
  case 'u'|0x80:
404
587
    printf(
405
588
      "%8s %5d %s %s %5ld %4ld %s %c %s %s",
406
 
      do_user(), P_pid, do_cpu(1), do_mem(1), P_vsize, P_rss, tty, P_state,
 
589
      do_user(), P_pid, do_cpu(1), do_mem(1), P_vsize, P_rss, P_tty_text, P_state,
407
590
      do_stime(), do_time(P_utime+P_stime)
408
591
    );
409
592
    break;
410
593
  case 'v'|0x80:
411
594
    printf(
412
595
      "%5d %s %c %s %6d   -   - %5d %s",
413
 
      P_pid, tty, P_state, do_time(P_utime+P_stime), (int)P_maj_flt,
 
596
      P_pid, P_tty_text, P_state, do_time(P_utime+P_stime), (int)P_maj_flt,
414
597
      (int)P_rss, do_mem(1)
415
598
    );
416
599
    break;
417
600
  case 'j'|0x80:
418
601
    printf(
419
602
      "%5d %5d %5d %5d %s %5d %c %5d %s",
420
 
      P_ppid, P_pid, P_pgrp, P_session, tty, P_tpgid, P_state, P_euid, do_time(P_utime+P_stime)
 
603
      P_ppid, P_pid, P_pgrp, P_session, P_tty_text, P_tpgid, P_state, P_euid, do_time(P_utime+P_stime)
421
604
    );
422
605
    break;
423
606
  case 'l'|0x80:
424
607
    printf(
425
 
      "%03x %5d %5d %5d %3d %3d "
 
608
      "0 %5d %5d %5d %3d %3d "
426
609
      "%5ld %4ld %06x %c %s %s",
427
 
      (unsigned)P_flags&0x777, P_euid, P_pid, P_ppid, (int)P_priority, (int)P_nice,
428
 
      P_vsize, P_rss, (unsigned)(P_wchan&0xffffff), P_state, tty, do_time(P_utime+P_stime)
 
610
      P_euid, P_pid, P_ppid, (int)P_priority, (int)P_nice,
 
611
      P_vsize, P_rss, (unsigned)(P_wchan&0xffffff), P_state, P_tty_text, do_time(P_utime+P_stime)
429
612
    );
430
613
    break;
431
614
  default:
 
615
    ;
432
616
  }
433
617
  if(show_args) printf(" [%s]\n", P_cmd);
434
618
  else          printf(" %s\n", P_cmd);
445
629
    switch(ps_format){
446
630
    default: /* can't happen */
447
631
    case 0:        head = "  PID TTY         TIME CMD"; break;
448
 
    case 'l':      head = "  F S   UID   PID  PPID  C PRI  NI ADDR SZ WCHAN    TTY       TIME CMD"; break;
 
632
    case 'l':      head = "F S   UID   PID  PPID  C PRI  NI ADDR SZ WCHAN    TTY       TIME CMD"; break;
449
633
    case 'f':      head = "USER       PID  PPID  C STIME   TTY       TIME CMD"; break;
450
634
    case 'j':      head = "  PID  PGID   SID TTY         TIME CMD"; break;
451
635
    case 'u'|0x80: head = "USER       PID %CPU %MEM   VSZ  RSS   TTY   S START     TIME COMMAND"; break;
452
636
    case 'v'|0x80: head = "  PID   TTY   S     TIME  MAJFL TRS DRS   RSS %MEM COMMAND"; break;
453
637
    case 'j'|0x80: head = " PPID   PID  PGID   SID   TTY   TPGID S   UID     TIME COMMAND"; break;
454
 
    case 'l'|0x80: head = "  F   UID   PID  PPID PRI  NI   VSZ  RSS WCHAN  S   TTY       TIME COMMAND"; break;
 
638
    case 'l'|0x80: head = "F   UID   PID  PPID PRI  NI   VSZ  RSS WCHAN  S   TTY       TIME COMMAND"; break;
455
639
    }
456
640
    printf("%s\n",head);
457
641
  }
459
643
    if(stat2proc(want_one_pid)) print_proc();
460
644
    else exit(1);
461
645
  }else{
462
 
    struct direct *ent;          /* dirent handle */
 
646
    struct dirent *ent;          /* dirent handle */
463
647
    DIR *dir;
464
648
    int ouruid;
465
649
    int found_a_proc;
472
656
      if(want_one_command){
473
657
        if(strcmp(want_one_command,P_cmd)) continue;
474
658
      }else{
475
 
        if(!select_notty && P_tty==-1) continue;
 
659
        if(!select_notty && P_tty_num==NO_TTY_VALUE) continue;
476
660
        if(!select_all && P_euid!=ouruid) continue;
477
661
      }
478
662
      found_a_proc++;