From 99e6ffb7f88b9d61eda8e7523657f7d072f5d5eb Mon Sep 17 00:00:00 2001 From: Jianfeng Jiang Date: Fri, 3 Mar 2023 10:14:27 +0800 Subject: [PATCH] support controlling trait methods --- src/Cargo.lock | 45 +++++++---------- .../cargo-component/analysis/src/lib.rs | 42 +++++++++++----- .../cargo-component/rust-toolchain.toml | 1 + .../cargo-component/tests/trait_method.rs | 28 +++++++++++ .../tests/trait_method_test/Cargo.toml | 2 + .../tests/trait_method_test/Components.toml | 19 ++++++++ .../tests/trait_method_test/bar/Cargo.toml | 9 ++++ .../tests/trait_method_test/bar/src/lib.rs | 26 ++++++++++ .../tests/trait_method_test/foo/Cargo.toml | 9 ++++ .../tests/trait_method_test/foo/src/lib.rs | 48 +++++++++++++++++++ 10 files changed, 190 insertions(+), 39 deletions(-) create mode 100644 src/services/comp-sys/cargo-component/tests/trait_method.rs create mode 100644 src/services/comp-sys/cargo-component/tests/trait_method_test/Cargo.toml create mode 100644 src/services/comp-sys/cargo-component/tests/trait_method_test/Components.toml create mode 100644 src/services/comp-sys/cargo-component/tests/trait_method_test/bar/Cargo.toml create mode 100644 src/services/comp-sys/cargo-component/tests/trait_method_test/bar/src/lib.rs create mode 100644 src/services/comp-sys/cargo-component/tests/trait_method_test/foo/Cargo.toml create mode 100644 src/services/comp-sys/cargo-component/tests/trait_method_test/foo/src/lib.rs diff --git a/src/Cargo.lock b/src/Cargo.lock index ae835e89c..d7b7bf0e8 100644 --- a/src/Cargo.lock +++ b/src/Cargo.lock @@ -60,21 +60,6 @@ version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" -[[package]] -name = "bootloader" -version = "0.10.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24e13520aa8580a2850fc9f5390dc6753f1062fb66f90e5a61bd5c72b55df731" - -[[package]] -name = "bootloader-locator" -version = "0.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aaaa9db3339d32c2622f2e5d0731eb82a468d3439797c9d4fe426744fe2bd551" -dependencies = [ - "json", -] - [[package]] name = "buddy_system_allocator" version = "0.6.0" @@ -213,10 +198,10 @@ dependencies = [ name = "jinux" version = "0.1.0" dependencies = [ - "bootloader", "component", "jinux-frame", "jinux-std", + "limine", ] [[package]] @@ -240,8 +225,6 @@ name = "jinux-boot" version = "0.1.0" dependencies = [ "anyhow", - "bootloader-locator", - "locate-cargo-manifest", "runner-utils", ] @@ -251,11 +234,11 @@ version = "0.1.0" dependencies = [ "acpi", "bitflags", - "bootloader", "buddy_system_allocator", "font8x8", "intrusive-collections", "lazy_static", + "limine", "linked_list_allocator", "log", "pod", @@ -375,6 +358,15 @@ version = "0.2.137" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fc7fcc620a3bff7cdd7a365be3376c97191aeaccc2a603e600951e452615bf89" +[[package]] +name = "limine" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e9d0c951056ac044f0e6b09448b9d702f8fb1001db89cffd2bc467bd1c25307" +dependencies = [ + "uuid", +] + [[package]] name = "linked_list_allocator" version = "0.9.1" @@ -384,15 +376,6 @@ dependencies = [ "spinning_top", ] -[[package]] -name = "locate-cargo-manifest" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db985b63431fe09e8d71f50aeceffcc31e720cb86be8dad2f38d084c5a328466" -dependencies = [ - "json", -] - [[package]] name = "lock_api" version = "0.4.9" @@ -660,6 +643,12 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "936e4b492acfd135421d8dca4b1aa80a7bfc26e702ef3af710e0752684df5372" +[[package]] +name = "uuid" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1674845326ee10d37ca60470760d4288a6f80f304007d92e5c53bab78c9cfd79" + [[package]] name = "version_check" version = "0.9.4" diff --git a/src/services/comp-sys/cargo-component/analysis/src/lib.rs b/src/services/comp-sys/cargo-component/analysis/src/lib.rs index 5d10f2d8d..6382901bd 100644 --- a/src/services/comp-sys/cargo-component/analysis/src/lib.rs +++ b/src/services/comp-sys/cargo-component/analysis/src/lib.rs @@ -20,7 +20,8 @@ use rustc_middle::mir::{ Constant, InlineAsmOperand, LocalDecl, Operand, Rvalue, Statement, StatementKind, Terminator, TerminatorKind, }; -use rustc_middle::ty::{InstanceDef, TyCtxt, TyKind, WithOptConstParam}; +use rustc_middle::query::Key; +use rustc_middle::ty::{ImplSubject, InstanceDef, TyCtxt, TyKind, WithOptConstParam}; use rustc_span::def_id::{DefId, LocalDefId, LOCAL_CRATE}; use rustc_span::Span; @@ -221,7 +222,7 @@ fn def_path_if_invalid_access(def_id: DefId, tcx: TyCtxt<'_>) -> Option fn def_path_if_not_in_whitelist(def_id: DefId, tcx: TyCtxt<'_>) -> Option { let crate_symbol = tcx.crate_name(LOCAL_CRATE); let crate_name = crate_symbol.as_str(); - let def_path_str = def_path_str(def_id, tcx); + let def_path_str = def_path_for_def_id(tcx, def_id); if conf::CONFIG .get() .unwrap() @@ -233,15 +234,6 @@ fn def_path_if_not_in_whitelist(def_id: DefId, tcx: TyCtxt<'_>) -> Option) -> String { - // The def_path_str of TyCtxt will panic the compiler, - // while the def_path_debug_str contains noisy info. - // This function is like def_path_debug_str. - let def_path = tcx.def_path(def_id); - let crate_name = tcx.crate_name(def_path.krate); - format!("{}{}", crate_name, def_path.to_string_no_crate_verbose()) -} - /// if the def_id has attribute component_access_control::controlled, return true, else return false fn contains_controlled_attr(def_id: DefId, tcx: TyCtxt<'_>) -> bool { for attr in tcx.get_attrs_unchecked(def_id) { @@ -262,6 +254,34 @@ fn contains_controlled_attr(def_id: DefId, tcx: TyCtxt<'_>) -> bool { false } +fn def_path_for_def_id(tcx: TyCtxt<'_>, def_id: DefId) -> String { + match tcx.impl_of_method(def_id) { + None => common_def_path_str(tcx, def_id), + Some(impl_def_id) => def_path_str_for_impl(tcx, def_id, impl_def_id), + } +} + +/// def path for function, type, static variables and trait methods +fn common_def_path_str(tcx: TyCtxt<'_>, def_id: DefId) -> String { + // This function is like def_path_debug_str without noisy info + let def_path = tcx.def_path(def_id); + let crate_name = tcx.crate_name(def_path.krate); + format!("{}{}", crate_name, def_path.to_string_no_crate_verbose()) +} + +/// def path for impl, if the impl is not for trait. +fn def_path_str_for_impl(tcx: TyCtxt<'_>, def_id: DefId, impl_def_id: DefId) -> String { + let item_name = tcx.item_name(def_id).to_string(); + let impl_subject = tcx.impl_subject(impl_def_id); + if let ImplSubject::Inherent(impl_ty) = impl_subject { + let impl_ty_def_id = impl_ty.ty_adt_id().expect("Method should impl an adt type"); + let impl_ty_name = common_def_path_str(tcx, impl_ty_def_id); + return format!("{impl_ty_name}::{item_name}"); + } + // impl trait goes here, which is impossible + unreachable!() +} + fn emit_note(tcx: TyCtxt<'_>, span: Span, crate_name: &str, def_paths: Vec) { if def_paths.len() > 0 { let sess = tcx.sess; diff --git a/src/services/comp-sys/cargo-component/rust-toolchain.toml b/src/services/comp-sys/cargo-component/rust-toolchain.toml index 1f6f0ea95..19d918006 100644 --- a/src/services/comp-sys/cargo-component/rust-toolchain.toml +++ b/src/services/comp-sys/cargo-component/rust-toolchain.toml @@ -1,2 +1,3 @@ [toolchain] channel = "nightly-2023-02-05" +components = ["cargo", "llvm-tools", "rust-src", "rust-std", "rustc", "rustc-dev", "rustfmt"] diff --git a/src/services/comp-sys/cargo-component/tests/trait_method.rs b/src/services/comp-sys/cargo-component/tests/trait_method.rs new file mode 100644 index 000000000..b4e5dbaec --- /dev/null +++ b/src/services/comp-sys/cargo-component/tests/trait_method.rs @@ -0,0 +1,28 @@ +//! This test checks that if cargo-component can control method and trait method + +#![feature(once_cell)] + +use std::path::PathBuf; +use test_utils::{cargo_clean, cargo_component, clean_after_test}; +mod test_utils; + +#[test] +fn trait_method() { + let root_dir = PathBuf::from(env!("CARGO_MANIFEST_DIR")); + let target_dir = root_dir.join("target").join("trait_method_test"); + let cwd = root_dir.join("tests").join("trait_method_test"); + let output = cargo_clean(&cwd, &target_dir); + assert!(output.status.success()); + + let output = cargo_component(&cwd, &target_dir); + let stderr = String::from_utf8_lossy(&output.stderr); + println!("stderr: {stderr}"); + + assert!(output.status.success()); + assert!(stderr.contains("access controlled entry point is disallowed")); + assert!(stderr.contains("access foo::Foo::method in bar")); + assert!(stderr.contains("access foo::FooTrait::trait_associate_fn in bar")); + assert!(stderr.contains("access foo::FooTrait::trait_method in bar")); + + clean_after_test(&cwd); +} diff --git a/src/services/comp-sys/cargo-component/tests/trait_method_test/Cargo.toml b/src/services/comp-sys/cargo-component/tests/trait_method_test/Cargo.toml new file mode 100644 index 000000000..5dfe3c120 --- /dev/null +++ b/src/services/comp-sys/cargo-component/tests/trait_method_test/Cargo.toml @@ -0,0 +1,2 @@ +[workspace] +members = ["foo", "bar"] diff --git a/src/services/comp-sys/cargo-component/tests/trait_method_test/Components.toml b/src/services/comp-sys/cargo-component/tests/trait_method_test/Components.toml new file mode 100644 index 000000000..5c3c1367d --- /dev/null +++ b/src/services/comp-sys/cargo-component/tests/trait_method_test/Components.toml @@ -0,0 +1,19 @@ +[components] +foo = { name = "foo" } +bar = { name = "bar" } + +[whitelist] +[whitelist.foo.FooTrait.trait_method] +bar = false + +[whitelist.foo.FooTrait.trait_associate_fn] +bar = false + +[whitelist.foo.Foo.method] +bar = false + +[whitelist.foo.ObjectSafeTrait.get] +bar = true + +[whitelist.foo.Foo.associate_fn] +bar = true diff --git a/src/services/comp-sys/cargo-component/tests/trait_method_test/bar/Cargo.toml b/src/services/comp-sys/cargo-component/tests/trait_method_test/bar/Cargo.toml new file mode 100644 index 000000000..0978ddf95 --- /dev/null +++ b/src/services/comp-sys/cargo-component/tests/trait_method_test/bar/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "bar" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +foo = {path = "../foo"} diff --git a/src/services/comp-sys/cargo-component/tests/trait_method_test/bar/src/lib.rs b/src/services/comp-sys/cargo-component/tests/trait_method_test/bar/src/lib.rs new file mode 100644 index 000000000..41d7e605c --- /dev/null +++ b/src/services/comp-sys/cargo-component/tests/trait_method_test/bar/src/lib.rs @@ -0,0 +1,26 @@ +use foo::{ObjectSafeTrait, Foo, FooTrait}; + +pub fn method() { + let foo_struct = Foo::associate_fn(); + let val = foo_struct.method(); + println!("val = {}", val); +} + +pub fn trait_method() { + Foo::trait_associate_fn(); + let foo_struct = Foo::associate_fn(); + foo_struct.trait_method(); +} + +pub fn dyn_trait() { + let foo_as_dyn = Box::new(Foo::associate_fn()) as Box; + foo_as_dyn.get(); +} + +pub fn opaque_type(object: impl ObjectSafeTrait) { + object.get(); +} + +pub fn generic(object: T) { + object.get(); +} diff --git a/src/services/comp-sys/cargo-component/tests/trait_method_test/foo/Cargo.toml b/src/services/comp-sys/cargo-component/tests/trait_method_test/foo/Cargo.toml new file mode 100644 index 000000000..6c9d38eb0 --- /dev/null +++ b/src/services/comp-sys/cargo-component/tests/trait_method_test/foo/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "foo" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +controlled = {path = "../../../../controlled"} diff --git a/src/services/comp-sys/cargo-component/tests/trait_method_test/foo/src/lib.rs b/src/services/comp-sys/cargo-component/tests/trait_method_test/foo/src/lib.rs new file mode 100644 index 000000000..f3cc2fdbc --- /dev/null +++ b/src/services/comp-sys/cargo-component/tests/trait_method_test/foo/src/lib.rs @@ -0,0 +1,48 @@ +#![feature(register_tool)] +#![register_tool(component_access_control)] + +#[macro_use] +extern crate controlled; + +pub struct Foo; + +impl Foo { + #[controlled] + pub fn associate_fn() -> Self { + todo!() + } + + #[controlled] + pub fn method(&self) -> usize { + todo!() + } +} + +pub trait FooTrait { + #[controlled] + fn trait_associate_fn(); + + #[controlled] + fn trait_method(&self) -> usize; +} + +impl FooTrait for Foo { + fn trait_associate_fn() { + todo!() + } + + fn trait_method(&self) -> usize { + todo!() + } +} + +pub trait ObjectSafeTrait { + #[controlled] + fn get(&self) -> usize; +} + +impl ObjectSafeTrait for Foo { + fn get(&self) -> usize { + todo!() + } +}