Example #1
0
static ssize_t scribe_do_write(struct file *file, const char __user *buf,
			       ssize_t count, loff_t *ppos)
{
	struct scribe_ps *scribe = current->scribe;
	int force_block = 0;
	ssize_t ret;

	if (!is_scribed(scribe))
		return do_write(file, buf, count, ppos, force_block);

	if (is_kernel_copy())
		goto out;

	if (!should_scribe_data(scribe))
		goto out;

	scribe_need_syscall_ret(scribe);

	if (is_replaying(scribe)) {
		count = scribe->orig_ret;
		if (count <= 0)
			return count;
		force_block = 1;
	}

out:
	scribe->in_read_write = true;
	ret = do_write(file, buf, count, ppos, force_block);
	scribe->in_read_write = false;

	return ret;
}
Example #2
0
void scribe_pre_uaccess(const void *data, const void __user *user_ptr,
			size_t size, int flags)
{
	struct scribe_ps *scribe = current->scribe;

	if (!is_scribed(scribe) || !should_scribe_data(scribe))
		return;

	if (!is_kernel_copy() && size)
		__scribe_allow_uaccess(scribe);
	scribe->to_be_copied_size = size;
}
Example #3
0
static bool need_action(struct scribe_ps *scribe, struct data_desc *desc)
{
	if (!desc->size)
		return false;

	if (!should_scribe_data(scribe))
		return false;

	if (is_kernel_copy())
		return false;

	if (desc->flags & SCRIBE_DATA_IGNORE)
		return false;

	return desc->do_det || desc->do_non_det || desc->do_info;
}
Example #4
0
static ssize_t scribe_do_read(struct file *file, char __user *buf,
			      ssize_t len, loff_t *ppos)
{
	struct scribe_ps *scribe = current->scribe;
	int force_block = 0;
	ssize_t ret;

	if (!is_scribed(scribe))
		return do_read(file, buf, len, ppos, force_block);

	if (is_kernel_copy())
		goto out;

	if (!should_scribe_data(scribe))
		goto out;

	scribe_need_syscall_ret(scribe);

	if (is_replaying(scribe)) {
		len = scribe->orig_ret;
		if (len <= 0)
			return len;
		force_block = 1;
	}

	if (is_deterministic(file))
		goto out;

	scribe_data_non_det();

	if (is_recording(scribe))
		goto out;

	return scribe_emul_copy_to_user(scribe, buf, len);

out:
	scribe->in_read_write = true;
	ret = do_read(file, buf, len, ppos, force_block);
	scribe->in_read_write = false;
	return ret;
}
Example #5
0
static ssize_t scribe_do_readv_writev(int type, struct file *file,
				      const struct iovec __user * uvector,
				      unsigned long nr_segs, loff_t *pos)
{
	struct scribe_ps *scribe = current->scribe;
	struct iovec iovstack[UIO_FASTIOV];
	struct iovec *iov = iovstack;
	int force_block = 0;
	ssize_t ret, len = 0;

	if (!is_scribed(scribe))
		return do_readv_writev(type, file, uvector, nr_segs, 0, pos,
				       force_block);

	if (is_kernel_copy())
		goto out;

	if (!should_scribe_data(scribe))
		goto out;

	scribe_need_syscall_ret(scribe);

	if (is_replaying(scribe)) {
		len = scribe->orig_ret;
		if (len <= 0) {
			rw_copy_check_uvector(type, uvector, nr_segs,
					      ARRAY_SIZE(iovstack), iovstack,
					      &iov);
			ret = len;
			goto free;
		}
		force_block = 1;
	}

	if (type == READ) {
		if (is_deterministic(file))
			goto out;

		scribe_data_non_det();

		if (is_recording(scribe))
			goto out;

		rw_copy_check_uvector(type, uvector, nr_segs,
				      ARRAY_SIZE(iovstack), iovstack, &iov);

		ret =  __do_loop_readv_writev(file, iov, nr_segs, len, pos,
					      io_scribe_emul_copy_to_user);
		goto free;
	}

out:
	scribe->in_read_write = true;
	ret = do_readv_writev(type, file, uvector, nr_segs, len, pos,
			      force_block);
	scribe->in_read_write = false;
free:
	if (iov != iovstack)
		kfree(iov);
	return ret;
}