|
1 | 1 | use crate::common::jobs::{HashAlgorithm, Request, Response};
|
2 | 2 | use crate::hsm::keystore::{Curve, KeyId};
|
3 | 3 | use crate::integration::raw_errors::JobErrorRaw;
|
4 |
| -use core::mem::offset_of; |
| 4 | +use core::mem::{offset_of, MaybeUninit}; |
5 | 5 | use core::slice;
|
6 | 6 | use strum::EnumCount;
|
7 | 7 |
|
@@ -475,16 +475,31 @@ impl RequestRaw {
|
475 | 475 | /// valid `RequestRaw` instance.
|
476 | 476 | ///
|
477 | 477 | pub unsafe fn from_raw(ptr: *const u8) -> Result<Self, ValidationError> {
|
| 478 | + // We create a copy of the untrusted request on the stack to prevent a potential |
| 479 | + // point-of-check/point-of-use issue |
| 480 | + let mut request: MaybeUninit<RequestRaw> = MaybeUninit::uninit(); |
| 481 | + |
478 | 482 | // SAFETY: Pointer and size must be checked by integrator
|
479 |
| - let tag: u8 = unsafe { *(ptr.add(offset_of!(RequestRaw, data))) }; |
| 483 | + unsafe { |
| 484 | + core::ptr::copy(ptr.cast(), request.as_mut_ptr(), 1); |
| 485 | + } |
| 486 | + |
| 487 | + // SAFETY: request is of type RequestRaw, so adding the offset of a field of such a struct |
| 488 | + // still falls under the object behind the pointer |
| 489 | + let tag: u8 = unsafe { |
| 490 | + *(request |
| 491 | + .as_ptr() |
| 492 | + .cast::<u8>() |
| 493 | + .add(offset_of!(RequestRaw, data))) |
| 494 | + }; |
480 | 495 |
|
481 | 496 | // Validate tag value. Invalid tag values cause UB when transmuted into an enum.
|
482 | 497 | if tag >= RequestDataRaw::COUNT as u8 {
|
483 | 498 | return Err(ValidationError::InvalidTagValue);
|
484 | 499 | }
|
485 | 500 |
|
486 |
| - // SAFETY: All members of RequestRaw are valid for all possible values found in memory |
487 |
| - Ok(*ptr.cast::<RequestRaw>()) |
| 501 | + // SAFETY: Besides the tag, which we checked, all other members are ok with any value |
| 502 | + Ok(unsafe { request.assume_init() }) |
488 | 503 | }
|
489 | 504 |
|
490 | 505 | pub fn verify<'data>(
|
@@ -1701,16 +1716,31 @@ impl ResponseRaw {
|
1701 | 1716 | /// valid `ResponseRaw` instance.
|
1702 | 1717 | ///
|
1703 | 1718 | pub unsafe fn from_raw(ptr: *const u8) -> Result<Self, ValidationError> {
|
| 1719 | + // We create a copy of the untrusted response on the stack to prevent a potential |
| 1720 | + // point-of-check/point-of-use issue |
| 1721 | + let mut response: MaybeUninit<ResponseRaw> = MaybeUninit::uninit(); |
| 1722 | + |
1704 | 1723 | // SAFETY: Pointer and size must be checked by integrator
|
1705 |
| - let tag: u8 = unsafe { *(ptr.add(offset_of!(RequestRaw, data))) }; |
| 1724 | + unsafe { |
| 1725 | + core::ptr::copy(ptr.cast(), response.as_mut_ptr(), 1); |
| 1726 | + } |
| 1727 | + |
| 1728 | + // SAFETY: response is of type ResponseRaw, so adding the offset of a field of such a struct |
| 1729 | + // still falls under the object behind the pointer |
| 1730 | + let tag: u8 = unsafe { |
| 1731 | + *(response |
| 1732 | + .as_ptr() |
| 1733 | + .cast::<u8>() |
| 1734 | + .add(offset_of!(ResponseRaw, data))) |
| 1735 | + }; |
1706 | 1736 |
|
1707 | 1737 | // Validate tag value. Invalid tag values cause UB when transmuted into an enum.
|
1708 | 1738 | if tag >= ResponseDataRaw::COUNT as u8 {
|
1709 | 1739 | return Err(ValidationError::InvalidTagValue);
|
1710 | 1740 | }
|
1711 | 1741 |
|
1712 |
| - // SAFETY: All members of RequestRaw are valid for all possible values found in memory |
1713 |
| - Ok(*ptr.cast::<ResponseRaw>()) |
| 1742 | + // SAFETY: Besides the tag, which we checked, all other members are ok with any value |
| 1743 | + Ok(unsafe { response.assume_init() }) |
1714 | 1744 | }
|
1715 | 1745 | }
|
1716 | 1746 |
|
|
0 commit comments