@@ -53,6 +53,7 @@ use rustc_span::symbol::Symbol;
5353use std:: any:: Any ;
5454use std:: ffi:: CStr ;
5555use std:: io:: Write ;
56+ use std:: mem:: ManuallyDrop ;
5657
5758mod back {
5859 pub mod archive;
@@ -408,8 +409,9 @@ pub struct ModuleLlvm {
408409 llcx : & ' static mut llvm:: Context ,
409410 llmod_raw : * const llvm:: Module ,
410411
411- // independent from llcx and llmod_raw, resources get disposed by drop impl
412- tm : OwnedTargetMachine ,
412+ // This field is `ManuallyDrop` because it is important that the `TargetMachine`
413+ // is disposed prior to the `Context` being disposed otherwise UAFs can occur.
414+ tm : ManuallyDrop < OwnedTargetMachine > ,
413415}
414416
415417unsafe impl Send for ModuleLlvm { }
@@ -420,15 +422,23 @@ impl ModuleLlvm {
420422 unsafe {
421423 let llcx = llvm:: LLVMRustContextCreate ( tcx. sess . fewer_names ( ) ) ;
422424 let llmod_raw = context:: create_module ( tcx, llcx, mod_name) as * const _ ;
423- ModuleLlvm { llmod_raw, llcx, tm : create_target_machine ( tcx, mod_name) }
425+ ModuleLlvm {
426+ llmod_raw,
427+ llcx,
428+ tm : ManuallyDrop :: new ( create_target_machine ( tcx, mod_name) ) ,
429+ }
424430 }
425431 }
426432
427433 fn new_metadata ( tcx : TyCtxt < ' _ > , mod_name : & str ) -> Self {
428434 unsafe {
429435 let llcx = llvm:: LLVMRustContextCreate ( tcx. sess . fewer_names ( ) ) ;
430436 let llmod_raw = context:: create_module ( tcx, llcx, mod_name) as * const _ ;
431- ModuleLlvm { llmod_raw, llcx, tm : create_informational_target_machine ( tcx. sess ) }
437+ ModuleLlvm {
438+ llmod_raw,
439+ llcx,
440+ tm : ManuallyDrop :: new ( create_informational_target_machine ( tcx. sess ) ) ,
441+ }
432442 }
433443 }
434444
@@ -449,7 +459,7 @@ impl ModuleLlvm {
449459 }
450460 } ;
451461
452- Ok ( ModuleLlvm { llmod_raw, llcx, tm } )
462+ Ok ( ModuleLlvm { llmod_raw, llcx, tm : ManuallyDrop :: new ( tm ) } )
453463 }
454464 }
455465
@@ -461,6 +471,7 @@ impl ModuleLlvm {
461471impl Drop for ModuleLlvm {
462472 fn drop ( & mut self ) {
463473 unsafe {
474+ ManuallyDrop :: drop ( & mut self . tm ) ;
464475 llvm:: LLVMContextDispose ( & mut * ( self . llcx as * mut _ ) ) ;
465476 }
466477 }
0 commit comments