Add state limitation to thread_*_state

This commit is contained in:
Ben Pig Chu 2020-08-30 15:25:35 +08:00
parent 2eb60e1946
commit 2fbd468bee
2 changed files with 29 additions and 5 deletions

View File

@ -318,6 +318,10 @@ impl Thread {
/// Read one aspect of thread state.
pub fn read_state(&self, kind: ThreadStateKind, buf: &mut [u8]) -> ZxResult<usize> {
let inner = self.inner.lock();
let state = inner.state();
if state != ThreadState::BlockedException && state != ThreadState::Suspended {
return Err(ZxError::BAD_STATE);
}
let context = inner.context.as_ref().ok_or(ZxError::BAD_STATE)?;
context.read_state(kind, buf)
}
@ -325,6 +329,10 @@ impl Thread {
/// Write one aspect of thread state.
pub fn write_state(&self, kind: ThreadStateKind, buf: &[u8]) -> ZxResult {
let mut inner = self.inner.lock();
let state = inner.state();
if state != ThreadState::BlockedException && state != ThreadState::Suspended {
return Err(ZxError::BAD_STATE);
}
let context = inner.context.as_mut().ok_or(ZxError::BAD_STATE)?;
context.write_state(kind, buf)
}
@ -402,6 +410,24 @@ impl Thread {
pub fn update_flags(&self, f: impl FnOnce(&mut ThreadFlag)) {
f(&mut self.inner.lock().flags)
}
/// Set the thread local fsbase register on x86_64.
#[cfg(target_arch = "x86_64")]
pub fn set_fsbase(&self, fsbase: usize) -> ZxResult {
let mut inner = self.inner.lock();
let context = inner.context.as_mut().ok_or(ZxError::BAD_STATE)?;
context.general.fsbase = fsbase;
Ok(())
}
/// Set the thread local gsbase register on x86_64.
#[cfg(target_arch = "x86_64")]
pub fn set_gsbase(&self, gsbase: usize) -> ZxResult {
let mut inner = self.inner.lock();
let context = inner.context.as_mut().ok_or(ZxError::BAD_STATE)?;
context.general.gsbase = gsbase;
Ok(())
}
}
impl Task for Thread {

View File

@ -139,16 +139,14 @@ impl Syscall<'_> {
Property::RegisterFs => {
let thread = proc.get_object::<Thread>(handle_value)?;
let fsbase = UserInPtr::<usize>::from_addr_size(buffer, buffer_size)?.read()?;
let buf = fsbase.to_ne_bytes();
thread.write_state(ThreadStateKind::FS, &buf)?;
thread.set_fsbase(fsbase)?;
Ok(())
}
#[cfg(target_arch = "x86_64")]
Property::RegisterGs => {
let thread = proc.get_object::<Thread>(handle_value)?;
let fsbase = UserInPtr::<usize>::from_addr_size(buffer, buffer_size)?.read()?;
let buf = fsbase.to_ne_bytes();
thread.write_state(ThreadStateKind::GS, &buf)?;
let gsbase = UserInPtr::<usize>::from_addr_size(buffer, buffer_size)?.read()?;
thread.set_gsbase(gsbase)?;
Ok(())
}
Property::ProcessBreakOnLoad => {