Skip to content

Commit c6a9521

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 e100792 commit c6a9521

File tree

51 files changed

+193
-151
lines changed

Some content is hidden

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

51 files changed

+193
-151
lines changed

Cargo.lock

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4119,6 +4119,7 @@ name = "rustc_log"
41194119
version = "0.0.0"
41204120
dependencies = [
41214121
"tracing",
4122+
"tracing-core",
41224123
"tracing-subscriber",
41234124
"tracing-tree",
41244125
]

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
@@ -30,6 +30,7 @@ use rustc_codegen_ssa::traits::*;
3030
use rustc_codegen_ssa::{ModuleCodegen, ModuleKind, looks_like_rust_object_file};
3131
use rustc_data_structures::memmap::Mmap;
3232
use rustc_errors::DiagCtxtHandle;
33+
use rustc_log::tracing::info;
3334
use rustc_middle::bug;
3435
use rustc_middle::dep_graph::WorkProduct;
3536
use rustc_session::config::Lto;

compiler/rustc_codegen_gcc/src/back/write.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ use rustc_codegen_ssa::back::link::ensure_removed;
55
use rustc_codegen_ssa::back::write::{BitcodeSection, CodegenContext, EmitObj, ModuleConfig};
66
use rustc_codegen_ssa::{CompiledModule, ModuleCodegen};
77
use rustc_fs_util::link_or_copy;
8+
use rustc_log::tracing::debug;
89
use rustc_session::config::OutputType;
910
use rustc_target::spec::SplitDebuginfo;
1011

compiler/rustc_codegen_gcc/src/consts.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ use rustc_codegen_ssa::traits::{
88
use rustc_hir::attrs::Linkage;
99
use rustc_hir::def::DefKind;
1010
use rustc_hir::def_id::LOCAL_CRATE;
11+
use rustc_log::tracing::trace;
1112
use rustc_middle::middle::codegen_fn_attrs::{CodegenFnAttrFlags, CodegenFnAttrs};
1213
use rustc_middle::mir::interpret::{
1314
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;
@@ -44,6 +38,7 @@ extern crate rustc_hir;
4438
extern crate rustc_index;
4539
#[cfg(feature = "master")]
4640
extern crate rustc_interface;
41+
extern crate rustc_log;
4742
extern crate rustc_macros;
4843
extern crate rustc_middle;
4944
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
@@ -44,6 +44,8 @@ use std::fmt;
4444
pub use atomic_ref::AtomicRef;
4545
pub use ena::{snapshot_vec, undo_log, unify};
4646
pub use rustc_index::static_assert_size;
47+
// Re-export some data-structure crates which are part of our public API.
48+
pub use {either, indexmap, smallvec, thin_vec};
4749

4850
pub mod aligned;
4951
pub mod base_n;

compiler/rustc_lint/messages.ftl

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -325,6 +325,9 @@ lint_impl_trait_overcaptures = `{$self_ty}` will capture more lifetimes than pos
325325
lint_impl_trait_redundant_captures = all possible in-scope parameters are already captured, so `use<...>` syntax is redundant
326326
.suggestion = remove the `use<...>` syntax
327327
328+
lint_implicit_sysroot_crate_import = dangerous use of `extern crate {$name}` which is not guaranteed to exist exactly once in the sysroot
329+
.help = try using a cargo dependency or using a re-export of the dependency provided by a rustc_* crate
330+
328331
lint_implicit_unsafe_autorefs = implicit autoref creates a reference to the dereference of a raw pointer
329332
.note = creating a reference requires the pointer target to be valid and imposes aliasing requirements
330333
.raw_ptr = this raw pointer has type `{$raw_ptr_ty}`

compiler/rustc_lint/src/internal.rs

Lines changed: 41 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, DefaultHashTypesDiag, DiagOutOfImpl, ImplicitSysrootCrateImportDiag,
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

@@ -745,3 +745,40 @@ impl<'tcx> LateLintPass<'tcx> for SymbolInternStringLiteral {
745745
}
746746
}
747747
}
748+
749+
declare_tool_lint! {
750+
/// The `implicit_sysroot_crate_import` detects use of `extern crate` to import non-sysroot crates
751+
/// (e.g. crates.io deps) from the sysroot, which is dangerous because these crates are not guaranteed
752+
/// to exist exactly once, and so may be missing entirely or appear multiple times resulting in ambiguity.
753+
pub rustc::IMPLICIT_SYSROOT_CRATE_IMPORT,
754+
Allow,
755+
"Forbid uses of non-sysroot crates in `extern crate`",
756+
report_in_external_macro: true
757+
}
758+
759+
declare_lint_pass!(ImplicitSysrootCrateImport => [IMPLICIT_SYSROOT_CRATE_IMPORT]);
760+
761+
impl EarlyLintPass for ImplicitSysrootCrateImport {
762+
fn check_item(&mut self, cx: &EarlyContext<'_>, item: &ast::Item) {
763+
fn is_whitelisted(crate_name: &str) -> bool {
764+
// Whitelist of allowed crates.
765+
crate_name.starts_with("rustc_")
766+
|| matches!(
767+
crate_name,
768+
"test" | "self" | "core" | "alloc" | "std" | "proc_macro" | "tikv_jemalloc_sys"
769+
)
770+
}
771+
772+
if let ast::ItemKind::ExternCrate(original_name, imported_name) = &item.kind {
773+
let name = original_name.as_ref().unwrap_or(&imported_name.name).as_str();
774+
let externs = &cx.builder.sess().opts.externs;
775+
if externs.get(name).is_none() && !is_whitelisted(name) {
776+
cx.emit_span_lint(
777+
IMPLICIT_SYSROOT_CRATE_IMPORT,
778+
item.span,
779+
ImplicitSysrootCrateImportDiag { name },
780+
);
781+
}
782+
}
783+
}
784+
}

0 commit comments

Comments
 (0)