11// Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
22// SPDX-License-Identifier: Apache-2.0
3+ //! Serialization support for primitive data types.
34#![ allow( clippy:: float_cmp) ]
45
56use self :: super :: { VersionMap , Versionize , VersionizeError , VersionizeResult } ;
67use vmm_sys_util:: fam:: { FamStruct , FamStructWrapper } ;
78
9+ /// Maximum string len in bytes (16KB).
10+ pub const MAX_STRING_LEN : usize = 16384 ;
11+ /// Maximum vec len in bytes (10MB).
12+ pub const MAX_VEC_LEN : usize = 10_485_760 ;
13+
814/// Implements the Versionize trait for primitive types that also implement
915/// serde's Serialize/Deserialize: use serde_bincode as a backend for
1016/// serialization.
@@ -60,7 +66,53 @@ impl_versionize!(u64);
6066impl_versionize ! ( f32 ) ;
6167impl_versionize ! ( f64 ) ;
6268impl_versionize ! ( char ) ;
63- impl_versionize ! ( String ) ;
69+
70+ impl Versionize for String {
71+ #[ inline]
72+ fn serialize < W : std:: io:: Write > (
73+ & self ,
74+ writer : & mut W ,
75+ version_map : & VersionMap ,
76+ app_version : u16 ,
77+ ) -> VersionizeResult < ( ) > {
78+ // It is better to fail early at serialization time.
79+ if self . len ( ) > MAX_STRING_LEN {
80+ return Err ( VersionizeError :: StringLength ( self . len ( ) ) ) ;
81+ }
82+
83+ self . len ( ) . serialize ( writer, version_map, app_version) ?;
84+ writer
85+ . write_all ( self . as_bytes ( ) )
86+ . map_err ( |e| VersionizeError :: Io ( e. raw_os_error ( ) . unwrap_or ( 0 ) ) ) ?;
87+ Ok ( ( ) )
88+ }
89+
90+ #[ inline]
91+ fn deserialize < R : std:: io:: Read > (
92+ mut reader : & mut R ,
93+ version_map : & VersionMap ,
94+ app_version : u16 ,
95+ ) -> VersionizeResult < Self > {
96+ let len = usize:: deserialize ( & mut reader, version_map, app_version) ?;
97+ // Even if we fail in serialize, we still need to enforce this on the hot path
98+ // in case the len is corrupted.
99+ if len > MAX_STRING_LEN {
100+ return Err ( VersionizeError :: StringLength ( len) ) ;
101+ }
102+
103+ let mut v = vec ! [ 0u8 ; len] ;
104+ reader
105+ . read_exact ( v. as_mut_slice ( ) )
106+ . map_err ( |e| VersionizeError :: Io ( e. raw_os_error ( ) . unwrap_or ( 0 ) ) ) ?;
107+ Ok ( String :: from_utf8 ( v)
108+ . map_err ( |err| VersionizeError :: Deserialize ( format ! ( "Utf8 error: {:?}" , err) ) ) ?)
109+ }
110+
111+ // Not used yet.
112+ fn version ( ) -> u16 {
113+ 1
114+ }
115+ }
64116
65117macro_rules! impl_versionize_array_with_size {
66118 ( $ty: literal) => {
@@ -239,15 +291,17 @@ where
239291 version_map : & VersionMap ,
240292 app_version : u16 ,
241293 ) -> VersionizeResult < ( ) > {
294+ let bytes_len = self . len ( ) * std:: mem:: size_of :: < T > ( ) ;
295+ if bytes_len > MAX_VEC_LEN {
296+ return Err ( VersionizeError :: VecLength ( bytes_len) ) ;
297+ }
242298 // Serialize in the same fashion as bincode:
243299 // Write len.
244300 bincode:: serialize_into ( & mut writer, & self . len ( ) )
245301 . map_err ( |ref err| VersionizeError :: Serialize ( format ! ( "{:?}" , err) ) ) ?;
246- // Walk the vec and write each elemenet .
302+ // Walk the vec and write each element .
247303 for element in self {
248- element
249- . serialize ( writer, version_map, app_version)
250- . map_err ( |ref err| VersionizeError :: Serialize ( format ! ( "{:?}" , err) ) ) ?;
304+ element. serialize ( writer, version_map, app_version) ?;
251305 }
252306 Ok ( ( ) )
253307 }
@@ -259,8 +313,14 @@ where
259313 app_version : u16 ,
260314 ) -> VersionizeResult < Self > {
261315 let mut v = Vec :: new ( ) ;
262- let len: u64 = bincode:: deserialize_from ( & mut reader)
316+ let len: usize = bincode:: deserialize_from ( & mut reader)
263317 . map_err ( |ref err| VersionizeError :: Deserialize ( format ! ( "{:?}" , err) ) ) ?;
318+
319+ let bytes_len = len * std:: mem:: size_of :: < T > ( ) ;
320+ if bytes_len > MAX_VEC_LEN {
321+ return Err ( VersionizeError :: VecLength ( bytes_len) ) ;
322+ }
323+
264324 for _ in 0 ..len {
265325 let element: T = T :: deserialize ( reader, version_map, app_version)
266326 . map_err ( |ref err| VersionizeError :: Deserialize ( format ! ( "{:?}" , err) ) ) ?;
@@ -935,4 +995,33 @@ mod tests {
935995 ) ;
936996 assert_eq ! ( original_values, restored_values) ;
937997 }
998+
999+ #[ test]
1000+ fn test_vec_limit ( ) {
1001+ // We need extra 8 bytes for vector len.
1002+ let mut snapshot_mem = vec ! [ 0u8 ; MAX_VEC_LEN + 8 ] ;
1003+ let err = vec ! [ 123u8 ; MAX_VEC_LEN + 1 ]
1004+ . serialize ( & mut snapshot_mem. as_mut_slice ( ) , & VersionMap :: new ( ) , 1 )
1005+ . unwrap_err ( ) ;
1006+ assert_eq ! ( err, VersionizeError :: VecLength ( MAX_VEC_LEN + 1 ) ) ;
1007+ assert_eq ! (
1008+ format!( "{}" , err) ,
1009+ "Vec length exceeded 10485761 > 10485760 bytes"
1010+ ) ;
1011+ }
1012+
1013+ #[ test]
1014+ fn test_string_limit ( ) {
1015+ // We need extra 8 bytes for string len.
1016+ let mut snapshot_mem = vec ! [ 0u8 ; MAX_STRING_LEN + 8 ] ;
1017+ let err = String :: from_utf8 ( vec ! [ 123u8 ; MAX_STRING_LEN + 1 ] )
1018+ . unwrap ( )
1019+ . serialize ( & mut snapshot_mem. as_mut_slice ( ) , & VersionMap :: new ( ) , 1 )
1020+ . unwrap_err ( ) ;
1021+ assert_eq ! ( err, VersionizeError :: StringLength ( MAX_STRING_LEN + 1 ) ) ;
1022+ assert_eq ! (
1023+ format!( "{}" , err) ,
1024+ "String length exceeded 16385 > 16384 bytes"
1025+ ) ;
1026+ }
9381027}
0 commit comments