status_t
_user_get_next_socket_stat(int family, uint32 *_cookie, struct net_stat *_stat)
{
	// check parameters and copy cookie from userland
	if (_cookie == NULL || _stat == NULL)
		return B_BAD_VALUE;

	uint32 cookie;
	if (!IS_USER_ADDRESS(_stat) || !IS_USER_ADDRESS(_cookie)
		|| user_memcpy(&cookie, _cookie, sizeof(cookie)) != B_OK) {
		return B_BAD_ADDRESS;
	}

	net_stat stat;
	SyscallRestartWrapper<status_t> error;
	error = common_get_next_socket_stat(family, &cookie, &stat);
	if (error != B_OK)
		return error;

	// copy cookie and data back to userland
	if (user_memcpy(_cookie, &cookie, sizeof(cookie)) != B_OK
		|| user_memcpy(_stat, &stat, sizeof(net_stat)) != B_OK) {
		return B_BAD_ADDRESS;
	}

	return B_OK;
}
Esempio n. 2
0
status_t
_user_get_next_image_info(team_id team, int32 *_cookie, image_info *userInfo,
	size_t size)
{
	image_info info;
	status_t status;
	int32 cookie;

	if (size > sizeof(image_info))
		return B_BAD_VALUE;

	if (!IS_USER_ADDRESS(userInfo) || !IS_USER_ADDRESS(_cookie)
		|| user_memcpy(&cookie, _cookie, sizeof(int32)) < B_OK) {
		return B_BAD_ADDRESS;
	}

	status = _get_next_image_info(team, &cookie, &info, sizeof(image_info));

	if (user_memcpy(userInfo, &info, size) < B_OK
		|| user_memcpy(_cookie, &cookie, sizeof(int32)) < B_OK) {
		return B_BAD_ADDRESS;
	}

	return status;
}
Esempio n. 3
0
int	user_port_get_next_port_info(proc_id uproc,
				uint32 *ucookie,
				struct port_info *uinfo)
{
	int 				res;
	struct port_info	info;
	uint32				cookie;
	int					rc;

	if (ucookie == NULL)
		return ERR_INVALID_ARGS;
	if (uinfo == NULL)
		return ERR_INVALID_ARGS;
	if(is_kernel_address(ucookie))
		return ERR_VM_BAD_USER_MEMORY;
	if(is_kernel_address(uinfo))
		return ERR_VM_BAD_USER_MEMORY;

	// copy from userspace
	rc = user_memcpy(&cookie, ucookie, sizeof(uint32));
	if(rc < 0)
		return rc;

	res = port_get_next_port_info(uproc, &cookie, &info);
	// copy to userspace
	rc = user_memcpy(ucookie, &info, sizeof(uint32));
	if(rc < 0)
		return rc;
	rc = user_memcpy(uinfo,   &info, sizeof(struct port_info));
	if(rc < 0)
		return rc;
	return res;
}
Esempio n. 4
0
status_t
get_route_information(struct net_domain* _domain, void* value, size_t length)
{
	struct net_domain_private* domain = (net_domain_private*)_domain;

	if (length < sizeof(route_entry))
		return B_BAD_VALUE;

	route_entry entry;
	if (user_memcpy(&entry, value, sizeof(route_entry)) < B_OK)
		return B_BAD_ADDRESS;

	sockaddr_storage destination;
	status_t status = user_copy_address(entry.destination, &destination);
	if (status != B_OK)
		return status;

	RecursiveLocker locker(domain->lock);

	net_route_private* route = find_route(domain, (sockaddr*)&destination);
	if (route == NULL)
		return B_ENTRY_NOT_FOUND;

	status = fill_route_entry(&entry, value, length, route);
	if (status != B_OK)
		return status;

	return user_memcpy(value, &entry, sizeof(route_entry));
}
status_t
_user_getsockopt(int socket, int level, int option, void *userValue,
	socklen_t *_length)
{
	// check params
	if (userValue == NULL || _length == NULL)
		return B_BAD_VALUE;
	if (!IS_USER_ADDRESS(userValue) || !IS_USER_ADDRESS(_length))
		return B_BAD_ADDRESS;

	// copy length from userland
	socklen_t length;
	if (user_memcpy(&length, _length, sizeof(socklen_t)) != B_OK)
		return B_BAD_ADDRESS;

	if (length > MAX_SOCKET_OPTION_LENGTH)
		return B_BAD_VALUE;

	// getsockopt()
	char value[MAX_SOCKET_OPTION_LENGTH];
	SyscallRestartWrapper<status_t> error;
	error = common_getsockopt(socket, level, option, value, &length,
		false);
	if (error != B_OK)
		return error;

	// copy value back to userland
	if (user_memcpy(userValue, value, length) != B_OK)
		return B_BAD_ADDRESS;

	return B_OK;
}
Esempio n. 6
0
status_t
ice1712_buffer_exchange(ice1712 *card, multi_buffer_info *data)
{
	int cpu_status;

	multi_buffer_info buffer_info;

#ifdef __HAIKU__
	if (user_memcpy(&buffer_info, data, sizeof(buffer_info)) < B_OK)
		return B_BAD_ADDRESS;
#else
	memcpy(&buffer_info, data, sizeof(buffer_info));
#endif

	buffer_info.flags = B_MULTI_BUFFER_PLAYBACK | B_MULTI_BUFFER_RECORD;

	if (acquire_sem_etc(card->buffer_ready_sem, 1, B_RELATIVE_TIMEOUT
		| B_CAN_INTERRUPT, 50000) == B_TIMED_OUT) {
		TRACE("buffer_exchange timeout\n");
	};

	cpu_status = lock();

	// Playback buffers info
	buffer_info.played_real_time = card->played_time;
	buffer_info.played_frames_count = card->frames_count;
	buffer_info.playback_buffer_cycle = (card->buffer - 1)
		% SWAPPING_BUFFERS; //Buffer played

	// Record buffers info
	buffer_info.recorded_real_time = card->played_time;
	buffer_info.recorded_frames_count = card->frames_count;
	buffer_info.record_buffer_cycle = (card->buffer - 1)
		% SWAPPING_BUFFERS; //Buffer filled

	unlock(cpu_status);

/*	if ((card->buffer % 1500) == 0) {
		uint8 reg8, reg8_dir;
		reg8 = read_gpio(card);
		reg8_dir = read_cci_uint8(card, CCI_GPIO_DIRECTION_CONTROL);
		TRACE("DEBUG === GPIO = %d (dir %d)\n", reg8, reg8_dir);

		reg8 = spdif_read(card, CS84xx_VERSION_AND_CHIP_ID);
		TRACE("DEBUG === S/PDif Version : 0x%x\n", reg8);
	}*/

#ifdef __HAIKU__
	if (user_memcpy(data, &buffer_info, sizeof(buffer_info)) < B_OK)
		return B_BAD_ADDRESS;
#else
	memcpy(data, &buffer_info, sizeof(buffer_info));
#endif

	return B_OK;
}
ssize_t
_user_recvmsg(int socket, struct msghdr *userMessage, int flags)
{
	// copy message from userland
	msghdr message;
	iovec* userVecs;
	MemoryDeleter vecsDeleter;
	void* userAddress;
	char address[MAX_SOCKET_ADDRESS_LENGTH];

	status_t error = prepare_userland_msghdr(userMessage, message, userVecs,
		vecsDeleter, userAddress, address);
	if (error != B_OK)
		return error;

	// prepare a buffer for ancillary data
	MemoryDeleter ancillaryDeleter;
	void* ancillary = NULL;
	void* userAncillary = message.msg_control;
	if (userAncillary != NULL) {
		if (!IS_USER_ADDRESS(userAncillary))
			return B_BAD_ADDRESS;
		if (message.msg_controllen < 0)
			return B_BAD_VALUE;
		if (message.msg_controllen > MAX_ANCILLARY_DATA_LENGTH)
			message.msg_controllen = MAX_ANCILLARY_DATA_LENGTH;

		message.msg_control = ancillary = malloc(message.msg_controllen);
		if (message.msg_control == NULL)
			return B_NO_MEMORY;

		ancillaryDeleter.SetTo(ancillary);
	}

	// recvmsg()
	SyscallRestartWrapper<ssize_t> result;

	result = common_recvmsg(socket, &message, flags, false);
	if (result < 0)
		return result;

	// copy the address, the ancillary data, and the message header back to
	// userland
	message.msg_name = userAddress;
	message.msg_iov = userVecs;
	message.msg_control = userAncillary;
	if ((userAddress != NULL && user_memcpy(userAddress, address,
				message.msg_namelen) != B_OK)
		|| (userAncillary != NULL && user_memcpy(userAncillary, ancillary,
				message.msg_controllen) != B_OK)
		|| user_memcpy(userMessage, &message, sizeof(msghdr)) != B_OK) {
		return B_BAD_ADDRESS;
	}

	return result;
}
static status_t
prepare_userland_msghdr(const msghdr* userMessage, msghdr& message,
	iovec*& userVecs, MemoryDeleter& vecsDeleter, void*& userAddress,
	char* address)
{
	if (userMessage == NULL)
		return B_BAD_VALUE;

	// copy message from userland
	if (!IS_USER_ADDRESS(userMessage)
			|| user_memcpy(&message, userMessage, sizeof(msghdr)) != B_OK) {
		return B_BAD_ADDRESS;
	}

	userVecs = message.msg_iov;
	userAddress = message.msg_name;

	// copy iovecs from userland
	if (message.msg_iovlen < 0 || message.msg_iovlen > IOV_MAX)
		return EMSGSIZE;
	if (userVecs != NULL && message.msg_iovlen > 0) {
		iovec* vecs = (iovec*)malloc(sizeof(iovec) * message.msg_iovlen);
		if (vecs == NULL)
			return B_NO_MEMORY;
		vecsDeleter.SetTo(vecs);

		if (!IS_USER_ADDRESS(message.msg_iov)
			|| user_memcpy(vecs, message.msg_iov,
					message.msg_iovlen * sizeof(iovec)) != B_OK) {
			return B_BAD_ADDRESS;
		}

		for (int i = 0; i < message.msg_iovlen; i++) {
			if (!IS_USER_ADDRESS(vecs[i].iov_base))
				return B_BAD_ADDRESS;
		}

		message.msg_iov = vecs;
	} else {
		message.msg_iov = NULL;
		message.msg_iovlen = 0;
	}

	// prepare the address field
	userAddress = message.msg_name;
	if (userAddress != NULL) {
		if (!IS_USER_ADDRESS(message.msg_name))
			return B_BAD_ADDRESS;
		if (message.msg_namelen > MAX_SOCKET_ADDRESS_LENGTH)
			message.msg_namelen = MAX_SOCKET_ADDRESS_LENGTH;

		message.msg_name = address;
	}

	return B_OK;
}
Esempio n. 9
0
status_t
read_cdda_data(int fd, off_t endFrame, off_t offset, void *data, size_t length,
	off_t bufferOffset, void *buffer, size_t bufferSize)
{
	if (bufferOffset >= 0 && bufferOffset <= offset + length
		&& bufferOffset + bufferSize > offset) {
		if (offset >= bufferOffset) {
			// buffer reaches into the beginning of the request
			off_t dataOffset = offset - bufferOffset;
			size_t bytes = min_c(bufferSize - dataOffset, length);
			if (user_memcpy(data, (uint8 *)buffer + dataOffset, bytes) < B_OK)
				return B_BAD_ADDRESS;

			data = (void *)((uint8 *)data + bytes);
			length -= bytes;
			offset += bytes;
		} else if (offset < bufferOffset
			&& offset + length < bufferOffset + bufferSize) {
			// buffer overlaps at the end of the request
			off_t dataOffset = bufferOffset - offset;
			size_t bytes = length - dataOffset;
			if (user_memcpy((uint8 *)data + dataOffset, buffer, bytes) < B_OK)
				return B_BAD_ADDRESS;

			length -= bytes;
		}
		// we don't handle the case where we would need to split the request
	}

	while (length > 0) {
		off_t frame = offset / kFrameSize;
		uint32 count = bufferSize / kFrameSize;
		if (frame + count > endFrame)
			count = endFrame - frame;

		status_t status = read_frames(fd, frame, (uint8 *)buffer, count);
		if (status < B_OK)
			return status;

		off_t dataOffset = offset % kFrameSize;
		size_t bytes = bufferSize - dataOffset;
		if (bytes > length)
			bytes = length;

		if (user_memcpy(data, (uint8 *)buffer + dataOffset, bytes) < B_OK)
			return B_BAD_ADDRESS;

		data = (void *)((uint8 *)data + bytes);
		length -= bytes;
		offset += bytes;
	}

	return B_OK;
}
Esempio n. 10
0
status_t
socket_control(net_socket* socket, int32 op, void* data, size_t length)
{
	switch (op) {
		case FIONBIO:
		{
			if (data == NULL)
				return B_BAD_VALUE;

			int value;
			if (is_syscall()) {
				if (!IS_USER_ADDRESS(data)
					|| user_memcpy(&value, data, sizeof(int)) != B_OK) {
					return B_BAD_ADDRESS;
				}
			} else
				value = *(int*)data;

			return socket_setsockopt(socket, SOL_SOCKET, SO_NONBLOCK, &value,
				sizeof(int));
		}

		case FIONREAD:
		{
			if (data == NULL)
				return B_BAD_VALUE;

			ssize_t available = socket_read_avail(socket);
			if (available < B_OK)
				return available;

			if (is_syscall()) {
				if (!IS_USER_ADDRESS(data)
					|| user_memcpy(data, &available, sizeof(ssize_t)) != B_OK) {
					return B_BAD_ADDRESS;
				}
			} else
				*(ssize_t *)data = available;

			return B_OK;
		}

		case B_SET_BLOCKING_IO:
		case B_SET_NONBLOCKING_IO:
		{
			int value = op == B_SET_NONBLOCKING_IO;
			return socket_setsockopt(socket, SOL_SOCKET, SO_NONBLOCK, &value,
				sizeof(int));
		}
	}

	return socket->first_info->control(socket->first_protocol,
		LEVEL_DRIVER_IOCTL, op, data, &length);
}
Esempio n. 11
0
status_t
_user_set_signal_stack(const stack_t *newUserStack, stack_t *oldUserStack)
{
	struct thread *thread = thread_get_current_thread();
	struct stack_t newStack, oldStack;
	bool onStack = false;

	if ((newUserStack != NULL && user_memcpy(&newStack, newUserStack,
				sizeof(stack_t)) < B_OK)
		|| (oldUserStack != NULL && user_memcpy(&oldStack, oldUserStack,
				sizeof(stack_t)) < B_OK))
		return B_BAD_ADDRESS;

	if (thread->signal_stack_enabled) {
		// determine wether or not the user thread is currently
		// on the active signal stack
		onStack = arch_on_signal_stack(thread);
	}

	if (oldUserStack != NULL) {
		oldStack.ss_sp = (void *)thread->signal_stack_base;
		oldStack.ss_size = thread->signal_stack_size;
		oldStack.ss_flags = (thread->signal_stack_enabled ? 0 : SS_DISABLE)
			| (onStack ? SS_ONSTACK : 0);
	}

	if (newUserStack != NULL) {
		// no flags other than SS_DISABLE are allowed
		if ((newStack.ss_flags & ~SS_DISABLE) != 0)
			return B_BAD_VALUE;

		if ((newStack.ss_flags & SS_DISABLE) == 0) {
			// check if the size is valid
			if (newStack.ss_size < MINSIGSTKSZ)
				return B_NO_MEMORY;
			if (onStack)
				return B_NOT_ALLOWED;
			if (!IS_USER_ADDRESS(newStack.ss_sp))
				return B_BAD_VALUE;

			thread->signal_stack_base = (addr_t)newStack.ss_sp;
			thread->signal_stack_size = newStack.ss_size;
			thread->signal_stack_enabled = true;
		} else
			thread->signal_stack_enabled = false;
	}

	// only copy the old stack info if a pointer has been given
	if (oldUserStack != NULL
		&& user_memcpy(oldUserStack, &oldStack, sizeof(stack_t)) < B_OK)
		return B_BAD_ADDRESS;

	return B_OK;
}
Esempio n. 12
0
static status_t
acpi_battery_control(void* _cookie, uint32 op, void* arg, size_t len)
{
	battery_device_cookie* device = (battery_device_cookie*)_cookie;
	status_t err;

	switch (op) {
		case IDENTIFY_DEVICE: {
			if (len < sizeof(uint32))
				return B_BAD_VALUE;

			uint32 magicId = kMagicACPIBatteryID;
			return user_memcpy(arg, &magicId, sizeof(magicId));
		}

		case GET_BATTERY_INFO: {
			if (len < sizeof(acpi_battery_info))
				return B_BAD_VALUE;

			acpi_battery_info batteryInfo;
			err = ReadBatteryStatus(device->driver_cookie, &batteryInfo);
			if (err != B_OK)
				return err;
			return user_memcpy(arg, &batteryInfo, sizeof(batteryInfo));
		}

		case GET_EXTENDED_BATTERY_INFO: {
			if (len < sizeof(acpi_extended_battery_info))
				return B_BAD_VALUE;

			acpi_extended_battery_info extBatteryInfo;
			err = ReadBatteryInfo(device->driver_cookie, &extBatteryInfo);
			if (err != B_OK)
				return err;
			return user_memcpy(arg, &extBatteryInfo, sizeof(extBatteryInfo));
		}

		case WATCH_BATTERY:
			sBatteryCondition.Wait();
			if (atomic_get(&(device->stop_watching))) {
				atomic_set(&(device->stop_watching), 0);
				return B_ERROR;
			}
			return B_OK;

		case STOP_WATCHING_BATTERY:
			atomic_set(&(device->stop_watching), 1);
			sBatteryCondition.NotifyAll();
			return B_OK;
	}

	return B_DEV_INVALID_IOCTL;
}
Esempio n. 13
0
static int vesa_ioctl(dev_cookie cookie, int op, void *buf, size_t len)
{
	int err = 0;

	if(!vesa.enabled)
		return ERR_NOT_FOUND;

	switch(op) {
		case IOCTL_DEVFS_GET_FRAMEBUFFER_INFO:
			if(is_kernel_address(buf))
				err = ERR_VM_BAD_USER_MEMORY;
			else
				err = user_memcpy(buf, &vesa.fb_info, sizeof(vesa.fb_info));
			break;
		case IOCTL_DEVFS_MAP_FRAMEBUFFER: {
			aspace_id aid = vm_get_current_user_aspace_id();
			region_id rid;
			void *address;

			if(is_kernel_address(buf)) {
				err = ERR_VM_BAD_USER_MEMORY;
				goto out;
			}

			// map the framebuffer into the user's address space
			rid = vm_map_physical_memory(aid, "vesa_fb", &address, REGION_ADDR_ANY_ADDRESS,
				vesa.phys_memory.size, LOCK_RW, vesa.phys_memory.start);
			if(rid < 0) {
				err = rid;
				goto out;
			}

			// copy the new pointer back to the user
			err = user_memcpy(buf, &address, sizeof(address));
			if(err < 0) {
				vm_delete_region(aid, rid);
				goto out;
			}

			// return the region id as the return code
			err = rid;

			break;
		}
		default:
			err = ERR_INVALID_ARGS;
	}

out:
	return err;
}
Esempio n. 14
0
status_t
_user_get_timezone(time_t *_timezoneOffset, bool *_daylightSavingTime)
{
	time_t offset = (time_t)(sTimezoneOffset / 1000000LL);

	if (!IS_USER_ADDRESS(_timezoneOffset)
		|| !IS_USER_ADDRESS(_daylightSavingTime)
		|| user_memcpy(_timezoneOffset, &offset, sizeof(time_t)) < B_OK
		|| user_memcpy(_daylightSavingTime, &sDaylightSavingTime,
				sizeof(bool)) < B_OK)
		return B_BAD_ADDRESS;

	return B_OK;
}
Esempio n. 15
0
ssize_t
_user_sendmsg(int socket, const struct msghdr *userMessage, int flags)
{
	// copy message from userland
	msghdr message;
	iovec* userVecs;
	MemoryDeleter vecsDeleter;
	void* userAddress;
	char address[MAX_SOCKET_ADDRESS_LENGTH];

	status_t error = prepare_userland_msghdr(userMessage, message, userVecs,
		vecsDeleter, userAddress, address);
	if (error != B_OK)
		return error;

	// copy the address from userland
	if (userAddress != NULL
			&& user_memcpy(address, userAddress, message.msg_namelen) != B_OK) {
		return B_BAD_ADDRESS;
	}

	// copy ancillary data from userland
	MemoryDeleter ancillaryDeleter;
	void* userAncillary = message.msg_control;
	if (userAncillary != NULL) {
		if (!IS_USER_ADDRESS(userAncillary))
			return B_BAD_ADDRESS;
		if (message.msg_controllen < 0
				|| message.msg_controllen > MAX_ANCILLARY_DATA_LENGTH) {
			return B_BAD_VALUE;
		}

		message.msg_control = malloc(message.msg_controllen);
		if (message.msg_control == NULL)
			return B_NO_MEMORY;
		ancillaryDeleter.SetTo(message.msg_control);

		if (user_memcpy(message.msg_control, userAncillary,
				message.msg_controllen) != B_OK) {
			return B_BAD_ADDRESS;
		}
	}

	// sendmsg()
	SyscallRestartWrapper<ssize_t> result;

	return result = common_sendmsg(socket, &message, flags, false);
}
Esempio n. 16
0
status_t
_user_system_profiler_next_buffer(size_t bytesRead, uint64* _droppedEvents)
{
	if (_droppedEvents != NULL && !IS_USER_ADDRESS(_droppedEvents))
		return B_BAD_ADDRESS;

	team_id team = thread_get_current_thread()->team->id;

	InterruptsSpinLocker locker(sProfilerLock);
	if (sProfiler == NULL || sProfiler->TeamID() != team)
		return B_BAD_VALUE;

	// get a reference to the profiler
	SystemProfiler* profiler = sProfiler;
	BReference<SystemProfiler> reference(profiler);
	locker.Unlock();

	uint64 droppedEvents;
	status_t error = profiler->NextBuffer(bytesRead,
		_droppedEvents != NULL ? &droppedEvents : NULL);
	if (error == B_OK && _droppedEvents != NULL)
		user_memcpy(_droppedEvents, &droppedEvents, sizeof(droppedEvents));

	return error;
}
Esempio n. 17
0
status_t
_user_socketpair(int family, int type, int protocol, int *userSocketVector)
{
	// check parameters
	if (userSocketVector == NULL)
		return B_BAD_VALUE;
	if (!IS_USER_ADDRESS(userSocketVector))
		return B_BAD_ADDRESS;

	// socketpair()
	int socketVector[2];
	SyscallRestartWrapper<status_t> error;
	error = common_socketpair(family, type, protocol, socketVector, false);
	if (error != B_OK)
		return error;

	// copy FDs back to userland
	if (user_memcpy(userSocketVector, socketVector,
			sizeof(socketVector)) != B_OK) {
		_user_close(socketVector[0]);
		_user_close(socketVector[1]);
		return B_BAD_ADDRESS;
	}

	return B_OK;
}
Esempio n. 18
0
static status_t
copy_address_to_userland(const void* address, socklen_t addressLength,
	sockaddr* userAddress, socklen_t userAddressBufferSize,
	socklen_t* userAddressLength)
{
	// copy address size and address back to userland
	if (user_memcpy(userAddressLength, &addressLength,
			sizeof(socklen_t)) != B_OK
		|| (userAddress != NULL
			&& user_memcpy(userAddress, address,
				min_c(addressLength, userAddressBufferSize)) != B_OK)) {
		return B_BAD_ADDRESS;
	}

	return B_OK;
}
Esempio n. 19
0
status_t
_user_writev_port_etc(port_id port, int32 messageCode, const iovec *userVecs,
	size_t vecCount, size_t bufferSize, uint32 flags, bigtime_t timeout)
{
	syscall_restart_handle_timeout_pre(flags, timeout);

	if (userVecs == NULL && bufferSize != 0)
		return B_BAD_VALUE;
	if (userVecs != NULL && !IS_USER_ADDRESS(userVecs))
		return B_BAD_ADDRESS;

	iovec *vecs = NULL;
	if (userVecs && vecCount != 0) {
		vecs = (iovec*)malloc(sizeof(iovec) * vecCount);
		if (vecs == NULL)
			return B_NO_MEMORY;

		if (user_memcpy(vecs, userVecs, sizeof(iovec) * vecCount) < B_OK) {
			free(vecs);
			return B_BAD_ADDRESS;
		}
	}

	status_t status = writev_port_etc(port, messageCode, vecs, vecCount,
		bufferSize, flags | PORT_FLAG_USE_USER_MEMCPY | B_CAN_INTERRUPT,
		timeout);

	free(vecs);
	return syscall_restart_handle_timeout_post(status, timeout);
}
Esempio n. 20
0
static status_t
prepare_userland_address_result(struct sockaddr* userAddress,
	socklen_t* _addressLength, socklen_t& addressLength, bool addressRequired)
{
	// check parameters
	if (_addressLength == NULL)
		return B_BAD_VALUE;
	if (userAddress == NULL) {
		if (addressRequired)
			return B_BAD_VALUE;
	} else if (!IS_USER_ADDRESS(userAddress)
			|| !IS_USER_ADDRESS(_addressLength)) {
		return B_BAD_ADDRESS;
	}

	// copy the buffer size from userland
	addressLength = 0;
	if (userAddress != NULL
			&& user_memcpy(&addressLength, _addressLength, sizeof(socklen_t))
				!= B_OK) {
		return B_BAD_ADDRESS;
	}

	if (addressLength > MAX_SOCKET_ADDRESS_LENGTH)
		addressLength = MAX_SOCKET_ADDRESS_LENGTH;

	return B_OK;
}
Esempio n. 21
0
File: mem.c Progetto: mmuman/haiku
status_t
mem_write(void* cookie, off_t position, const void* buffer, size_t* numBytes)
{
	void *virtualAddress;
	area_id area;
	status_t status = B_OK;

	/* check permissions */
	if (getuid() != 0 && geteuid() != 0) {
		*numBytes = 0;
		return EPERM;
	}

	area = mem_map_target(position, *numBytes, B_WRITE_AREA, &virtualAddress);
	if (area < 0) {
		*numBytes = 0;
		return area;
	}

	if (user_memcpy(virtualAddress, buffer, *numBytes) != B_OK)
		status = B_BAD_ADDRESS;

	delete_area(area);
	return status;
}
Esempio n. 22
0
status_t
_user_get_timer(int32 timerID, thread_id threadID,
	struct user_timer_info* userInfo)
{
	// get the timer
	TimerLocker timerLocker;
	UserTimer* timer;
	status_t error = timerLocker.LockAndGetTimer(threadID, timerID, timer);
	if (error != B_OK)
		return error;

	// get the info
	user_timer_info info;
	timer->GetInfo(info.remaining_time, info.interval, info.overrun_count);

	// Sanitize remaining_time. If it's <= 0, we set it to 1, the least valid
	// value.
	if (info.remaining_time <= 0)
		info.remaining_time = 1;

	timerLocker.Unlock();

	// copy it back to userland
	if (userInfo != NULL
		&& (!IS_USER_ADDRESS(userInfo)
			|| user_memcpy(userInfo, &info, sizeof(info)) != B_OK)) {
		return B_BAD_ADDRESS;
	}

	return B_OK;
}
Esempio n. 23
0
status_t device_ioctl(void* cookie, uint32 msg, void* buf, size_t len)
{
	TRACE("device_ioctl\n");
	
	DeviceInfo* dev = (DeviceInfo*)cookie;
	
	switch (msg) {
	case B_GET_ACCELERANT_SIGNATURE:
		strcpy((char*)buf, "vboxvideo.accelerant");
		return B_OK;
	
	case VBOXVIDEO_GET_PRIVATE_DATA:
		return user_memcpy(buf, &dev->sharedArea, sizeof(area_id));
		
	case VBOXVIDEO_GET_DEVICE_NAME:
		if (user_strlcpy((char*)buf, gDeviceInfo.name, len) < B_OK)
			return B_BAD_ADDRESS;
		else
			return B_OK;
	
	case VBOXVIDEO_SET_DISPLAY_MODE: {
		display_mode* mode = (display_mode*)buf;
		VBoxVideoSetModeRegisters(mode->timing.h_display, mode->timing.v_display,
			mode->timing.h_display, get_depth_for_color_space(mode->space), 0, 0, 0);
		gDeviceInfo.sharedInfo->currentMode = *mode;
		return B_OK;
	}
	default:
		return B_BAD_VALUE;
	}
	
}
Esempio n. 24
0
status_t
_user_system_profiler_recorded(struct system_profiler_parameters* userParameters)
{
	if (userParameters == NULL || !IS_USER_ADDRESS(userParameters))
		return B_BAD_ADDRESS;
	if (sRecordedParameters == NULL)
		return B_ERROR;

	// Transfer the area to the userland process

	void* address;
	area_id newArea = transfer_area(sRecordedParameters->buffer_area, &address,
		B_ANY_ADDRESS, team_get_current_team_id(), true);
	if (newArea < 0)
		return newArea;

	status_t status = set_area_protection(newArea, B_READ_AREA);
	if (status == B_OK) {
		sRecordedParameters->buffer_area = newArea;

		status = user_memcpy(userParameters, sRecordedParameters,
			sizeof(system_profiler_parameters));
	}
	if (status != B_OK)
		delete_area(newArea);

	delete sRecordedParameters;
	sRecordedParameters = NULL;

	return status;
}
Esempio n. 25
0
ssize_t
_user_sendto(int socket, const void *data, size_t length, int flags,
	const struct sockaddr *userAddress, socklen_t addressLength)
{
	if (data == NULL || !IS_USER_ADDRESS(data))
		return B_BAD_ADDRESS;

	// TODO: If this is a connection-mode socket, the address parameter is
	// supposed to be ignored.
	if (userAddress == NULL || addressLength <= 0
			|| addressLength > MAX_SOCKET_ADDRESS_LENGTH) {
		return B_BAD_VALUE;
	}

	// copy address from userland
	char address[MAX_SOCKET_ADDRESS_LENGTH];
	if (!IS_USER_ADDRESS(userAddress)
			|| user_memcpy(address, userAddress, addressLength) != B_OK) {
		return B_BAD_ADDRESS;
	}

	// sendto()
	SyscallRestartWrapper<ssize_t> result;

	return result = common_sendto(socket, data, length, flags,
		(sockaddr*)address, addressLength, false);
}
Esempio n. 26
0
ssize_t	user_port_read_etc(port_id uport, int32 *umsg_code, void *umsg_buffer,
							size_t ubuffer_size, uint32 uflags, bigtime_t utimeout)
{
	ssize_t	res;
	int32	msg_code;
	int		rc;

	if (umsg_code == NULL)
		return ERR_INVALID_ARGS;
	if (umsg_buffer == NULL)
		return ERR_INVALID_ARGS;

	if(is_kernel_address(umsg_code))
		return ERR_VM_BAD_USER_MEMORY;
	if(is_kernel_address(umsg_buffer))
		return ERR_VM_BAD_USER_MEMORY;

	res = port_read_etc(uport, &msg_code, umsg_buffer, ubuffer_size,
						uflags | PORT_FLAG_USE_USER_MEMCPY | SEM_FLAG_INTERRUPTABLE, utimeout);

	rc = user_memcpy(umsg_code, &msg_code, sizeof(int32));
	if(rc < 0)
		return rc;

	return res;
}
Esempio n. 27
0
status_t
device_ioctl(void *data, uint32 msg, void *buffer, size_t bufferLength)
{
	struct sis_info *info;

	if (checkDeviceInfo(info = data) != B_OK)
		return EINVAL;

	switch (msg) {
		case ETHER_GETADDR:
			TRACE(("ioctl: get MAC address\n"));
			memcpy(buffer, &info->address, 6);
			return B_OK;

		case ETHER_INIT:
			TRACE(("ioctl: init\n"));
			return B_OK;

		case ETHER_GETFRAMESIZE:
			TRACE(("ioctl: get frame size\n"));
			*(uint32*)buffer = MAX_FRAME_SIZE;
			return B_OK;

		case ETHER_SETPROMISC:
			TRACE(("ioctl: set promisc\n"));
			sis900_setPromiscuous(info, *(uint32 *)buffer != 0);
			return B_OK;

		case ETHER_NONBLOCK:
			info->blockFlag = *(int32 *)buffer ? B_TIMEOUT : 0;
			TRACE(("ioctl: non blocking ? %s\n", info->blockFlag ? "yes" : "no"));
			return B_OK;

		case ETHER_ADDMULTI:
			TRACE(("ioctl: add multicast\n"));
			/* not yet implemented */
			break;

#ifdef HAIKU_TARGET_PLATFORM_HAIKU
		case ETHER_GET_LINK_STATE:
		{
			ether_link_state_t state;
			state.media = (info->link ? IFM_ACTIVE : 0) | IFM_ETHER
				| (info->full_duplex ? IFM_FULL_DUPLEX : IFM_HALF_DUPLEX)
				| (info->speed == LINK_SPEED_100_MBIT ? IFM_100_TX : IFM_10_T);
			state.speed = info->speed == LINK_SPEED_100_MBIT
				? 100000 : 10000;
			state.quality = 1000;

			return user_memcpy(buffer, &state, sizeof(ether_link_state_t));
		}
#endif

		default:
			TRACE(("ioctl: unknown message %lu (length = %ld)\n", msg, bufferLength));
			break;
	}
	return B_ERROR;
}
Esempio n. 28
0
status_t
_user_sigwait(const sigset_t *userSet, int *_userSignal)
{
	if (userSet == NULL || _userSignal == NULL)
		return B_BAD_VALUE;

	sigset_t set;
	if (user_memcpy(&set, userSet, sizeof(sigset_t)) < B_OK)
		return B_BAD_ADDRESS;

	int signal;
	status_t status = sigwait(&set, &signal);
	if (status < B_OK)
		return syscall_restart_handle_post(status);

	return user_memcpy(_userSignal, &signal, sizeof(int));
}
Esempio n. 29
0
static status_t
get_int_option(void* target, size_t length, int value)
{
	if (length != sizeof(int))
		return B_BAD_VALUE;

	return user_memcpy(target, &value, sizeof(int));
}
Esempio n. 30
0
static status_t
device_ioctl(void* dev, uint32 msg, void* buffer, size_t bufferLength)
{
	DeviceInfo& di = *((DeviceInfo*)dev);

//	TRACE("device_ioctl(); ioctl: %lu, buffer: 0x%08lx, bufLen: %lu\n", msg,
//		(uint32)buffer, bufferLength);

	switch (msg) {
		case B_GET_ACCELERANT_SIGNATURE:
			strcpy((char*)buffer, ATI_ACCELERANT_NAME);
			return B_OK;

		case ATI_DEVICE_NAME:
			strncpy((char*)buffer, di.name, B_OS_NAME_LENGTH);
			((char*)buffer)[B_OS_NAME_LENGTH -1] = '\0';
			return B_OK;

		case ATI_GET_SHARED_DATA:
			if (bufferLength != sizeof(area_id))
				return B_BAD_DATA;

			*((area_id*)buffer) = di.sharedArea;
			return B_OK;

		case ATI_GET_EDID:
		{
			if (bufferLength != sizeof(edid1_raw))
				return B_BAD_DATA;

			edid1_raw rawEdid;
			status_t status = GetEdidFromBIOS(rawEdid);
			if (status == B_OK)
				user_memcpy((edid1_raw*)buffer, &rawEdid, sizeof(rawEdid));
			return status;
		}

		case ATI_SET_VESA_DISPLAY_MODE:
			if (bufferLength != sizeof(uint16))
				return B_BAD_DATA;

			return SetVesaDisplayMode(*((uint16*)buffer));

		case ATI_RUN_INTERRUPTS:
			if (bufferLength != sizeof(bool))
				return B_BAD_DATA;

			if (*((bool*)buffer))
				EnableVBI();
			else
				DisableVBI();

			return B_OK;
	}

	return B_DEV_INVALID_IOCTL;
}