예제 #1
0
/**
 * sys_acct - enable/disable process accounting
 * @name: file name for accounting records or NULL to shutdown accounting
 *
 * Returns 0 for success or negative errno values for failure.
 *
 * sys_acct() is the only system call needed to implement process
 * accounting. It takes the name of the file where accounting records
 * should be written. If the filename is NULL, accounting will be
 * shutdown.
 */
SYSCALL_DEFINE1(acct, const char __user *, name)
{
	int error;

	if (!capable(CAP_SYS_PACCT))
		return -EPERM;

	if (name) {
		char *tmp = getname(name);
		if (IS_ERR(tmp))
			return (PTR_ERR(tmp));
		error = acct_on(tmp);
		putname(tmp);
	} else {
		struct bsd_acct_struct *acct;

		acct = task_active_pid_ns(current)->bacct;
		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);
		}
	}
	return error;
}
예제 #2
0
파일: acct.c 프로젝트: Tigrouzen/k1099
static int acct_on(char *name)
{
	struct file *file;
	int error;

	/* Difference from BSD - they don't do O_APPEND */
	file = filp_open(name, O_WRONLY|O_APPEND|O_LARGEFILE, 0);
	if (IS_ERR(file))
		return PTR_ERR(file);

	if (!S_ISREG(file->f_path.dentry->d_inode->i_mode)) {
		filp_close(file, NULL);
		return -EACCES;
	}

	if (!file->f_op->write) {
		filp_close(file, NULL);
		return -EIO;
	}

	error = security_acct(file);
	if (error) {
		filp_close(file, NULL);
		return error;
	}

	spin_lock(&acct_globals.lock);
	mnt_pin(file->f_path.mnt);
	acct_file_reopen(file);
	spin_unlock(&acct_globals.lock);

	mntput(file->f_path.mnt); /* it's pinned, now give up active reference */

	return 0;
}
예제 #3
0
파일: acct.c 프로젝트: AppEngine/linux-2.6
static int acct_on(char *name)
{
	struct file *file;
	struct vfsmount *mnt;
	int error;
	struct pid_namespace *ns;
	struct bsd_acct_struct *acct = NULL;

	/* Difference from BSD - they don't do O_APPEND */
	file = filp_open(name, O_WRONLY|O_APPEND|O_LARGEFILE, 0);
	if (IS_ERR(file))
		return PTR_ERR(file);

	if (!S_ISREG(file->f_path.dentry->d_inode->i_mode)) {
		filp_close(file, NULL);
		return -EACCES;
	}

	if (!file->f_op->write) {
		filp_close(file, NULL);
		return -EIO;
	}

	ns = task_active_pid_ns(current);
	if (ns->bacct == NULL) {
		acct = kzalloc(sizeof(struct bsd_acct_struct), GFP_KERNEL);
		if (acct == NULL) {
			filp_close(file, NULL);
			return -ENOMEM;
		}
	}

	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 = file->f_path.mnt;
	mnt_pin(mnt);
	acct_file_reopen(ns->bacct, file, ns);
	spin_unlock(&acct_lock);

	mntput(mnt); /* it's pinned, now give up active reference */
	kfree(acct);

	return 0;
}
예제 #4
0
/*
 *  sys_acct() is the only system call needed to implement process
 *  accounting. It takes the name of the file where accounting records
 *  should be written. If the filename is NULL, accounting will be
 *  shutdown.
 */
asmlinkage long sys_acct(const char __user *name)
{
	struct file *file = NULL;
	char *tmp;
	int error;

	if (!capable(CAP_SYS_PACCT))
		return -EPERM;

	if (name) {
		tmp = getname(name);
		if (IS_ERR(tmp)) {
			return (PTR_ERR(tmp));
		}
		/* Difference from BSD - they don't do O_APPEND */
		file = filp_open(tmp, O_WRONLY|O_APPEND, 0);
		putname(tmp);
		if (IS_ERR(file)) {
			return (PTR_ERR(file));
		}
		if (!S_ISREG(file->f_dentry->d_inode->i_mode)) {
			filp_close(file, NULL);
			return (-EACCES);
		}

		if (!file->f_op->write) {
			filp_close(file, NULL);
			return (-EIO);
		}
	}

	error = security_acct(file);
	if (error) {
		if (file)
			filp_close(file, NULL);
		return error;
	}

	spin_lock(&acct_globals.lock);
	acct_file_reopen(file);
	spin_unlock(&acct_globals.lock);

	return (0);
}
예제 #5
0
파일: acct.c 프로젝트: Tigrouzen/k1099
/**
 * sys_acct - enable/disable process accounting
 * @name: file name for accounting records or NULL to shutdown accounting
 *
 * Returns 0 for success or negative errno values for failure.
 *
 * sys_acct() is the only system call needed to implement process
 * accounting. It takes the name of the file where accounting records
 * should be written. If the filename is NULL, accounting will be
 * shutdown.
 */
asmlinkage long sys_acct(const char __user *name)
{
	int error;

	if (!capable(CAP_SYS_PACCT))
		return -EPERM;

	if (name) {
		char *tmp = getname(name);
		if (IS_ERR(tmp))
			return (PTR_ERR(tmp));
		error = acct_on(tmp);
		putname(tmp);
	} else {
		error = security_acct(NULL);
		if (!error) {
			spin_lock(&acct_globals.lock);
			acct_file_reopen(NULL);
			spin_unlock(&acct_globals.lock);
		}
	}
	return error;
}
예제 #6
0
/*
 *  sys_acct() is the only system call needed to implement process
 *  accounting. It takes the name of the file where accounting records
 *  should be written. If the filename is NULL, accounting will be
 *  shutdown.
 */
asmlinkage long sys_acct(const char *name)
{
	struct file *file = NULL, *old_acct = NULL;
	char *tmp;
	int error;

	if (!capable(CAP_SYS_PACCT))
		return -EPERM;

	if (name) {
		tmp = getname(name);
		error = PTR_ERR(tmp);
		if (IS_ERR(tmp))
			goto out;
		/* Difference from BSD - they don't do O_APPEND */
		file = filp_open(tmp, O_WRONLY|O_APPEND, 0);
		putname(tmp);
		if (IS_ERR(file)) {
			error = PTR_ERR(file);
			goto out;
		}
		error = -EACCES;
		if (!S_ISREG(file->f_dentry->d_inode->i_mode)) 
			goto out_err;

		error = -EIO;
		if (!file->f_op->write) 
			goto out_err;
	}

	if ((error = security_acct(file)))
		goto out_err;

	error = 0;
	lock_kernel();
	if (acct_file) {
		old_acct = acct_file;
		del_timer(&acct_timer);
		acct_active = 0;
		acct_needcheck = 0;
		acct_file = NULL;
	}
	if (name) {
		acct_file = file;
		acct_needcheck = 0;
		acct_active = 1;
		/* It's been deleted if it was used before so this is safe */
		init_timer(&acct_timer);
		acct_timer.function = acct_timeout;
		acct_timer.expires = jiffies + ACCT_TIMEOUT*HZ;
		add_timer(&acct_timer);
	}
	unlock_kernel();
	if (old_acct) {
		do_acct_process(0,old_acct);
		filp_close(old_acct, NULL);
	}
out:
	return error;
out_err:
	if (file)
		filp_close(file, NULL);
	goto out;
}