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

Missing facts due to not modeling memset #11

Open
langston-barrett opened this issue Aug 11, 2022 · 1 comment
Open

Missing facts due to not modeling memset #11

langston-barrett opened this issue Aug 11, 2022 · 1 comment
Labels
bug/unsoundness The analysis is unsound, i.e., missing points-to facts

Comments

@langston-barrett
Copy link
Collaborator

langston-barrett commented Aug 11, 2022

#include <stdlib.h>
#include <string.h>
#include <stdio.h>

typedef struct s {
  char **z;
  int y;
} s;

char glob = 'c';

char **__attribute__((noinline)) get(s *x) {
  printf("Don't inline me, please! %p\n", x);
  return &x[1].z[0];
}

int main() {
  s x[2] = {0};
  char **u = get(x); // points to x[1].z[0]
  return *x[1].z[0];
}
%struct.s = type { i8**, i32 }

@glob = dso_local local_unnamed_addr global i8 99, align 1
@.str = private unnamed_addr constant [29 x i8] c"Don't inline me, please! %p\0A\00", align 1

; Function Attrs: noinline nounwind uwtable
define dso_local i8** @get(%struct.s*) local_unnamed_addr #0 {
  %2 = tail call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([29 x i8], [29 x i8]* @.str, i64 0, i64 0), %struct.s* %0)
  %3 = getelementptr inbounds %struct.s, %struct.s* %0, i64 1, i32 0
  %4 = load i8**, i8*** %3, align 8, !tbaa !2
  ret i8** %4
}

; Function Attrs: nounwind
declare dso_local i32 @printf(i8* nocapture readonly, ...) local_unnamed_addr #1

; Function Attrs: nounwind uwtable
define dso_local i32 @main() local_unnamed_addr #2 {
  %1 = alloca [2 x %struct.s], align 16
  %2 = bitcast [2 x %struct.s]* %1 to i8*
  call void @llvm.lifetime.start.p0i8(i64 32, i8* nonnull %2) #4
  call void @llvm.memset.p0i8.i64(i8* nonnull align 16 %2, i8 0, i64 32, i1 false)
  %3 = getelementptr inbounds [2 x %struct.s], [2 x %struct.s]* %1, i64 0, i64 0
  %4 = call i8** @get(%struct.s* nonnull %3)
  %5 = getelementptr inbounds [2 x %struct.s], [2 x %struct.s]* %1, i64 0, i64 1, i32 0
  %6 = load i8**, i8*** %5, align 16, !tbaa !2
  %7 = load i8*, i8** %6, align 8, !tbaa !8
  %8 = load i8, i8* %7, align 1, !tbaa !9
  %9 = sext i8 %8 to i32
  call void @llvm.lifetime.end.p0i8(i64 32, i8* nonnull %2) #4
  ret i32 %9
}

Both @get:%4 and @main:%4 should point to x[1].z[0] (i.e., *null*), but they don't point to anything:

[<<main-context>>, nil]	*stack_alloc@main[[2 x %struct.s]* %1]	[<<main-context>>, nil]	</mate/out.ll>:get:%0
[<<main-context>>, nil]	*stack_alloc@main[[2 x %struct.s]* %1][0]	[<<main-context>>, nil]	</mate/out.ll>:get:%0
[<<main-context>>, nil]	*stack_alloc@main[[2 x %struct.s]* %1][0][0]	[<<main-context>>, nil]	</mate/out.ll>:get:%0
[<<main-context>>, nil]	*stack_alloc@main[[2 x %struct.s]* %1]	[<<main-context>>, nil]	</mate/out.ll>:main:%1
[<<main-context>>, nil]	*stack_alloc@main[[2 x %struct.s]* %1][1]	[<<main-context>>, nil]	</mate/out.ll>:get:%3
[<<main-context>>, nil]	*stack_alloc@main[[2 x %struct.s]* %1][1].?/0	[<<main-context>>, nil]	</mate/out.ll>:get:%3
[<<main-context>>, nil]	*stack_alloc@main[[2 x %struct.s]* %1][0][1]	[<<main-context>>, nil]	</mate/out.ll>:get:%3
[<<main-context>>, nil]	*stack_alloc@main[[2 x %struct.s]* %1][0][1].?/0	[<<main-context>>, nil]	</mate/out.ll>:get:%3
[<<main-context>>, nil]	*stack_alloc@main[[2 x %struct.s]* %1][1]	[<<main-context>>, nil]	</mate/out.ll>:main:%5
[<<main-context>>, nil]	*stack_alloc@main[[2 x %struct.s]* %1][1].?/0	[<<main-context>>, nil]	</mate/out.ll>:main:%5
[<<main-context>>, nil]	*stack_alloc@main[[2 x %struct.s]* %1][0][1]	[<<main-context>>, nil]	</mate/out.ll>:main:%5
[<<main-context>>, nil]	*stack_alloc@main[[2 x %struct.s]* %1][0][1].?/0	[<<main-context>>, nil]	</mate/out.ll>:main:%5
[<<main-context>>, nil]	*stack_alloc@main[[2 x %struct.s]* %1]	[<<main-context>>, nil]	</mate/out.ll>:main:%3
[<<main-context>>, nil]	*stack_alloc@main[[2 x %struct.s]* %1][0]	[<<main-context>>, nil]	</mate/out.ll>:main:%3
[<<main-context>>, nil]	*stack_alloc@main[[2 x %struct.s]* %1][0][0]	[<<main-context>>, nil]	</mate/out.ll>:main:%3
[<<main-context>>, nil]	*stack_alloc@main[[2 x %struct.s]* %1]	[<<main-context>>, nil]	</mate/out.ll>:main:%2
@langston-barrett langston-barrett added the bug/unsoundness The analysis is unsound, i.e., missing points-to facts label Aug 11, 2022
@langston-barrett
Copy link
Collaborator Author

While this is labeled "unsoundness", it's only concerning a points-to fact involving null, which may or may not be a big deal depending on the use-case.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug/unsoundness The analysis is unsound, i.e., missing points-to facts
Projects
None yet
Development

No branches or pull requests

1 participant