Skip to content

Commit 8561f09

Browse files
committed
Restrict sysroot crate imports to those defined in this repo.
It's common to import dependencies from the sysroot via `extern crate` rather than use an explicit cargo dependency, when it's necessary to use the same dependency version as used by rustc itself. However, this is dangerous for crates.io crates, since rustc may not pull in the dependency on some targets, or may pull in multiple versions. In both cases, the `extern crate` fails to resolve. To address this, re-export all such dependencies from the appropriate `rustc_*` crates, and use this alias from crates which would otherwise need to use `extern crate`.
1 parent 915e535 commit 8561f09

File tree

50 files changed

+121
-81
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

50 files changed

+121
-81
lines changed

compiler/rustc_codegen_cranelift/src/lib.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,13 +26,12 @@ extern crate rustc_fs_util;
2626
extern crate rustc_hir;
2727
extern crate rustc_incremental;
2828
extern crate rustc_index;
29+
extern crate rustc_log;
2930
extern crate rustc_metadata;
3031
extern crate rustc_session;
3132
extern crate rustc_span;
3233
extern crate rustc_symbol_mangling;
3334
extern crate rustc_target;
34-
#[macro_use]
35-
extern crate tracing;
3635

3736
// This prevents duplicating functions and statics that are already part of the host rustc process.
3837
#[allow(unused_extern_crates)]
@@ -46,6 +45,7 @@ use cranelift_codegen::isa::TargetIsa;
4645
use cranelift_codegen::settings::{self, Configurable};
4746
use rustc_codegen_ssa::traits::CodegenBackend;
4847
use rustc_codegen_ssa::{CodegenResults, TargetConfig};
48+
use rustc_log::tracing::info;
4949
use rustc_middle::dep_graph::{WorkProduct, WorkProductId};
5050
use rustc_session::Session;
5151
use rustc_session::config::OutputFilenames;

compiler/rustc_codegen_gcc/src/back/lto.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ use rustc_codegen_ssa::{ModuleCodegen, ModuleKind, looks_like_rust_object_file};
3232
use rustc_data_structures::memmap::Mmap;
3333
use rustc_errors::{DiagCtxtHandle, FatalError};
3434
use rustc_hir::def_id::LOCAL_CRATE;
35+
use rustc_log::tracing::info;
3536
use rustc_middle::bug;
3637
use rustc_middle::dep_graph::WorkProduct;
3738
use rustc_middle::middle::exported_symbols::{SymbolExportInfo, SymbolExportLevel};

compiler/rustc_codegen_gcc/src/back/write.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ use rustc_codegen_ssa::back::write::{BitcodeSection, CodegenContext, EmitObj, Mo
66
use rustc_codegen_ssa::{CompiledModule, ModuleCodegen};
77
use rustc_errors::DiagCtxtHandle;
88
use rustc_fs_util::link_or_copy;
9+
use rustc_log::tracing::debug;
910
use rustc_session::config::OutputType;
1011
use rustc_span::fatal_error::FatalError;
1112
use rustc_target::spec::SplitDebuginfo;

compiler/rustc_codegen_gcc/src/consts.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ use rustc_codegen_ssa::traits::{
66
BaseTypeCodegenMethods, ConstCodegenMethods, StaticCodegenMethods,
77
};
88
use rustc_hir::def::DefKind;
9+
use rustc_log::tracing::trace;
910
use rustc_middle::middle::codegen_fn_attrs::{CodegenFnAttrFlags, CodegenFnAttrs};
1011
use rustc_middle::mir::interpret::{
1112
self, ConstAllocation, ErrorHandled, Scalar as InterpScalar, read_target_uint,

compiler/rustc_codegen_gcc/src/gcc_util.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
#[cfg(feature = "master")]
22
use gccjit::Context;
33
use rustc_codegen_ssa::target_features;
4+
use rustc_data_structures::smallvec::{SmallVec, smallvec};
45
use rustc_session::Session;
5-
use smallvec::{SmallVec, smallvec};
66

77
fn gcc_features_by_flags(sess: &Session, features: &mut Vec<String>) {
88
target_features::retpoline_features_by_flags(sess, features);

compiler/rustc_codegen_gcc/src/lib.rs

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -25,12 +25,6 @@
2525
#![deny(clippy::pattern_type_mismatch)]
2626
#![allow(clippy::needless_lifetimes, clippy::uninlined_format_args)]
2727

28-
// These crates are pulled from the sysroot because they are part of
29-
// rustc's public API, so we need to ensure version compatibility.
30-
extern crate smallvec;
31-
#[macro_use]
32-
extern crate tracing;
33-
3428
// The rustc crates we need
3529
extern crate rustc_abi;
3630
extern crate rustc_apfloat;
@@ -45,6 +39,7 @@ extern crate rustc_hir;
4539
extern crate rustc_index;
4640
#[cfg(feature = "master")]
4741
extern crate rustc_interface;
42+
extern crate rustc_log;
4843
extern crate rustc_macros;
4944
extern crate rustc_middle;
5045
extern crate rustc_session;

compiler/rustc_data_structures/src/lib.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,8 @@ use std::fmt;
4343
pub use atomic_ref::AtomicRef;
4444
pub use ena::{snapshot_vec, undo_log, unify};
4545
pub use rustc_index::static_assert_size;
46+
// Re-export some data-structure crates which are part of our public API.
47+
pub use {either, indexmap, smallvec, thin_vec};
4648

4749
pub mod aligned;
4850
pub mod base_n;

compiler/rustc_lint/messages.ftl

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,9 @@ lint_confusable_identifier_pair = found both `{$existing_sym}` and `{$sym}` as i
207207
208208
lint_custom_inner_attribute_unstable = custom inner attributes are unstable
209209
210+
lint_dangerous_extern_crate = dangerous use of `extern crate {$name}` which is not guaranteed to exist exactly once in the sysroot
211+
.help = try using a cargo dependency or using a re-export of the dependency provided by a rustc_* crate
212+
210213
lint_dangling_pointers_from_temporaries = a dangling pointer will be produced because the temporary `{$ty}` will be dropped
211214
.label_ptr = this pointer will immediately be invalid
212215
.label_temporary = this `{$ty}` is deallocated at the end of the statement, bind it to a variable to extend its lifetime

compiler/rustc_lint/src/internal.rs

Lines changed: 38 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,10 @@ use tracing::debug;
1212
use {rustc_ast as ast, rustc_hir as hir};
1313

1414
use crate::lints::{
15-
BadOptAccessDiag, DefaultHashTypesDiag, DiagOutOfImpl, LintPassByHand,
16-
NonGlobImportTypeIrInherent, QueryInstability, QueryUntracked, SpanUseEqCtxtDiag,
17-
SymbolInternStringLiteralDiag, TyQualified, TykindDiag, TykindKind, TypeIrDirectUse,
18-
TypeIrInherentUsage, TypeIrTraitUsage, UntranslatableDiag,
15+
BadOptAccessDiag, DangerousExternCrateDiag, DefaultHashTypesDiag, DiagOutOfImpl,
16+
LintPassByHand, NonGlobImportTypeIrInherent, QueryInstability, QueryUntracked,
17+
SpanUseEqCtxtDiag, SymbolInternStringLiteralDiag, TyQualified, TykindDiag, TykindKind,
18+
TypeIrDirectUse, TypeIrInherentUsage, TypeIrTraitUsage, UntranslatableDiag,
1919
};
2020
use crate::{EarlyContext, EarlyLintPass, LateContext, LateLintPass, LintContext};
2121

@@ -703,3 +703,37 @@ impl<'tcx> LateLintPass<'tcx> for SymbolInternStringLiteral {
703703
}
704704
}
705705
}
706+
707+
declare_tool_lint! {
708+
/// The `dangerous_extern_crate` detects use of `extern crate` to import non-whitelisted crates
709+
/// from the sysroot, which is dangerous because these crates are not guaranteed to exist
710+
/// exactly once, and so may be missing entirely or appear multiple times resulting in ambiguity.
711+
pub rustc::DANGEROUS_EXTERN_CRATE,
712+
Deny,
713+
"Forbid uses of non-whitelisted crates in `extern crate`",
714+
report_in_external_macro: true
715+
}
716+
717+
declare_lint_pass!(DangerousExternCrate => [DANGEROUS_EXTERN_CRATE]);
718+
719+
impl EarlyLintPass for DangerousExternCrate {
720+
fn check_item(&mut self, cx: &EarlyContext<'_>, item: &ast::Item) {
721+
fn is_whitelisted(crate_name: &str) -> bool {
722+
// Whitelist of allowed crates.
723+
crate_name.starts_with("rustc_")
724+
|| matches!(crate_name, "test" | "self" | "core" | "alloc" | "std")
725+
}
726+
727+
if let ast::ItemKind::ExternCrate(original_name, imported_name) = &item.kind {
728+
let name = original_name.as_ref().unwrap_or(&imported_name.name).as_str();
729+
let externs = &cx.builder.sess().opts.externs;
730+
if externs.get(name).is_none() && !is_whitelisted(name) {
731+
cx.emit_span_lint(
732+
DANGEROUS_EXTERN_CRATE,
733+
item.span,
734+
DangerousExternCrateDiag { name },
735+
);
736+
}
737+
}
738+
}
739+
}

compiler/rustc_lint/src/lib.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -648,6 +648,8 @@ fn register_internals(store: &mut LintStore) {
648648
store.register_late_mod_pass(|_| Box::new(SpanUseEqCtxt));
649649
store.register_lints(&SymbolInternStringLiteral::lint_vec());
650650
store.register_late_mod_pass(|_| Box::new(SymbolInternStringLiteral));
651+
store.register_lints(&DangerousExternCrate::lint_vec());
652+
store.register_early_pass(|| Box::new(DangerousExternCrate));
651653
// FIXME(davidtwco): deliberately do not include `UNTRANSLATABLE_DIAGNOSTIC` and
652654
// `DIAGNOSTIC_OUTSIDE_OF_IMPL` here because `-Wrustc::internal` is provided to every crate and
653655
// these lints will trigger all of the time - change this once migration to diagnostic structs
@@ -670,6 +672,7 @@ fn register_internals(store: &mut LintStore) {
670672
LintId::of(BAD_OPT_ACCESS),
671673
LintId::of(SPAN_USE_EQ_CTXT),
672674
LintId::of(DIRECT_USE_OF_RUSTC_TYPE_IR),
675+
LintId::of(DANGEROUS_EXTERN_CRATE),
673676
],
674677
);
675678
}

0 commit comments

Comments
 (0)