support controlling trait methods
This commit is contained in:
parent
cd2d516be1
commit
99e6ffb7f8
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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<String>
|
|||
fn def_path_if_not_in_whitelist(def_id: DefId, tcx: TyCtxt<'_>) -> Option<String> {
|
||||
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
|
|||
}
|
||||
}
|
||||
|
||||
fn def_path_str(def_id: DefId, tcx: TyCtxt<'_>) -> 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<String>) {
|
||||
if def_paths.len() > 0 {
|
||||
let sess = tcx.sess;
|
||||
|
|
|
|||
|
|
@ -1,2 +1,3 @@
|
|||
[toolchain]
|
||||
channel = "nightly-2023-02-05"
|
||||
components = ["cargo", "llvm-tools", "rust-src", "rust-std", "rustc", "rustc-dev", "rustfmt"]
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
[workspace]
|
||||
members = ["foo", "bar"]
|
||||
|
|
@ -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
|
||||
|
|
@ -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"}
|
||||
|
|
@ -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<dyn ObjectSafeTrait>;
|
||||
foo_as_dyn.get();
|
||||
}
|
||||
|
||||
pub fn opaque_type(object: impl ObjectSafeTrait) {
|
||||
object.get();
|
||||
}
|
||||
|
||||
pub fn generic<T: ObjectSafeTrait>(object: T) {
|
||||
object.get();
|
||||
}
|
||||
|
|
@ -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"}
|
||||
|
|
@ -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!()
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue