-
Notifications
You must be signed in to change notification settings - Fork 107
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fix: insert critical overflow checks preventing heap corruption (#3077)
Fixes two classes of `u32`-undetected overflow bugs that could corrupt heap, stable variables, or both: * ic.rs: `alloc_words` wasn't checking validity of addresses, leading to possible (and observed) heap corruption. * compile.ml: `buffer_size` wasn't checking overflow of 32-bit size pre-computation. The first is fixed using an overflow detecting add function of Rust. The second is checked by using a local `i64` in each type-directed size function. These functions are MV and return two `i32`s (for the data buffer and (vestigial) reference buffer sizes. I did not modify the functions to return 2 `i64`s because our MultiValue emulation only support `i32` at the moment. Fixes #3068.
- Loading branch information
Showing
19 changed files
with
245 additions
and
7 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
// test incremental oom by allocating 5 GB, one GB at a time! | ||
import P "mo:⛔"; | ||
actor { | ||
|
||
var c = 5; | ||
|
||
while(c > 0) { | ||
let a : [var Nat8] = P.Array_init<Nat8>(1024*1024*1024/4, 0xFF); | ||
c -= 1; | ||
}; | ||
|
||
} | ||
|
||
//SKIP run | ||
//SKIP run-low | ||
//SKIP run-ir | ||
// too slow on ic-ref-run: | ||
//SKIP comp-ref | ||
// too resource heavy on GH: | ||
//SKIP comp | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
ingress Completed: Reply: 0x4449444c016c01b3c4b1f204680100010a00000000000000000101 | ||
ingress Completed: Reply: 0x4449444c0000 | ||
Err: IC0503: Canister rwlgt-iiaaa-aaaaa-aaaaa-cai trapped explicitly: RTS error: Out of memory |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
ingress Completed: Reply: 0x4449444c016c01b3c4b1f204680100010a00000000000000000101 | ||
ingress Completed: Reply: 0x4449444c0000 | ||
Err: IC0503: Canister rwlgt-iiaaa-aaaaa-aaaaa-cai trapped explicitly: RTS error: Out of memory |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
ingress Completed: Reply: 0x4449444c016c01b3c4b1f204680100010a00000000000000000101 | ||
ingress Completed: Reply: 0x4449444c0000 | ||
Err: IC0503: Canister rwlgt-iiaaa-aaaaa-aaaaa-cai trapped explicitly: buffer_size overflow | ||
Err: IC0503: Canister rwlgt-iiaaa-aaaaa-aaaaa-cai trapped explicitly: buffer_size overflow |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
→ update create_canister(record {settings = null}) | ||
← replied: (record {hymijyo = principal "cvccv-qqaaq-aaaaa-aaaaa-c"}) | ||
→ update install_code(record {arg = blob ""; kca_xin = blob "\00asm\01\00\00\00\0… | ||
← replied: () | ||
→ query overflow() | ||
← rejected (RC_CANISTER_ERROR): canister trapped: EvalTrapError region:0xXXX-0xXXX "canister trapped explicitly: buffer_size overflow" | ||
→ query overflowOpt() | ||
← rejected (RC_CANISTER_ERROR): canister trapped: EvalTrapError region:0xXXX-0xXXX "canister trapped explicitly: buffer_size overflow" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
ingress Completed: Reply: 0x4449444c016c01b3c4b1f204680100010a00000000000000000101 | ||
ingress Completed: Reply: 0x4449444c0000 | ||
debug.print: upgrading... | ||
ingress Err: IC0503: Canister rwlgt-iiaaa-aaaaa-aaaaa-cai trapped explicitly: buffer_size overflow |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
→ update create_canister(record {settings = null}) | ||
← replied: (record {hymijyo = principal "cvccv-qqaaq-aaaaa-aaaaa-c"}) | ||
→ update install_code(record {arg = blob ""; kca_xin = blob "\00asm\01\00\00\00\0… | ||
← replied: () | ||
→ update install_code(record {arg = blob ""; kca_xin = blob "\00asm\01\00\00\00\0… | ||
debug.print: upgrading... | ||
← rejected (RC_CANISTER_ERROR): Pre-upgrade trapped: EvalTrapError region:0xXXX-0xXXX "canister trapped explicitly: buffer_size overflow" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
// test incremental oom | ||
import P "mo:⛔"; | ||
actor { | ||
|
||
public query func go() : async () { | ||
// allocate 3GB | ||
var c = 3; | ||
while(c > 0) { | ||
let a : [var Nat8] = P.Array_init<Nat8>(1024*1024*1024/4, 0xFF); | ||
c -= 1; | ||
}; | ||
|
||
// allocate 1GB in 1k chunks and trigger Oom | ||
var d = 1024*1024; | ||
while(d > 0) { | ||
let a : [var Nat8] = P.Array_init<Nat8>(1024/4, 0xFF); | ||
d -= 1; | ||
}; | ||
} | ||
} | ||
|
||
//SKIP run | ||
//SKIP run-low | ||
//SKIP run-ir | ||
// too slow on ic-ref-run: | ||
//SKIP comp-ref | ||
|
||
//CALL query go "DIDL\x00\x00" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
// test incremental oom | ||
import P "mo:⛔"; | ||
actor { | ||
|
||
public query func go() : async () { | ||
// allocate 3GB | ||
var c = 3; | ||
while(c > 0) { | ||
let a : [var Nat8] = P.Array_init<Nat8>(1024*1024*1024/4, 0xFF); | ||
c -= 1; | ||
}; | ||
|
||
// allocate 1GB in 1k chunks and trigger Oom | ||
var d = 1024*1024; | ||
while(d > 0) { | ||
let a : [var Nat8] = P.Array_init<Nat8>(1024/4, 0xFF); | ||
d -= 1; | ||
}; | ||
|
||
} | ||
} | ||
|
||
//SKIP run | ||
//SKIP run-low | ||
//SKIP run-ir | ||
// too slow on ic-ref-run: | ||
//SKIP comp-ref | ||
//CALL query go "DIDL\x00\x00" | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
import P "mo:⛔"; | ||
import SM "stable-mem/StableMemory"; | ||
|
||
// Our users may not thank us that we only preserve sharing for mutable data, but nothing else. | ||
actor { | ||
|
||
ignore SM.grow(1); | ||
|
||
let page : Blob = SM.loadBlob(0,65536); | ||
assert (page.size() == 65536); | ||
|
||
public query func overflow() : async [Blob] { | ||
P.Array_tabulate<Blob>(65536,func _ { page }); | ||
}; | ||
|
||
public query func overflowOpt() : async (?[Blob]){ | ||
? P.Array_tabulate<Blob>(65536,func _ { page }); | ||
}; | ||
|
||
} | ||
|
||
//SKIP run | ||
//SKIP run-low | ||
//SKIP run-ir | ||
|
||
//OR-CALL query overflow "DIDL\x00\x00" | ||
//OR-CALL query overflowOpt "DIDL\x00\x00" | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
import P "mo:⛔"; | ||
import SM "stable-mem/StableMemory"; | ||
|
||
actor { | ||
|
||
ignore SM.grow(1); | ||
|
||
let page : Blob = SM.loadBlob(0,65536); | ||
assert (page.size() == 65536); | ||
|
||
stable | ||
let a : [Blob] = P.Array_tabulate<Blob>(65536,func _ { page }); | ||
|
||
system func preupgrade() { | ||
P.debugPrint("upgrading..."); | ||
}; | ||
} | ||
|
||
//SKIP run | ||
//SKIP run-low | ||
//SKIP run-ir | ||
|
||
//CALL upgrade "" | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
import P "mo:⛔"; | ||
|
||
actor { | ||
stable var a : [Nat] = P.Array_tabulate<Nat>(268435456 / 4, func _ { 0x0F } ); // 0.25 GB array (I think) | ||
|
||
system func preupgrade() { P.debugPrint("pre"); }; | ||
|
||
system func postupgrade() { P.debugPrint("post"); } | ||
} | ||
|
||
//SKIP run | ||
//SKIP run-low | ||
//SKIP run-ir | ||
// too slow on ic-ref-run: | ||
//SKIP comp-ref | ||
// too resource heavy on GH: | ||
//SKIP comp | ||
|
||
//CALL upgrade "" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
import P "mo:⛔"; | ||
|
||
actor { | ||
stable var a : [var Nat] = P.Array_init(268435456 / 4, 0x0F); // 0.25 GB array (I think) | ||
|
||
system func preupgrade() { P.debugPrint("pre"); }; | ||
|
||
system func postupgrade() { P.debugPrint("post"); } | ||
} | ||
|
||
//SKIP run | ||
//SKIP run-low | ||
//SKIP run-ir | ||
// too slow on ic-ref-run: | ||
//SKIP comp-ref | ||
// too resource heavy on GH: | ||
//SKIP comp | ||
|
||
//CALL upgrade "" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
// test incremental oom by allocating 5 GB, one GB at a time | ||
import P "mo:⛔"; | ||
do { | ||
|
||
var c = 5; | ||
|
||
while(c > 0) { | ||
let a : [var Nat8] = P.Array_init<Nat8>(1024*1024*1024/4, 0xFF); | ||
c -= 1; | ||
}; | ||
|
||
} | ||
|
||
//SKIP run | ||
//SKIP run-low | ||
//SKIP run-ir | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
RTS error: Out of memory |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
Return code 134 |