dimforge / dimforge/nalgebra

Several soundness issues related to exception safety

Open
#1,610 0 comments 0 reactions 0 assignees View on GitHub
Dominant language
Rust
Stars
4.8k
Forks
565
PR merge metrics
No merged PRs in 30d

Description

Hello, we are security researchers targeting Rust security. By running our tool in this repository, we found several soundness issues. **This report is written by 100% human**. We promise that all you read will never be generated by LLM.

It's clear that the `CsMatrix::new_uninitialized_generic` is unsound and should not be declared safe, and I found that there is already an issue talking about it: #556

https://github.com/dimforge/nalgebra/blob/3320ecca21dc08f7a93c9595f6b257f05ba21273/src/sparse/cs_matrix.rs#L262-L286

`CsCholesky::nonzero_pattern` has similar problem.

However, even if it is declared as `unsafe`, there are still several soundness issues across the repository.

# Issue 1: `CsMatrix::transpose`

https://github.com/dimforge/nalgebra/blob/3320ecca21dc08f7a93c9595f6b257f05ba21273/src/sparse/cs_matrix.rs#L421-L453

in line 442, a for loop is used to consume an iterator `ColumnEntries` created by `.column_entries(j)`, which will invoke `T::clone` at line 35.

https://github.com/dimforge/nalgebra/blob/3320ecca21dc08f7a93c9595f6b257f05ba21273/src/sparse/cs_matrix.rs#L26-L41

However, since the `clone` implementation is provided by users, users can provide a `clone` that deliberately calls `panic!`. In this situation, the `CsMatrix` is partially initialized, but its destructor will be called during unwinding, which will treat every element in the inner vector as initialized and invoke individual `drop`, leading to use of uninitialized variable. This is similar to the typical example suggested in [The Rustonomicon](https://doc.rust-lang.org/nomicon/exception-safety.html#vecpush_all).

# Issue 2: `CsMatrix::from_triplet_generic`

https://github.com/dimforge/nalgebra/blob/3320ecca21dc08f7a93c9595f6b257f05ba21273/src/sparse/cs_matrix_conversion.rs#L28-L66

Similar to issue 1, the user-provided `Clone` implementation is called at line 53.

# Issue 3: `>::from`

https://github.com/dimforge/nalgebra/blob/3320ecca21dc08f7a93c9595f6b257f05ba21273/src/sparse/cs_matrix_conversion.rs#L87-L113

Similar to issue 1, the user-provided `Clone` implementation is called at line 105.

# Issue 4: `CsMatrix::mul` and `CsMatrix::add`

https://github.com/dimforge/nalgebra/blob/3320ecca21dc08f7a93c9595f6b257f05ba21273/src/sparse/cs_matrix_ops.rs#L142-L175

Similar to issue 1, the user-provided `Clone` implementation is called at line 161, 162, 163.

# Issue 5: `CsMatrix::solve_lower_triangular_cs`

https://github.com/dimforge/nalgebra/blob/3320ecca21dc08f7a93c9595f6b257f05ba21273/src/sparse/cs_matrix_solve.rs#L139-L201

Similar to issue 1, the user-provided `Clone` implementation is called at line 196.

# Issue 6: `CsCholesky::decompose_left_looking` and `CsCholesky::decompose_up_looking`

https://github.com/dimforge/nalgebra/blob/3320ecca21dc08f7a93c9595f6b257f05ba21273/src/sparse/cs_matrix_cholesky.rs#L78-L225

These two methods seem to be used to initialized a `CsCholesky`, but there are several calls to `T::zero` and `T::clone`, which is similar to issue 1.

Contributor guide

No contributing guide indexed for this repository

Research direction

Start with the cited implementations in src/sparse/cs_matrix.rs, cs_matrix_conversion.rs, cs_matrix_ops.rs, cs_matrix_solve.rs, and cs_matrix_cholesky.rs, then read Rustonomicon's exception-safety discussion. Trace each reported Clone or zero call during unwinding; done requires an agreed soundness treatment for all six areas and regression coverage for the affected operations.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
security
Issue type
Bug
Difficulty
5/5
Estimated time
Over a week
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.