Skip to content

Undefined behavior in CK_ATTRIBUTE::try_from or Session::get_attributes #323

@nwalfield

Description

@nwalfield

While testing sequoia-cryptoki using SoftHSM2, I encountered a panic:

unsafe precondition(s) violated: slice::from_raw_parts requires the pointer to be aligned and non-null, and the total size of the slice not to exceed `isize::MAX`

The error message suggests that there is undefined behavior. Examining the backtrace, CK_ATTRIBUTE::try_from, was executing which is called from Session::get_attributes, which is immediately preceded by an unsafe block:

        // Allocating a chunk of memory where to put the attributes value.
        let attrs_memory: Vec<(AttributeType, Vec<u8>)> = attrs_info
            .iter()
            .zip(attributes.iter())
            .filter_map(|(attr_info, attr_type)| {
                if let AttributeInfo::Available(size) = attr_info {
                    Some((*attr_type, vec![0; *size]))
                } else {
                    None
                }
            })
            .collect();

        let mut template: Vec<CK_ATTRIBUTE> = attrs_memory
            .iter()
            .map(|(attr_type, memory)| {
                Ok(CK_ATTRIBUTE {
                    type_: (*attr_type).into(),
                    pValue: memory.as_ptr() as *mut std::ffi::c_void,
                    ulValueLen: memory.len().try_into()?,
                })
            })
            .collect::<Result<Vec<CK_ATTRIBUTE>>>()?;

        // This should only return OK as all attributes asked should be
        // available. Concurrency problem?
        unsafe {
            Rv::from(get_pkcs11!(self.client(), C_GetAttributeValue)(
                self.handle(),
                object.handle(),
                template.as_mut_ptr(),
                template.len().try_into()?,
            ))
            .into_result(Function::GetAttributeValue)?;
        }

        // Convert from CK_ATTRIBUTE to Attribute
        template.into_iter().map(|attr| attr.try_into()).collect()

In my code, the call to Session::get_attributes is here.

Instrumenting my code, I see the error occurs while fetching the AllowedMechanisms attribute whose attribute info was Available(0).

The following shows how to reproduce the crash. Note that sequoia-cryptoki uses rust-cryptoki's HEAD, which is currently 2702bba.

I'm compiling with rustc 1.85.1 and the issue is only triggered is debug mode; compiling with --release doesn't trigger the issue. I'm on Debian Stable and am using softhsm2 2.6.1-3.

$ git clone https://gitlab.com/sequoia-pgp/sequoia-cryptoki.git
Cloning into 'sequoia-cryptoki'...
remote: Enumerating objects: 1313, done.
remote: Counting objects: 100% (88/88), done.
remote: Compressing objects: 100% (16/16), done.
remote: Total 1313 (delta 84), reused 72 (delta 72), pack-reused 1225 (from 1)
Receiving objects: 100% (1313/1313), 400.48 KiB | 2.00 MiB/s, done.
Resolving deltas: 100% (834/834), done.
us@alice:/tmp/cryptoki (0)$ git checkout 537f0f84
fatal: not a git repository (or any parent up to mount point /)
Stopping at filesystem boundary (GIT_DISCOVERY_ACROSS_FILESYSTEM not set).
$ cd sequoia-cryptoki/
$ git checkout 537f0f84
Note: switching to '537f0f84'.
...
HEAD is now at 537f0f8 tools: Improve PIN long help
$ cargo build --features sequoia-openpgp/crypto-openssl --no-default-features
...
    Finished `dev` profile [unoptimized + debuginfo] target(s) in 9.59s
$ rm -rf /tmp/softhsm/
config.file  tokens/      
$ cat /tmp/softhsm/config.file 
directories.tokendir = /tmp/softhsm/tokens/
objectstore.backend = file

# ERROR, WARNING, INFO, DEBUG
log.level = ERROR

# If CKF_REMOVABLE_DEVICE flag should be set
slots.removable = false
$ rm -rf /tmp/softhsm/tokens/
$ mkdir -p /tmp/softhsm/tokens/
$ SOFTHSM2_CONF=/tmp/softhsm/config.file target/debug/sq-cryptoki --module /usr/lib/softhsm/libsofthsm2.so token init --new-token-label foo
Token not yet initialized.  Performing initial initialization.
Please enter a PIN to protect the SO PIN: 
                   Please repeat the PIN: 
Please enter a PIN to protect the user PIN: 
                     Please repeat the PIN: 
$ SOFTHSM2_CONF=/tmp/softhsm/config.file target/debug/sq-cryptoki --module /usr/lib/softhsm/libsofthsm2.so key generate --token-label foo --random-key-label --can-certify --new-cert
Please enter the PIN to unlock the user PIN: 
Warning: /usr/lib/softhsm/libsofthsm2.so's slot 1 is unusable: Function::OpenSession: PKCS11 error: The Cryptoki library and/or slot does not recognize the token in the slot.
Warning: /usr/lib/softhsm/libsofthsm2.so's slot 1 is unusable: Function::OpenSession: PKCS11 error: The Cryptoki library and/or slot does not recognize the token in the slot.
-----BEGIN PGP PUBLIC KEY BLOCK-----
Cryptoki-ID: pgp:v4:eddsa:20251118T090408Z:scrap-heat-mouse
Cryptoki-Label: scrap-heat-mouse

xjMEaRw2iBYJKwYBBAHaRw8BAQdAtMqd22erF066DFOOdGKtVLdKn3otDCmie07t
1Dbfwo/CwAsEHxYKAH0FgmkcNogDCwkHCRALbiC0oZbPHEcUAAAAAAAeACBzYWx0
QG5vdGF0aW9ucy5zZXF1b2lhLXBncC5vcmfGYoMI2Cjo3UWb8//gUtRp2Kv0mL/5
ZDgn/9wzrOKUYwMVCggCmwECHgkWIQSOCXstP5hJzIyg5UgLbiC0oZbPHAAAozgB
APBx80X6nhUPl4bvNLq0UP9W0iH+GLJXYmnhQVzmvWIwAP0fiwPV1RyxCHi32oF1
w9qGFmuV4y7drOTLIK9Id8w3DA==
=fM3c
-----END PGP PUBLIC KEY BLOCK-----
$ RUST_BACKTRACE=full SOFTHSM2_CONF=/tmp/softhsm/config.file target/debug/sq-cryptoki --module /usr/lib/softhsm/libsofthsm2.so token list --key-label scrap-heat-mouse

thread 'main' panicked at library/core/src/panicking.rs:218:5:
unsafe precondition(s) violated: slice::from_raw_parts requires the pointer to be aligned and non-null, and the total size of the slice not to exceed `isize::MAX`
stack backtrace:
   0:     0x56250730a73a - std::backtrace_rs::backtrace::libunwind::trace::h2740d05102fd9881
                               at /rustc/4eb161250e340c8f48f66e2b929ef4a5bed7c181/library/std/src/../../backtrace/src/backtrace/libunwind.rs:116:5
   1:     0x56250730a73a - std::backtrace_rs::backtrace::trace_unsynchronized::h93ae2edf130065c8
                               at /rustc/4eb161250e340c8f48f66e2b929ef4a5bed7c181/library/std/src/../../backtrace/src/backtrace/mod.rs:66:5
   2:     0x56250730a73a - std::sys::backtrace::_print_fmt::h7660a544e6110dd9
                               at /rustc/4eb161250e340c8f48f66e2b929ef4a5bed7c181/library/std/src/sys/backtrace.rs:66:9
   3:     0x56250730a73a - <std::sys::backtrace::BacktraceLock::print::DisplayBacktrace as core::fmt::Display>::fmt::hfc616348d9ad0abc
                               at /rustc/4eb161250e340c8f48f66e2b929ef4a5bed7c181/library/std/src/sys/backtrace.rs:39:26
   4:     0x56250732e073 - core::fmt::rt::Argument::fmt::h3a92517f8117fcd5
                               at /rustc/4eb161250e340c8f48f66e2b929ef4a5bed7c181/library/core/src/fmt/rt.rs:177:76
   5:     0x56250732e073 - core::fmt::write::h7ca648217bc79799
                               at /rustc/4eb161250e340c8f48f66e2b929ef4a5bed7c181/library/core/src/fmt/mod.rs:1440:21
   6:     0x562507307623 - std::io::Write::write_fmt::h7960c58bfa5ccbcb
                               at /rustc/4eb161250e340c8f48f66e2b929ef4a5bed7c181/library/std/src/io/mod.rs:1887:15
   7:     0x56250730a582 - std::sys::backtrace::BacktraceLock::print::h3fb349e80cbe0423
                               at /rustc/4eb161250e340c8f48f66e2b929ef4a5bed7c181/library/std/src/sys/backtrace.rs:42:9
   8:     0x56250730b5f0 - std::panicking::default_hook::{{closure}}::h3366e5842cba645d
                               at /rustc/4eb161250e340c8f48f66e2b929ef4a5bed7c181/library/std/src/panicking.rs:295:22
   9:     0x56250730b3d0 - std::panicking::default_hook::hd7573a5d4879884b
                               at /rustc/4eb161250e340c8f48f66e2b929ef4a5bed7c181/library/std/src/panicking.rs:322:9
  10:     0x56250730bd52 - std::panicking::rust_panic_with_hook::h66e909d048c263a9
                               at /rustc/4eb161250e340c8f48f66e2b929ef4a5bed7c181/library/std/src/panicking.rs:828:13
  11:     0x56250730bac6 - std::panicking::begin_panic_handler::{{closure}}::h8d9aa8be7e8634cf
                               at /rustc/4eb161250e340c8f48f66e2b929ef4a5bed7c181/library/std/src/panicking.rs:694:13
  12:     0x56250730ac49 - std::sys::backtrace::__rust_end_short_backtrace::h7d7e47ef99abf6aa
                               at /rustc/4eb161250e340c8f48f66e2b929ef4a5bed7c181/library/std/src/sys/backtrace.rs:168:18
  13:     0x56250730b78d - rust_begin_unwind
                               at /rustc/4eb161250e340c8f48f66e2b929ef4a5bed7c181/library/std/src/panicking.rs:692:5
  14:     0x562506a44f4d - core::panicking::panic_nounwind_fmt::runtime::h19438eeae7eaf031
                               at /rustc/4eb161250e340c8f48f66e2b929ef4a5bed7c181/library/core/src/panicking.rs:117:22
  15:     0x562506a44f4d - core::panicking::panic_nounwind_fmt::h57347130f21a7343
                               at /rustc/4eb161250e340c8f48f66e2b929ef4a5bed7c181/library/core/src/intrinsics/mod.rs:3869:9
  16:     0x562506a44fe2 - core::panicking::panic_nounwind::h2f7749cb358aa979
                               at /rustc/4eb161250e340c8f48f66e2b929ef4a5bed7c181/library/core/src/panicking.rs:218:5
  17:     0x562506d7f2c3 - core::slice::raw::from_raw_parts::precondition_check::h3c75f0263862b151
                               at /rustc/4eb161250e340c8f48f66e2b929ef4a5bed7c181/library/core/src/ub_checks.rs:68:21
  18:     0x562506d7f08f - core::slice::raw::from_raw_parts::h1fcb92e9a7016678
                               at /rustc/4eb161250e340c8f48f66e2b929ef4a5bed7c181/library/core/src/ub_checks.rs:75:17
  19:     0x562506d5f046 - <cryptoki::object::Attribute as core::convert::TryFrom<cryptoki_sys::CK_ATTRIBUTE>>::try_from::hdc4d38e483f52cfb
                               at /home/us/.cargo/git/checkouts/rust-cryptoki-d5dc7807e7b467b4/e702367/cryptoki/src/object.rs:955:21
  20:     0x562506d6c97e - <T as core::convert::TryInto<U>>::try_into::hecd42c0a58963277
                               at /rustc/4eb161250e340c8f48f66e2b929ef4a5bed7c181/library/core/src/convert/mod.rs:800:9
  21:     0x562506d57aa5 - cryptoki::session::object_management::<impl cryptoki::session::Session>::get_attributes::{{closure}}::hf48fdd4ad86c40d7
                               at /home/us/.cargo/git/checkouts/rust-cryptoki-d5dc7807e7b467b4/e702367/cryptoki/src/session/object_management.rs:547:41
  22:     0x562506d741b3 - core::iter::adapters::map::map_try_fold::{{closure}}::h30e3e631e9395c74
                               at /rustc/4eb161250e340c8f48f66e2b929ef4a5bed7c181/library/core/src/iter/adapters/map.rs:95:28
  23:     0x562506d51660 - <alloc::vec::into_iter::IntoIter<T,A> as core::iter::traits::iterator::Iterator>::try_fold::h88e818c6261d99a6
                               at /rustc/4eb161250e340c8f48f66e2b929ef4a5bed7c181/library/alloc/src/vec/into_iter.rs:346:25
  24:     0x562506d73a90 - <core::iter::adapters::map::Map<I,F> as core::iter::traits::iterator::Iterator>::try_fold::h78826b022f8e313c
                               at /rustc/4eb161250e340c8f48f66e2b929ef4a5bed7c181/library/core/src/iter/adapters/map.rs:121:9
  25:     0x562506d6dc6c - <core::iter::adapters::GenericShunt<I,R> as core::iter::traits::iterator::Iterator>::try_fold::h18f91d3c85a7b99d
                               at /rustc/4eb161250e340c8f48f66e2b929ef4a5bed7c181/library/core/src/iter/adapters/mod.rs:191:9
  26:     0x562506d6dace - core::iter::traits::iterator::Iterator::try_for_each::h780c17ea7f5530e3
                               at /rustc/4eb161250e340c8f48f66e2b929ef4a5bed7c181/library/core/src/iter/traits/iterator.rs:2431:9
  27:     0x562506d6dace - <core::iter::adapters::GenericShunt<I,R> as core::iter::traits::iterator::Iterator>::next::h66764564edac8663
                               at /rustc/4eb161250e340c8f48f66e2b929ef4a5bed7c181/library/core/src/iter/adapters/mod.rs:174:14
  28:     0x562506d48451 - <alloc::vec::Vec<T> as alloc::vec::spec_from_iter_nested::SpecFromIterNested<T,I>>::from_iter::haf3e6fb6f2c0758e
                               at /rustc/4eb161250e340c8f48f66e2b929ef4a5bed7c181/library/alloc/src/vec/spec_from_iter_nested.rs:25:32
  29:     0x562506d78905 - <alloc::vec::Vec<T> as alloc::vec::spec_from_iter_nested::SpecFromIterNested<T,I>>::from_iter{{reify.shim}}::h7a12c5bce59ab962
                               at /rustc/4eb161250e340c8f48f66e2b929ef4a5bed7c181/library/alloc/src/vec/spec_from_iter_nested.rs:19:5
  30:     0x562506d4b2be - alloc::vec::in_place_collect::<impl alloc::vec::spec_from_iter::SpecFromIter<T,I> for alloc::vec::Vec<T>>::from_iter::h193cc45ef1110893
                               at /rustc/4eb161250e340c8f48f66e2b929ef4a5bed7c181/library/alloc/src/vec/in_place_collect.rs:246:9
  31:     0x562506d4b9f3 - <alloc::vec::Vec<T> as core::iter::traits::collect::FromIterator<T>>::from_iter::h125c9b82fab0133d
                               at /rustc/4eb161250e340c8f48f66e2b929ef4a5bed7c181/library/alloc/src/vec/mod.rs:3427:9
  32:     0x562506d417a9 - core::iter::traits::iterator::Iterator::collect::h3bebcb28a8355402
                               at /rustc/4eb161250e340c8f48f66e2b929ef4a5bed7c181/library/core/src/iter/traits/iterator.rs:1971:9
  33:     0x562506d417a9 - <core::result::Result<V,E> as core::iter::traits::collect::FromIterator<core::result::Result<A,E>>>::from_iter::{{closure}}::ha72dfe59c9d09579
                               at /rustc/4eb161250e340c8f48f66e2b929ef4a5bed7c181/library/core/src/result.rs:1985:51
  34:     0x562506d6efba - core::iter::adapters::try_process::h2e61e5506f36e223
                               at /rustc/4eb161250e340c8f48f66e2b929ef4a5bed7c181/library/core/src/iter/adapters/mod.rs:160:17
  35:     0x562506d41649 - <core::result::Result<V,E> as core::iter::traits::collect::FromIterator<core::result::Result<A,E>>>::from_iter::h90fa2de9d45a8d71
                               at /rustc/4eb161250e340c8f48f66e2b929ef4a5bed7c181/library/core/src/result.rs:1985:9
  36:     0x562506d73dee - core::iter::traits::iterator::Iterator::collect::h1fc70cf577cb49ac
                               at /rustc/4eb161250e340c8f48f66e2b929ef4a5bed7c181/library/core/src/iter/traits/iterator.rs:1971:9
  37:     0x562506d4fe18 - cryptoki::session::object_management::<impl cryptoki::session::Session>::get_attributes::ha0e17c654666027c
                               at /home/us/.cargo/git/checkouts/rust-cryptoki-d5dc7807e7b467b4/e702367/cryptoki/src/session/object_management.rs:547:9
  38:     0x562506ae2249 - sq_cryptoki::commands::token::list::list::h35abe4f2c0812a87
                               at /tmp/cryptoki/sequoia-cryptoki/tools/src/commands/token/list.rs:685:45
  39:     0x562506a82273 - sq_cryptoki::commands::token::dispatch::hcce07600e7141a7b
                               at /tmp/cryptoki/sequoia-cryptoki/tools/src/commands/token.rs:16:20
  40:     0x562506a780ef - sq_cryptoki::commands::dispatch::h464f15db3271631c
                               at /tmp/cryptoki/sequoia-cryptoki/tools/src/commands.rs:21:13
  41:     0x562506af2b44 - sq_cryptoki::real_main::h144368cd99acf4cf
                               at /tmp/cryptoki/sequoia-cryptoki/tools/src/main.rs:169:11
  42:     0x562506af1b69 - sq_cryptoki::main::ha4fbf0c7d75042b3
                               at /tmp/cryptoki/sequoia-cryptoki/tools/src/main.rs:25:21
  43:     0x562506a6890b - core::ops::function::FnOnce::call_once::h10abfd2b003a13ff
                               at /rustc/4eb161250e340c8f48f66e2b929ef4a5bed7c181/library/core/src/ops/function.rs:250:5
  44:     0x562506acd61e - std::sys::backtrace::__rust_begin_short_backtrace::h2244fbeab20830e4
                               at /rustc/4eb161250e340c8f48f66e2b929ef4a5bed7c181/library/std/src/sys/backtrace.rs:152:18
  45:     0x562506af6191 - std::rt::lang_start::{{closure}}::h09212e6202408097
                               at /rustc/4eb161250e340c8f48f66e2b929ef4a5bed7c181/library/std/src/rt.rs:195:18
  46:     0x5625072feda7 - core::ops::function::impls::<impl core::ops::function::FnOnce<A> for &F>::call_once::h6889704b556d4c77
                               at /rustc/4eb161250e340c8f48f66e2b929ef4a5bed7c181/library/core/src/ops/function.rs:284:13
  47:     0x5625072feda7 - std::panicking::try::do_call::hb54df035e1ac8c92
                               at /rustc/4eb161250e340c8f48f66e2b929ef4a5bed7c181/library/std/src/panicking.rs:584:40
  48:     0x5625072feda7 - std::panicking::try::h58823af4bcc61a96
                               at /rustc/4eb161250e340c8f48f66e2b929ef4a5bed7c181/library/std/src/panicking.rs:547:19
  49:     0x5625072feda7 - std::panic::catch_unwind::hc30ff8fe04ef2371
                               at /rustc/4eb161250e340c8f48f66e2b929ef4a5bed7c181/library/std/src/panic.rs:358:14
  50:     0x5625072feda7 - std::rt::lang_start_internal::{{closure}}::h527f54f1892dcb9b
                               at /rustc/4eb161250e340c8f48f66e2b929ef4a5bed7c181/library/std/src/rt.rs:174:48
  51:     0x5625072feda7 - std::panicking::try::do_call::h41aaba5fff752501
                               at /rustc/4eb161250e340c8f48f66e2b929ef4a5bed7c181/library/std/src/panicking.rs:584:40
  52:     0x5625072feda7 - std::panicking::try::hf0596d206f5fce25
                               at /rustc/4eb161250e340c8f48f66e2b929ef4a5bed7c181/library/std/src/panicking.rs:547:19
  53:     0x5625072feda7 - std::panic::catch_unwind::h5a2061dbbb8ffdf4
                               at /rustc/4eb161250e340c8f48f66e2b929ef4a5bed7c181/library/std/src/panic.rs:358:14
  54:     0x5625072feda7 - std::rt::lang_start_internal::heee0af441e41a6d2
                               at /rustc/4eb161250e340c8f48f66e2b929ef4a5bed7c181/library/std/src/rt.rs:174:20
  55:     0x562506af616a - std::rt::lang_start::he0267f468637608e
                               at /rustc/4eb161250e340c8f48f66e2b929ef4a5bed7c181/library/std/src/rt.rs:194:17
  56:     0x562506af45ee - main
  57:     0x7f6423b43ca8 - __libc_start_call_main
                               at ./csu/../sysdeps/nptl/libc_start_call_main.h:58:16
  58:     0x7f6423b43d65 - __libc_start_main_impl
                               at ./csu/../csu/libc-start.c:360:3
  59:     0x562506a45791 - _start
  60:                0x0 - <unknown>
thread caused non-unwinding panic. aborting.
Aborted (core dumped)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions