Example #1
0
static int mm_check_read_msghdr(const struct msghdr *msg)
{
	if (!mm_check_read(msg, sizeof(struct msghdr)))
		return 0;
	if (msg->msg_namelen && !mm_check_read(msg->msg_name, msg->msg_namelen))
		return 0;
	if (msg->msg_iovlen && !mm_check_read(msg->msg_iov, sizeof(struct iovec) * msg->msg_iovlen))
		return 0;
	if (msg->msg_controllen && !mm_check_read(msg->msg_control, msg->msg_controllen))
		return 0;
	for (int i = 0; i < msg->msg_iovlen; i++)
	{
		log_info("iov %d: [%p, %p)", i, msg->msg_iov[i].iov_base, (uintptr_t)msg->msg_iov[i].iov_base + msg->msg_iov[i].iov_len);
		if (!mm_check_read(msg->msg_iov[i].iov_base, msg->msg_iov[i].iov_len))
			return 0;
	}
	return 1;
}
Example #2
0
File: timer.c Project: xwlan/flinux
DEFINE_SYSCALL(nanosleep, const struct timespec *, req, struct timespec *, rem)
{
	log_info("nanosleep(0x%p, 0x%p)", req, rem);
	if (!mm_check_read(req, sizeof(struct timespec)) || rem && !mm_check_write(rem, sizeof(struct timespec)))
		return -L_EFAULT;
	LARGE_INTEGER delay_interval;
	delay_interval.QuadPart = 0ULL - (((uint64_t)req->tv_sec * 1000000000ULL + req->tv_nsec) / 100ULL);
	NtDelayExecution(FALSE, &delay_interval);
	return 0;
}
Example #3
0
DEFINE_SYSCALL(sendto, int, sockfd, const void *, buf, size_t, len, int, flags, const struct sockaddr *, dest_addr, int, addrlen)
{
	log_info("sendto(%d, %p, %d, %x, %p, %d)", sockfd, buf, len, flags, dest_addr, addrlen);
	if (!mm_check_read(buf, len))
		return -L_EFAULT;
	if (dest_addr && !mm_check_read(dest_addr, addrlen))
		return -L_EFAULT;
	struct file *f = vfs_get(sockfd);
	if (!f)
		return -L_EBADF;
	int r;
	if (!f->op_vtable->sendto)
	{
		log_error("sendto() not implemented.");
		r = -L_ENOTSOCK;
	}
	else
		r = f->op_vtable->sendto(f, buf, len, flags, dest_addr, addrlen);
	vfs_release(f);
	return r;
}
Example #4
0
DEFINE_SYSCALL(setrlimit, int, resource, const struct rlimit *, rlim)
{
	log_info("setrlimit(%d, %p)\n", resource, rlim);
	if (!mm_check_read(rlim, sizeof(struct rlimit)))
		return -EFAULT;
	switch (resource)
	{
	default:
		log_error("Unsupported resource: %d\n", resource);
		return -EINVAL;
	}
}
Example #5
0
DEFINE_SYSCALL(setsockopt, int, sockfd, int, level, int, optname, const void *, optval, int, optlen)
{
	log_info("setsockopt(%d, %d, %d, %p, %d)", sockfd, level, optname, optval, optlen);
	if (optval && !mm_check_read(optval, optlen))
		return -L_EFAULT;
	struct file *f = vfs_get(sockfd);
	if (!f)
		return -L_EBADF;
	int r;
	if (!f->op_vtable->setsockopt)
	{
		log_error("setsockopt() not implemented.");
		r = -L_ENOTSOCK;
	}
	else
		r = f->op_vtable->setsockopt(f, level, optname, optval, optlen);
	vfs_release(f);
	return r;
}
Example #6
0
DEFINE_SYSCALL(send, int, sockfd, const void *, buf, size_t, len, int, flags)
{
	log_info("send(%d, %p, %d, %x)", sockfd, buf, len, flags);
	if (!mm_check_read(buf, len))
		return -L_EFAULT;
	struct file *f = vfs_get(sockfd);
	if (!f)
		return -L_EBADF;
	int r;
	if (!f->op_vtable->sendto)
	{
		log_error("send() not implemented.");
		r = -L_ENOTSOCK;
	}
	else
		r = f->op_vtable->sendto(f, buf, len, flags, NULL, 0);
	vfs_release(f);
	return r;
}
Example #7
0
DEFINE_SYSCALL(connect, int, sockfd, const struct sockaddr *, addr, size_t, addrlen)
{
	log_info("connect(%d, %p, %d)", sockfd, addr, addrlen);
	if (!mm_check_read(addr, sizeof(struct sockaddr)))
		return -L_EFAULT;
	struct file *f = vfs_get(sockfd);
	if (!f)
		return -L_EBADF;
	int r;
	if (!f->op_vtable->connect)
	{
		log_error("connect() not implemented.");
		r = -L_ENOTSOCK;
	}
	else
		r = f->op_vtable->connect(f, addr, addrlen);
	vfs_release(f);
	return r;
}
Example #8
0
DEFINE_SYSCALL(socketcall, int, call, uintptr_t *, args)
{
	if (call < 1 || call > SYS_SENDMMSG)
		return -L_EINVAL;
	if (!mm_check_read(args, nargs[call]))
		return -L_EFAULT;
	switch (call)
	{
	case SYS_SOCKET:
		return sys_socket(args[0], args[1], args[2]);

	case SYS_BIND:
		return sys_bind(args[0], (const struct sockaddr *)args[1], args[2]);

	case SYS_CONNECT:
		return sys_connect(args[0], (const struct sockaddr *)args[1], args[2]);

	case SYS_LISTEN:
		return sys_listen(args[0], args[1]);

	case SYS_ACCEPT:
		return sys_accept(args[0], (struct sockaddr *)args[1], (int *)args[2]);

	case SYS_GETSOCKNAME:
		return sys_getsockname(args[0], (struct sockaddr *)args[1], (int *)args[2]);

	case SYS_GETPEERNAME:
		return sys_getpeername(args[0], (struct sockaddr *)args[1], (int *)args[2]);

	case SYS_SEND:
		return sys_send(args[0], (const void *)args[1], args[2], args[3]);

	case SYS_RECV:
		return sys_recv(args[0], (void *)args[1], args[2], args[3]);

	case SYS_SENDTO:
		return sys_sendto(args[0], (const void *)args[1], args[2], args[3], (const struct sockaddr *)args[4], args[5]);
		
	case SYS_RECVFROM:
		return sys_recvfrom(args[0], (void *)args[1], args[2], args[3], (struct sockaddr *)args[4], (int *)args[5]);

	case SYS_SHUTDOWN:
		return sys_shutdown(args[0], args[1]);

	case SYS_SETSOCKOPT:
		return sys_setsockopt(args[0], args[1], args[2], (const void *)args[3], args[4]);

	case SYS_GETSOCKOPT:
		return sys_getsockopt(args[0], args[1], args[2], (void *)args[3], (int *)args[4]);

	case SYS_SENDMSG:
		return sys_sendmsg(args[0], (const struct msghdr *)args[1], args[2]);

	case SYS_RECVMSG:
		return sys_recvmsg(args[0], (struct msghdr *)args[1], args[2]);

	case SYS_ACCEPT4:
		return sys_accept4(args[0], (struct sockaddr *)args[1], (int *)args[2], args[3]);

	case SYS_SENDMMSG:
		return sys_sendmmsg(args[0], (struct mmsghdr *)args[1], args[2], args[3]);

	default:
	{
		log_error("Unimplemented socketcall: %d", call);
		return -L_EINVAL;
	}
	}
}
Example #9
0
static int dsp_ioctl(struct file *f, unsigned int cmd, unsigned long arg)
{
	AcquireSRWLockExclusive(&f->rw_lock);
	int r = 0;
	struct dsp_file *dsp = (struct dsp_file *)f;
	switch (cmd)
	{
	case SNDCTL_DSP_RESET:
	{
		log_info("SNDCTL_DSP_RESET.");
		dsp_reset(dsp);
		break;
	}
	case SNDCTL_DSP_SPEED:
	{
		if (!mm_check_read((int *)arg, sizeof(int)))
		{
			r = -L_EFAULT;
			break;
		}
		int speed = *(int *)arg;
		log_info("SNDCTL_DSP_SPEED: %d", speed);
		DWORD old_speed = dsp->format.nSamplesPerSec;
		dsp->format.nSamplesPerSec = speed;
		if (!dsp_test_format(&dsp->format))
		{
			log_warning("Speed not supported.");
			dsp->format.nSamplesPerSec = old_speed;
			r = -L_EINVAL;
		}
		break;
	}
	case SNDCTL_DSP_STEREO:
	{
		if (!mm_check_read((int *)arg, sizeof(int)))
		{
			r = -L_EFAULT;
			break;
		}
		int c = *(int *)arg;
		log_info("SNDCTL_DSP_STEREO: %d", c);
		if (c == 0)
			dsp->format.nChannels = 1;
		else if (c == 1)
			dsp->format.nChannels = 2;
		else
		{
			log_warning("Invalid argument (can only be 0 or 1).");
			r = -L_EINVAL;
		}
		break;
	}
	case SNDCTL_DSP_SETFMT:
	{
		if (!mm_check_read((int *)arg, sizeof(int)))
		{
			r = -L_EFAULT;
			break;
		}
		int fmt = *(int *)arg;
		log_info("SNDCTL_DSP_SETFMT: 0x%x", fmt);
		if (fmt == AFMT_S16_LE)
			dsp->format.wBitsPerSample = 16;
		else if (fmt == AFMT_U8)
			dsp->format.wBitsPerSample = 8;
		else
		{
			log_warning("Invalid argument (can only be AFMT_S16_LE or AFMT_U8).");
			r = -L_EINVAL;
		}
		break;
	}
	case SNDCTL_DSP_GETFMTS:
	{
		if (!mm_check_write((int *)arg, sizeof(int)))
		{
			r = -L_EFAULT;
			break;
		}
		log_info("SNDCTL_DSP_GETFMTS");
		*(int *)arg = AFMT_U8 | AFMT_S16_LE;
		break;
	}
	}
	ReleaseSRWLockExclusive(&f->rw_lock);
	return r;
}