示例#1
0
static int scribe_recvmsg(struct kiocb *iocb, struct socket *sock,
			  struct msghdr *m, size_t total_len,
			  int flags)
{
	struct scribe_ps *scribe = current->scribe;
	int ret, err;

	if (scribe_is_deterministic(sock) || !is_scribed(scribe)) {
		if (is_replaying(scribe)) {
			flags &= ~MSG_DONTWAIT;
			flags |= MSG_WAITALL;

			if (!scribe_is_in_read_write(scribe))
				total_len = scribe->orig_ret;
			if ((ssize_t)total_len <= 0)
				return total_len;
		}
		scribe_data_det();
		ret = sock->real_ops->recvmsg(iocb, sock, m, total_len, flags),
		scribe_data_pop_flags();
		return ret;
	}

	scribe_data_non_det_need_info();

	err = scribe_result_cond(
		ret, sock->real_ops->recvmsg(iocb, sock, m, total_len, flags),
		!scribe_is_in_read_write(scribe) || ret > 0);
	if (err)
		goto out;
	if (ret <= 0)
		goto out;

	if (is_replaying(scribe))
		scribe_emul_copy_to_user(scribe, NULL, INT_MAX);

	err = scribe_value(&m->msg_namelen);
	if (err)
		goto out;
	err = scribe_buffer(m->msg_name, m->msg_namelen);

out:
	scribe_data_pop_flags();
	return err ?: ret;
}
示例#2
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;
}
示例#3
0
static int scribe_getsockopt(struct socket *sock, int level,
			     int optname, char __user *optval,
			     int __user *optlen)
{
	struct scribe_ps *scribe = current->scribe;
	int ret, err;

	scribe_data_non_det_need_info();

	err = scribe_result(
		ret, sock->real_ops->getsockopt(sock, level, optname,
						optval, optlen));
	if (err)
		return err;
	if (ret < 0)
		return ret;

	if (is_replaying(scribe))
		scribe_emul_copy_to_user(scribe, NULL, INT_MAX);
	return ret;
}
示例#4
0
static ssize_t io_scribe_emul_copy_to_user(struct file *filp, char __user *buf,
					   size_t len, loff_t *ppos)
{
	return scribe_emul_copy_to_user(current->scribe, buf, len);
}