diff options
author | KaiGai Kohei <kaigai@ak.jp.nec.com> | 2006-06-25 08:49:25 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-06-25 13:01:25 -0400 |
commit | f6ec29a42d7ac3b309a9cef179b686d23986ab98 (patch) | |
tree | 5150d4f403833ac18b468bd0e0e0a9a7cdd9f4be /kernel/acct.c | |
parent | 0e4648141af02331f21aabcd34940c70f09a2d04 (diff) |
[PATCH] pacct: avoidance to refer the last thread as a representation of the process
When pacct facility generate an 'ac_flag' field in accounting record, it
refers a task_struct of the thread which died last in the process. But any
other task_structs are ignored.
Therefore, pacct facility drops ASU flag even if root-privilege operations are
used by any other threads except the last one. In addition, AFORK flag is
always set when the thread of group-leader didn't die last, although this
process has called execve() after fork().
We have a same matter in ac_exitcode. The recorded ac_exitcode is an exit
code of the last thread in the process. There is a possibility this exitcode
is not the group leader's one.
Diffstat (limited to 'kernel/acct.c')
-rw-r--r-- | kernel/acct.c | 42 |
1 files changed, 24 insertions, 18 deletions
diff --git a/kernel/acct.c b/kernel/acct.c index b35263137824..4c85fdf615da 100644 --- a/kernel/acct.c +++ b/kernel/acct.c | |||
@@ -75,7 +75,7 @@ int acct_parm[3] = {4, 2, 30}; | |||
75 | /* | 75 | /* |
76 | * External references and all of the globals. | 76 | * External references and all of the globals. |
77 | */ | 77 | */ |
78 | static void do_acct_process(long, struct file *); | 78 | static void do_acct_process(struct file *); |
79 | 79 | ||
80 | /* | 80 | /* |
81 | * This structure is used so that all the data protected by lock | 81 | * This structure is used so that all the data protected by lock |
@@ -196,7 +196,7 @@ static void acct_file_reopen(struct file *file) | |||
196 | if (old_acct) { | 196 | if (old_acct) { |
197 | mnt_unpin(old_acct->f_vfsmnt); | 197 | mnt_unpin(old_acct->f_vfsmnt); |
198 | spin_unlock(&acct_globals.lock); | 198 | spin_unlock(&acct_globals.lock); |
199 | do_acct_process(0, old_acct); | 199 | do_acct_process(old_acct); |
200 | filp_close(old_acct, NULL); | 200 | filp_close(old_acct, NULL); |
201 | spin_lock(&acct_globals.lock); | 201 | spin_lock(&acct_globals.lock); |
202 | } | 202 | } |
@@ -419,7 +419,7 @@ static u32 encode_float(u64 value) | |||
419 | /* | 419 | /* |
420 | * do_acct_process does all actual work. Caller holds the reference to file. | 420 | * do_acct_process does all actual work. Caller holds the reference to file. |
421 | */ | 421 | */ |
422 | static void do_acct_process(long exitcode, struct file *file) | 422 | static void do_acct_process(struct file *file) |
423 | { | 423 | { |
424 | struct pacct_struct *pacct = ¤t->signal->pacct; | 424 | struct pacct_struct *pacct = ¤t->signal->pacct; |
425 | acct_t ac; | 425 | acct_t ac; |
@@ -496,17 +496,10 @@ static void do_acct_process(long exitcode, struct file *file) | |||
496 | old_encode_dev(tty_devnum(current->signal->tty)) : 0; | 496 | old_encode_dev(tty_devnum(current->signal->tty)) : 0; |
497 | read_unlock(&tasklist_lock); | 497 | read_unlock(&tasklist_lock); |
498 | 498 | ||
499 | ac.ac_flag = 0; | ||
500 | if (current->flags & PF_FORKNOEXEC) | ||
501 | ac.ac_flag |= AFORK; | ||
502 | if (current->flags & PF_SUPERPRIV) | ||
503 | ac.ac_flag |= ASU; | ||
504 | if (current->flags & PF_DUMPCORE) | ||
505 | ac.ac_flag |= ACORE; | ||
506 | if (current->flags & PF_SIGNALED) | ||
507 | ac.ac_flag |= AXSIG; | ||
508 | spin_lock(¤t->sighand->siglock); | 499 | spin_lock(¤t->sighand->siglock); |
500 | ac.ac_flag = pacct->ac_flag; | ||
509 | ac.ac_mem = encode_comp_t(pacct->ac_mem); | 501 | ac.ac_mem = encode_comp_t(pacct->ac_mem); |
502 | ac.ac_exitcode = pacct->ac_exitcode; | ||
510 | spin_unlock(¤t->sighand->siglock); | 503 | spin_unlock(¤t->sighand->siglock); |
511 | ac.ac_io = encode_comp_t(0 /* current->io_usage */); /* %% */ | 504 | ac.ac_io = encode_comp_t(0 /* current->io_usage */); /* %% */ |
512 | ac.ac_rw = encode_comp_t(ac.ac_io / 1024); | 505 | ac.ac_rw = encode_comp_t(ac.ac_io / 1024); |
@@ -515,7 +508,6 @@ static void do_acct_process(long exitcode, struct file *file) | |||
515 | ac.ac_majflt = encode_comp_t(current->signal->maj_flt + | 508 | ac.ac_majflt = encode_comp_t(current->signal->maj_flt + |
516 | current->maj_flt); | 509 | current->maj_flt); |
517 | ac.ac_swaps = encode_comp_t(0); | 510 | ac.ac_swaps = encode_comp_t(0); |
518 | ac.ac_exitcode = exitcode; | ||
519 | 511 | ||
520 | /* | 512 | /* |
521 | * Kernel segment override to datasegment and write it | 513 | * Kernel segment override to datasegment and write it |
@@ -544,13 +536,15 @@ void acct_init_pacct(struct pacct_struct *pacct) | |||
544 | 536 | ||
545 | /** | 537 | /** |
546 | * acct_collect - collect accounting information into pacct_struct | 538 | * acct_collect - collect accounting information into pacct_struct |
539 | * @exitcode: task exit code | ||
540 | * @group_dead: not 0, if this thread is the last one in the process. | ||
547 | */ | 541 | */ |
548 | void acct_collect(void) | 542 | void acct_collect(long exitcode, int group_dead) |
549 | { | 543 | { |
550 | struct pacct_struct *pacct = ¤t->signal->pacct; | 544 | struct pacct_struct *pacct = ¤t->signal->pacct; |
551 | unsigned long vsize = 0; | 545 | unsigned long vsize = 0; |
552 | 546 | ||
553 | if (current->mm) { | 547 | if (group_dead && current->mm) { |
554 | struct vm_area_struct *vma; | 548 | struct vm_area_struct *vma; |
555 | down_read(¤t->mm->mmap_sem); | 549 | down_read(¤t->mm->mmap_sem); |
556 | vma = current->mm->mmap; | 550 | vma = current->mm->mmap; |
@@ -562,7 +556,19 @@ void acct_collect(void) | |||
562 | } | 556 | } |
563 | 557 | ||
564 | spin_lock(¤t->sighand->siglock); | 558 | spin_lock(¤t->sighand->siglock); |
565 | pacct->ac_mem = vsize / 1024; | 559 | if (group_dead) |
560 | pacct->ac_mem = vsize / 1024; | ||
561 | if (thread_group_leader(current)) { | ||
562 | pacct->ac_exitcode = exitcode; | ||
563 | if (current->flags & PF_FORKNOEXEC) | ||
564 | pacct->ac_flag |= AFORK; | ||
565 | } | ||
566 | if (current->flags & PF_SUPERPRIV) | ||
567 | pacct->ac_flag |= ASU; | ||
568 | if (current->flags & PF_DUMPCORE) | ||
569 | pacct->ac_flag |= ACORE; | ||
570 | if (current->flags & PF_SIGNALED) | ||
571 | pacct->ac_flag |= AXSIG; | ||
566 | spin_unlock(¤t->sighand->siglock); | 572 | spin_unlock(¤t->sighand->siglock); |
567 | } | 573 | } |
568 | 574 | ||
@@ -572,7 +578,7 @@ void acct_collect(void) | |||
572 | * | 578 | * |
573 | * handles process accounting for an exiting task | 579 | * handles process accounting for an exiting task |
574 | */ | 580 | */ |
575 | void acct_process(long exitcode) | 581 | void acct_process() |
576 | { | 582 | { |
577 | struct file *file = NULL; | 583 | struct file *file = NULL; |
578 | 584 | ||
@@ -591,7 +597,7 @@ void acct_process(long exitcode) | |||
591 | get_file(file); | 597 | get_file(file); |
592 | spin_unlock(&acct_globals.lock); | 598 | spin_unlock(&acct_globals.lock); |
593 | 599 | ||
594 | do_acct_process(exitcode, file); | 600 | do_acct_process(file); |
595 | fput(file); | 601 | fput(file); |
596 | } | 602 | } |
597 | 603 | ||