SVF
SVF copied to clipboard
some questions about complex nested struct
; LLVM 16.0.6
; generate from openssl/ssl/statem/statem_srvr.c
; s->s3.alpn_selected = OPENSSL_memdup(selected, selected_len);
; if (s->s3.alpn_selected == NULL) {
%183 = call noalias ptr @CRYPTO_memdup(ptr noundef %178, i64 noundef %182, ptr noundef @.str.1, i32 noundef 4234), !dbg !4741
%184 = load ptr, ptr %3, align 8, !dbg !4742
%185 = getelementptr inbounds %struct.ssl_connection_st, ptr %184, i32 0, i32 50, !dbg !4743
%186 = load ptr, ptr %185, align 8, !dbg !4743
%187 = getelementptr inbounds %struct.ssl_session_st, ptr %186, i32 0, i32 26, !dbg !4744
%188 = getelementptr inbounds %struct.anon, ptr %187, i32 0, i32 6, !dbg !4745
store ptr %183, ptr %188, align 8, !dbg !4746
%189 = load ptr, ptr %3, align 8, !dbg !4747
%190 = getelementptr inbounds %struct.ssl_connection_st, ptr %189, i32 0, i32 50, !dbg !4749
%191 = load ptr, ptr %190, align 8, !dbg !4749
%192 = getelementptr inbounds %struct.ssl_session_st, ptr %191, i32 0, i32 26, !dbg !4750
%193 = getelementptr inbounds %struct.anon, ptr %192, i32 0, i32 6, !dbg !4751
%194 = load ptr, ptr %193, align 8, !dbg !4751
%195 = icmp eq ptr %194, null, !dbg !4752
br i1 %195, label %196, label %203, !dbg !4753
When I traverse the function's return value (%183) along svfg, it faild, here are the nodes on the graph.
ActualRetVFGNode ID: 10114 CS[{ "ln": 4234, "cl": 17, "fl": "../ssl/statem/statem_srvr.c" }]ValVar ID: 4735
%183 = call noalias ptr @CRYPTO_memdup(ptr noundef %178, i64 noundef %182, ptr noundef @.str.1, i32 noundef 4234), !dbg !2168 { "ln": 4234, "cl": 17, "fl": "../ssl/statem/statem_srvr.c" }
StoreVFGNode ID: 6584 StoreStmt: [Var4743 <-- Var4735]
store ptr %183, ptr %188, align 8, !dbg !2173 { "ln": 4233, "cl": 43, "fl": "../ssl/statem/statem_srvr.c" }
I expect to be able to get the load node (%194) after the store node.
By the way, is there an option to print a partial svfg plot, even if I select the smallest bitcode, the generated svfg is still very large.
I don't have your c example and your bc is incomplete. But from your bc code fragment. %183 and %194 are not aliases. The store (store ptr %183, ptr %188) should not be connected to the load %194.
In my view, %183 and %194 are aliases. Anyway, I find a similar issue #340. This is caused by missing a call
of target function
.
Here are the c code reconstructed by GPT.
extern char* CRYPTO_memdup(char*, int);
struct anon
{
char* data;
};
struct anon2
{
char* data;
int len;
};
struct ssl_session_st
{
struct anon* tlsext_tick;
};
struct ssl_connection_st
{
struct anon2* misc;
struct ssl_session_st* session;
};
void test(struct ssl_connection_st* ssl)
{
ssl->session->tlsext_tick->data =
CRYPTO_memdup(ssl->misc->data, ssl->misc->len);
if (!ssl->session->tlsext_tick->data)
{
}
}
If I add a call of test
, it works.
void test_driver()
{
struct anon anon;
struct anon2 anon2;
struct ssl_session_st session = {.tlsext_tick = &anon};
struct ssl_connection_st ssl = {.misc = &anon2, .session = &session};
test(&ssl);
}
The value flow of CRYPTO_memdup
belows:
ActualRetVFGNode ID: 120 CS[{ "ln": 56, "cl": 9, "fl": "demo.c" }]ValVar ID: 24
%13 = call ptr @CRYPTO_memdup(ptr noundef %7, i32 noundef %12), !dbg !43 { "ln": 56, "cl": 9, "fl": "demo.c" }
StoreVFGNode ID: 85 StoreStmt: [Var32 <-- Var24]
store ptr %13, ptr %19, align 8, !dbg !48 { "ln": 55, "cl": 37, "fl": "demo.c" }
LoadVFGNode ID: 69 LoadStmt: [Var40 <-- Var39]
%26 = load ptr, ptr %25, align 8, !dbg !53 { "ln": 57, "cl": 37, "fl": "demo.c" }
FormalOUTSVFGNode ID: 196 {fun: test}RETMU(36V_2)
pts{212 }
CmpVFGNode ID: 134 PAGEdge: [41 = cmp(0, 40, )]
%27 = icmp ne ptr %26, null, !dbg !49 { "ln": 57, "cl": 10, "fl": "demo.c" }
ActualOUTSVFGNode ID: 208 at callsite: call void @test(ptr noundef %4), !dbg !44 { "ln": 68, "cl": 5, "fl": "demo.c" } {fun: test_driver}36V_2 = CSCHI(MR_36V_2)
pts{212 }
CS[{ "ln": 68, "cl": 5, "fl": "demo.c" }]
BranchVFGNode ID: 129 PAGEdge: [BranchStmt: [Condition Var41]
Successor 0 ICFGNode32 Successor 1 ICFGNode33
br i1 %27, label %29, label %28, !dbg !54 { "ln": 57, "cl": 9, "fl": "demo.c" }
I think this is not good for analyzing libraries, it is not possible to write a driver for each library function. Is there any better way?