^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * linux/kernel/acct.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * BSD Process Accounting for Linux
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * Author: Marco van Wieringen <mvw@planets.elm.net>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * Some code based on ideas and code from:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) * Thomas K. Dyas <tdyas@eden.rutgers.edu>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) * This file implements BSD-style process accounting. Whenever any
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) * process exits, an accounting record of type "struct acct" is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) * written to the file specified with the acct() system call. It is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) * up to user-level programs to do useful things with the accounting
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) * log. The kernel just provides the raw accounting information.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) * (C) Copyright 1995 - 1997 Marco van Wieringen - ELM Consultancy B.V.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) * Plugged two leaks. 1) It didn't return acct_file into the free_filps if
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) * the file happened to be read-only. 2) If the accounting was suspended
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) * due to the lack of space it happily allowed to reopen it and completely
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) * lost the old acct_file. 3/10/98, Al Viro.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) * Now we silently close acct_file on attempt to reopen. Cleaned sys_acct().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) * XTerms and EMACS are manifestations of pure evil. 21/10/98, AV.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) * Fixed a nasty interaction with sys_umount(). If the accounting
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) * was suspeneded we failed to stop it on umount(). Messy.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) * Another one: remount to readonly didn't stop accounting.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) * Question: what should we do if we have CAP_SYS_ADMIN but not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) * CAP_SYS_PACCT? Current code does the following: umount returns -EBUSY
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) * unless we are messing with the root. In that case we are getting a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) * real mess with do_remount_sb(). 9/11/98, AV.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) * Fixed a bunch of races (and pair of leaks). Probably not the best way,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) * but this one obviously doesn't introduce deadlocks. Later. BTW, found
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) * one race (and leak) in BSD implementation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) * OK, that's better. ANOTHER race and leak in BSD variant. There always
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) * is one more bug... 10/11/98, AV.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) * Oh, fsck... Oopsable SMP race in do_process_acct() - we must hold
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) * ->mmap_lock to walk the vma list of current->mm. Nasty, since it leaks
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) * a struct file opened for write. Fixed. 2/6/2000, AV.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) #include <linux/mm.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) #include <linux/acct.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) #include <linux/capability.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) #include <linux/file.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) #include <linux/tty.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) #include <linux/security.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) #include <linux/vfs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) #include <linux/jiffies.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) #include <linux/times.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) #include <linux/syscalls.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) #include <linux/mount.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) #include <linux/uaccess.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) #include <linux/sched/cputime.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) #include <asm/div64.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) #include <linux/blkdev.h> /* sector_div */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) #include <linux/pid_namespace.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) #include <linux/fs_pin.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) * These constants control the amount of freespace that suspend and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) * resume the process accounting system, and the time delay between
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) * each check.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) * Turned into sysctl-controllable parameters. AV, 12/11/98
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) int acct_parm[3] = {4, 2, 30};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) #define RESUME (acct_parm[0]) /* >foo% free space - resume */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) #define SUSPEND (acct_parm[1]) /* <foo% free space - suspend */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) #define ACCT_TIMEOUT (acct_parm[2]) /* foo second timeout between checks */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) * External references and all of the globals.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) struct bsd_acct_struct {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) struct fs_pin pin;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) atomic_long_t count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) struct rcu_head rcu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) struct mutex lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) int active;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) unsigned long needcheck;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) struct file *file;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) struct pid_namespace *ns;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) struct work_struct work;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) struct completion done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) static void do_acct_process(struct bsd_acct_struct *acct);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) * Check the amount of free space and suspend/resume accordingly.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) static int check_free_space(struct bsd_acct_struct *acct)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) struct kstatfs sbuf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) if (time_is_after_jiffies(acct->needcheck))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) /* May block */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) if (vfs_statfs(&acct->file->f_path, &sbuf))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) if (acct->active) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) u64 suspend = sbuf.f_blocks * SUSPEND;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) do_div(suspend, 100);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) if (sbuf.f_bavail <= suspend) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) acct->active = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) pr_info("Process accounting paused\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) u64 resume = sbuf.f_blocks * RESUME;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) do_div(resume, 100);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) if (sbuf.f_bavail >= resume) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) acct->active = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) pr_info("Process accounting resumed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) acct->needcheck = jiffies + ACCT_TIMEOUT*HZ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) return acct->active;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) static void acct_put(struct bsd_acct_struct *p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) if (atomic_long_dec_and_test(&p->count))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) kfree_rcu(p, rcu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) static inline struct bsd_acct_struct *to_acct(struct fs_pin *p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) return p ? container_of(p, struct bsd_acct_struct, pin) : NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) static struct bsd_acct_struct *acct_get(struct pid_namespace *ns)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) struct bsd_acct_struct *res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) again:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) smp_rmb();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) res = to_acct(READ_ONCE(ns->bacct));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) if (!res) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) if (!atomic_long_inc_not_zero(&res->count)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) cpu_relax();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) goto again;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) mutex_lock(&res->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) if (res != to_acct(READ_ONCE(ns->bacct))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) mutex_unlock(&res->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) acct_put(res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) goto again;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) return res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) static void acct_pin_kill(struct fs_pin *pin)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) struct bsd_acct_struct *acct = to_acct(pin);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) mutex_lock(&acct->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) do_acct_process(acct);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) schedule_work(&acct->work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) wait_for_completion(&acct->done);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) cmpxchg(&acct->ns->bacct, pin, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) mutex_unlock(&acct->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) pin_remove(pin);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) acct_put(acct);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) static void close_work(struct work_struct *work)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) struct bsd_acct_struct *acct = container_of(work, struct bsd_acct_struct, work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) struct file *file = acct->file;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) if (file->f_op->flush)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) file->f_op->flush(file, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) __fput_sync(file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) complete(&acct->done);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) static int acct_on(struct filename *pathname)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) struct file *file;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) struct vfsmount *mnt, *internal;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) struct pid_namespace *ns = task_active_pid_ns(current);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) struct bsd_acct_struct *acct;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) struct fs_pin *old;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) acct = kzalloc(sizeof(struct bsd_acct_struct), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) if (!acct)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) /* Difference from BSD - they don't do O_APPEND */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) file = file_open_name(pathname, O_WRONLY|O_APPEND|O_LARGEFILE, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) if (IS_ERR(file)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) kfree(acct);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) return PTR_ERR(file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) if (!S_ISREG(file_inode(file)->i_mode)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) kfree(acct);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) filp_close(file, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) return -EACCES;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) if (!(file->f_mode & FMODE_CAN_WRITE)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) kfree(acct);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) filp_close(file, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) internal = mnt_clone_internal(&file->f_path);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) if (IS_ERR(internal)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) kfree(acct);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) filp_close(file, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) return PTR_ERR(internal);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) err = __mnt_want_write(internal);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) mntput(internal);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) kfree(acct);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) filp_close(file, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) mnt = file->f_path.mnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) file->f_path.mnt = internal;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) atomic_long_set(&acct->count, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) init_fs_pin(&acct->pin, acct_pin_kill);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) acct->file = file;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) acct->needcheck = jiffies;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) acct->ns = ns;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) mutex_init(&acct->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) INIT_WORK(&acct->work, close_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) init_completion(&acct->done);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) mutex_lock_nested(&acct->lock, 1); /* nobody has seen it yet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) pin_insert(&acct->pin, mnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) old = xchg(&ns->bacct, &acct->pin);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) mutex_unlock(&acct->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) pin_kill(old);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) __mnt_drop_write(mnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) mntput(mnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) static DEFINE_MUTEX(acct_on_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) * sys_acct - enable/disable process accounting
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) * @name: file name for accounting records or NULL to shutdown accounting
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) * sys_acct() is the only system call needed to implement process
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) * accounting. It takes the name of the file where accounting records
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) * should be written. If the filename is NULL, accounting will be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) * shutdown.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) * Returns: 0 for success or negative errno values for failure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) SYSCALL_DEFINE1(acct, const char __user *, name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) int error = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) if (!capable(CAP_SYS_PACCT))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) return -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) if (name) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) struct filename *tmp = getname(name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) if (IS_ERR(tmp))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) return PTR_ERR(tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) mutex_lock(&acct_on_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) error = acct_on(tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) mutex_unlock(&acct_on_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) putname(tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) pin_kill(task_active_pid_ns(current)->bacct);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) void acct_exit_ns(struct pid_namespace *ns)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) pin_kill(ns->bacct);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) * encode an unsigned long into a comp_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) * This routine has been adopted from the encode_comp_t() function in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) * the kern_acct.c file of the FreeBSD operating system. The encoding
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) * is a 13-bit fraction with a 3-bit (base 8) exponent.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) #define MANTSIZE 13 /* 13 bit mantissa. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) #define EXPSIZE 3 /* Base 8 (3 bit) exponent. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) #define MAXFRACT ((1 << MANTSIZE) - 1) /* Maximum fractional value. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) static comp_t encode_comp_t(unsigned long value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) int exp, rnd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) exp = rnd = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) while (value > MAXFRACT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) rnd = value & (1 << (EXPSIZE - 1)); /* Round up? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) value >>= EXPSIZE; /* Base 8 exponent == 3 bit shift. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) exp++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) * If we need to round up, do it (and handle overflow correctly).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) if (rnd && (++value > MAXFRACT)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) value >>= EXPSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) exp++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) * Clean it up and polish it off.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) exp <<= MANTSIZE; /* Shift the exponent into place */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) exp += value; /* and add on the mantissa. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) return exp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) #if ACCT_VERSION == 1 || ACCT_VERSION == 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) * encode an u64 into a comp2_t (24 bits)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) * Format: 5 bit base 2 exponent, 20 bits mantissa.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) * The leading bit of the mantissa is not stored, but implied for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) * non-zero exponents.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) * Largest encodable value is 50 bits.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) #define MANTSIZE2 20 /* 20 bit mantissa. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) #define EXPSIZE2 5 /* 5 bit base 2 exponent. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) #define MAXFRACT2 ((1ul << MANTSIZE2) - 1) /* Maximum fractional value. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) #define MAXEXP2 ((1 << EXPSIZE2) - 1) /* Maximum exponent. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) static comp2_t encode_comp2_t(u64 value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) int exp, rnd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) exp = (value > (MAXFRACT2>>1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) rnd = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) while (value > MAXFRACT2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) rnd = value & 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) value >>= 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) exp++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) * If we need to round up, do it (and handle overflow correctly).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) if (rnd && (++value > MAXFRACT2)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) value >>= 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) exp++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) if (exp > MAXEXP2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) /* Overflow. Return largest representable number instead. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) return (1ul << (MANTSIZE2+EXPSIZE2-1)) - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) return (value & (MAXFRACT2>>1)) | (exp << (MANTSIZE2-1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) #if ACCT_VERSION == 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) * encode an u64 into a 32 bit IEEE float
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) static u32 encode_float(u64 value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) unsigned exp = 190;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) unsigned u;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) if (value == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) while ((s64)value > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) value <<= 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) exp--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) u = (u32)(value >> 40) & 0x7fffffu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) return u | (exp << 23);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) * Write an accounting entry for an exiting process
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) * The acct_process() call is the workhorse of the process
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) * accounting system. The struct acct is built here and then written
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) * into the accounting file. This function should only be called from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) * do_exit() or when switching to a different output file.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) static void fill_ac(acct_t *ac)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) struct pacct_struct *pacct = ¤t->signal->pacct;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) u64 elapsed, run_time;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) time64_t btime;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) struct tty_struct *tty;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) * Fill the accounting struct with the needed info as recorded
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) * by the different kernel functions.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) memset(ac, 0, sizeof(acct_t));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) ac->ac_version = ACCT_VERSION | ACCT_BYTEORDER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) strlcpy(ac->ac_comm, current->comm, sizeof(ac->ac_comm));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) /* calculate run_time in nsec*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) run_time = ktime_get_ns();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) run_time -= current->group_leader->start_time;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) /* convert nsec -> AHZ */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) elapsed = nsec_to_AHZ(run_time);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) #if ACCT_VERSION == 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) ac->ac_etime = encode_float(elapsed);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) ac->ac_etime = encode_comp_t(elapsed < (unsigned long) -1l ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) (unsigned long) elapsed : (unsigned long) -1l);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) #if ACCT_VERSION == 1 || ACCT_VERSION == 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) /* new enlarged etime field */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) comp2_t etime = encode_comp2_t(elapsed);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) ac->ac_etime_hi = etime >> 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) ac->ac_etime_lo = (u16) etime;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) do_div(elapsed, AHZ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) btime = ktime_get_real_seconds() - elapsed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) ac->ac_btime = clamp_t(time64_t, btime, 0, U32_MAX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) #if ACCT_VERSION==2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) ac->ac_ahz = AHZ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) spin_lock_irq(¤t->sighand->siglock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) tty = current->signal->tty; /* Safe as we hold the siglock */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) ac->ac_tty = tty ? old_encode_dev(tty_devnum(tty)) : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) ac->ac_utime = encode_comp_t(nsec_to_AHZ(pacct->ac_utime));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) ac->ac_stime = encode_comp_t(nsec_to_AHZ(pacct->ac_stime));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) ac->ac_flag = pacct->ac_flag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) ac->ac_mem = encode_comp_t(pacct->ac_mem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) ac->ac_minflt = encode_comp_t(pacct->ac_minflt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) ac->ac_majflt = encode_comp_t(pacct->ac_majflt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) ac->ac_exitcode = pacct->ac_exitcode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) spin_unlock_irq(¤t->sighand->siglock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) * do_acct_process does all actual work. Caller holds the reference to file.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) static void do_acct_process(struct bsd_acct_struct *acct)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) acct_t ac;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) unsigned long flim;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) const struct cred *orig_cred;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) struct file *file = acct->file;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) * Accounting records are not subject to resource limits.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) flim = current->signal->rlim[RLIMIT_FSIZE].rlim_cur;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) current->signal->rlim[RLIMIT_FSIZE].rlim_cur = RLIM_INFINITY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) /* Perform file operations on behalf of whoever enabled accounting */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) orig_cred = override_creds(file->f_cred);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) * First check to see if there is enough free_space to continue
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) * the process accounting system.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) if (!check_free_space(acct))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) fill_ac(&ac);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) /* we really need to bite the bullet and change layout */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) ac.ac_uid = from_kuid_munged(file->f_cred->user_ns, orig_cred->uid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) ac.ac_gid = from_kgid_munged(file->f_cred->user_ns, orig_cred->gid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) #if ACCT_VERSION == 1 || ACCT_VERSION == 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) /* backward-compatible 16 bit fields */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) ac.ac_uid16 = ac.ac_uid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) ac.ac_gid16 = ac.ac_gid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) #if ACCT_VERSION == 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) struct pid_namespace *ns = acct->ns;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) ac.ac_pid = task_tgid_nr_ns(current, ns);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) ac.ac_ppid = task_tgid_nr_ns(rcu_dereference(current->real_parent),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) ns);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) * Get freeze protection. If the fs is frozen, just skip the write
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) * as we could deadlock the system otherwise.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) if (file_start_write_trylock(file)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) /* it's been opened O_APPEND, so position is irrelevant */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) loff_t pos = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) __kernel_write(file, &ac, sizeof(acct_t), &pos);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) file_end_write(file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) current->signal->rlim[RLIMIT_FSIZE].rlim_cur = flim;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) revert_creds(orig_cred);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) * acct_collect - collect accounting information into pacct_struct
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) * @exitcode: task exit code
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) * @group_dead: not 0, if this thread is the last one in the process.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) void acct_collect(long exitcode, int group_dead)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) struct pacct_struct *pacct = ¤t->signal->pacct;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) u64 utime, stime;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) unsigned long vsize = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) if (group_dead && current->mm) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) struct vm_area_struct *vma;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) mmap_read_lock(current->mm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) vma = current->mm->mmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) while (vma) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) vsize += vma->vm_end - vma->vm_start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) vma = vma->vm_next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) mmap_read_unlock(current->mm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) spin_lock_irq(¤t->sighand->siglock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) if (group_dead)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) pacct->ac_mem = vsize / 1024;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) if (thread_group_leader(current)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) pacct->ac_exitcode = exitcode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) if (current->flags & PF_FORKNOEXEC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) pacct->ac_flag |= AFORK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) if (current->flags & PF_SUPERPRIV)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) pacct->ac_flag |= ASU;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) if (current->flags & PF_DUMPCORE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) pacct->ac_flag |= ACORE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) if (current->flags & PF_SIGNALED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) pacct->ac_flag |= AXSIG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) task_cputime(current, &utime, &stime);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) pacct->ac_utime += utime;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) pacct->ac_stime += stime;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) pacct->ac_minflt += current->min_flt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) pacct->ac_majflt += current->maj_flt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) spin_unlock_irq(¤t->sighand->siglock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) static void slow_acct_process(struct pid_namespace *ns)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) for ( ; ns; ns = ns->parent) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) struct bsd_acct_struct *acct = acct_get(ns);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) if (acct) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) do_acct_process(acct);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) mutex_unlock(&acct->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) acct_put(acct);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) * acct_process - handles process accounting for an exiting task
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) void acct_process(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) struct pid_namespace *ns;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) * This loop is safe lockless, since current is still
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) * alive and holds its namespace, which in turn holds
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) * its parent.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) for (ns = task_active_pid_ns(current); ns != NULL; ns = ns->parent) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) if (ns->bacct)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) if (unlikely(ns))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) slow_acct_process(ns);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) }