1
1
// Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
2
2
// SPDX-License-Identifier: Apache-2.0
3
+ //! Serialization support for primitive data types.
3
4
#![ allow( clippy:: float_cmp) ]
4
5
5
6
use self :: super :: { VersionMap , Versionize , VersionizeError , VersionizeResult } ;
6
7
use vmm_sys_util:: fam:: { FamStruct , FamStructWrapper } ;
7
8
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
+
8
14
/// Implements the Versionize trait for primitive types that also implement
9
15
/// serde's Serialize/Deserialize: use serde_bincode as a backend for
10
16
/// serialization.
@@ -60,7 +66,53 @@ impl_versionize!(u64);
60
66
impl_versionize ! ( f32 ) ;
61
67
impl_versionize ! ( f64 ) ;
62
68
impl_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
+ }
64
116
65
117
macro_rules! impl_versionize_array_with_size {
66
118
( $ty: literal) => {
@@ -239,15 +291,17 @@ where
239
291
version_map : & VersionMap ,
240
292
app_version : u16 ,
241
293
) -> 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
+ }
242
298
// Serialize in the same fashion as bincode:
243
299
// Write len.
244
300
bincode:: serialize_into ( & mut writer, & self . len ( ) )
245
301
. map_err ( |ref err| VersionizeError :: Serialize ( format ! ( "{:?}" , err) ) ) ?;
246
- // Walk the vec and write each elemenet .
302
+ // Walk the vec and write each element .
247
303
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) ?;
251
305
}
252
306
Ok ( ( ) )
253
307
}
@@ -259,8 +313,14 @@ where
259
313
app_version : u16 ,
260
314
) -> VersionizeResult < Self > {
261
315
let mut v = Vec :: new ( ) ;
262
- let len: u64 = bincode:: deserialize_from ( & mut reader)
316
+ let len: usize = bincode:: deserialize_from ( & mut reader)
263
317
. 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
+
264
324
for _ in 0 ..len {
265
325
let element: T = T :: deserialize ( reader, version_map, app_version)
266
326
. map_err ( |ref err| VersionizeError :: Deserialize ( format ! ( "{:?}" , err) ) ) ?;
@@ -935,4 +995,33 @@ mod tests {
935
995
) ;
936
996
assert_eq ! ( original_values, restored_values) ;
937
997
}
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
+ }
938
1027
}
0 commit comments