Rust ์ปดํ์ผ๋ฌ๋ ๋๋ถ๋ถ์ ๊ฐ๋ฐ์๊ฐ ๊ฒฝํํ๊ฒ ๋ ๊ฐ์ฅ ๋
๋จ์ ์ธ ์ฝ๋ ๋ฆฌ๋ทฐ์ด๋ผ๊ณ ํ ์ ์์ต๋๋ค. ์์ ๊ถ ์์คํ
, ๋น๋ฆผ ๊ฒ์ฌ๊ธฐ, ๊ทธ๋ฆฌ๊ณ ์๋ช
์ฃผ๊ธฐ ๊ฐ์ ์ ์ฉ์ C์ C++ ์ฝ๋๋ฒ ์ด์ค๋ฅผ ๊ดด๋กญํ๋ ์๋ง์ ๋ฒ๊ทธ ์ ํ์ ์ ๊ฑฐํฉ๋๋ค. ํ์ง๋ง ๋ฉ๋ชจ๋ฆฌ ์ค๋ฅ๋ฅผ ๋ฐฉ์งํ๋ ์ปดํ์ผ๋ฌ๊ฐ ์๋ฒฝํ ํ์ง ์์คํ
์ ๊ฐ์ถ ๊ฒ์ ์๋๋๋ค. ๋
ผ๋ฆฌ์ ๋ฒ๊ทธ, ๋ถ์์ ํ ์์กด์ฑ ์ฒด์ธ, ์์ ํ์ง ์์ ๋ธ๋ก ์ฌ์ฉ, ์ฑ๋ฅ ์ํฐ ํจํด, ๊ทธ๋ฆฌ๊ณ ์คํ์ผ ํธ์ฐจ๋ ์ฌ์ ํ ๋จ์ ์์ต๋๋ค. rustc๋๊ท๋ชจ๋ก ์์ ์ ์ธ Rust๋ฅผ ๋ฐฐํฌํ๋ ํ์ ์ปดํ์ผ๋ฌ์ ๊ณ์ธตํ๋ ์ ์ ๋ถ์ ๋๊ตฌ ์ธํธ๋ฅผ ๊ฒฐํฉํ์ฌ ์ฌ์ฉํ๋ฉฐ, ๊ฐ ๋๊ตฌ๋ ํ์ง ํ๋ฉด์ ์๋ก ๋ค๋ฅธ ๋ถ๋ถ์ ๋ค๋ฃน๋๋ค.
์๋ชป๋ ์กฐํฉ์ ์ ํํ๋ฉด CI ์๊ฐ์ด ๋ญ๋น๋๊ณ ๊ฐ๋ฐ์๋ค์ด ๋ฌด์ํ๊ฒ ๋๋ ๋ถํ์ํ ๋ ธ์ด์ฆ๊ฐ ๋ฐ์ํฉ๋๋ค. ๋ฐ๋๋ก ์ฌ๋ฐ๋ฅธ ์กฐํฉ์ ์ ํํ๋ฉด ์ปดํ์ผ๋ฌ์ ์๊ฒฉ์ฑ์ด ํ๊ณ๊ฐ ์๋ ์ต์ ๊ธฐ์ค์ฒ๋ผ ๋๊ปด์ง๋๋ค. ์ด ๊ฐ์ด๋์์๋ ๋๊ตฌ๋ค์ ์ํ๋ฒณ์์ด ์๋ ์ค์ ๊ธฐ๋ฅ๋ณ๋ก ์ ๋ฆฌํ์ฌ ํ์์ ๋ฆฐํ ๋ฐ ๊ด์ฉ๊ตฌ, ์์กด์ฑ ๋ณด์, ์์ ์ ์ค์ํ๊ฑฐ๋ ๋ณด์์ ๋ฏผ๊ฐํ ์ฝ๋์ ๋ํ ์ฌ์ธต ๊ฒ์ฆ ๋ฑ ์ธ ๊ฐ์ง ํ์ง ๊ณ์ธต์ ๋ชจ๋ ํฌ๊ดํ๋ ์คํ์ ๊ตฌ์ถํ ์ ์๋๋ก ํ์ต๋๋ค.
SMART TS XL
์ธ์ด์ ๊ฐ๋ ฅํ ์์ ์ฑ์ด ๋ณด์ฅ๋๋๋ผ๋, ์ต์ Rust ๊ฐ๋ฐ์์ ํ์ง์ ์ ์งํ๋ ๊ฒ์ ์ด๋ ต์ต๋๋ค. SMART TS XL Rust์ ๊ณ ์ ํ ๊ธฐ๋ฅ์ ๋ง์ถฐ ์ฌ์ธต์ ์ธ ์ ์ ๋ถ์ ๊ธฐ๋ฅ์ ์ ๊ณตํ์ฌ ํ์ด ์์ ์ ์ด๊ณ ์ ์ง ๊ด๋ฆฌ๊ฐ ์ฉ์ดํ๋ฉฐ ์์ ํ ์ํํธ์จ์ด๋ฅผ ๊ตฌ์ถํ ์ ์๋๋ก ์ค๊ณ๋์์ต๋๋ค. ๋ฌธ์ ๋ฅผ ์กฐ๊ธฐ์ ๋ฐ๊ฒฌํ๊ณ , ์ผ๊ด์ฑ์ ์ ์งํ๋ฉฐ, ์๋ ๊ฒํ ์์ ์ ์ค์ฌ ์ ๋ฌธ์ ์ธ ์์ง๋์ด๋ง ์ํฌํ๋ก๋ฅผ ์ง์ํฉ๋๋ค.
๋ น์ ์ธ ๊ฐ์ง ์ธต์ ์ ์ ๋ถ์
์ด๋ค ๋๊ตฌ๊ฐ ์ด๋์ ์ ํฉํ์ง ์ดํดํ๋ฉด ๋ฆฐํฐ๋ก ์ถฉ๋ถํ ๊ณณ์ ํ์ ๊ฒ์ฆ ๋๊ตฌ๋ฅผ ์ฌ์ฉํ๊ฑฐ๋ ๋ณด์ ์ค์บ๋๊ฐ ํ์ํ ๊ณณ์ ๋ฆฐํฐ๋ง ์ฌ์ฉํ๋ ํํ ์ค์๋ฅผ ๋ฐฉ์งํ ์ ์์ต๋๋ค. ๋ชจ๋ ์์ฑ๋ ๋์ Rust ํ๋ก์ ํธ๋ ์ด ์ธ ๊ฐ์ง ๊ณ์ธต์ ๋ชจ๋ ๋ค๋ค์ผ ํฉ๋๋ค.
1๋จ๊ณ: ๋ณดํ ์ ๊ฑฐ ๋ฐ ์คํ์ผ๋ง ๊ด์ฉ์ ์ธ ํํ ์๋ฐ, ํํ ์ค์ ๋ฐ ์ ์ง๋ณด์ ๋ฌธ์ ๋ฅผ ์ก์๋ ๋๋ค. ์ฌ์ฉ ๋๊ตฌ: Clippy, rustfmt, rust-analyzer.
2๋จ๊ณ: ์์กด์ฑ ๋ฐ ๊ณต๊ธ๋ง ๋ณด์ ํ์ฌ ํฌ๋ ์ดํธ์์ ์๋ ค์ง ์ทจ์ฝ์ ๋ฐ ์ ์ฑ ์๋ฐ ์ฌํญ์ ๊ฐ์ฌํฉ๋๋ค. ์ฌ์ฉ ๋๊ตฌ: cargo-audit, cargo-deny, cargo-auditable.
3๋จ๊ณ: ์ฌ์ธต ๊ฒ์ฆ ์์ ํ์ง ์์ ์ฝ๋์์ ๋ฉ๋ชจ๋ฆฌ ์์ ์ฑ ๋ฌธ์ ๋ฅผ ๋ฐ๊ฒฌํ๊ณ , ์ ์๋์ง ์์ ๋์์ ๋ถ์ํ๋ฉฐ, ํต์ฌ ํจ์์ ์์ฑ์ ํ์์ ์ผ๋ก ์ฆ๋ช ํฉ๋๋ค. ์ฌ์ฉ ๋๊ตฌ: Miri, Kani, MIRAI, Rudra, Creusot, Prusti.
์๋ ํ๋ ๊ฐ ์ฃผ์ ๋๊ตฌ๋ฅผ ํด๋น ๊ณ์ธต, ๋น์ฉ, CI ์ ํฉ์ฑ ๋ฐ ์ฃผ์ ์ฌ์ฉ ์ฌ๋ก์ ์ฐ๊ฒฐํฉ๋๋ค.
| ์๋จ | ์ธต | ๋น์ฉ | CI ์ ํฉ | ์ฃผ์ ์ฌ์ฉ ์ฌ๋ก |
|---|---|---|---|---|
| ํด๋ฆฌ ํผ | ๋ณดํ | ๋ฌด๋ฃ / ์คํ์์ค | ๊ฐ๋ฅ | ๊ด์ฉ์ ์ธ ๋ฆฐํ , ์คํ์ผ, ์ผ๋ฐ์ ์ธ ๋ฒ๊ทธ |
| ๋ฌ์คํธfmt | ๋ณดํ | ๋ฌด๋ฃ / ์คํ์์ค | ๊ฐ๋ฅ | ์ฝ๋ ์์ ๊ฐ์ ์ ์ฉ |
| ๋ น ๋ถ์๊ธฐ | ๋ฆฐํ / DX | ๋ฌด๋ฃ / ์คํ์์ค | ์ผ๋ถ์ | IDE ์ง๋จ, ์ธ๋ผ์ธ ๋ถ์ |
| ํ๋ฌผ ๊ฐ์ฌ | ์ข ์์ฑ ๋ณด์ | ๋ฌด๋ฃ / ์คํ์์ค | ๊ฐ๋ฅ | ํฌ๋ ์ดํธ์์ ๋ฐ๊ฒฌ๋ ์๋ ค์ง CVE |
| ํ๋ฌผ ๊ฑฐ๋ถ | ์ข ์์ฑ ๋ณด์ | ๋ฌด๋ฃ / ์คํ์์ค | ๊ฐ๋ฅ | ๋ผ์ด์ ์ค, ๋ณต์ ๋ณธ, ๊ถ๊ณ ์ฌํญ |
| ํ๋ฌผ ๊ฐ์ฌ ๊ฐ๋ฅ | ์ข ์์ฑ ๋ณด์ | ๋ฌด๋ฃ / ์คํ์์ค | ๊ฐ๋ฅ | ๋ฐ์ด๋๋ฆฌ์ ์ข ์์ฑ ๋ฐ์ดํฐ๋ฅผ ํฌํจ์ํค์ธ์ |
| ๋ฏธ๋ฆฌ | ์ฌ์ธต ๊ฒ์ฆ | ๋ฌด๋ฃ / ์คํ์์ค | ์ ํ์ ์ธ | ์์ ํ์ง ์์ ์ฝ๋์์ ์ ์๋์ง ์์ ๋์์ด ๋ฐ์ํฉ๋๋ค. |
| ์นด๋ | ์ฌ์ธต ๊ฒ์ฆ | ๋ฌด๋ฃ / ์คํ์์ค | ์ ํ์ ์ธ | ํ์ ๊ฒ์ฆ, ๋ชจ๋ธ ๊ฒ์ฆ |
| ๋ฏธ๋ผ์ด | ์ฌ์ธต ๊ฒ์ฆ | ๋ฌด๋ฃ / ์คํ์์ค | ์ ํ์ ์ธ | ์ถ์ ํด์, ์ค์ผ ๋ถ์ |
| ๋ฃจ๋๋ผ | ์ฌ์ธต ๊ฒ์ฆ | ๋ฌด๋ฃ / ์คํ์์ค | ๋ฆฌ์จ์น | ์์ ํ์ง ์์ Rust ์ฝ๋์ ๋ฉ๋ชจ๋ฆฌ ์์ ์ฑ ๋ฒ๊ทธ |
| ์ ๊ทธ๋ | ๊ต์ฐจ ์ ๋จ | ๋ฌด๋ฃ ํฐ์ด + ์ ๋ฃ ํฐ์ด | ๊ฐ๋ฅ | ๋ง์ถคํ ๋ณด์ ํจํด, ๋ค๊ตญ์ด ์ง์ |
| ์๋ํด๋ผ์ฐ๋ | ๊ต์ฐจ ์ ๋จ | ๋ฌด๋ฃ ํฐ์ด + ์ ๋ฃ ํฐ์ด | ๊ฐ๋ฅ | ์ง์์ ์ธ ํ์ง ๊ด๋ฆฌ, ๋์๋ณด๋ |
๋ ์ด์ด 1: ๋ฆฐํ , ์คํ์ผ ๋ฐ ๊ฐ๋ฐ์ ๊ฒฝํ
ํด๋ฆฌ ํผ
Clippy๋ Rust ์ ์ ๋ถ์์ ์ํ ์ต๊ณ ์ ์์์ ์ ๋๋ค. ๊ณต์ Rust ํด์ฒด์ธ์ ํฌํจ๋์ด ์ ๊ณต๋๋ Clippy๋ ์ ํ์ฑ, ์ฑ๋ฅ, ์คํ์ผ, ๋ณต์ก์ฑ ๋ฐ ์ ์ฝ ์กฐ๊ฑด์ ํฌ๊ดํ๋ 700๊ฐ ์ด์์ ๋ฆฐํธ ํญ๋ชฉ์ ์ ๊ณตํฉ๋๋ค. ๋๋ถ๋ถ์ Rust ๊ฐ๋ฐํ์ด ๋งค์ผ ์ฌ์ฉํ๋ ๋๊ตฌ์ธ ๋ฐ์๋ ์ด์ ๊ฐ ์์ต๋๋ค. Clippy๋ ๋จ์ํ ์คํ์ผ ์๊ฒฌ์ด ์๋ ์ค์ ๋ฒ๊ทธ๋ฅผ ์ก์๋ด๊ธฐ ๋๋ฌธ์ ๋๋ค.
์ธ๊ฒ ๋๋ฆฌ๋ค
# Run all lints including pedantic and nursery groups
cargo clippy -- -W clippy::all -W clippy::pedantic
# Fail CI on any warning
cargo clippy -- -D warnings
# Check specific lint group
cargo clippy -- -W clippy::correctness -W clippy::suspicious
Clippy์ ๋ฆฐํธ ์นดํ ๊ณ ๋ฆฌ๋ ๋ช ํํ๊ฒ ์ดํดํ ๊ฐ์น๊ฐ ์์ต๋๋ค.
| ์นดํ ๊ณ ๋ฆฌ | ๊ทธ๊ฒ์ด ์ก๋ ๊ฒ |
|---|---|
correctness | ๊ฑฐ์ ํ์คํ ํ๋ฆฐ ์ฝ๋ (ํญ์ ๊ฑฐ๋ถ) |
suspicious | ์๋ชป๋์๊ฑฐ๋ ๋งค์ฐ ๋๋ผ์ด ์ฝ๋ |
style | ๋ช ํํ ๊ฐ์ ์ ์ ๋ณด์ฌ์ฃผ๋ ๋น๊ด์ฉ์ ํจํด |
complexity | ๋ถํ์ํ๊ฒ ๋ณต์กํ ๊ตฌ์กฐ |
performance | ์ปดํ์ผ์ ๋์ง๋ง ์คํ ์๋๊ฐ ์์๋ณด๋ค ๋๋ฆฐ ์ฝ๋ |
pedantic | ์๊ฒฉํ ์ง์นจ, ์ฃผ๊ด์ ๊ด์ (์ ํ์ ์ผ๋ก ํ์ฑํ) |
restriction | ํน์ ์ํฉ์์ ์ ์ฉํ๊ณ ์ถ์ ๊ท์น |
nursery | ์๋ก์ด ๋ณดํธ๋ผ๊ธฐ๋ ์คํ์ง๋ฅผ ์ ๋ฐํ ์ ์์ต๋๋ค. |
ํ๋ฌผ ๊ฒ์ฌ vs ํด๋ฆฌํผ: cargo check ๋ฐ์ด๋๋ฆฌ ํ์ผ์ ์์ฑํ์ง ์๊ณ ํ์
์ ํ์ฑ๊ณผ ์ปดํ์ผ์ฑ์ ๊ฒ์ฆํฉ๋๋ค. ๋น ๋ฅด๊ณ ๋น๋ ๊ฒ์ฆ์ ์ ํฉํฉ๋๋ค. cargo clippy ์คํ cargo check ๋ชจ๋ ๋ฆฐํธ ๋ถ์๋ ํฌํจ๋ฉ๋๋ค. CI์ ๊ฒฝ์ฐ, ๋ค์ ๋ช
๋ น์ ์คํํ์ธ์. cargo check ๋น ๋ฅธ ์ปดํ์ผ ํผ๋๋ฐฑ์ ์ํด cargo clippy -- -D warnings ๋ณ๋์ ํ์ง ๊ด๋ฆฌ ์ ์ฐจ์
๋๋ค. ์๋ก ํธํ๋์ง ์์ต๋๋ค. cargo check ๊ด์ฉ์ ์ธ ๋ฌธ์ ๋ฅผ ํฌ์ฐฉํ์ง ๋ชปํ ๊ฒ์ด๋ฉฐ, cargo clippy ๋ ๋๋ฆฝ๋๋ค.
Clippy ์ค์ ํ๊ธฐ ๋ฅผ ํตํด clippy.toml ๋๋ ์ธ๋ผ์ธ ์์ฑ์ ํตํด ํ์ ๋
ธ์ด์ฆ๋ฅผ ์ ์ดํ ์ ์์ต๋๋ค.
ํฐ
# clippy.toml
avoid-breaking-exported-api = false
msrv = "1.70"
๋ น
// Suppress a lint for one function with documented reason
#[allow(clippy::too_many_arguments)]
fn complex_setup(...) { ... }
Clippy์์ ์ง์ํ์ง ์๋ ๊ธฐ๋ฅ์ ๋ชจ๋ ๊ฐ ์ฌ์ธต ๋ฐ์ดํฐ ํ๋ฆ ๋ถ์, ์ข ์์ฑ ๋ณด์ ์ทจ์ฝ์ ์ค์บ, ํ์์ ์ ํ์ฑ ์ฆ๋ช ๋๋ ์กฐ์ง๋ณ ๋ง์ถค ๊ท์น ์ค์ ์ ๋๋ค. ์ด๋ฌํ ๊ธฐ๋ฅ์ ๋ค๋ฅธ ๊ณ์ธต์ ๋๊ตฌ๊ฐ ํ์ํฉ๋๋ค.
๋ฌ์คํธfmt
rustfmt๋ ์ฝ๋๋ฒ ์ด์ค ์ ์ฒด์ ๊ฑธ์ณ ์ผ๊ด๋ ์์์ ์ ์ฉํฉ๋๋ค. cargo fmt. ๊ทธ๋งํผ rustfmt.toml ์ค์ ํ์ผ์ ํ๋ก์ ํธ ์ ์ฒด์ ์คํ์ผ ๊ท์น์ ์ค์ ํฉ๋๋ค. CI ํ๊ฒฝ์์๋ cargo fmt -- --check ํ์ผ์ด ์ฌํฌ๋งท๋ ๊ฒฝ์ฐ 0์ด ์๋ ์ข
๋ฃ ์ฝ๋๋ฅผ ๋ฐํํ๋ฏ๋ก ๊ตฌ์ฑ ์ค๋ฒํค๋ ์์ด ๊น๋ํ ํ์ง ๊ฒ์ฌ ์ญํ ์ ํฉ๋๋ค.
์ธ๊ฒ ๋๋ฆฌ๋ค
# Check formatting without modifying files (CI mode)
cargo fmt -- --check
# Apply formatting (developer mode)
cargo fmt
Rust ๋ถ์๊ธฐ์ IDE ํตํฉ
rust-analyzer๋ Rust์ฉ ์ธ์ด ์๋ฒ ํ๋กํ ์ฝ(LSP) ๊ตฌํ์ฒด๋ก, LSP ํธํ ํธ์ง๊ธฐ์์ ์ค์๊ฐ ์ง๋จ, ์ฝ๋ ์๋ ์์ฑ, ์ ์ ์์น๋ก ์ด๋, Clippy ๊ฒฝ๊ณ ํ์ ๋ฑ์ ๊ธฐ๋ฅ์ ์ ๊ณตํฉ๋๋ค. ๋ ์ด์ ์ฌ์ฉ๋์ง ์๋ RLS(Rust Language Server)๋ฅผ ๋์ฒดํ๋ฉฐ, ์๋ก์ด ํ๋ก์ ํธ์์๋ Rust ์ธ์ด ์๋ฒ๋ง ์ฌ์ฉํ๋ ๊ฒ์ด ์ข์ต๋๋ค.
์ ์ ๋ถ์ ๊ด์ ์์ ๋ณด๋ฉด, rust-analyzer๋ ๊ฐ๋ฐ์๊ฐ ์ ๋ ฅํ๋ ๋์ Clippy ๋ฆฐํธ ๊ฒฐ๊ณผ๋ฅผ ๋ฐ๋ก ํ์ํ์ฌ ๋ณ๋์ ํฐ๋ฏธ๋ ์คํ ์์ด๋ ์คํ์ผ ๋ฐ ์ ํ์ฑ ๋ฌธ์ ์ ๋ํ ์ฆ๊ฐ์ ์ธ ํผ๋๋ฐฑ์ ์ ๊ณตํฉ๋๋ค.
JSON
// VS Code settings.json: enable Clippy via rust-analyzer
{
"rust-analyzer.check.command": "clippy",
"rust-analyzer.check.extraArgs": [
"--", "-W", "clippy::all", "-W", "clippy::pedantic"
]
}
rust-analyzer๋ ์ถ๋ก ๋ ์ ํ, ๋น๋ฆผ ์๋ช ๋ฐ ๋งค๊ฐ๋ณ์ ์ด๋ฆ์ ๋ํ ์ธ๋ ์ด ํํธ๋ฅผ ์ ๊ณตํ๋ฏ๋ก ์ ์๋ก ์ด๋ํ์ง ์๊ณ ๋ ์ต์ํ์ง ์์ ์ฝ๋๋ฅผ ๊ฒํ ํ๋ ๋ฐ ์ ์ฉํฉ๋๋ค.
2๋จ๊ณ: ์์กด์ฑ ๋ฐ ๊ณต๊ธ๋ง ๋ณด์
ํ๋ฌผ ๊ฐ์ฌ
ํ๋ฌผ ๊ฐ์ฌ ๊ฒ์ฌ๋ ๋ค์์ ํ์ธํฉ๋๋ค. Cargo.lock RustSec Advisory Database์ ๋ํ ํ์ผ์ ๊ฒ์ฌํ์ฌ ์ง์ ๋ฐ ๊ฐ์ ์ข
์์ฑ์์ ์๋ ค์ง CVE๋ฅผ ์๋ณํฉ๋๋ค. ์ด๋ ๋ชจ๋ Rust ํ๋ก์ ํธ๊ฐ CI์์ ์คํํด์ผ ํ๋ ์ต์ํ์ ์ข
์์ฑ ๋ณด์ ๋๊ตฌ์
๋๋ค.
์ธ๊ฒ ๋๋ฆฌ๋ค
# Install
cargo install cargo-audit
# Run audit
cargo audit
# Ignore a specific advisory (document the reason in comments)
cargo audit --ignore RUSTSEC-2024-0001
# JSON output for pipeline integration
cargo audit --json | jq '.vulnerabilities'
cargo-audit๋ ์๋ ค์ง๊ณ ๊ณต๊ฐ๋ ๋ณด์ ๊ถ๊ณ ์ฌํญ๋ง ํ์งํฉ๋๋ค. ์ฌ์ฉ์ ์ฝ๋์ ์ทจ์ฝ์ , RustSec ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์์ง ๋ฑ๋ก๋์ง ์์ ๋ฌธ์ ๋๋ ์์น ์๋ ๋ผ์ด์ ์ค์ ๊ฐ์ ์ ์ฑ ์๋ฐ ์ฌํญ์ ํ์งํ ์ ์์ต๋๋ค.
ํ๋ฌผ ๊ฑฐ๋ถ
cargo-deny๋ ์๋ ค์ง CVE๋ฅผ ๋์ด ๋ผ์ด์ ์ค ์ค์, ์ค๋ณต ํฌ๋ ์ดํธ ๊ฐ์ง, ์ฌ์ฉ์ ์ง์ ๊ธ์ง/ํ์ฉ ์ ์ฑ ๊น์ง ์ข ์์ฑ ๊ด๋ฆฌ๋ฅผ ํ์ฅํฉ๋๋ค. ์ด๋ ๊ท์ ์ค์ ์๊ฑด์ด ์๋ ์กฐ์ง์ ๋์ฑ ํฌ๊ด์ ์ธ ๋๊ตฌ์ ๋๋ค.
ํฐ
# deny.toml
[advisories]
vulnerability = "deny"
unmaintained = "warn"
[licenses]
allow = ["MIT", "Apache-2.0", "ISC", "BSD-2-Clause", "BSD-3-Clause"]
deny = ["GPL-2.0"]
copyleft = "warn"
[bans]
multiple-versions = "warn"
์ธ๊ฒ ๋๋ฆฌ๋ค
cargo install cargo-deny
cargo deny check
ํ๋ฌผ ๊ฐ์ฌ ๊ฐ๋ฅ
cargo-auditable์ ์ปดํ์ผ๋ Rust ๋ฐ์ด๋๋ฆฌ์ ๊ตฌ์กฐํ๋ ๋ฉํ๋ฐ์ดํฐ ํํ๋ก ์ ์ฒด ์ข ์์ฑ ํธ๋ฆฌ๋ฅผ ํฌํจ์์ผ ์ ์ฉ ๋ง์ปค ์น์ ์ ๋ฐฐ์นํฉ๋๋ค. ์ด๋ฅผ ํตํด ์์ค ์ฝ๋์ ์ ๊ทผํ์ง ์๊ณ ๋ ๋ฐฐํฌ๋ ๋ฐ์ด๋๋ฆฌ๋ฅผ ๊ฐ์ฌํ ์ ์์ผ๋ฏ๋ก, ๋ฐฐํฌ ํ ๋ณด์ ๊ฒํ ๋ฐ ๊ณต๊ธ๋ง ํฌ๋ช ์ฑ ํ๋ณด์ ์ ์ฉํฉ๋๋ค.
์ธ๊ฒ ๋๋ฆฌ๋ค
cargo install cargo-auditable
cargo auditable build --release
# The binary now contains auditable dependency metadata
# Audit a binary directly:
cargo audit bin ./target/release/my-service
3๋จ๊ณ: ์ฌ์ธต ๊ฒ์ฆ
์ด ๊ณ์ธต์ ๋๊ตฌ๋ ๋ ๋ง์ ์ค์ , ์ ๋ฌธ ์ง์ ๋ฐ ๋ถ์ ์๊ฐ์ ์๊ตฌํฉ๋๋ค. ๋ชจ๋ ์ฝ๋๋ฒ ์ด์ค์ ๋ชจ๋ ๊ธฐ๋ฅ์ ์ ํฉํ ๊ฒ์ ์๋๋๋ค. ์์ ํ์ง ์์ ์ฝ๋, ์ํธํ ๊ตฌํ, ์ ๋ขฐํ ์ ์๋ ์ ๋ ฅ์ ์ฒ๋ฆฌํ๋ ํ์ ๋ก์ง, ๊ทธ๋ฆฌ๊ณ ํ ์คํธ๋ณด๋ค๋ ์ ํ์ฑ์ ์ ์ฆํด์ผ ํ๋ ๋ชจ๋ ์ฝ๋์ ํ์์ ์ ๋๋ค.
Miri: ์ ์๋์ง ์์ ๋์ ๊ฐ์ง
Miri๋ Rust์ ์ค๊ฐ ์์ค ํํ(MIR)์ ์ํ ์ธํฐํ๋ฆฌํฐ๋ก, ์ปดํ์ผ๋ฌ๊ฐ ํ์ฉํ์ง๋ง Rust์ ์์ ์ฑ ๋ณด์ฅ์ ์๋ฐํ๋ ๋ฏธ์ ์ ๋์์ ๊ฐ์งํ๋ ๋ฐฉ์์ผ๋ก ์ฝ๋๋ฅผ ์คํํฉ๋๋ค. ์ด๋ฌํ ๋ฏธ์ ์ ๋์์๋ ์์ ํ์ง ์์ ๋ธ๋ก์์์ ๊ฒฝ๊ณ๋ฅผ ๋ฒ์ด๋ ๋ฉ๋ชจ๋ฆฌ ์ ๊ทผ, ํด์ ํ ์ฌ์ฉ, ์ ๋ ฌ๋์ง ์์ ํฌ์ธํฐ ์ญ์ฐธ์กฐ, ๋ฉํฐ์ค๋ ๋ ํ๊ฒฝ์์์ ์์ ํ์ง ์์ ์ฝ๋์์์ ๋ฐ์ดํฐ ๊ฒฝ์, Rust์ ๋ณ์นญ ๋ชจ๋ธ ์๋ฐ ๋ฑ์ด ํฌํจ๋ฉ๋๋ค.
์ธ๊ฒ ๋๋ฆฌ๋ค
# Install Miri (requires nightly)
rustup +nightly component add miri
# Run tests under Miri
cargo +nightly miri test
# Enable strict aliasing validation
MIRIFLAGS="-Zmiri-strict-provenance" cargo +nightly miri test
๋ฏธ๋ฆฌ๊ฐ ๊ฐ์งํ๋ ๊ฒ: ์ ์๋์ง ์์ ๋์ unsafe ๋ธ๋ก, ๋ฉ๋ชจ๋ฆฌ ์ ๊ทผ ์๋ฐ, ํด์ ํ ์ฌ์ฉ, ์ ๋ ฌ๋์ง ์์ ์ ๊ทผ, ๋๋ฒ๊ทธ ๋น๋์์์ ์ ์ ์ค๋ฒํ๋ก, ์์ ํ์ง ์์ ๋์ ์คํ ์ฝ๋์์์ ๋ฐ์ดํฐ ๊ฒฝ์.
๋ฏธ๋ฆฌ๊ฐ ๋ค๋ฃจ์ง ์๋ ๋ด์ฉ: ๋ฏธ์ ์ ๋์, ์์กด์ฑ ์ทจ์ฝ์ , ์ฝ๋ ์คํ์ผ ๋๋ ์ฑ๋ฅ ๋ฌธ์ ๋ฅผ ํฌํจํ์ง ์๋ ์์ ํ ์ฝ๋ ๋ด์ ๋ ผ๋ฆฌ์ ๋ฒ๊ทธ.
CI ํตํฉMiri๋ 10~50๋ฐฐ ๋๋ฆฌ๊ฒ ์คํ๋ฉ๋๋ค. cargo test. ํน์ ๋ชจ๋์ ๋ํด์๋ง ์ ํ์ ์ผ๋ก ์คํํฉ๋๋ค. unsafe ์ฝ๋๋ฅผ ์
๋ฐ์ดํธํ๊ฑฐ๋, ๋งค๋ฒ ์ปค๋ฐํ ๋๋ง๋ค ์
๋ฐ์ดํธํ๋ ๋์ ์ผ๊ฐ์ ์
๋ฐ์ดํธํ๋ ๊ฒ๋ ๊ณ ๋ คํด ๋ณผ ์ ์์ต๋๋ค.
์
- name: Miri on unsafe modules
run: |
rustup +nightly component add miri
cargo +nightly miri test --package my-unsafe-crate
Kani: ๋ชจ๋ธ ๊ฒ์ฆ ๋ฐ ํ์ ๊ฒ์ฆ
Amazon Web Services์์ ๊ฐ๋ฐํ Kani๋ ์ ์๋ ๋ฒ์๊น์ง ์คํ ๊ฒฝ๋ก๋ฅผ ์ฒ ์ ํ๊ฒ ํ์ํ์ฌ Rust ์ฝ๋์ ์์ฑ์ ํ์์ ์ผ๋ก ๊ฒ์ฆํ๋ ๋ชจ๋ธ ๊ฒ์ฆ ๋๊ตฌ์ ๋๋ค. Miri๊ฐ ์ค์ ํ ์คํธ ์ผ์ด์ค๋ฅผ ์คํํ๊ณ ๊ตฌ์ฒด์ ์ธ ๋ฒ๊ทธ๋ฅผ ์ฐพ๋ ๋ฐ๋ฉด, Kani๋ ๋ถ์ ๋ฒ์ ๋ด์ ๋ชจ๋ ์ ๋ ฅ์ ๋ํด ์์ฑ์ด ์ฑ๋ฆฝํ๋์ง ์ฌ๋ถ๋ฅผ ์ฆ๋ช ํ๊ฑฐ๋ ๋ฐ์ฆํฉ๋๋ค.
Kani๋ฅผ ์ฌ์ฉํ๋ ค๋ฉด ๊ฒ์ฆ ํ๋ค์ค๋ฅผ ์์ฑํด์ผ ํฉ๋๋ค. ์ฆ, ์ ๋ ฅ ๊ณต๊ฐ๊ณผ ๊ฒ์ฆํ ์์ฑ์ ์ ์ํ๋ ํจ์๋ฅผ ์์ฑํด์ผ ํฉ๋๋ค.
๋ น
#[cfg(kani)]
mod verification {
use super::*;
#[kani::proof]
fn verify_add_no_overflow() {
let a: u32 = kani::any();
let b: u32 = kani::any();
if a.checked_add(b).is_some() {
let result = safe_add(a, b);
assert!(result == a + b);
}
}
}
์ธ๊ฒ ๋๋ฆฌ๋ค
cargo install --locked kani-verifier
cargo kani setup
cargo kani
๋ค์๊ณผ ๊ฐ์ ์ฉ๋์ ๊ฐ์ฅ ์ ํฉํฉ๋๋ค: ์์ ์ ๋งค์ฐ ์ค์ํ ๊ธฐ๋ฅ, ํ๋กํ ์ฝ ๊ตฌํ, ๊ธ์ต ๋๋ ์ํธํ ์ฝ๋์ ์ฐ์ ์ฐ์ฐ, ๊ทธ๋ฆฌ๊ณ ์ ํ์ฑ ์์ฑ์ ๋จ์ํ ํ ์คํธํ๋ ๊ฒ์ด ์๋๋ผ ์ฆ๋ช ํด์ผ ํ๋ ๋ชจ๋ ๊ธฐ๋ฅ.
MIRAI: ์ถ์ ํด์ ๋ฐ ์ค์ผ ๋ถ์
Facebook Research์์ ๊ฐ๋ฐํ MIRAI๋ ์ถ์์ ์ธ ํด์์ ์ฌ์ฉํ์ฌ Rust์ MIR์ ๋ถ์ํฉ๋๋ค. ํจ์ ํธ์ถ์ ํตํด ๊ฐ์ด ์ด๋ป๊ฒ ํ๋ฅด๋์ง ์ถ์ ํ๋ ํ๋ก์์ ๊ฐ ๋ถ์์ ์ํํ์ฌ ์ ์ฌ์ ์ธ ํจ๋, ๊ณ์ฝ ์๋ฐ ๋ฐ ์ฝ๋ ์ ์ฒด์ ์ค์ผ์ด ์ ํ๋๋ ๊ฒ์ ๊ฐ์งํฉ๋๋ค.
๋ น
use mirai_annotations::*;
fn divide(a: i32, b: i32) -> i32 {
precondition!(b != 0); // MIRAI verifies all callers satisfy this
a / b
}
MIRAI๋ ์ผ๊ฐ์ ๋ฐฐํฌ๋๋ Rust ์ปดํ์ผ๋ฌ๋ฅผ ํ์๋ก ํ๋ฉฐ ์ค์ ๊ณผ์ ์ด ์๋นํ ๋ณต์กํ๊ธฐ ๋๋ฌธ์ ๋ณด์ ์์ง๋์ด๋ง ์ ๋ดํ์ด๋ ์ฐ๊ตฌ ์ค์ฌ์ ํ์ง ์๊ตฌ ์ฌํญ์ ๊ฐ์ง ํ์ ๊ฐ์ฅ ์ ํฉํฉ๋๋ค.
Rudra: ์์ ํ์ง ์์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ ์ฝ๋์์์ ๋ฉ๋ชจ๋ฆฌ ์์ ์ฑ
Rudra๋ Rust์ ์์ ๊ถ ๋ชจ๋ธ์ ํนํ๋ ๋ฉ๋ชจ๋ฆฌ ์์ ์ฑ ๋ฒ๊ทธ๋ฅผ ํ์งํ๊ธฐ ์ํด ํฌ๋ ์ดํธ ์ ๋ฐ์ ๊ฑธ์ณ ํ๋ก๊ทธ๋จ ์ ์ฒด๋ฅผ ๋ถ์ํฉ๋๋ค. ์ด๋ฌํ ๋ฒ๊ทธ์๋ Send/Sync ํธ๋ ์ดํธ ์์ ์ฑ ์๋ฐ, ๋ถ์์ ํ ์๋ช ์ฐ์ฅ์ ํ์ฉํ๋ ๊ณ ์ฐจ ํ์ ์๋ช ๋ฌธ์ , ์์ ํ์ง ์์ ์ฝ๋์ ํจ๋ ์์ ์ฑ ๋ฌธ์ ๋ฑ์ด ํฌํจ๋ฉ๋๋ค. ์๋ ์ฐ๊ตฌ์๋ค์ด ๊ฐ๋ฐํ Rudra๋ ์ปดํ์ผ๋ฌ ํ๋ฌ๊ทธ์ธ์ผ๋ก ์๋ํ๋ฉฐ ํน์ ๋์ดํ๋ฆฌ ๋ฒ์ ์ ํ์๋ก ํฉ๋๋ค. ์์ ํ์ง ์์ ๋ด๋ถ ๊ตฌ์กฐ๋ฅผ ๊ฐ์ง ๋ผ์ด๋ธ๋ฌ๋ฆฌ ํฌ๋ ์ดํธ์ ๊ฒฝ์ฐ, ๋งค ์ปค๋ฐ๋ง๋ค ์คํํ๊ธฐ๋ณด๋ค๋ ์์ฝ๋ ์๊ฐ์ ์คํํ๋ ๊ฒ์ด ์ข์ต๋๋ค.
ํฌ๋ฃจ์์ ํ๋ฃจ์คํฐ: ์ฐ์ญ์ ๊ฒ์ฆ
Creusot์ Prusti๋ Rust ํ๋ก๊ทธ๋จ์ ์ํ์ ์์ฑ์ ์ฆ๋ช ํ๋ ์ฐ์ญ์ ๊ฒ์ฆ ๋๊ตฌ์ ๋๋ค. ๋ ๋๊ตฌ ๋ชจ๋ ํ์ ๋ช ์ธ(์ฌ์ ์กฐ๊ฑด, ์ฌํ ์กฐ๊ฑด, ๋ฃจํ ๋ถ๋ณ ์กฐ๊ฑด)๋ฅผ ํ์๋ก ํ๋ฉฐ, ์๋ ์ ๋ฆฌ ์ฆ๋ช ๊ธฐ๋ฅผ ์ฌ์ฉํ์ฌ ๊ตฌํ์ด ์ด๋ฌํ ๋ช ์ธ์ ์ผ์นํ๋์ง ๊ฒ์ฆํฉ๋๋ค. ์ด๋ค์ ์์ ํ Rust ์ฝ๋์ ์ ํ๋ ํ์ ์งํฉ์ ๋์์ผ๋ก ํ๋ฉฐ, ํ์ ๋ฐฉ๋ฒ๋ก ์ ๋ํ ์ ๋ฌธ ์ง์์ ์๊ตฌํฉ๋๋ค. ๊ท์ ์ฐ์ , ์ํธํ ๋ผ์ด๋ธ๋ฌ๋ฆฌ ๊ฐ๋ฐ ๋๋ ์ํ์ ์ ํ์ฑ ์ฆ๋ช ์ด ๊ณ์ฝ์ด๋ ๊ท์ ์๊ฑด์ธ ๋ชจ๋ ํ๊ฒฝ์ ์ ํฉํฉ๋๋ค.
์ถ๊ฐ๋ก ํฌํจํ ๋งํ ๋๊ตฌ
์ฌ์ฉ์ ์ง์ ๋ณด์ ํจํด์ ์ํ Semgrep
Semgrep์ ์ฌ๋ฌ ์ธ์ด์์ ๋์์ ์๋ํ๋ ํจํด ๊ธฐ๋ฐ ์ ์ ๋ถ์ ๊ธฐ๋ฅ์ ์ ๊ณตํฉ๋๋ค. Rust์ ๊ฒฝ์ฐ, Semgrep์ ์ฌ์ฉํ๋ฉด Clippy๋ก๋ ํํํ ์ ์๋ ์กฐ์ง ๋ณด์ ์ ์ฑ ๋ฐ ์ฝ๋๋ฒ ์ด์ค๋ณ ํจํด์ ์ ์ฉํ๋ ์ฌ์ฉ์ ์ง์ ๊ท์น์ ์์ฑํ ์ ์์ต๋๋ค.
์
# Custom rule: flag .unwrap() in production paths
rules:
- id: no-unwrap-in-production
pattern: $X.unwrap()
message: "Use proper error handling instead of .unwrap()"
languages: [rust]
severity: WARNING
Semgrep์ ์ปค๋ฎค๋ํฐ์์ ๊ด๋ฆฌํ๋ Rust ๋ณด์ ๊ท์น์ด ํฌํจ๋ ๊ด๋ฆฌํ ๊ท์น ๋ ์ง์คํธ๋ฆฌ๋ ์ ๊ณตํฉ๋๋ค.
SonarCloud/SonarQube๋ฅผ ํ์ฉํ ์ง์์ ์ธ ํ์ง ๊ฒ์ดํธ ํ ์คํธ
SonarCloud๋ ๋์๋ณด๋, ํธ๋ ๋ ์ถ์ , ํ ๋ฆฌํ์คํธ ๋ฐ์ฝ๋ ์ด์ ๊ธฐ๋ฅ์ ํตํด ์ง์์ ์ธ ์ฝ๋ ํ์ง ๋ถ์์ ์ ๊ณตํฉ๋๋ค. Rust ์ง์์ ํตํด ์ผ๋ฐ์ ์ธ ๋ฒ๊ทธ ํจํด, ๋ณด์ ์ทจ์ฝ์ , ์ฝ๋ ์ค๋ฉ ๋ฑ์ ํ์ ํ ์ ์์ต๋๋ค. ์ด๋ฏธ ๋ค๋ฅธ ์ธ์ด์ SonarCloud๋ฅผ ์ฌ์ฉํ๊ณ ์๋ ๊ธฐ์ ํ์ Rust๋ฅผ ๋์ผํ ํ์ดํ๋ผ์ธ์ ์ถ๊ฐํ์ฌ ์คํ ์ ๋ฐ์ ๊ฑธ์ณ ํตํฉ๋ ํ์ง ๊ฐ์์ฑ์ ํ๋ณดํ ์ ์์ต๋๋ค.
๊ณ์ธตํ CI/CD ํ์ดํ๋ผ์ธ ๊ตฌ์ถ
๋ค์ GitHub Actions ์ํฌํ๋ก๋ ๊ณผ๋ํ ์ค๊ณ ์์ด ํฌ๊ด์ ์ธ Rust ํ์ง ๊ฒ์ฆ์ ์ํ๋ ํ์ ์ํ ์ค์ฉ์ ์ธ ์์์ ์ ์ ์ํฉ๋๋ค.
์
# .github/workflows/quality.yml
name: Code Quality and Security
on: [push, pull_request]
jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@stable
with:
components: clippy, rustfmt
- name: Check formatting
run: cargo fmt -- --check
- name: Clippy (treat warnings as errors)
run: cargo clippy -- -D warnings
security:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@stable
- name: Install security tools
run: |
cargo install cargo-audit
cargo install cargo-deny
- name: Dependency audit
run: cargo audit --deny warnings
- name: License and policy check
run: cargo deny check
verify:
runs-on: ubuntu-latest
# Scheduled or manually triggered, not on every push
if: github.event_name == 'schedule' || github.event_name == 'workflow_dispatch'
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@nightly
with:
components: miri
- name: Miri on unsafe modules
run: cargo +nightly miri test --package my-unsafe-crate
์ด๋ค ๋๊ตฌ๋ฅผ ์ฌ์ฉํด์ผ ํ ๊น์? ๊ฒฐ์ ๊ฐ์ด๋
์๋ก์ด Rust ํ๋ก์ ํธ ์์ํ๊ธฐClippy + rustfmt + cargo-audit. 5๋ถ ์ด๋ด์ ์ค์ ๊ฐ๋ฅํ๋ฉฐ, ํ์์ ํํ ์ ํ๋ ๋๋ถ๋ถ์ ํ์ง ๋ฐ ๋ณด์ ๋ฌธ์ ๋ฅผ ์ก์๋ ๋๋ค.
์ธ๋ถ ์ข ์์ฑ์ด ์๋ ํ๋ก๋์ ์๋น์ค๋ผ์ด์ ์ค ์ค์ ๋ฐ ๊ณต๊ธ๋ง ์ ์ฑ ์ํ์ ์ํด CVE ์ธ์๋ ํ๋ฌผ ๊ฑฐ๋ถ ๊ธฐ๋ฅ์ ์ถ๊ฐํฉ๋๋ค.
๋ด๋ถ ๊ตฌ์กฐ๊ฐ ์์ ํ์ง ์์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ ํฌ๋ ์ดํธ์์ ํ์ง ์์ ์ฝ๋๊ฐ ํฌํจ๋ ๋ชจ๋์ ๋ํด Miri๋ฅผ ํ ์คํธ ์ค์ํธ์ ์ถ๊ฐํ์ธ์. Rudra๋ฅผ ์์ฝ๋ ์๊ฐ์ ์คํํ์ธ์.
์์ ํ์ ์ฝ๋ ๋๋ ์ํธํ ์ฝ๋๊ฐ์ฅ ์ค์ํ ๊ธฐ๋ฅ์ ๋ํด Kani ๊ฒ์ฆ ๋๊ตฌ๋ฅผ ์์ฑํ์ญ์์ค. ํ์ ์ ํ ๋ฐฉ๋ฒ๋ก ์ ๋ฌธ ์ง์์ด ์๋ค๋ฉด Creusot ๋๋ Prusti๋ฅผ ๊ณ ๋ คํด ๋ณด์ญ์์ค.
๋ณด์์ ์ค์ ์ ๋ ์กฐ์ง: ์กฐ์ง ๋ณด์ ์ ์ฑ ์ ๋ํ ์ฌ์ฉ์ ์ง์ ๊ท์น์ ํฌํจํ๋ Semgrep์ ์ถ๊ฐํ๊ณ , ๋ฆด๋ฆฌ์ค ๋น๋์์ cargo-auditable์ ์ง์ํฉ๋๋ค.
๋ ํฐ ํ์ ์ํ ์ง์์ ์ธ ๊ฐ์์ฑ ํ๋ณดSonarCloud๋ ํธ๋ ๋ ์ถ์ , ํ ๋ฆฌํ์คํธ ๊ด๋ฆฌ ๋ฐ ํ์ง ๊ด๋ฆฌ ๊ธฐ๋ฅ์ ๋น๋กฏํ์ฌ ์คํ ์์ค ๋๊ตฌ๋ค์ ์ ๊ณตํฉ๋๋ค.
๋ค๊ตญ์ด ๊ธฐ์ ํ๊ฒฝ Rust๊ฐ COBOL, Java ๋๋ ๊ธฐํ ๋ ๊ฑฐ์ ์ธ์ด์ ์ํธ ์์ฉํ๋ ๊ฒฝ์ฐ, ๋จ์ผ ์ธ์ด Rust ๋๊ตฌ๋ ์ธ์ด ๊ฒฝ๊ณ๋ฅผ ๋์ด ์ํธ ์์ฉํ ์ ์์ต๋๋ค. SMART TS XL ์ ์ฒด ์์คํ ์ ํฌ๊ดํ๋ ์ธ์ด ๊ฐ ๋ถ์์ ์ ๊ณตํฉ๋๋ค.
Rust ์ ์ ๋ถ์์ด ์ํฐํ๋ผ์ด์ฆ ์์คํ ๊ณผ ๋ง๋ ๋
Rust๋ COBOL, Java, PL/I, RPG ๋ฑ์ ๋ฉ์ธํ๋ ์์ด๋ ๋ ๊ฑฐ์ ํ๋ซํผ์์ ์คํํ๋ ์กฐ์ง์์ ์๋ก์ด ์๋น์ค๋ฅผ ๊ฐ๋ฐํ๋ ๋ฐ ์ ์ ๋ ๋ง์ด ์ฌ์ฉ๋๊ณ ์์ต๋๋ค. ์ด๋ฌํ ํ๊ฒฝ์์ ์ ์ ๋ถ์์ Rust ์ ์ฉ ๋๊ตฌ๊ฐ ๋ค๋ฃฐ ์ ์๋ ๋ฒ์๋ฅผ ๋์ด์ญ๋๋ค. Rust ๋ง์ดํฌ๋ก์๋น์ค๋ COBOL ํ๋ก๊ทธ๋จ์ ํธ์ถํ๊ฑฐ๋, ๊ณต์ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ๋ฐ์ดํฐ๋ฅผ ์ฐ๊ฑฐ๋, ๋ ๊ฑฐ์ ๋ฐฐ์น ์์คํ ์์ ์์ฑ๋ ์ด๋ฒคํธ๋ฅผ ์๋นํ ์ ์์ต๋๋ค. ๊ธฐ์ ์ํคํ ํธ์๊ฒ ์ค์ํ ํ์ง ๋ฐ ์ข ์์ฑ ๋ถ์์ ์ด๋ฌํ ๋ชจ๋ ์์คํ ์ ๋์์ ์์ฐ๋ฅด๋ ๊ฒ์ ๋๋ค.
SMART TS XL Clippy์ cargo-audit์ Rust๋ง ์ธ์ํ๋ ๋ฐ๋ฉด, Cargo-audit์ ์ ์ฒด ์ ํ๋ฆฌ์ผ์ด์ ํฌํธํด๋ฆฌ์ค์ ๊ฑธ์ณ ์ธ์ด ๊ฐ ์ข ์์ฑ ๋ถ์์ ์ ๊ณตํ์ฌ ์ด๋ฌํ ๊ฒฉ์ฐจ๋ฅผ ํด์ํฉ๋๋ค. SMART TS XL Rust ์๋น์ค๊ฐ ๊ณต์ ๋ฐ์ดํฐ ๊ตฌ์กฐ, ๋ ๊ฑฐ์ ํ๋ก๊ทธ๋จ ๋ฐ ์ํฐํ๋ผ์ด์ฆ API์ ์ด๋ป๊ฒ ์์กดํ๋์ง, ๊ทธ๋ฆฌ๊ณ ์ด๋ฌํ ์์กด์ฑ์ ๋ณ๊ฒฝํ ๊ฒฝ์ฐ ์ด๋ค ์ํฅ์ ๋ฏธ์น ์ง ํ์ ํ๋ ๋ฐ ์ ์ฉํ ๋๊ตฌ์ ๋๋ค. ๋ฐ๋ผ์ Rust ์๋น์ค๋ ์ด๋ฌํ ์ข ์์ฑ ๋ถ์์ ํนํ ์ ํฉํฉ๋๋ค. ์ํฅ ๋ถ์ ๊ธฐ์กด ์์คํ ํ๋ํ ๊ณํ Rust๊ฐ ์ฌ๋ฌ ์ธ์ด ์ค ํ๋๋ก ์ฌ์ฉ๋๋ ํ๊ฒฝ์์.
๋๊ท๋ชจ ์ํฐํ๋ผ์ด์ฆ ์ฝ๋๋ฒ ์ด์ค ๋ด์์ Rust๋ฅผ ์ ์ง์ ์ผ๋ก ๋์ ํ๋ ํ์ ๊ฒฝ์ฐ, SMART TS XL์ ์ ์ ์ฝ๋ ๋ถ์ Rust ์ปดํฌ๋ํธ๊ฐ ๋ ํฐ ์์คํ ์ ์ด๋ป๊ฒ ํตํฉ๋๋์ง ์ดํดํ๋ ๋ฐ ํ์ํ ๊ตฌ์กฐ์ ๊ฐ์์ฑ์ ์ ๊ณตํ์ฌ ๋ค๋ฅธ ์ธ์ด๋ก ์์ฑ๋ ์ปดํฌ๋ํธ์ ์ํฅ์ ์ค ์ ์๋ ๋ณ๊ฒฝ ์์ ์ ์ํํ๊ธฐ ์ ์ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ ์ ์๋๋ก ํฉ๋๋ค. ์ด๋ฌํ ๋งฅ๋ฝ์์ ์ดํด๋ณด๋ฉด ๋ค์๊ณผ ๊ฐ์ต๋๋ค. ์์กด์ฑ ๊ทธ๋ํ ๋ฐ ์ ํ๋ฆฌ์ผ์ด์ ์ํ์์คํ ์ ํ์ฅํ๊ธฐ ์ ์ ์ ์ฒด ์ข ์์ฑ ๊ตฌ์กฐ๋ฅผ ํ์ ํ๋ ๊ฒ์ด ์ํํ ๋ณ๊ฒฝ๊ณผ ์๋ฌด๋ ํ ์คํธํ ์๊ฐ์ ํ์ง ๋ชปํ๋ ๊ตฌ์ฑ ์์์์ ์ค๋ฅ๋ฅผ ๋ฐ์์ํค๋ ๋ณ๊ฒฝ์ ๊ตฌ๋ถํ๋ ํต์ฌ ์์์ ๋๋ค.
๊ณ์ธต์ ์ ๊ทผ ๋ฐฉ์์ด ํต์ฌ์ ๋๋ค.
Rust์์์ ์ ์ ๋ถ์์ ๋จ ํ๋์ ๋๊ตฌ ์ ํ์ผ๋ก ๊ฒฐ์ ๋๋ ๊ฒ์ด ์๋๋๋ค. ์ปดํ์ผ๋ฌ๊ฐ ๋ฌด๋ฃ๋ก ์ ๊ณตํ๋ ๊ธฐ๋ฅ๋ถํฐ ์์ํ์ฌ ์ฝ๋์ ์ํ ํ๋กํ์ ๋ฐ๋ผ ํ์ฅํด ๋๊ฐ๋ ๊ณ์ธต์ ์ธ ์ ๊ทผ ๋ฐฉ์์ ๋๋ค. Clippy์ rustfmt๋ ์ต์ํ์ ๋๊ตฌ์ด๋ฉฐ, ์ธ๋ถ ์์กด์ฑ์ด ์๋ ํ๋ก์ ํธ๋ผ๋ฉด cargo-audit์ ํ์์ ๋๋ค. Miri๋ ์์ ํ์ง ์์ ์ฝ๋๊ฐ ์๋ ํ๋ก์ ํธ์ ๋ฐ๋์ ์ฌ์ฉํด์ผ ํฉ๋๋ค. Kani์ ๊ฐ์ ํ์ ๊ฒ์ฆ ๋๊ตฌ๋ ์ค๋ฅ๊ฐ ์ ๋ ์ฉ๋ฉ๋ ์ ์๋ ํจ์์ ์ฌ์ฉํฉ๋๋ค.
์ด๋ฌํ ๋ฐฉ์์ ์ ๋๋ก ์ดํดํ๋ ํ์ ์ ์ ๋ถ์์ ๊ฐ๋ฐ ๋ฃจํ์ ํตํฉํฉ๋๋ค. ์๋ฅผ ๋ค์ด, ์๋ํฐ์ Clippy๋ฅผ ์ธ๋ผ์ธ์ผ๋ก ์ฌ์ฉํ๊ณ , ๋ชจ๋ CI ์คํ์ cargo-audit์ ํฌํจ์ํค๋ฉฐ, ํ ์คํธ๋ง์ผ๋ก๋ ์ก์๋ผ ์ ์๋ ์ค๋ฅ๋ฅผ ํฌ์ฐฉํ๋ ์ผ๊ฐ ์์ ์ Miri๋ฅผ ์คํํฉ๋๋ค. ๊ทธ ๊ฒฐ๊ณผ, ๋ฒ๊ทธ ์๊ฐ ์ค์ด๋๋ ๊ฒ๋ฟ๋ง ์๋๋ผ, ๊ฐ๋ฐ ํ๊ฒฝ๊ณผ ํ๋ก๋์ ํ๊ฒฝ ์ฌ์ด์ ์๋ ๋ถ์ ๊ณ์ธต์ด ์ ๋๋ก ์๋ํ๊ณ ์๋ค๋ ํ์ ์ ๋ฐํ์ผ๋ก ํ์ด ์ ์ํ๊ฒ ๋ณ๊ฒฝ ์์ ์ ์งํํ ์ ์๊ฒ ๋ฉ๋๋ค.