]> nv-tegra.nvidia Code Review - linux-2.6.git/blobdiff - kernel/acct.c
cgroup: Add generic cgroup subsystem permission checks.
[linux-2.6.git] / kernel / acct.c
index f6006a60df5ddff73990656f73ea7fff55dcf9b8..fa7eb3de2ddcd11eb5b0c7852aa840e9f4c19cc1 100644 (file)
@@ -122,7 +122,7 @@ static int check_free_space(struct bsd_acct_struct *acct, struct file *file)
        spin_unlock(&acct_lock);
 
        /* May block */
-       if (vfs_statfs(file->f_path.dentry, &sbuf))
+       if (vfs_statfs(&file->f_path, &sbuf))
                return res;
        suspend = sbuf.f_blocks * SUSPEND;
        resume = sbuf.f_blocks * RESUME;
@@ -215,7 +215,7 @@ static void acct_file_reopen(struct bsd_acct_struct *acct, struct file *file,
 static int acct_on(char *name)
 {
        struct file *file;
-       int error;
+       struct vfsmount *mnt;
        struct pid_namespace *ns;
        struct bsd_acct_struct *acct = NULL;
 
@@ -243,24 +243,18 @@ static int acct_on(char *name)
                }
        }
 
-       error = security_acct(file);
-       if (error) {
-               kfree(acct);
-               filp_close(file, NULL);
-               return error;
-       }
-
        spin_lock(&acct_lock);
        if (ns->bacct == NULL) {
                ns->bacct = acct;
                acct = NULL;
        }
 
-       mnt_pin(file->f_path.mnt);
+       mnt = file->f_path.mnt;
+       mnt_pin(mnt);
        acct_file_reopen(ns->bacct, file, ns);
        spin_unlock(&acct_lock);
 
-       mntput(file->f_path.mnt); /* it's pinned, now give up active reference */
+       mntput(mnt); /* it's pinned, now give up active reference */
        kfree(acct);
 
        return 0;
@@ -277,9 +271,9 @@ static int acct_on(char *name)
  * should be written. If the filename is NULL, accounting will be
  * shutdown.
  */
-asmlinkage long sys_acct(const char __user *name)
+SYSCALL_DEFINE1(acct, const char __user *, name)
 {
-       int error;
+       int error = 0;
 
        if (!capable(CAP_SYS_PACCT))
                return -EPERM;
@@ -297,13 +291,11 @@ asmlinkage long sys_acct(const char __user *name)
                if (acct == NULL)
                        return 0;
 
-               error = security_acct(NULL);
-               if (!error) {
-                       spin_lock(&acct_lock);
-                       acct_file_reopen(acct, NULL, NULL);
-                       spin_unlock(&acct_lock);
-               }
+               spin_lock(&acct_lock);
+               acct_file_reopen(acct, NULL, NULL);
+               spin_unlock(&acct_lock);
        }
+
        return error;
 }
 
@@ -351,17 +343,18 @@ restart:
 
 void acct_exit_ns(struct pid_namespace *ns)
 {
-       struct bsd_acct_struct *acct;
+       struct bsd_acct_struct *acct = ns->bacct;
 
-       spin_lock(&acct_lock);
-       acct = ns->bacct;
-       if (acct != NULL) {
-               if (acct->file != NULL)
-                       acct_file_reopen(acct, NULL, NULL);
+       if (acct == NULL)
+               return;
 
-               kfree(acct);
-       }
+       del_timer_sync(&acct->timer);
+       spin_lock(&acct_lock);
+       if (acct->file != NULL)
+               acct_file_reopen(acct, NULL, NULL);
        spin_unlock(&acct_lock);
+
+       kfree(acct);
 }
 
 /*
@@ -489,13 +482,17 @@ static void do_acct_process(struct bsd_acct_struct *acct,
        u64 run_time;
        struct timespec uptime;
        struct tty_struct *tty;
+       const struct cred *orig_cred;
+
+       /* Perform file operations on behalf of whoever enabled accounting */
+       orig_cred = override_creds(file->f_cred);
 
        /*
         * First check to see if there is enough free_space to continue
         * the process accounting system.
         */
        if (!check_free_space(acct, file))
-               return;
+               goto out;
 
        /*
         * Fill the accounting struct with the needed info as recorded
@@ -530,15 +527,15 @@ static void do_acct_process(struct bsd_acct_struct *acct,
        do_div(elapsed, AHZ);
        ac.ac_btime = get_seconds() - elapsed;
        /* we really need to bite the bullet and change layout */
-       ac.ac_uid = current->uid;
-       ac.ac_gid = current->gid;
+       ac.ac_uid = orig_cred->uid;
+       ac.ac_gid = orig_cred->gid;
 #if ACCT_VERSION==2
        ac.ac_ahz = AHZ;
 #endif
 #if ACCT_VERSION==1 || ACCT_VERSION==2
        /* backward-compatible 16 bit fields */
-       ac.ac_uid16 = current->uid;
-       ac.ac_gid16 = current->gid;
+       ac.ac_uid16 = ac.ac_uid;
+       ac.ac_gid16 = ac.ac_gid;
 #endif
 #if ACCT_VERSION==3
        ac.ac_pid = task_tgid_nr_ns(current, ns);
@@ -577,16 +574,8 @@ static void do_acct_process(struct bsd_acct_struct *acct,
                               sizeof(acct_t), &file->f_pos);
        current->signal->rlim[RLIMIT_FSIZE].rlim_cur = flim;
        set_fs(fs);
-}
-
-/**
- * acct_init_pacct - initialize a new pacct_struct
- * @pacct: per-process accounting info struct to initialize
- */
-void acct_init_pacct(struct pacct_struct *pacct)
-{
-       memset(pacct, 0, sizeof(struct pacct_struct));
-       pacct->ac_utime = pacct->ac_stime = cputime_zero;
+out:
+       revert_creds(orig_cred);
 }
 
 /**