Fix mprotect and mremap potential failure
This commit is contained in:
parent
9e9c7c1644
commit
0bf4a5a7f7
@ -390,14 +390,15 @@ impl ProcessVM {
|
|||||||
// Collect merged vmas which will be the output of this function
|
// Collect merged vmas which will be the output of this function
|
||||||
let mut merged_vmas = Vec::new();
|
let mut merged_vmas = Vec::new();
|
||||||
|
|
||||||
// Insert the merged chunks or unchanged chunks back to mem_chunk list
|
// Insert unchanged chunks back to mem_chunks list and collect merged vmas for output
|
||||||
for chunk in single_vma_chunks.into_iter().filter_map(|chunk| {
|
for chunk in single_vma_chunks.into_iter().filter_map(|chunk| {
|
||||||
if !chunk.is_single_dummy_vma() {
|
if !chunk.is_single_dummy_vma() {
|
||||||
if chunk.is_single_vma_with_conflict_size() {
|
if chunk.is_single_vma_with_conflict_size() {
|
||||||
let new_vma = chunk.get_vma_for_single_vma_chunk();
|
let new_vma = chunk.get_vma_for_single_vma_chunk();
|
||||||
merged_vmas.push(new_vma.clone());
|
merged_vmas.push(new_vma);
|
||||||
|
|
||||||
Some(Arc::new(Chunk::new_chunk_with_vma(new_vma)))
|
// Don't insert the merged chunks to mem_chunk list here. It should be updated later.
|
||||||
|
None
|
||||||
} else {
|
} else {
|
||||||
Some(chunk)
|
Some(chunk)
|
||||||
}
|
}
|
||||||
|
@ -58,8 +58,6 @@ impl VMManager {
|
|||||||
|
|
||||||
// Allocate single VMA chunk for new process whose process VM is not ready yet
|
// Allocate single VMA chunk for new process whose process VM is not ready yet
|
||||||
pub fn alloc(&self, options: &VMMapOptions) -> Result<(VMRange, ChunkRef)> {
|
pub fn alloc(&self, options: &VMMapOptions) -> Result<(VMRange, ChunkRef)> {
|
||||||
let addr = *options.addr();
|
|
||||||
let size = *options.size();
|
|
||||||
if let Ok(new_chunk) = self.internal().mmap_chunk(options) {
|
if let Ok(new_chunk) = self.internal().mmap_chunk(options) {
|
||||||
return Ok((new_chunk.range().clone(), new_chunk));
|
return Ok((new_chunk.range().clone(), new_chunk));
|
||||||
}
|
}
|
||||||
@ -428,11 +426,11 @@ impl VMManager {
|
|||||||
// Must lock the internal manager first here in case the chunk's range and vma are conflict when other threads are operating the VM
|
// Must lock the internal manager first here in case the chunk's range and vma are conflict when other threads are operating the VM
|
||||||
let mut internal_manager = self.internal.lock().unwrap();
|
let mut internal_manager = self.internal.lock().unwrap();
|
||||||
let mut merged_vmas = current.vm().merge_all_single_vma_chunks()?;
|
let mut merged_vmas = current.vm().merge_all_single_vma_chunks()?;
|
||||||
|
internal_manager.clean_single_vma_chunks();
|
||||||
while merged_vmas.len() != 0 {
|
while merged_vmas.len() != 0 {
|
||||||
let merged_vma = merged_vmas.pop().unwrap();
|
let merged_vma = merged_vmas.pop().unwrap();
|
||||||
internal_manager.add_new_chunk(¤t, merged_vma);
|
internal_manager.add_new_chunk(¤t, merged_vma);
|
||||||
}
|
}
|
||||||
internal_manager.clean_single_vma_chunks();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Deternmine the chunk of the old range
|
// Deternmine the chunk of the old range
|
||||||
@ -774,12 +772,14 @@ impl InternalVMManager {
|
|||||||
self.chunks.insert(new_chunk);
|
self.chunks.insert(new_chunk);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// protect_range should a sub-range of the chunk range
|
||||||
pub fn mprotect_single_vma_chunk(
|
pub fn mprotect_single_vma_chunk(
|
||||||
&mut self,
|
&mut self,
|
||||||
chunk: &ChunkRef,
|
chunk: &ChunkRef,
|
||||||
protect_range: VMRange,
|
protect_range: VMRange,
|
||||||
new_perms: VMPerms,
|
new_perms: VMPerms,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
|
debug_assert!(chunk.range().is_superset_of(&protect_range));
|
||||||
let vma = match chunk.internal() {
|
let vma = match chunk.internal() {
|
||||||
ChunkType::MultiVMA(_) => {
|
ChunkType::MultiVMA(_) => {
|
||||||
unreachable!();
|
unreachable!();
|
||||||
@ -838,7 +838,8 @@ impl InternalVMManager {
|
|||||||
)
|
)
|
||||||
};
|
};
|
||||||
|
|
||||||
let updated_vmas = vec![containing_vma.clone(), new_vma, remaining_old_vma];
|
// Put containing_vma at last to be updated first.
|
||||||
|
let updated_vmas = vec![new_vma, remaining_old_vma, containing_vma.clone()];
|
||||||
updated_vmas
|
updated_vmas
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
@ -858,28 +859,33 @@ impl InternalVMManager {
|
|||||||
);
|
);
|
||||||
VMPerms::apply_perms(&new_vma, new_vma.perms());
|
VMPerms::apply_perms(&new_vma, new_vma.perms());
|
||||||
|
|
||||||
let updated_vmas = vec![containing_vma.clone(), new_vma];
|
// Put containing_vma at last to be updated first.
|
||||||
|
let updated_vmas = vec![new_vma, containing_vma.clone()];
|
||||||
updated_vmas
|
updated_vmas
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let current = current!();
|
let current = current!();
|
||||||
while updated_vmas.len() > 1 {
|
// First update current vma chunk
|
||||||
let vma = updated_vmas.pop().unwrap();
|
if updated_vmas.len() > 1 {
|
||||||
self.add_new_chunk(¤t, vma);
|
let update_vma = updated_vmas.pop().unwrap();
|
||||||
|
self.update_single_vma_chunk(¤t, &chunk, update_vma);
|
||||||
}
|
}
|
||||||
|
|
||||||
debug_assert!(updated_vmas.len() == 1);
|
// Then add new chunks if any
|
||||||
let vma = updated_vmas.pop().unwrap();
|
updated_vmas.into_iter().for_each(|vma| {
|
||||||
self.update_single_vma_chunk(¤t, &chunk, vma);
|
self.add_new_chunk(¤t, vma);
|
||||||
|
});
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Must make sure that all the chunks are valid before adding new chunks
|
||||||
fn add_new_chunk(&mut self, current_thread: &ThreadRef, new_vma: VMArea) {
|
fn add_new_chunk(&mut self, current_thread: &ThreadRef, new_vma: VMArea) {
|
||||||
let new_vma_chunk = Arc::new(Chunk::new_chunk_with_vma(new_vma));
|
let new_vma_chunk = Arc::new(Chunk::new_chunk_with_vma(new_vma));
|
||||||
self.chunks.insert(new_vma_chunk.clone());
|
let success = self.chunks.insert(new_vma_chunk.clone());
|
||||||
|
debug_assert!(success);
|
||||||
current_thread.vm().add_mem_chunk(new_vma_chunk);
|
current_thread.vm().add_mem_chunk(new_vma_chunk);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user