saf_core/spec/mod.rs
1//! Function specification system for external/library function modeling.
2//!
3//! This module provides a pluggable system for describing the behavior of external
4//! functions (libc, POSIX, user libraries) that cannot be analyzed directly. Specs
5//! are used by various analyses:
6//!
7//! - **PTA**: Memory allocation, aliasing, pointer returns
8//! - **Nullness**: Pre/post-conditions on pointer validity
9//! - **Taint**: Sources, sinks, sanitizers, propagation rules
10//! - **Interval**: Numeric return bounds
11//!
12//! # Spec Format
13//!
14//! Specs are defined in YAML files with version "1.0":
15//!
16//! ```yaml
17//! version: "1.0"
18//! specs:
19//! - name: malloc
20//! role: allocator
21//! returns:
22//! pointer: fresh_heap
23//! nullness: maybe_null
24//! params:
25//! - index: 0
26//! semantic: allocation_size
27//! ```
28//!
29//! # Name Matching
30//!
31//! - **Exact**: `name: malloc`
32//! - **Glob**: `name: "glob:str*"`
33//! - **Regex**: `name: "regex:^mem(cpy|set|move)$"`
34//!
35//! # Discovery Order
36//!
37//! Specs are loaded from multiple paths (later overrides earlier per-function):
38//! 1. `<binary>/../share/saf/specs/*.yaml` — shipped defaults
39//! 2. `~/.saf/specs/*.yaml` — user global
40//! 3. `./saf-specs/*.yaml` — project local
41//! 4. `$SAF_SPECS_PATH/*.yaml` — explicit override
42//!
43//! # Example
44//!
45//! ```
46//! use saf_core::spec::{SpecRegistry, FunctionSpec, Role};
47//!
48//! // Load from default paths
49//! let registry = SpecRegistry::new(); // Empty for now
50//!
51//! // Programmatic construction
52//! let mut registry = SpecRegistry::new();
53//! let mut spec = FunctionSpec::new("my_alloc");
54//! spec.role = Some(Role::Allocator);
55//! registry.add(spec).unwrap();
56//!
57//! if let Some(spec) = registry.lookup("my_alloc") {
58//! assert_eq!(spec.role, Some(Role::Allocator));
59//! }
60//! ```
61
62mod analyzed;
63mod derived;
64mod pattern;
65mod registry;
66mod schema;
67mod types;
68
69// Re-export main types
70pub use analyzed::{AnalyzedSpecRegistry, LookupResult};
71pub use derived::{BoundMode, ComputedBound, DerivedSpec};
72pub use pattern::{NamePattern, PatternError};
73pub use registry::{RegistryError, SpecRegistry};
74pub use schema::{CURRENT_VERSION, SchemaError, SpecFile};
75pub use types::{
76 FunctionSpec, Nullness, ParamSpec, Pointer, ReturnSpec, Role, TaintLocation, TaintPropagation,
77 TaintSpec,
78};