[scudo] Implement stricter separation of C vs C++
Summary:
Initially, Scudo had a monolithic design where both C and C++ functions were
living in the same library. This was not necessarily ideal, and with the work
on -fsanitize=scudo, it became more apparent that this needed to change.
We are splitting the new/delete interceptor in their own C++ library. This
allows more flexibility, notably with regard to std::bad_alloc when the work is
done. This also allows us to not link new & delete when using pure C.
Additionally, we add the UBSan runtimes with Scudo, in order to be able to have
a -fsanitize=scudo,undefined in Clang (see work in D39334).
The changes in this patch:
- split the cxx specific code in the scudo cmake file into a new library;
(remove the spurious foreach loop, that was not necessary)
- add the UBSan runtimes (both C and C++);
- change the test cmake file to allow for specific C & C++ tests;
- make C tests pure C, rename their extension accordingly.
Reviewers: alekseyshl
Reviewed By: alekseyshl
Subscribers: srhines, mgorny, llvm-commits
Differential Revision: https://reviews.llvm.org/D39461
llvm-svn: 317097
2017-11-01 23:28:20 +08:00
|
|
|
// RUN: %clangxx_scudo %s -lstdc++ -o %t
|
2017-12-14 04:41:35 +08:00
|
|
|
// RUN: %run %t ownership 2>&1
|
|
|
|
// RUN: %run %t ownership-and-size 2>&1
|
|
|
|
// RUN: %run %t heap-size 2>&1
|
|
|
|
// RUN: %env_scudo_opts="allocator_may_return_null=1" %run %t soft-limit 2>&1
|
|
|
|
// RUN: %env_scudo_opts="allocator_may_return_null=1" not %run %t hard-limit 2>&1
|
[scudo] 32-bit and hardware agnostic support
Summary:
This update introduces i386 support for the Scudo Hardened Allocator, and
offers software alternatives for functions that used to require hardware
specific instruction sets. This should make porting to new architectures
easier.
Among the changes:
- The chunk header has been changed to accomodate the size limitations
encountered on 32-bit architectures. We now fit everything in 64-bit. This
was achieved by storing the amount of unused bytes in an allocation rather
than the size itself, as one can be deduced from the other with the help
of the GetActuallyAllocatedSize function. As it turns out, this header can
be used for both 64 and 32 bit, and as such we dropped the requirement for
the 128-bit compare and exchange instruction support (cmpxchg16b).
- Add 32-bit support for the checksum and the PRNG functions: if the SSE 4.2
instruction set is supported, use the 32-bit CRC32 instruction, and in the
XorShift128, use a 32-bit based state instead of 64-bit.
- Add software support for CRC32: if SSE 4.2 is not supported, fallback on a
software implementation.
- Modify tests that were not 32-bit compliant, and expand them to cover more
allocation and alignment sizes. The random shuffle test has been deactivated
for linux-i386 & linux-i686 as the 32-bit sanitizer allocator doesn't
currently randomize chunks.
Reviewers: alekseyshl, kcc
Subscribers: filcab, llvm-commits, tberghammer, danalbert, srhines, mgorny, modocache
Differential Revision: https://reviews.llvm.org/D26358
llvm-svn: 288255
2016-12-01 01:32:20 +08:00
|
|
|
|
|
|
|
// Tests that the sanitizer interface functions behave appropriately.
|
|
|
|
|
|
|
|
#include <stdlib.h>
|
2017-02-04 04:49:42 +08:00
|
|
|
#include <assert.h>
|
|
|
|
#include <string.h>
|
2017-12-14 04:41:35 +08:00
|
|
|
#include <unistd.h>
|
[scudo] 32-bit and hardware agnostic support
Summary:
This update introduces i386 support for the Scudo Hardened Allocator, and
offers software alternatives for functions that used to require hardware
specific instruction sets. This should make porting to new architectures
easier.
Among the changes:
- The chunk header has been changed to accomodate the size limitations
encountered on 32-bit architectures. We now fit everything in 64-bit. This
was achieved by storing the amount of unused bytes in an allocation rather
than the size itself, as one can be deduced from the other with the help
of the GetActuallyAllocatedSize function. As it turns out, this header can
be used for both 64 and 32 bit, and as such we dropped the requirement for
the 128-bit compare and exchange instruction support (cmpxchg16b).
- Add 32-bit support for the checksum and the PRNG functions: if the SSE 4.2
instruction set is supported, use the 32-bit CRC32 instruction, and in the
XorShift128, use a 32-bit based state instead of 64-bit.
- Add software support for CRC32: if SSE 4.2 is not supported, fallback on a
software implementation.
- Modify tests that were not 32-bit compliant, and expand them to cover more
allocation and alignment sizes. The random shuffle test has been deactivated
for linux-i386 & linux-i686 as the 32-bit sanitizer allocator doesn't
currently randomize chunks.
Reviewers: alekseyshl, kcc
Subscribers: filcab, llvm-commits, tberghammer, danalbert, srhines, mgorny, modocache
Differential Revision: https://reviews.llvm.org/D26358
llvm-svn: 288255
2016-12-01 01:32:20 +08:00
|
|
|
|
|
|
|
#include <vector>
|
|
|
|
|
|
|
|
#include <sanitizer/allocator_interface.h>
|
2017-12-14 04:41:35 +08:00
|
|
|
#include <sanitizer/scudo_interface.h>
|
[scudo] 32-bit and hardware agnostic support
Summary:
This update introduces i386 support for the Scudo Hardened Allocator, and
offers software alternatives for functions that used to require hardware
specific instruction sets. This should make porting to new architectures
easier.
Among the changes:
- The chunk header has been changed to accomodate the size limitations
encountered on 32-bit architectures. We now fit everything in 64-bit. This
was achieved by storing the amount of unused bytes in an allocation rather
than the size itself, as one can be deduced from the other with the help
of the GetActuallyAllocatedSize function. As it turns out, this header can
be used for both 64 and 32 bit, and as such we dropped the requirement for
the 128-bit compare and exchange instruction support (cmpxchg16b).
- Add 32-bit support for the checksum and the PRNG functions: if the SSE 4.2
instruction set is supported, use the 32-bit CRC32 instruction, and in the
XorShift128, use a 32-bit based state instead of 64-bit.
- Add software support for CRC32: if SSE 4.2 is not supported, fallback on a
software implementation.
- Modify tests that were not 32-bit compliant, and expand them to cover more
allocation and alignment sizes. The random shuffle test has been deactivated
for linux-i386 & linux-i686 as the 32-bit sanitizer allocator doesn't
currently randomize chunks.
Reviewers: alekseyshl, kcc
Subscribers: filcab, llvm-commits, tberghammer, danalbert, srhines, mgorny, modocache
Differential Revision: https://reviews.llvm.org/D26358
llvm-svn: 288255
2016-12-01 01:32:20 +08:00
|
|
|
|
|
|
|
int main(int argc, char **argv)
|
|
|
|
{
|
2017-02-04 04:49:42 +08:00
|
|
|
assert(argc == 2);
|
|
|
|
|
|
|
|
if (!strcmp(argv[1], "ownership")) {
|
|
|
|
// Ensures that __sanitizer_get_ownership can be called before any other
|
|
|
|
// allocator function, and that it behaves properly on a pointer not owned
|
|
|
|
// by us.
|
|
|
|
assert(!__sanitizer_get_ownership(argv));
|
|
|
|
}
|
|
|
|
if (!strcmp(argv[1], "ownership-and-size")) {
|
|
|
|
// Tests that __sanitizer_get_ownership and __sanitizer_get_allocated_size
|
|
|
|
// behave properly on chunks allocated by the Primary and Secondary.
|
|
|
|
void *p;
|
|
|
|
std::vector<ssize_t> sizes{1, 8, 16, 32, 1024, 32768,
|
|
|
|
1 << 16, 1 << 17, 1 << 20, 1 << 24};
|
|
|
|
for (size_t size : sizes) {
|
|
|
|
p = malloc(size);
|
|
|
|
assert(p);
|
|
|
|
assert(__sanitizer_get_ownership(p));
|
|
|
|
assert(__sanitizer_get_allocated_size(p) >= size);
|
|
|
|
free(p);
|
|
|
|
}
|
[scudo] 32-bit and hardware agnostic support
Summary:
This update introduces i386 support for the Scudo Hardened Allocator, and
offers software alternatives for functions that used to require hardware
specific instruction sets. This should make porting to new architectures
easier.
Among the changes:
- The chunk header has been changed to accomodate the size limitations
encountered on 32-bit architectures. We now fit everything in 64-bit. This
was achieved by storing the amount of unused bytes in an allocation rather
than the size itself, as one can be deduced from the other with the help
of the GetActuallyAllocatedSize function. As it turns out, this header can
be used for both 64 and 32 bit, and as such we dropped the requirement for
the 128-bit compare and exchange instruction support (cmpxchg16b).
- Add 32-bit support for the checksum and the PRNG functions: if the SSE 4.2
instruction set is supported, use the 32-bit CRC32 instruction, and in the
XorShift128, use a 32-bit based state instead of 64-bit.
- Add software support for CRC32: if SSE 4.2 is not supported, fallback on a
software implementation.
- Modify tests that were not 32-bit compliant, and expand them to cover more
allocation and alignment sizes. The random shuffle test has been deactivated
for linux-i386 & linux-i686 as the 32-bit sanitizer allocator doesn't
currently randomize chunks.
Reviewers: alekseyshl, kcc
Subscribers: filcab, llvm-commits, tberghammer, danalbert, srhines, mgorny, modocache
Differential Revision: https://reviews.llvm.org/D26358
llvm-svn: 288255
2016-12-01 01:32:20 +08:00
|
|
|
}
|
2017-02-04 04:49:42 +08:00
|
|
|
if (!strcmp(argv[1], "heap-size")) {
|
|
|
|
// Ensures that __sanitizer_get_heap_size can be called before any other
|
2017-02-04 05:59:00 +08:00
|
|
|
// allocator function.
|
|
|
|
assert(__sanitizer_get_heap_size() >= 0);
|
2017-02-04 04:49:42 +08:00
|
|
|
}
|
2017-12-14 04:41:35 +08:00
|
|
|
if (!strcmp(argv[1], "soft-limit")) {
|
|
|
|
// Verifies that setting the soft RSS limit at runtime works as expected.
|
|
|
|
std::vector<void *> pointers;
|
|
|
|
size_t size = 1 << 19; // 512Kb
|
2018-01-02 02:19:06 +08:00
|
|
|
for (int i = 0; i < 5; i++) {
|
|
|
|
void *p = malloc(size);
|
|
|
|
memset(p, 0, size);
|
|
|
|
pointers.push_back(p);
|
|
|
|
}
|
2017-12-14 04:41:35 +08:00
|
|
|
// Set the soft RSS limit to 1Mb.
|
|
|
|
__scudo_set_rss_limit(1, 0);
|
|
|
|
usleep(20000);
|
|
|
|
// The following allocation should return NULL.
|
|
|
|
void *p = malloc(size);
|
|
|
|
assert(!p);
|
|
|
|
// Remove the soft RSS limit.
|
|
|
|
__scudo_set_rss_limit(0, 0);
|
|
|
|
// The following allocation should succeed.
|
|
|
|
p = malloc(size);
|
|
|
|
assert(p);
|
|
|
|
free(p);
|
|
|
|
while (!pointers.empty()) {
|
|
|
|
free(pointers.back());
|
|
|
|
pointers.pop_back();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (!strcmp(argv[1], "hard-limit")) {
|
|
|
|
// Verifies that setting the hard RSS limit at runtime works as expected.
|
|
|
|
std::vector<void *> pointers;
|
|
|
|
size_t size = 1 << 19; // 512Kb
|
2018-01-02 02:19:06 +08:00
|
|
|
for (int i = 0; i < 5; i++) {
|
|
|
|
void *p = malloc(size);
|
|
|
|
memset(p, 0, size);
|
|
|
|
pointers.push_back(p);
|
|
|
|
}
|
2017-12-14 04:41:35 +08:00
|
|
|
// Set the hard RSS limit to 1Mb
|
|
|
|
__scudo_set_rss_limit(1, 1);
|
|
|
|
usleep(20000);
|
|
|
|
// The following should trigger our death.
|
|
|
|
void *p = malloc(size);
|
|
|
|
}
|
2017-02-04 04:49:42 +08:00
|
|
|
|
[scudo] 32-bit and hardware agnostic support
Summary:
This update introduces i386 support for the Scudo Hardened Allocator, and
offers software alternatives for functions that used to require hardware
specific instruction sets. This should make porting to new architectures
easier.
Among the changes:
- The chunk header has been changed to accomodate the size limitations
encountered on 32-bit architectures. We now fit everything in 64-bit. This
was achieved by storing the amount of unused bytes in an allocation rather
than the size itself, as one can be deduced from the other with the help
of the GetActuallyAllocatedSize function. As it turns out, this header can
be used for both 64 and 32 bit, and as such we dropped the requirement for
the 128-bit compare and exchange instruction support (cmpxchg16b).
- Add 32-bit support for the checksum and the PRNG functions: if the SSE 4.2
instruction set is supported, use the 32-bit CRC32 instruction, and in the
XorShift128, use a 32-bit based state instead of 64-bit.
- Add software support for CRC32: if SSE 4.2 is not supported, fallback on a
software implementation.
- Modify tests that were not 32-bit compliant, and expand them to cover more
allocation and alignment sizes. The random shuffle test has been deactivated
for linux-i386 & linux-i686 as the 32-bit sanitizer allocator doesn't
currently randomize chunks.
Reviewers: alekseyshl, kcc
Subscribers: filcab, llvm-commits, tberghammer, danalbert, srhines, mgorny, modocache
Differential Revision: https://reviews.llvm.org/D26358
llvm-svn: 288255
2016-12-01 01:32:20 +08:00
|
|
|
return 0;
|
|
|
|
}
|