CodeQL / Analyze (actions) (push) Canceled after 0s
CodeQL / Analyze (python) (push) Canceled after 0s
pre-commit / pre-commit (push) Canceled after 0s
Multi-Arch CI / setup (push) Canceled after 0s
Publish build_manylinux_x86_64 images / publish_build_manylinux_x86_64 (push) Canceled after 0s
Setup (Multi-Arch) / setup (push) Canceled after 0s
Multi-Arch CI / Linux::${{ fromJSON(needs.setup.outputs.linux_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubi10 image / publish_no_rocm_image_ubi10 (push) Canceled after 0s
Multi-Arch CI / Windows::${{ fromJSON(needs.setup.outputs.windows_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Multi-Arch CI / Manifest Diff (push) Canceled after 0s
TheRock Manifest Diff Report / Generate Manifest Diff Report (push) Canceled after 0s
Multi-Arch CI / CI Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_ocl_rt images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_rocgdb images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Unit Tests / Unit Tests :: ubuntu-24.04 (push) Canceled after 0s
Unit Tests / Unit Tests :: windows-2022 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_media (push) Canceled after 0s
Unit Tests / Unit Tests Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_openmpi (push) Canceled after 0s
333 lines
8.7 KiB
C
333 lines
8.7 KiB
C
// RUN: %clang_analyze_cc1 \
|
|
// RUN: -analyzer-checker=security.cert.env.InvalidPtr\
|
|
// RUN: -analyzer-config security.cert.env.InvalidPtr:InvalidatingGetEnv=true \
|
|
// RUN: -analyzer-output=text -verify -Wno-unused %s
|
|
|
|
#include "../Inputs/system-header-simulator.h"
|
|
char *getenv(const char *name);
|
|
char *setlocale(int category, const char *locale);
|
|
char *strerror(int errnum);
|
|
|
|
typedef struct {
|
|
char * field;
|
|
} lconv;
|
|
lconv *localeconv(void);
|
|
|
|
typedef struct {
|
|
} tm;
|
|
char *asctime(const tm *timeptr);
|
|
|
|
int strcmp(const char*, const char*);
|
|
extern void foo(char *e);
|
|
extern char* bar(void);
|
|
|
|
|
|
void getenv_test1(void) {
|
|
char *p;
|
|
|
|
p = getenv("VAR");
|
|
*p; // no-warning
|
|
|
|
p = getenv("VAR2");
|
|
*p; // no-warning, getenv result was assigned to the same pointer
|
|
}
|
|
|
|
void getenv_test2(void) {
|
|
char *p, *p2;
|
|
|
|
p = getenv("VAR");
|
|
// expected-note@-1{{previous function call was here}}
|
|
*p; // no-warning
|
|
|
|
p2 = getenv("VAR2");
|
|
// expected-note@-1{{'getenv' call may invalidate the result of the previous 'getenv'}}
|
|
|
|
*p;
|
|
// expected-warning@-1{{dereferencing an invalid pointer}}
|
|
// expected-note@-2{{dereferencing an invalid pointer}}
|
|
}
|
|
|
|
void getenv_test3(void) {
|
|
char *p, *p2, *p3;
|
|
|
|
p = getenv("VAR");
|
|
*p; // no-warning
|
|
|
|
p = getenv("VAR2");
|
|
// expected-note@-1{{previous function call was here}}
|
|
p2 = getenv("VAR2");
|
|
// expected-note@-1{{'getenv' call may invalidate the result of the previous 'getenv'}}
|
|
|
|
p3 = getenv("VAR3");
|
|
|
|
*p;
|
|
// expected-warning@-1{{dereferencing an invalid pointer}}
|
|
// expected-note@-2{{dereferencing an invalid pointer}}
|
|
}
|
|
|
|
void getenv_test4(void) {
|
|
char *p, *p2, *p3;
|
|
|
|
p = getenv("VAR");
|
|
// expected-note@-1{{previous function call was here}}
|
|
p2 = getenv("VAR2");
|
|
// expected-note@-1{{'getenv' call may invalidate the result of the previous 'getenv'}}
|
|
p3 = getenv("VAR3");
|
|
|
|
*p;
|
|
// expected-warning@-1{{dereferencing an invalid pointer}}
|
|
// expected-note@-2{{dereferencing an invalid pointer}}
|
|
}
|
|
|
|
void getenv_test5(void) {
|
|
char *p, *p2, *p3;
|
|
|
|
p = getenv("VAR");
|
|
p2 = getenv("VAR2");
|
|
// expected-note@-1{{previous function call was here}}
|
|
p3 = getenv("VAR3");
|
|
// expected-note@-1{{'getenv' call may invalidate the result of the previous 'getenv'}}
|
|
|
|
*p2;
|
|
// expected-warning@-1{{dereferencing an invalid pointer}}
|
|
// expected-note@-2{{dereferencing an invalid pointer}}
|
|
}
|
|
|
|
void getenv_test6(void) {
|
|
char *p, *p2;
|
|
p = getenv("VAR");
|
|
*p; // no-warning
|
|
|
|
p = getenv("VAR2");
|
|
// expected-note@-1{{previous function call was here}}
|
|
*p; // no-warning
|
|
|
|
p2 = getenv("VAR3");
|
|
// expected-note@-1{{previous function call was here}}
|
|
// expected-note@-2{{'getenv' call may invalidate the result of the previous 'getenv'}}
|
|
|
|
*p;
|
|
// expected-warning@-1{{dereferencing an invalid pointer}}
|
|
// expected-note@-2{{dereferencing an invalid pointer}}
|
|
|
|
*p2; // no-warning
|
|
|
|
p = getenv("VAR4");
|
|
// expected-note@-1{{'getenv' call may invalidate the result of the previous 'getenv'}}
|
|
|
|
*p; // no-warning
|
|
*p2;
|
|
// expected-warning@-1{{dereferencing an invalid pointer}}
|
|
// expected-note@-2{{dereferencing an invalid pointer}}
|
|
}
|
|
|
|
void getenv_test7(void) {
|
|
char *p, *p2;
|
|
p = getenv("VAR");
|
|
// expected-note@-1{{previous function call was here}}
|
|
*p; // no-warning
|
|
|
|
p2 = getenv("VAR2");
|
|
// expected-note@-1{{'getenv' call may invalidate the result of the previous 'getenv'}}
|
|
|
|
foo(p);
|
|
// expected-warning@-1{{use of invalidated pointer 'p' in a function call}}
|
|
// expected-note@-2{{use of invalidated pointer 'p' in a function call}}
|
|
}
|
|
|
|
void getenv_test8(void) {
|
|
static const char *array[] = {
|
|
0,
|
|
0,
|
|
"/var/tmp",
|
|
"/usr/tmp",
|
|
"/tmp",
|
|
"."
|
|
};
|
|
|
|
if( !array[0] )
|
|
// expected-note@-1{{Taking true branch}}
|
|
array[0] = getenv("TEMPDIR");
|
|
// expected-note@-1{{previous function call was here}}
|
|
|
|
if( !array[1] )
|
|
// expected-note@-1{{Taking true branch}}
|
|
array[1] = getenv("TMPDIR");
|
|
// expected-note@-1{{'getenv' call may invalidate the result of the previous 'getenv'}}
|
|
|
|
*array[0];
|
|
// expected-warning@-1{{dereferencing an invalid pointer}}
|
|
// expected-note@-2{{dereferencing an invalid pointer}}
|
|
}
|
|
|
|
void getenv_test9(void) {
|
|
char *p, *p2;
|
|
p = getenv("something");
|
|
p = bar();
|
|
p2 = getenv("something");
|
|
*p; // no-warning: p does not point to getenv anymore
|
|
}
|
|
|
|
void getenv_test10(void) {
|
|
strcmp(getenv("VAR1"), getenv("VAR2"));
|
|
// expected-note@-1{{'getenv' call may invalidate the result of the previous 'getenv'}}
|
|
// expected-note@-2{{previous function call was here}}
|
|
// expected-warning@-3{{use of invalidated pointer 'getenv("VAR1")' in a function call}}
|
|
// expected-note@-4{{use of invalidated pointer 'getenv("VAR1")' in a function call}}
|
|
}
|
|
|
|
void dereference_pointer(char* a) {
|
|
*a;
|
|
// expected-warning@-1{{dereferencing an invalid pointer}}
|
|
// expected-note@-2{{dereferencing an invalid pointer}}
|
|
}
|
|
|
|
void getenv_test11(void) {
|
|
char *p = getenv("VAR");
|
|
// expected-note@-1{{previous function call was here}}
|
|
|
|
char *pp = getenv("VAR2");
|
|
// expected-note@-1{{'getenv' call may invalidate the result of the previous 'getenv'}}
|
|
|
|
dereference_pointer(p);
|
|
// expected-note@-1{{Calling 'dereference_pointer'}}
|
|
}
|
|
|
|
void getenv_test12(int flag1, int flag2) {
|
|
char *p = getenv("VAR");
|
|
// expected-note@-1{{previous function call was here}}
|
|
|
|
if (flag1) {
|
|
// expected-note@-1{{Assuming 'flag1' is not equal to 0}}
|
|
// expected-note@-2{{Taking true branch}}
|
|
char *pp = getenv("VAR2");
|
|
// expected-note@-1{{'getenv' call may invalidate the result of the previous 'getenv'}}
|
|
}
|
|
|
|
if (flag2) {
|
|
// expected-note@-1{{Assuming 'flag2' is not equal to 0}}
|
|
// expected-note@-2{{Taking true branch}}
|
|
*p;
|
|
// expected-warning@-1{{dereferencing an invalid pointer}}
|
|
// expected-note@-2{{dereferencing an invalid pointer}}
|
|
}
|
|
}
|
|
|
|
void setlocale_test1(void) {
|
|
char *p, *p2;
|
|
p = setlocale(0, "VAR");
|
|
*p; // no-warning
|
|
|
|
p = setlocale(0, "VAR2");
|
|
// expected-note@-1{{previous function call was here}}
|
|
*p; // no-warning
|
|
|
|
p2 = setlocale(0, "VAR3");
|
|
// expected-note@-1{{'setlocale' call may invalidate the result of the previous 'setlocale'}}
|
|
|
|
*p;
|
|
// expected-warning@-1{{dereferencing an invalid pointer}}
|
|
// expected-note@-2{{dereferencing an invalid pointer}}
|
|
}
|
|
|
|
void setlocale_test2(int flag) {
|
|
char *p, *p2;
|
|
p = setlocale(0, "VAR");
|
|
*p; // no-warning
|
|
|
|
p = setlocale(0, "VAR2");
|
|
// expected-note@-1{{previous function call was here}}
|
|
*p; // no-warning
|
|
|
|
if (flag) {
|
|
// expected-note@-1{{Assuming 'flag' is not equal to 0}}
|
|
// expected-note@-2{{Taking true branch}}
|
|
p2 = setlocale(0, "VAR3");
|
|
// expected-note@-1{{'setlocale' call may invalidate the result of the previous 'setlocale'}}
|
|
}
|
|
|
|
*p;
|
|
// expected-warning@-1{{dereferencing an invalid pointer}}
|
|
// expected-note@-2{{dereferencing an invalid pointer}}
|
|
}
|
|
|
|
void strerror_test1(void) {
|
|
char *p, *p2;
|
|
|
|
p = strerror(0);
|
|
*p; // no-warning
|
|
|
|
p = strerror(1);
|
|
// expected-note@-1{{previous function call was here}}
|
|
*p; // no-warning
|
|
|
|
p2 = strerror(2);
|
|
// expected-note@-1{{'strerror' call may invalidate the result of the previous 'strerror'}}
|
|
|
|
*p;
|
|
// expected-warning@-1{{dereferencing an invalid pointer}}
|
|
// expected-note@-2{{dereferencing an invalid pointer}}
|
|
}
|
|
|
|
void strerror_test2(int errno) {
|
|
char *p, *p2;
|
|
|
|
p = strerror(0);
|
|
*p; // no-warning
|
|
|
|
p = strerror(1);
|
|
// expected-note@-1{{previous function call was here}}
|
|
*p; // no-warning
|
|
|
|
if (0 == 1) {
|
|
// expected-note@-1{{0 is not equal to 1}}
|
|
// expected-note@-2{{Taking false branch}}
|
|
p2 = strerror(2);
|
|
}
|
|
|
|
*p; // no-warning
|
|
|
|
if (errno) {
|
|
// expected-note@-1{{Assuming 'errno' is not equal to 0}}
|
|
// expected-note@-2{{Taking true branch}}
|
|
p2 = strerror(errno);
|
|
// expected-note@-1{{'strerror' call may invalidate the result of the previous 'strerror'}}
|
|
}
|
|
|
|
*p;
|
|
// expected-warning@-1{{dereferencing an invalid pointer}}
|
|
// expected-note@-2{{dereferencing an invalid pointer}}
|
|
}
|
|
|
|
void asctime_test(void) {
|
|
const tm *t;
|
|
const tm *tt;
|
|
|
|
char* p = asctime(t);
|
|
// expected-note@-1{{previous function call was here}}
|
|
char* pp = asctime(tt);
|
|
// expected-note@-1{{'asctime' call may invalidate the result of the previous 'asctime'}}
|
|
|
|
*p;
|
|
// expected-warning@-1{{dereferencing an invalid pointer}}
|
|
// expected-note@-2{{dereferencing an invalid pointer}}
|
|
}
|
|
|
|
void localeconv_test1(void) {
|
|
lconv *lc1 = localeconv();
|
|
// expected-note@-1{{previous function call was here}}
|
|
lconv *lc2 = localeconv();
|
|
// expected-note@-1{{'localeconv' call may invalidate the result of the previous 'localeconv'}}
|
|
|
|
*lc1;
|
|
// expected-warning@-1{{dereferencing an invalid pointer}}
|
|
// expected-note@-2{{dereferencing an invalid pointer}}
|
|
}
|
|
|
|
void localeconv_test2(void) {
|
|
// TODO: false negative
|
|
lconv *lc1 = localeconv();
|
|
lconv *lc2 = localeconv();
|
|
lc1->field;
|
|
}
|