Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add out-of-bounds check for memset and memcpy #1197

Merged
merged 23 commits into from
Oct 1, 2023
Merged
Show file tree
Hide file tree
Changes from 22 commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
f0c73c5
Add support for 3rd param of memcpy
mrstanb Sep 27, 2023
a2c99ad
Merge branch 'master' into memset-memcpy-size-check
mrstanb Sep 29, 2023
6e7c00e
Add out-of-bounds check for memset and memcpy
mrstanb Sep 29, 2023
5ed769f
Add regr. test case for memset and memcpy out-of-bounds
mrstanb Sep 29, 2023
12bee27
Add temporary fix for failing MacOS CI job
mrstanb Sep 29, 2023
391c6ce
Change memset/memcpy count warning from must to may
mrstanb Sep 29, 2023
fae7256
Use ID.lt to compare dest size with count
mrstanb Sep 29, 2023
655362e
Use join to combine all points-to elements sizes
mrstanb Sep 29, 2023
2534945
Do not ingore offsets when calling BlobSize for memset/memcpy
mrstanb Sep 29, 2023
033913b
Change name to get_size_of_dest which makes more sense
mrstanb Sep 29, 2023
4ec9895
Add exception handling for ID operations
mrstanb Sep 29, 2023
1e69b64
Fix wrong name use
mrstanb Sep 29, 2023
49dcac9
Fix incompatible ikinds
mrstanb Sep 29, 2023
87dadd2
Add more and more sophisticated memset and memcpy tests
mrstanb Sep 30, 2023
9e9b5e3
Add memset/memcpy test case with arrays
mrstanb Sep 30, 2023
5ca357d
Fix some bugs in memOutOfBounds and move memset/memcpy checks there
mrstanb Oct 1, 2023
8bf3705
Remove unused function
mrstanb Oct 1, 2023
3027910
Add further exception handling
mrstanb Oct 1, 2023
62b20a2
Add further memset/memcpy test
mrstanb Oct 1, 2023
5e683d4
Fix comment
mrstanb Oct 1, 2023
f03f81f
Remove some bot checks for ID arithmetic
mrstanb Oct 1, 2023
3da9205
Use size_of_type_in_bytes where possible
mrstanb Oct 1, 2023
89abb1a
Keep TODO about count of memset in base.ml
mrstanb Oct 1, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/analyses/base.ml
Original file line number Diff line number Diff line change
Expand Up @@ -2026,6 +2026,7 @@ struct
M.warn ~category:(Behavior (Undefined InvalidMemoryDeallocation)) ~tags:[CWE 761] "Free of memory not at start of buffer in function %s for pointer %a" special_fn.vname d_exp ptr
| _ -> M.warn ~category:MessageCategory.Analyzer "Pointer %a in function %s doesn't evaluate to a valid address." d_exp ptr special_fn.vname


let special ctx (lv:lval option) (f: varinfo) (args: exp list) =
let invalidate_ret_lv st = match lv with
| Some lv ->
Expand Down Expand Up @@ -2093,7 +2094,6 @@ struct
in
let st = match desc.special args, f.vname with
| Memset { dest; ch; count; }, _ ->
(* TODO: check count *)
mrstanb marked this conversation as resolved.
Show resolved Hide resolved
let eval_ch = eval_rv (Analyses.ask_of_ctx ctx) gs st ch in
let dest_a, dest_typ = addr_type_of_exp dest in
let value =
Expand All @@ -2110,7 +2110,7 @@ struct
let dest_a, dest_typ = addr_type_of_exp dest in
let value = VD.zero_init_value dest_typ in
set ~ctx (Analyses.ask_of_ctx ctx) gs st dest_a dest_typ value
| Memcpy { dest = dst; src }, _ ->
| Memcpy { dest = dst; src; n; }, _ ->
memory_copying dst src
(* strcpy(dest, src); *)
| Strcpy { dest = dst; src; n = None }, _ ->
Expand Down
2 changes: 1 addition & 1 deletion src/analyses/libraryDesc.ml
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ type special =
| Math of { fun_args: math; }
| Memset of { dest: Cil.exp; ch: Cil.exp; count: Cil.exp; }
| Bzero of { dest: Cil.exp; count: Cil.exp; }
| Memcpy of { dest: Cil.exp; src: Cil.exp }
| Memcpy of { dest: Cil.exp; src: Cil.exp; n: Cil.exp; }
| Strcpy of { dest: Cil.exp; src: Cil.exp; n: Cil.exp option; }
| Strcat of { dest: Cil.exp; src: Cil.exp; n: Cil.exp option; }
| Strlen of Cil.exp
Expand Down
18 changes: 9 additions & 9 deletions src/analyses/libraryFunctions.ml
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,13 @@ let c_descs_list: (string * LibraryDesc.t) list = LibraryDsl.[
("memset", special [__ "dest" [w]; __ "ch" []; __ "count" []] @@ fun dest ch count -> Memset { dest; ch; count; });
("__builtin_memset", special [__ "dest" [w]; __ "ch" []; __ "count" []] @@ fun dest ch count -> Memset { dest; ch; count; });
("__builtin___memset_chk", special [__ "dest" [w]; __ "ch" []; __ "count" []; drop "os" []] @@ fun dest ch count -> Memset { dest; ch; count; });
("memcpy", special [__ "dest" [w]; __ "src" [r]; drop "n" []] @@ fun dest src -> Memcpy { dest; src }); (* TODO: use n *)
("__builtin_memcpy", special [__ "dest" [w]; __ "src" [r]; drop "n" []] @@ fun dest src -> Memcpy { dest; src });
("__builtin___memcpy_chk", special [__ "dest" [w]; __ "src" [r]; drop "n" []; drop "os" []] @@ fun dest src -> Memcpy { dest; src });
("memccpy", special [__ "dest" [w]; __ "src" [r]; drop "c" []; drop "n" []] @@ fun dest src -> Memcpy {dest; src}); (* C23 *) (* TODO: use n and c *)
("memmove", special [__ "dest" [w]; __ "src" [r]; drop "count" []] @@ fun dest src -> Memcpy { dest; src });
("__builtin_memmove", special [__ "dest" [w]; __ "src" [r]; drop "count" []] @@ fun dest src -> Memcpy { dest; src });
("__builtin___memmove_chk", special [__ "dest" [w]; __ "src" [r]; drop "count" []; drop "os" []] @@ fun dest src -> Memcpy { dest; src });
("memcpy", special [__ "dest" [w]; __ "src" [r]; __ "n" []] @@ fun dest src n -> Memcpy { dest; src; n; });
("__builtin_memcpy", special [__ "dest" [w]; __ "src" [r]; __ "n" []] @@ fun dest src n -> Memcpy { dest; src; n; });
("__builtin___memcpy_chk", special [__ "dest" [w]; __ "src" [r]; __ "n" []; drop "os" []] @@ fun dest src n -> Memcpy { dest; src; n; });
("memccpy", special [__ "dest" [w]; __ "src" [r]; drop "c" []; __ "n" []] @@ fun dest src n -> Memcpy {dest; src; n; }); (* C23 *) (* TODO: use c *)
("memmove", special [__ "dest" [w]; __ "src" [r]; __ "count" []] @@ fun dest src count -> Memcpy { dest; src; n = count; });
("__builtin_memmove", special [__ "dest" [w]; __ "src" [r]; __ "count" []] @@ fun dest src count -> Memcpy { dest; src; n = count; });
("__builtin___memmove_chk", special [__ "dest" [w]; __ "src" [r]; __ "count" []; drop "os" []] @@ fun dest src count -> Memcpy { dest; src; n = count; });
("strcpy", special [__ "dest" [w]; __ "src" [r]] @@ fun dest src -> Strcpy { dest; src; n = None; });
("__builtin_strcpy", special [__ "dest" [w]; __ "src" [r]] @@ fun dest src -> Strcpy { dest; src; n = None; });
("__builtin___strcpy_chk", special [__ "dest" [w]; __ "src" [r]; drop "os" []] @@ fun dest src -> Strcpy { dest; src; n = None; });
Expand Down Expand Up @@ -479,8 +479,8 @@ let glibc_desc_list: (string * LibraryDesc.t) list = LibraryDsl.[
("strcasestr", unknown [drop "haystack" [r]; drop "needle" [r]]);
("inet_aton", unknown [drop "cp" [r]; drop "inp" [w]]);
("fopencookie", unknown [drop "cookie" []; drop "mode" [r]; drop "io_funcs" [s_deep]]); (* doesn't access cookie but passes it to io_funcs *)
("mempcpy", special [__ "dest" [w]; __ "src" [r]; drop "n" []] @@ fun dest src -> Memcpy { dest; src });
("__builtin___mempcpy_chk", special [__ "dest" [w]; __ "src" [r]; drop "n" []; drop "os" []] @@ fun dest src -> Memcpy { dest; src });
("mempcpy", special [__ "dest" [w]; __ "src" [r]; __ "n" []] @@ fun dest src n -> Memcpy { dest; src; n; });
("__builtin___mempcpy_chk", special [__ "dest" [w]; __ "src" [r]; __ "n" []; drop "os" []] @@ fun dest src n -> Memcpy { dest; src; n; });
("rawmemchr", unknown [drop "s" [r]; drop "c" []]);
("memrchr", unknown [drop "s" [r]; drop "c" []; drop "n" []]);
("memmem", unknown [drop "haystack" [r]; drop "haystacklen" []; drop "needle" [r]; drop "needlelen" [r]]);
Expand Down
Loading