Ejemplo n.º 1
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;
}
Ejemplo n.º 2
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);
}
Ejemplo n.º 3
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;
}
Ejemplo n.º 4
0
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;
}
Ejemplo n.º 5
0
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;
}
Ejemplo n.º 6
0
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;
}
Ejemplo n.º 7
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);
}
Ejemplo n.º 8
0
status_t
_user_mutex_switch_lock(int32* fromMutex, int32* toMutex, const char* name,
	uint32 flags, bigtime_t timeout)
{
	if (fromMutex == NULL || !IS_USER_ADDRESS(fromMutex)
			|| (addr_t)fromMutex % 4 != 0 || toMutex == NULL
			|| !IS_USER_ADDRESS(toMutex) || (addr_t)toMutex % 4 != 0) {
		return B_BAD_ADDRESS;
	}

	return user_mutex_switch_lock(fromMutex, toMutex, name,
		flags | B_CAN_INTERRUPT, timeout);
}
Ejemplo n.º 9
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;
}
Ejemplo n.º 10
0
ssize_t
_user_recvfrom(int socket, void *data, size_t length, int flags,
	struct sockaddr *userAddress, socklen_t *_addressLength)
{
	if (data == NULL || !IS_USER_ADDRESS(data))
		return B_BAD_ADDRESS;

	// check parameters
	socklen_t addressLength = 0;
	status_t error = prepare_userland_address_result(userAddress,
		_addressLength, addressLength, false);
	if (error != B_OK)
		return error;

	// recvfrom()
	SyscallRestartWrapper<ssize_t> result;

	char address[MAX_SOCKET_ADDRESS_LENGTH];
	socklen_t userAddressBufferSize = addressLength;
	result = common_recvfrom(socket, data, length, flags,
		userAddress != NULL ? (sockaddr*)address : NULL, &addressLength, false);
	if (result < 0)
		return result;

	// copy address size and address back to userland
	if (copy_address_to_userland(address, addressLength, userAddress,
			userAddressBufferSize, _addressLength) != B_OK) {
		return B_BAD_ADDRESS;
	}

	return result;
}
Ejemplo n.º 11
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;
}
Ejemplo n.º 12
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;
}
Ejemplo n.º 13
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;
}
Ejemplo n.º 14
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);
}
Ejemplo n.º 15
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;
}
status_t
_user_set_timezone(time_t timezoneOffset, const char *name, size_t nameLength)
{
	bigtime_t offset = (bigtime_t)timezoneOffset * 1000000LL;

	if (geteuid() != 0)
		return B_NOT_ALLOWED;

	TRACE(("old system_time_offset %Ld old %Ld new %Ld gmt %d\n",
		arch_rtc_get_system_time_offset(sRealTimeData), sTimezoneOffset,
		offset, sIsGMT));

	if (name != NULL && nameLength > 0) {
		if (!IS_USER_ADDRESS(name)
			|| user_strlcpy(sTimezoneName, name, sizeof(sTimezoneName)) < 0)
			return B_BAD_ADDRESS;
	}

	// We only need to update our time offset if the hardware clock
	// does not run in the local timezone.
	// Since this is shared data, we need to update it atomically.
	if (!sIsGMT) {
		arch_rtc_set_system_time_offset(sRealTimeData,
			arch_rtc_get_system_time_offset(sRealTimeData) + sTimezoneOffset
				- offset);
		real_time_clock_changed();
	}

	sTimezoneOffset = offset;

	TRACE(("new system_time_offset %Ld\n",
		arch_rtc_get_system_time_offset(sRealTimeData)));

	return B_OK;
}
Ejemplo n.º 17
0
char*
alloc_tracing_buffer_strcpy(const char* source, size_t maxSize, bool user)
{
	if (source == NULL || maxSize == 0)
		return NULL;

	if (user && !IS_USER_ADDRESS(source))
		return NULL;

	// limit maxSize to the actual source string len
	if (user) {
		ssize_t size = user_strlcpy(NULL, source, 0);
			// there's no user_strnlen()
		if (size < 0)
			return 0;
		maxSize = min_c(maxSize, (size_t)size + 1);
	} else
		maxSize = strnlen(source, maxSize - 1) + 1;

	char* buffer = (char*)alloc_tracing_buffer(maxSize);
	if (buffer == NULL)
		return NULL;

	if (user) {
		if (user_strlcpy(buffer, source, maxSize) < B_OK)
			return NULL;
	} else
		strlcpy(buffer, source, maxSize);

	return buffer;
}
status_t
_user_get_timezone(time_t *_timezoneOffset, char *userName, size_t nameLength)
{
	time_t offset = (time_t)(sTimezoneOffset / 1000000LL);

	if (_timezoneOffset != NULL
		&& (!IS_USER_ADDRESS(_timezoneOffset)
			|| user_memcpy(_timezoneOffset, &offset, sizeof(time_t)) < B_OK))
		return B_BAD_ADDRESS;

	if (userName != NULL
		&& (!IS_USER_ADDRESS(userName)
			|| user_strlcpy(userName, sTimezoneName, nameLength) < 0))
		return B_BAD_ADDRESS;

	return B_OK;
}
Ejemplo n.º 19
0
ssize_t
_user_recv(int socket, void *data, size_t length, int flags)
{
	if (data == NULL || !IS_USER_ADDRESS(data))
		return B_BAD_ADDRESS;

	SyscallRestartWrapper<ssize_t> result;
	return result = common_recv(socket, data, length, flags, false);
}
Ejemplo n.º 20
0
status_t
_user_get_tzfilename(char *userFilename, size_t length, bool *_userIsGMT)
{
	if ((userFilename == NULL || length == 0) && _userIsGMT == NULL)
		return B_BAD_VALUE;

	if (userFilename != NULL
		&& (!IS_USER_ADDRESS(userFilename)
			|| user_strlcpy(userFilename, sTimezoneFilename, length) < 0))
		return B_BAD_ADDRESS;

	if (_userIsGMT != NULL
		&& (!IS_USER_ADDRESS(_userIsGMT)
			|| user_memcpy(_userIsGMT, &sIsGMT, sizeof(bool)) != B_OK))
		return B_BAD_ADDRESS;

	return B_OK;
}
Ejemplo n.º 21
0
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;
}
Ejemplo n.º 22
0
static status_t
launch_speedup_control(const char *subsystem, uint32 function,
	void *buffer, size_t bufferSize)
{
	switch (function) {
		case LAUNCH_SPEEDUP_START_SESSION:
		{
			char name[B_OS_NAME_LENGTH];
			if (!IS_USER_ADDRESS(buffer)
				|| user_strlcpy(name, (const char *)buffer, B_OS_NAME_LENGTH) < B_OK)
				return B_BAD_ADDRESS;

			if (isdigit(name[0]) || name[0] == '.')
				return B_BAD_VALUE;

			sMainSession = start_session(-1, -1, -1, name, 60);
			sMainSession->Unlock();
			return B_OK;
		}

		case LAUNCH_SPEEDUP_STOP_SESSION:
		{
			char name[B_OS_NAME_LENGTH];
			if (!IS_USER_ADDRESS(buffer)
				|| user_strlcpy(name, (const char *)buffer, B_OS_NAME_LENGTH) < B_OK)
				return B_BAD_ADDRESS;

			// ToDo: this check is not thread-safe
			if (sMainSession == NULL || strcmp(sMainSession->Name(), name))
				return B_BAD_VALUE;

			if (!strcmp(name, "system boot"))
				dprintf("STOP BOOT %Ld\n", system_time());

			sMainSession->Lock();
			stop_session(sMainSession);
			sMainSession = NULL;
			return B_OK;
		}
	}

	return B_BAD_VALUE;
}
Ejemplo n.º 23
0
status_t
_user_get_cpu_topology_info(cpu_topology_node_info* topologyInfos,
	uint32* topologyInfoCount)
{
	if (topologyInfoCount == NULL || !IS_USER_ADDRESS(topologyInfoCount))
		return B_BAD_ADDRESS;

	const cpu_topology_node* node = get_cpu_topology();

	uint32 count = 0;
	count_topology_nodes(node, count);

	if (topologyInfos == NULL)
		return user_memcpy(topologyInfoCount, &count, sizeof(uint32));
	else if (!IS_USER_ADDRESS(topologyInfoCount))
		return B_BAD_ADDRESS;

	uint32 userCount;
	status_t error = user_memcpy(&userCount, topologyInfoCount, sizeof(uint32));
	if (error != B_OK)
		return error;
	if (userCount == 0)
		return B_OK;
	count = std::min(count, userCount);

	cpu_topology_node_info* topology
		= new(std::nothrow) cpu_topology_node_info[count];
	if (topology == NULL)
		return B_NO_MEMORY;
	ArrayDeleter<cpu_topology_node_info> _(topology);
	memset(topology, 0, sizeof(cpu_topology_node_info) * count);

	uint32 nodesLeft = count;
	generate_topology_array(topology, node, nodesLeft);
	ASSERT(nodesLeft == 0);

	error = user_memcpy(topologyInfos, topology,
		sizeof(cpu_topology_node_info) * count);
	if (error != B_OK)
		return error;
	return user_memcpy(topologyInfoCount, &count, sizeof(uint32));
}
Ejemplo n.º 24
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;
}
Ejemplo n.º 25
0
status_t
_user_ioctl(int fd, uint32 op, void* buffer, size_t length)
{
	if (!IS_USER_ADDRESS(buffer))
		return B_BAD_ADDRESS;

	TRACE(("user_ioctl: fd %d\n", fd));

	SyscallRestartWrapper<status_t> status;

	return status = fd_ioctl(false, fd, op, buffer, length);
}
Ejemplo n.º 26
0
inline ssize_t
RingBuffer::Read(void* buffer, size_t length, bool isUser)
{
	if (fBuffer == NULL)
		return B_NO_MEMORY;
	if (isUser && !IS_USER_ADDRESS(buffer))
		return B_BAD_ADDRESS;

	return isUser
		? ring_buffer_user_read(fBuffer, (uint8*)buffer, length)
		: ring_buffer_read(fBuffer, (uint8*)buffer, length);
}
Ejemplo n.º 27
0
ssize_t
_user_read_dir(int fd, struct dirent* userBuffer, size_t bufferSize,
	uint32 maxCount)
{
	TRACE(("user_read_dir(fd = %d, userBuffer = %p, bufferSize = %ld, count = "
		"%lu)\n", fd, userBuffer, bufferSize, maxCount));

	if (maxCount == 0)
		return 0;

	if (userBuffer == NULL || !IS_USER_ADDRESS(userBuffer))
		return B_BAD_ADDRESS;

	// get I/O context and FD
	io_context* ioContext = get_current_io_context(false);
	FDGetter fdGetter;
	struct file_descriptor* descriptor = fdGetter.SetTo(ioContext, fd, false);
	if (descriptor == NULL || (descriptor->open_mode & O_DISCONNECTED) != 0)
		return B_FILE_ERROR;

	if (descriptor->ops->fd_read_dir == NULL)
		return B_UNSUPPORTED;

	// restrict buffer size and allocate a heap buffer
	if (bufferSize > kMaxReadDirBufferSize)
		bufferSize = kMaxReadDirBufferSize;
	struct dirent* buffer = (struct dirent*)malloc(bufferSize);
	if (buffer == NULL)
		return B_NO_MEMORY;
	MemoryDeleter bufferDeleter(buffer);

	// read the directory
	uint32 count = maxCount;
	status_t status = descriptor->ops->fd_read_dir(ioContext, descriptor,
		buffer, bufferSize, &count);
	if (status != B_OK)
		return status;

	// copy the buffer back -- determine the total buffer size first
	size_t sizeToCopy = 0;
	struct dirent* entry = buffer;
	for (uint32 i = 0; i < count; i++) {
		size_t length = entry->d_reclen;
		sizeToCopy += length;
		entry = (struct dirent*)((uint8*)entry + length);
	}

	if (user_memcpy(userBuffer, buffer, sizeToCopy) != B_OK)
		return B_BAD_ADDRESS;

	return count;
}
Ejemplo n.º 28
0
port_id
_user_find_port(const char *userName)
{
	char name[B_OS_NAME_LENGTH];

	if (userName == NULL)
		return B_BAD_VALUE;
	if (!IS_USER_ADDRESS(userName)
		|| user_strlcpy(name, userName, B_OS_NAME_LENGTH) < B_OK)
		return B_BAD_ADDRESS;

	return find_port(name);
}
status_t
_user_get_real_time_clock_is_gmt(bool *_userIsGMT)
{
	if (_userIsGMT == NULL)
		return B_BAD_VALUE;

	if (_userIsGMT != NULL
		&& (!IS_USER_ADDRESS(_userIsGMT)
			|| user_memcpy(_userIsGMT, &sIsGMT, sizeof(bool)) != B_OK))
		return B_BAD_ADDRESS;

	return B_OK;
}
Ejemplo n.º 30
0
image_id
_user_register_image(extended_image_info *userInfo, size_t size)
{
	extended_image_info info;

	if (size != sizeof(info))
		return B_BAD_VALUE;

	if (!IS_USER_ADDRESS(userInfo)
		|| user_memcpy(&info, userInfo, size) < B_OK)
		return B_BAD_ADDRESS;

	return register_image(thread_get_current_thread()->team, &info, size);
}