Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
OpenHarmony
Third Party Musl
提交
320c0c4c
T
Third Party Musl
项目概览
OpenHarmony
/
Third Party Musl
1 年多 前同步成功
通知
37
Star
125
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
T
Third Party Musl
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
未验证
提交
320c0c4c
编写于
9月 05, 2022
作者:
O
openharmony_ci
提交者:
Gitee
9月 05, 2022
浏览文件
操作
浏览文件
下载
差异文件
!496 增加red zone/poison特性,提高musl内存分配器对溢出和UAF的防护能力
Merge pull request !496 from Far/quarantine
上级
4154ba6c
65228e15
变更
9
隐藏空白更改
内联
并排
Showing
9 changed file
with
630 addition
and
1 deletion
+630
-1
libc-test/src/regression/malloc-overflow-check.c
libc-test/src/regression/malloc-overflow-check.c
+112
-0
libc-test/src/regression/malloc-uaf-check.c
libc-test/src/regression/malloc-uaf-check.c
+139
-0
libc-test/src/regression/test_src_regression.gni
libc-test/src/regression/test_src_regression.gni
+9
-0
musl_template.gni
musl_template.gni
+3
-0
porting/linux/user/src/internal/malloc_config.h
porting/linux/user/src/internal/malloc_config.h
+8
-0
porting/linux/user/src/internal/malloc_impl.h
porting/linux/user/src/internal/malloc_impl.h
+36
-1
porting/linux/user/src/malloc/malloc.c
porting/linux/user/src/malloc/malloc.c
+222
-0
porting/linux/user/src/malloc/malloc_usable_size.c
porting/linux/user/src/malloc/malloc_usable_size.c
+30
-0
porting/linux/user/src/malloc/memalign.c
porting/linux/user/src/malloc/memalign.c
+71
-0
未找到文件。
libc-test/src/regression/malloc-overflow-check.c
0 → 100644
浏览文件 @
320c0c4c
/*
* Copyright (C) 2022 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>
#include <signal.h>
#include <errno.h>
#include <string.h>
#include "test.h"
#define ALIGNED_SIZE (4 * sizeof(size_t))
#define OVERFLOW_VAL 0xab
#define LOOP_SIZE 512
#define MALLOC_TIME 67
static
void
handler
(
int
s
)
{
}
static
int
child
(
void
)
{
char
*
ptr
[
MALLOC_TIME
];
for
(
int
i
=
0
;
i
<
LOOP_SIZE
;
++
i
)
{
for
(
int
j
=
0
;
j
<
MALLOC_TIME
;
++
j
)
{
ptr
[
j
]
=
(
char
*
)
malloc
(
ALIGNED_SIZE
-
1
);
if
(
!
ptr
[
j
])
{
t_error
(
"Malloc failed:%s
\n
"
,
strerror
(
errno
));
return
-
1
;
}
ptr
[
j
][
ALIGNED_SIZE
-
1
]
=
(
char
)(
OVERFLOW_VAL
-
j
);
}
for
(
int
j
=
0
;
j
<
MALLOC_TIME
;
++
j
)
{
free
(
ptr
[
j
]);
}
}
return
0
;
}
static
pid_t
start_child
(
void
)
{
pid_t
pid
=
0
;
int
ret
=
0
;
pid
=
fork
();
if
(
pid
==
0
)
{
ret
=
child
();
t_error
(
"child process normally out with %d
\n
"
,
ret
);
return
ret
;
}
return
pid
;
}
int
main
(
int
argc
,
char
*
argv
[])
{
sigset_t
set
;
int
status
=
0
;
pid_t
pid
=
0
;
int
flag
=
0
;
char
*
pname
=
(
argc
>
0
)
?
argv
[
0
]
:
"malloc-overflow-check"
;
sigemptyset
(
&
set
);
sigaddset
(
&
set
,
SIGCHLD
);
sigprocmask
(
SIG_BLOCK
,
&
set
,
0
);
signal
(
SIGCHLD
,
handler
);
pid
=
start_child
();
if
(
pid
==
-
1
)
{
t_error
(
"%s fork failed: %s
\n
"
,
pname
,
strerror
(
errno
));
return
-
1
;
}
if
(
sigtimedwait
(
&
set
,
0
,
&
(
struct
timespec
){
5
,
0
})
==
-
1
)
{
/* Wait for 5 seconds */
if
(
errno
==
EAGAIN
)
flag
=
1
;
else
t_error
(
"%s sigtimedwait failed: %s
\n
"
,
pname
,
strerror
(
errno
));
if
(
kill
(
pid
,
SIGKILL
)
==
-
1
)
t_error
(
"%s kill failed: %s
\n
"
,
pname
,
strerror
(
errno
));
}
if
(
waitpid
(
pid
,
&
status
,
0
)
!=
pid
)
{
t_error
(
"%s waitpid failed: %s
\n
"
,
pname
,
strerror
(
errno
));
return
-
1
;
}
if
(
flag
)
{
t_error
(
"Child process time out
\n
"
);
}
if
(
WIFSIGNALED
(
status
))
{
if
(
WTERMSIG
(
status
)
!=
SIGSEGV
&&
WTERMSIG
(
status
)
!=
SIGILL
)
{
t_error
(
"%s child process out with %s
\n
"
,
pname
,
strsignal
(
WTERMSIG
(
status
)));
return
-
1
;
}
}
else
{
t_error
(
"%s child process finished normally
\n
"
,
pname
);
}
return
t_status
;
}
libc-test/src/regression/malloc-uaf-check.c
0 → 100644
浏览文件 @
320c0c4c
/*
* Copyright (C) 2022 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>
#include <signal.h>
#include <errno.h>
#include <string.h>
#include "test.h"
#define ALIGNED_SIZE (8 * sizeof(size_t))
#define POINTER_USAGE (2 * sizeof(void *))
#define UAF_VAL 0xab
#define LOOP_SIZE 512
#define MALLOC_TIME 67
static
void
handler
(
int
s
)
{
}
static
int
child
(
void
)
{
char
*
ptr
[
MALLOC_TIME
];
char
*
ptr1
[
MALLOC_TIME
];
char
*
divide
[
MALLOC_TIME
];
for
(
int
i
=
0
;
i
<
LOOP_SIZE
;
++
i
)
{
for
(
int
j
=
0
;
j
<
MALLOC_TIME
;
++
j
)
{
ptr
[
j
]
=
(
char
*
)
malloc
(
ALIGNED_SIZE
-
1
);
if
(
!
ptr
[
j
])
{
t_error
(
"Malloc failed:%s
\n
"
,
strerror
(
errno
));
return
-
1
;
}
divide
[
j
]
=
(
char
*
)
malloc
(
ALIGNED_SIZE
-
1
);
if
(
!
divide
[
j
])
{
t_error
(
"Malloc divide failed:%s
\n
"
,
strerror
(
errno
));
return
-
1
;
}
}
for
(
int
j
=
0
;
j
<
MALLOC_TIME
;
++
j
)
{
free
(
ptr
[
j
]);
/* Use after free, we should avoid changing the bin/quarantine deque pointer */
ptr
[
j
][
POINTER_USAGE
]
=
(
char
)(
UAF_VAL
-
j
);
}
for
(
int
j
=
0
;
j
<
MALLOC_TIME
;
++
j
)
{
ptr1
[
j
]
=
(
char
*
)
malloc
(
ALIGNED_SIZE
-
1
);
if
(
!
ptr1
[
j
])
{
t_error
(
"Malloc failed:%s
\n
"
,
strerror
(
errno
));
return
-
1
;
}
}
for
(
int
j
=
0
;
j
<
MALLOC_TIME
;
++
j
)
{
free
(
divide
[
j
]);
divide
[
j
][
POINTER_USAGE
]
=
(
char
)(
UAF_VAL
-
j
);
}
for
(
int
j
=
0
;
j
<
MALLOC_TIME
;
++
j
)
{
free
(
ptr1
[
j
]);
ptr1
[
j
][
POINTER_USAGE
]
=
(
char
)(
UAF_VAL
-
j
);
}
}
return
0
;
}
static
pid_t
start_child
(
void
)
{
pid_t
pid
=
0
;
int
ret
=
0
;
pid
=
fork
();
if
(
pid
==
0
)
{
ret
=
child
();
t_error
(
"child process normally out with %d
\n
"
,
ret
);
return
ret
;
}
return
pid
;
}
int
main
(
int
argc
,
char
*
argv
[])
{
sigset_t
set
;
int
status
=
0
;
pid_t
pid
=
0
;
int
flag
=
0
;
char
*
pname
=
(
argc
>
0
)
?
argv
[
0
]
:
"malloc-uaf-check"
;
sigemptyset
(
&
set
);
sigaddset
(
&
set
,
SIGCHLD
);
sigprocmask
(
SIG_BLOCK
,
&
set
,
0
);
signal
(
SIGCHLD
,
handler
);
pid
=
start_child
();
if
(
pid
==
-
1
)
{
t_error
(
"%s fork failed: %s
\n
"
,
pname
,
strerror
(
errno
));
return
-
1
;
}
if
(
sigtimedwait
(
&
set
,
0
,
&
(
struct
timespec
){
5
,
0
})
==
-
1
)
{
/* Wait for 5 seconds */
if
(
errno
==
EAGAIN
)
flag
=
1
;
else
t_error
(
"%s sigtimedwait failed: %s
\n
"
,
pname
,
strerror
(
errno
));
if
(
kill
(
pid
,
SIGKILL
)
==
-
1
)
t_error
(
"%s kill failed: %s
\n
"
,
pname
,
strerror
(
errno
));
}
if
(
waitpid
(
pid
,
&
status
,
0
)
!=
pid
)
{
t_error
(
"%s waitpid failed: %s
\n
"
,
pname
,
strerror
(
errno
));
return
-
1
;
}
if
(
flag
)
{
t_error
(
"Child process time out
\n
"
);
}
if
(
WIFSIGNALED
(
status
))
{
if
(
WTERMSIG
(
status
)
!=
SIGSEGV
&&
WTERMSIG
(
status
)
!=
SIGILL
)
{
t_error
(
"%s child process out with %s
\n
"
,
pname
,
strsignal
(
WTERMSIG
(
status
)));
return
-
1
;
}
}
else
{
t_error
(
"%s child process finished normally
\n
"
,
pname
);
}
return
t_status
;
}
libc-test/src/regression/test_src_regression.gni
浏览文件 @
320c0c4c
import("../../../musl_config.gni")
regression_list = [
regression_list = [
"daemon-failure",
"daemon-failure",
"dn_expand-empty",
"dn_expand-empty",
...
@@ -77,3 +79,10 @@ regression_list = [
...
@@ -77,3 +79,10 @@ regression_list = [
"wcsncpy-read-overflow",
"wcsncpy-read-overflow",
"wcsstr-false-negative",
"wcsstr-false-negative",
]
]
if (musl_secure_level >= 3) {
regression_list += [
"malloc-overflow-check",
"malloc-uaf-check",
]
}
musl_template.gni
浏览文件 @
320c0c4c
...
@@ -270,6 +270,9 @@ template("musl_libs") {
...
@@ -270,6 +270,9 @@ template("musl_libs") {
if (musl_secure_level > 1) {
if (musl_secure_level > 1) {
defines += [ "MALLOC_FREELIST_QUARANTINE" ]
defines += [ "MALLOC_FREELIST_QUARANTINE" ]
}
}
if (musl_secure_level > 2) {
defines += [ "MALLOC_RED_ZONE" ]
}
if (is_debug || musl_secure_level >= 3) {
if (is_debug || musl_secure_level >= 3) {
defines += [ "MALLOC_SECURE_ALL" ]
defines += [ "MALLOC_SECURE_ALL" ]
}
}
...
...
porting/linux/user/src/internal/malloc_config.h
浏览文件 @
320c0c4c
...
@@ -25,10 +25,18 @@
...
@@ -25,10 +25,18 @@
#define MALLOC_FREELIST_QUARANTINE
#define MALLOC_FREELIST_QUARANTINE
#endif
#endif
#ifndef MALLOC_RED_ZONE
#define MALLOC_RED_ZONE
#endif
#endif // MALLOC_SECURE_ALL
#endif // MALLOC_SECURE_ALL
#if defined(MALLOC_FREELIST_QUARANTINE) && !defined(MALLOC_FREELIST_HARDENED)
#if defined(MALLOC_FREELIST_QUARANTINE) && !defined(MALLOC_FREELIST_HARDENED)
#error MALLOC_FREELIST_QUARANTINE can be only applied when MALLOC_FREELIST_HARDENED is set.
#error MALLOC_FREELIST_QUARANTINE can be only applied when MALLOC_FREELIST_HARDENED is set.
#endif
#endif
#if defined(MALLOC_RED_ZONE) && !defined(MALLOC_FREELIST_QUARANTINE)
#error MALLOC_RED_ZONE can be only applied when MALLOC_FREELIST_QUARANTINE is set.
#endif
#endif // MALLOC_CONFIG_H
#endif // MALLOC_CONFIG_H
porting/linux/user/src/internal/malloc_impl.h
浏览文件 @
320c0c4c
...
@@ -12,6 +12,10 @@ hidden void *__memalign(size_t, size_t);
...
@@ -12,6 +12,10 @@ hidden void *__memalign(size_t, size_t);
struct
chunk
{
struct
chunk
{
size_t
psize
,
csize
;
size_t
psize
,
csize
;
#ifdef MALLOC_RED_ZONE
size_t
usize
;
size_t
state
;
#endif
struct
chunk
*
next
,
*
prev
;
struct
chunk
*
next
,
*
prev
;
};
};
...
@@ -24,11 +28,21 @@ struct bin {
...
@@ -24,11 +28,21 @@ struct bin {
#endif
#endif
};
};
#define SIZE_ALIGN (4*sizeof(size_t))
#define SIZE_MASK (-SIZE_ALIGN)
#define SIZE_MASK (-SIZE_ALIGN)
#ifndef MALLOC_RED_ZONE
#define SIZE_ALIGN (4*sizeof(size_t))
#define OVERHEAD (2*sizeof(size_t))
#define OVERHEAD (2*sizeof(size_t))
#else
#define SIZE_ALIGN (8*sizeof(size_t))
#define OVERHEAD (4*sizeof(size_t))
#endif
#define MMAP_THRESHOLD (0x1c00*SIZE_ALIGN)
#define MMAP_THRESHOLD (0x1c00*SIZE_ALIGN)
#ifndef MALLOC_RED_ZONE
#define DONTCARE 16
#define DONTCARE 16
#else
#define DONTCARE OVERHEAD
#define POINTER_USAGE (2*sizeof(void *))
#endif
#define RECLAIM 163840
#define RECLAIM 163840
#ifdef MALLOC_FREELIST_QUARANTINE
#ifdef MALLOC_FREELIST_QUARANTINE
...
@@ -50,6 +64,21 @@ struct bin {
...
@@ -50,6 +64,21 @@ struct bin {
#define QUARANTINE_TO_CHUNK(i) (MEM_TO_CHUNK(&mal.quarantine[i].head))
#define QUARANTINE_TO_CHUNK(i) (MEM_TO_CHUNK(&mal.quarantine[i].head))
#endif
#endif
#ifdef MALLOC_RED_ZONE
#define M_STATE_FREE 0x00
#define M_STATE_USED 0x01U
#define M_STATE_BRK 0x02U
#define M_STATE_MMAP 0x04U
#define M_RZ_NONE 0x00
#define M_RZ_POISON 0x10U
#define M_STATE_MASK 0xffU
#define M_CHECKSUM_SHIFT 8
#define POISON_PERIOD 31
#endif
#define C_INUSE ((size_t)1)
#define C_INUSE ((size_t)1)
#define IS_MMAPPED(c) !((c)->csize & (C_INUSE))
#define IS_MMAPPED(c) !((c)->csize & (C_INUSE))
...
@@ -66,4 +95,10 @@ hidden void *internal_calloc(size_t m, size_t n);
...
@@ -66,4 +95,10 @@ hidden void *internal_calloc(size_t m, size_t n);
hidden
void
*
internal_realloc
(
void
*
p
,
size_t
n
);
hidden
void
*
internal_realloc
(
void
*
p
,
size_t
n
);
#ifdef MALLOC_RED_ZONE
hidden
void
chunk_checksum_set
(
struct
chunk
*
c
);
hidden
int
chunk_checksum_check
(
struct
chunk
*
c
);
#endif
#endif
#endif
porting/linux/user/src/malloc/malloc.c
浏览文件 @
320c0c4c
...
@@ -29,6 +29,11 @@ static struct {
...
@@ -29,6 +29,11 @@ static struct {
struct
bin
quarantine
[
QUARANTINE_NUM
];
struct
bin
quarantine
[
QUARANTINE_NUM
];
size_t
quarantined_count
[
QUARANTINE_NUM
];
size_t
quarantined_count
[
QUARANTINE_NUM
];
size_t
quarantined_size
[
QUARANTINE_NUM
];
size_t
quarantined_size
[
QUARANTINE_NUM
];
#ifdef MALLOC_RED_ZONE
char
poison
[
64
];
volatile
int
poison_lock
[
2
];
int
poison_count_down
;
#endif
#endif
#endif
}
mal
;
}
mal
;
...
@@ -146,6 +151,73 @@ static int bin_index_up(size_t x)
...
@@ -146,6 +151,73 @@ static int bin_index_up(size_t x)
return
bin_tab
[
x
/
128
-
4
]
+
17
;
return
bin_tab
[
x
/
128
-
4
]
+
17
;
}
}
#ifdef MALLOC_RED_ZONE
static
inline
size_t
chunk_checksum_calculate
(
struct
chunk
*
c
)
{
return
(((
size_t
)
c
)
^
c
->
csize
^
c
->
usize
^
(
c
->
state
&
M_STATE_MASK
))
<<
M_CHECKSUM_SHIFT
;
}
void
chunk_checksum_set
(
struct
chunk
*
c
)
{
c
->
state
=
(
c
->
state
&
M_STATE_MASK
)
|
chunk_checksum_calculate
(
c
);
}
int
chunk_checksum_check
(
struct
chunk
*
c
)
{
return
(
c
->
state
&
~
M_STATE_MASK
)
^
chunk_checksum_calculate
(
c
);
}
static
inline
char
get_poison
(
int
i
)
{
char
poison
=
0
;
lock
(
mal
.
poison_lock
);
if
(
!
mal
.
poison
[
i
])
{
mal
.
poison
[
i
]
=
(
char
)(
uintptr_t
)
next_key
();
}
poison
=
mal
.
poison
[
i
];
unlock
(
mal
.
poison_lock
);
return
poison
;
}
static
inline
int
need_poison
(
void
)
{
int
ret
=
0
;
lock
(
mal
.
poison_lock
);
if
(
mal
.
poison_count_down
==
0
)
{
/* Make sure the period is POISON_COUNT_DOWN_BASE */
mal
.
poison_count_down
=
POISON_PERIOD
-
1
;
ret
=
1
;
}
else
{
--
mal
.
poison_count_down
;
}
unlock
(
mal
.
poison_lock
);
return
ret
;
}
static
inline
void
chunk_poison_set
(
struct
chunk
*
c
)
{
char
*
start
=
((
char
*
)
CHUNK_TO_MEM
(
c
))
+
c
->
usize
;
size_t
size
=
CHUNK_SIZE
(
c
)
-
OVERHEAD
-
c
->
usize
;
char
val
=
get_poison
(
bin_index
(
CHUNK_SIZE
(
c
)));
memset
(
start
,
val
,
size
);
c
->
state
|=
M_RZ_POISON
;
}
void
chunk_poison_check
(
struct
chunk
*
c
)
{
size_t
csize
=
CHUNK_SIZE
(
c
);
char
poison
=
get_poison
(
bin_index
(
csize
));
size_t
padding_size
=
csize
-
OVERHEAD
-
c
->
usize
;
char
*
start
=
(
char
*
)
c
+
OVERHEAD
+
c
->
usize
;
for
(
size_t
i
=
0
;
i
<
padding_size
;
++
i
)
{
/* Poison not right, crash */
if
(
start
[
i
]
!=
poison
)
{
a_crash
();
}
}
}
#endif
#if 0
#if 0
void __dump_heap(int x)
void __dump_heap(int x)
{
{
...
@@ -207,6 +279,11 @@ static struct chunk *expand_heap(size_t n)
...
@@ -207,6 +279,11 @@ static struct chunk *expand_heap(size_t n)
* zero-size sentinel header at the old end-of-heap. */
* zero-size sentinel header at the old end-of-heap. */
w
=
MEM_TO_CHUNK
(
p
);
w
=
MEM_TO_CHUNK
(
p
);
w
->
csize
=
n
|
C_INUSE
;
w
->
csize
=
n
|
C_INUSE
;
#ifdef MALLOC_RED_ZONE
w
->
state
=
M_STATE_BRK
;
w
->
usize
=
POINTER_USAGE
;
chunk_checksum_set
(
w
);
#endif
unlock
(
heap_lock
);
unlock
(
heap_lock
);
...
@@ -225,7 +302,15 @@ static int adjust_size(size_t *n)
...
@@ -225,7 +302,15 @@ static int adjust_size(size_t *n)
return
0
;
return
0
;
}
}
}
}
#ifdef MALLOC_RED_ZONE
/*
* *n + OVERHEAD + SIZE_ALIGN + 1 - 1
* to make sure a least 1 byte for red zone
*/
*
n
=
(
*
n
+
OVERHEAD
+
SIZE_ALIGN
)
&
SIZE_MASK
;
#else
*
n
=
(
*
n
+
OVERHEAD
+
SIZE_ALIGN
-
1
)
&
SIZE_MASK
;
*
n
=
(
*
n
+
OVERHEAD
+
SIZE_ALIGN
-
1
)
&
SIZE_MASK
;
#endif
return
0
;
return
0
;
}
}
...
@@ -323,6 +408,13 @@ static int pretrim(struct chunk *self, size_t n, int i, int j)
...
@@ -323,6 +408,13 @@ static int pretrim(struct chunk *self, size_t n, int i, int j)
split
->
csize
=
n1
-
n
;
split
->
csize
=
n1
-
n
;
next
->
psize
=
n1
-
n
;
next
->
psize
=
n1
-
n
;
self
->
csize
=
n
|
C_INUSE
;
self
->
csize
=
n
|
C_INUSE
;
#ifdef MALLOC_RED_ZONE
/* split poison state keep up to self for less poison operations */
self
->
state
&=
~
M_RZ_POISON
;
split
->
state
=
M_STATE_BRK
;
split
->
usize
=
POINTER_USAGE
;
chunk_checksum_set
(
split
);
#endif
return
1
;
return
1
;
}
}
...
@@ -340,6 +432,12 @@ static void trim(struct chunk *self, size_t n)
...
@@ -340,6 +432,12 @@ static void trim(struct chunk *self, size_t n)
split
->
csize
=
n1
-
n
|
C_INUSE
;
split
->
csize
=
n1
-
n
|
C_INUSE
;
next
->
psize
=
n1
-
n
|
C_INUSE
;
next
->
psize
=
n1
-
n
|
C_INUSE
;
self
->
csize
=
n
|
C_INUSE
;
self
->
csize
=
n
|
C_INUSE
;
#ifdef MALLOC_RED_ZONE
/* Remove the poison tag, because of triming chunk */
split
->
state
=
M_STATE_BRK
;
split
->
usize
=
POINTER_USAGE
;
chunk_checksum_set
(
split
);
#endif
__bin_chunk
(
split
);
__bin_chunk
(
split
);
}
}
...
@@ -357,6 +455,10 @@ void *internal_malloc(size_t n)
...
@@ -357,6 +455,10 @@ void *internal_malloc(size_t n)
{
{
struct
chunk
*
c
;
struct
chunk
*
c
;
int
i
,
j
;
int
i
,
j
;
#ifdef MALLOC_RED_ZONE
size_t
user_size
=
n
;
char
poison
;
#endif
if
(
adjust_size
(
&
n
)
<
0
)
return
0
;
if
(
adjust_size
(
&
n
)
<
0
)
return
0
;
...
@@ -371,6 +473,14 @@ void *internal_malloc(size_t n)
...
@@ -371,6 +473,14 @@ void *internal_malloc(size_t n)
c
=
(
void
*
)(
base
+
SIZE_ALIGN
-
OVERHEAD
);
c
=
(
void
*
)(
base
+
SIZE_ALIGN
-
OVERHEAD
);
c
->
csize
=
len
-
(
SIZE_ALIGN
-
OVERHEAD
);
c
->
csize
=
len
-
(
SIZE_ALIGN
-
OVERHEAD
);
c
->
psize
=
SIZE_ALIGN
-
OVERHEAD
;
c
->
psize
=
SIZE_ALIGN
-
OVERHEAD
;
#ifdef MALLOC_RED_ZONE
c
->
state
=
M_STATE_MMAP
|
M_STATE_USED
;
c
->
usize
=
user_size
;
if
(
need_poison
())
{
chunk_poison_set
(
c
);
}
chunk_checksum_set
(
c
);
#endif
return
CHUNK_TO_MEM
(
c
);
return
CHUNK_TO_MEM
(
c
);
}
}
...
@@ -397,6 +507,11 @@ void *internal_malloc(size_t n)
...
@@ -397,6 +507,11 @@ void *internal_malloc(size_t n)
#endif
#endif
c
=
encode_chunk
(
mal
.
bins
[
j
].
head
,
key
);
/* Decode the head pointer */
c
=
encode_chunk
(
mal
.
bins
[
j
].
head
,
key
);
/* Decode the head pointer */
if
(
c
!=
BIN_TO_CHUNK
(
j
))
{
if
(
c
!=
BIN_TO_CHUNK
(
j
))
{
#ifdef MALLOC_RED_ZONE
if
(
c
->
state
&
M_RZ_POISON
)
{
chunk_poison_check
(
c
);
}
#endif
if
(
!
pretrim
(
c
,
n
,
i
,
j
))
unbin
(
c
,
j
);
if
(
!
pretrim
(
c
,
n
,
i
,
j
))
unbin
(
c
,
j
);
unlock_bin
(
j
);
unlock_bin
(
j
);
break
;
break
;
...
@@ -407,6 +522,16 @@ void *internal_malloc(size_t n)
...
@@ -407,6 +522,16 @@ void *internal_malloc(size_t n)
/* Now patch up in case we over-allocated */
/* Now patch up in case we over-allocated */
trim
(
c
,
n
);
trim
(
c
,
n
);
#ifdef MALLOC_RED_ZONE
c
->
usize
=
user_size
;
c
->
state
|=
M_STATE_USED
;
if
(
need_poison
())
{
chunk_poison_set
(
c
);
}
else
{
c
->
state
&=
~
M_RZ_POISON
;
}
chunk_checksum_set
(
c
);
#endif
return
CHUNK_TO_MEM
(
c
);
return
CHUNK_TO_MEM
(
c
);
}
}
...
@@ -461,6 +586,9 @@ void *internal_realloc(void *p, size_t n)
...
@@ -461,6 +586,9 @@ void *internal_realloc(void *p, size_t n)
struct
chunk
*
self
,
*
next
;
struct
chunk
*
self
,
*
next
;
size_t
n0
,
n1
;
size_t
n0
,
n1
;
void
*
new
;
void
*
new
;
#ifdef MALLOC_RED_ZONE
size_t
user_size
=
n
;
#endif
if
(
!
p
)
return
internal_malloc
(
n
);
if
(
!
p
)
return
internal_malloc
(
n
);
if
(
!
n
)
{
if
(
!
n
)
{
...
@@ -472,6 +600,12 @@ void *internal_realloc(void *p, size_t n)
...
@@ -472,6 +600,12 @@ void *internal_realloc(void *p, size_t n)
self
=
MEM_TO_CHUNK
(
p
);
self
=
MEM_TO_CHUNK
(
p
);
n1
=
n0
=
CHUNK_SIZE
(
self
);
n1
=
n0
=
CHUNK_SIZE
(
self
);
#ifdef MALLOC_RED_ZONE
/* Not a valid chunk */
if
(
!
(
self
->
state
&
M_STATE_USED
))
a_crash
();
if
(
chunk_checksum_check
(
self
))
a_crash
();
if
(
self
->
state
&
M_RZ_POISON
)
chunk_poison_check
(
self
);
#endif
if
(
IS_MMAPPED
(
self
))
{
if
(
IS_MMAPPED
(
self
))
{
size_t
extra
=
self
->
psize
;
size_t
extra
=
self
->
psize
;
...
@@ -479,6 +613,10 @@ void *internal_realloc(void *p, size_t n)
...
@@ -479,6 +613,10 @@ void *internal_realloc(void *p, size_t n)
size_t
oldlen
=
n0
+
extra
;
size_t
oldlen
=
n0
+
extra
;
size_t
newlen
=
n
+
extra
;
size_t
newlen
=
n
+
extra
;
/* Crash on realloc of freed chunk */
/* Crash on realloc of freed chunk */
#ifdef MALLOC_RED_ZONE
/* Wrong malloc type */
if
(
!
(
self
->
state
&
M_STATE_MMAP
))
a_crash
();
#endif
if
(
extra
&
1
)
a_crash
();
if
(
extra
&
1
)
a_crash
();
if
(
newlen
<
PAGE_SIZE
&&
(
new
=
internal_malloc
(
n
-
OVERHEAD
)))
{
if
(
newlen
<
PAGE_SIZE
&&
(
new
=
internal_malloc
(
n
-
OVERHEAD
)))
{
n0
=
n
;
n0
=
n
;
...
@@ -491,6 +629,15 @@ void *internal_realloc(void *p, size_t n)
...
@@ -491,6 +629,15 @@ void *internal_realloc(void *p, size_t n)
goto
copy_realloc
;
goto
copy_realloc
;
self
=
(
void
*
)(
base
+
extra
);
self
=
(
void
*
)(
base
+
extra
);
self
->
csize
=
newlen
-
extra
;
self
->
csize
=
newlen
-
extra
;
#ifdef MALLOC_RED_ZONE
self
->
usize
=
user_size
;
if
(
need_poison
())
{
chunk_poison_set
(
self
);
}
else
{
self
->
state
&=
~
M_RZ_POISON
;
}
chunk_checksum_set
(
self
);
#endif
return
CHUNK_TO_MEM
(
self
);
return
CHUNK_TO_MEM
(
self
);
}
}
...
@@ -505,6 +652,10 @@ void *internal_realloc(void *p, size_t n)
...
@@ -505,6 +652,10 @@ void *internal_realloc(void *p, size_t n)
if
(
n
>
n1
&&
alloc_fwd
(
next
))
{
if
(
n
>
n1
&&
alloc_fwd
(
next
))
{
n1
+=
CHUNK_SIZE
(
next
);
n1
+=
CHUNK_SIZE
(
next
);
next
=
NEXT_CHUNK
(
next
);
next
=
NEXT_CHUNK
(
next
);
#ifdef MALLOC_RED_ZONE
/* alloc forward arises, remove the poison tag */
self
->
state
&=
~
M_RZ_POISON
;
#endif
}
}
/* FIXME: find what's wrong here and reenable it..? */
/* FIXME: find what's wrong here and reenable it..? */
if
(
0
&&
n
>
n1
&&
alloc_rev
(
self
))
{
if
(
0
&&
n
>
n1
&&
alloc_rev
(
self
))
{
...
@@ -518,6 +669,15 @@ void *internal_realloc(void *p, size_t n)
...
@@ -518,6 +669,15 @@ void *internal_realloc(void *p, size_t n)
if
(
n
<=
n1
)
{
if
(
n
<=
n1
)
{
//memmove(CHUNK_TO_MEM(self), p, n0-OVERHEAD);
//memmove(CHUNK_TO_MEM(self), p, n0-OVERHEAD);
trim
(
self
,
n
);
trim
(
self
,
n
);
#ifdef MALLOC_RED_ZONE
self
->
usize
=
user_size
;
if
(
need_poison
())
{
chunk_poison_set
(
self
);
}
else
{
self
->
state
&=
~
M_RZ_POISON
;
}
chunk_checksum_set
(
self
);
#endif
return
CHUNK_TO_MEM
(
self
);
return
CHUNK_TO_MEM
(
self
);
}
}
...
@@ -526,7 +686,12 @@ copy_realloc:
...
@@ -526,7 +686,12 @@ copy_realloc:
new
=
internal_malloc
(
n
-
OVERHEAD
);
new
=
internal_malloc
(
n
-
OVERHEAD
);
if
(
!
new
)
return
0
;
if
(
!
new
)
return
0
;
copy_free_ret:
copy_free_ret:
#ifndef MALLOC_RED_ZONE
memcpy
(
new
,
p
,
n0
-
OVERHEAD
);
memcpy
(
new
,
p
,
n0
-
OVERHEAD
);
#else
memcpy
(
new
,
p
,
self
->
usize
<
user_size
?
self
->
usize
:
user_size
);
chunk_checksum_set
(
self
);
#endif
internal_free
(
CHUNK_TO_MEM
(
self
));
internal_free
(
CHUNK_TO_MEM
(
self
));
return
new
;
return
new
;
}
}
...
@@ -571,6 +736,10 @@ void __bin_chunk(struct chunk *self)
...
@@ -571,6 +736,10 @@ void __bin_chunk(struct chunk *self)
reclaim
=
1
;
reclaim
=
1
;
next
=
NEXT_CHUNK
(
next
);
next
=
NEXT_CHUNK
(
next
);
}
}
#ifdef MALLOC_RED_ZONE
/* if poisoned chunk is combined, we should remove the poisoned tag */
self
->
state
&=
~
M_RZ_POISON
;
#endif
}
}
if
(
!
(
mal
.
binmap
&
1ULL
<<
i
))
if
(
!
(
mal
.
binmap
&
1ULL
<<
i
))
...
@@ -600,9 +769,15 @@ void __bin_chunk(struct chunk *self)
...
@@ -600,9 +769,15 @@ void __bin_chunk(struct chunk *self)
#else
#else
__mmap
((
void
*
)
a
,
b
-
a
,
PROT_READ
|
PROT_WRITE
,
__mmap
((
void
*
)
a
,
b
-
a
,
PROT_READ
|
PROT_WRITE
,
MAP_PRIVATE
|
MAP_ANONYMOUS
|
MAP_FIXED
,
-
1
,
0
);
MAP_PRIVATE
|
MAP_ANONYMOUS
|
MAP_FIXED
,
-
1
,
0
);
#endif
#ifdef MALLOC_RED_ZONE
self
->
state
&=
~
M_RZ_POISON
;
#endif
#endif
}
}
#ifdef MALLOC_RED_ZONE
chunk_checksum_set
(
self
);
#endif
unlock_bin
(
i
);
unlock_bin
(
i
);
}
}
...
@@ -611,6 +786,10 @@ static void unmap_chunk(struct chunk *self)
...
@@ -611,6 +786,10 @@ static void unmap_chunk(struct chunk *self)
size_t
extra
=
self
->
psize
;
size_t
extra
=
self
->
psize
;
char
*
base
=
(
char
*
)
self
-
extra
;
char
*
base
=
(
char
*
)
self
-
extra
;
size_t
len
=
CHUNK_SIZE
(
self
)
+
extra
;
size_t
len
=
CHUNK_SIZE
(
self
)
+
extra
;
#ifdef MALLOC_RED_ZONE
/* Wrong chunk type */
if
(
!
(
self
->
state
&
M_STATE_MMAP
))
a_crash
();
#endif
/* Crash on double free */
/* Crash on double free */
if
(
extra
&
1
)
a_crash
();
if
(
extra
&
1
)
a_crash
();
__munmap
(
base
,
len
);
__munmap
(
base
,
len
);
...
@@ -631,6 +810,11 @@ static void quarantine_contained(struct chunk *self)
...
@@ -631,6 +810,11 @@ static void quarantine_contained(struct chunk *self)
struct
chunk
*
prev
;
struct
chunk
*
prev
;
void
*
key
;
void
*
key
;
#ifdef MALLOC_RED_ZONE
/* Wrong chunk type */
if
(
!
(
self
->
state
&
M_STATE_BRK
))
a_crash
();
#endif
lock_quarantine
(
i
);
lock_quarantine
(
i
);
key
=
mal
.
quarantine
[
i
].
key
;
key
=
mal
.
quarantine
[
i
].
key
;
cur
=
encode_chunk
(
mal
.
quarantine
[
i
].
head
,
key
);
cur
=
encode_chunk
(
mal
.
quarantine
[
i
].
head
,
key
);
...
@@ -657,8 +841,22 @@ static void quarantine_bin(struct chunk *self)
...
@@ -657,8 +841,22 @@ static void quarantine_bin(struct chunk *self)
void
*
key
;
void
*
key
;
int
i
;
int
i
;
#ifdef MALLOC_RED_ZONE
self
->
state
&=
~
M_STATE_USED
;
#endif
/* Avoid quarantining large memory */
/* Avoid quarantining large memory */
if
(
size
>
QUARANTINE_THRESHOLD
)
{
if
(
size
>
QUARANTINE_THRESHOLD
)
{
#ifdef MALLOC_RED_ZONE
self
->
usize
=
POINTER_USAGE
;
if
((
self
->
psize
&
self
->
csize
&
NEXT_CHUNK
(
self
)
->
csize
&
C_INUSE
)
&&
need_poison
())
{
/* Self will not be combined mostly */
chunk_poison_set
(
self
);
}
else
{
self
->
state
&=
~
M_RZ_POISON
;
}
chunk_checksum_set
(
self
);
#endif
__bin_chunk
(
self
);
__bin_chunk
(
self
);
return
;
return
;
}
}
...
@@ -677,6 +875,9 @@ static void quarantine_bin(struct chunk *self)
...
@@ -677,6 +875,9 @@ static void quarantine_bin(struct chunk *self)
/* Bin the quarantined chunk */
/* Bin the quarantined chunk */
do
{
do
{
next
=
encode_chunk
(
cur
->
next
,
key
);
next
=
encode_chunk
(
cur
->
next
,
key
);
#ifdef MALLOC_RED_ZONE
if
(
cur
->
state
&
M_RZ_POISON
)
chunk_poison_check
(
cur
);
#endif
__bin_chunk
(
cur
);
__bin_chunk
(
cur
);
cur
=
next
;
cur
=
next
;
}
while
(
cur
!=
QUARANTINE_TO_CHUNK
(
i
));
}
while
(
cur
!=
QUARANTINE_TO_CHUNK
(
i
));
...
@@ -692,6 +893,16 @@ static void quarantine_bin(struct chunk *self)
...
@@ -692,6 +893,16 @@ static void quarantine_bin(struct chunk *self)
mal
.
quarantined_size
[
i
]
+=
size
;
mal
.
quarantined_size
[
i
]
+=
size
;
mal
.
quarantined_count
[
i
]
+=
1
;
mal
.
quarantined_count
[
i
]
+=
1
;
#ifdef MALLOC_RED_ZONE
if
(
need_poison
())
{
self
->
usize
=
POINTER_USAGE
;
chunk_poison_set
(
self
);
}
else
{
self
->
state
&=
~
M_RZ_POISON
;
}
chunk_checksum_set
(
self
);
#endif
unlock_quarantine
(
i
);
unlock_quarantine
(
i
);
}
}
#endif
#endif
...
@@ -711,6 +922,12 @@ void internal_free(void *p)
...
@@ -711,6 +922,12 @@ void internal_free(void *p)
struct
chunk
*
self
=
MEM_TO_CHUNK
(
p
);
struct
chunk
*
self
=
MEM_TO_CHUNK
(
p
);
#ifdef MALLOC_RED_ZONE
/* This is not a valid chunk for freeing */
if
(
chunk_checksum_check
(
self
))
a_crash
();
if
(
!
(
self
->
state
&
M_STATE_USED
))
a_crash
();
if
(
self
->
state
&
M_RZ_POISON
)
chunk_poison_check
(
self
);
#endif
if
(
IS_MMAPPED
(
self
))
if
(
IS_MMAPPED
(
self
))
unmap_chunk
(
self
);
unmap_chunk
(
self
);
else
{
else
{
...
@@ -739,5 +956,10 @@ void __malloc_donate(char *start, char *end)
...
@@ -739,5 +956,10 @@ void __malloc_donate(char *start, char *end)
struct
chunk
*
c
=
MEM_TO_CHUNK
(
start
),
*
n
=
MEM_TO_CHUNK
(
end
);
struct
chunk
*
c
=
MEM_TO_CHUNK
(
start
),
*
n
=
MEM_TO_CHUNK
(
end
);
c
->
psize
=
n
->
csize
=
C_INUSE
;
c
->
psize
=
n
->
csize
=
C_INUSE
;
c
->
csize
=
n
->
psize
=
C_INUSE
|
(
end
-
start
);
c
->
csize
=
n
->
psize
=
C_INUSE
|
(
end
-
start
);
#ifdef MALLOC_RED_ZONE
c
->
usize
=
POINTER_USAGE
;
c
->
state
=
M_STATE_BRK
;
chunk_checksum_set
(
c
);
#endif
__bin_chunk
(
c
);
__bin_chunk
(
c
);
}
}
porting/linux/user/src/malloc/malloc_usable_size.c
0 → 100644
浏览文件 @
320c0c4c
#include <malloc.h>
#include "malloc_impl.h"
#include "malloc_config.h"
#ifdef MALLOC_RED_ZONE
#include "atomic.h"
#endif
hidden
void
*
(
*
const
__realloc_dep
)(
void
*
,
size_t
)
=
realloc
;
size_t
malloc_usable_size
(
void
*
p
)
{
#ifndef MALLOC_RED_ZONE
return
p
?
CHUNK_SIZE
(
MEM_TO_CHUNK
(
p
))
-
OVERHEAD
:
0
;
#else
struct
chunk
*
c
;
if
(
!
p
)
{
return
0
;
}
c
=
MEM_TO_CHUNK
(
p
);
if
(
chunk_checksum_check
(
c
))
{
a_crash
();
}
if
(
!
(
c
->
state
&
M_STATE_USED
))
{
return
0
;
}
return
c
->
usize
;
#endif
}
porting/linux/user/src/malloc/memalign.c
0 → 100644
浏览文件 @
320c0c4c
#include <stdlib.h>
#include <stdint.h>
#include <errno.h>
#include "malloc_impl.h"
#include "malloc_config.h"
void
*
__memalign
(
size_t
align
,
size_t
len
)
{
unsigned
char
*
mem
,
*
new
;
if
((
align
&
-
align
)
!=
align
)
{
errno
=
EINVAL
;
return
0
;
}
if
(
len
>
SIZE_MAX
-
align
||
__malloc_replaced
)
{
errno
=
ENOMEM
;
return
0
;
}
if
(
align
<=
SIZE_ALIGN
)
return
malloc
(
len
);
if
(
!
(
mem
=
malloc
(
len
+
align
-
1
)))
return
0
;
new
=
(
void
*
)((
uintptr_t
)
mem
+
align
-
1
&
-
align
);
if
(
new
==
mem
)
return
mem
;
struct
chunk
*
c
=
MEM_TO_CHUNK
(
mem
);
struct
chunk
*
n
=
MEM_TO_CHUNK
(
new
);
if
(
IS_MMAPPED
(
c
))
{
/* Apply difference between aligned and original
* address to the "extra" field of mmapped chunk.
*/
n
->
psize
=
c
->
psize
+
(
new
-
mem
);
n
->
csize
=
c
->
csize
-
(
new
-
mem
);
#ifdef MALLOC_RED_ZONE
n
->
usize
=
len
;
n
->
state
=
M_STATE_MMAP
|
M_STATE_USED
;
chunk_checksum_set
(
n
);
#endif
return
new
;
}
struct
chunk
*
t
=
NEXT_CHUNK
(
c
);
/* Split the allocated chunk into two chunks. The aligned part
* that will be used has the size in its footer reduced by the
* difference between the aligned and original addresses, and
* the resulting size copied to its header. A new header and
* footer are written for the split-off part to be freed. */
n
->
psize
=
c
->
csize
=
C_INUSE
|
(
new
-
mem
);
n
->
csize
=
t
->
psize
-=
new
-
mem
;
#ifdef MALLOC_RED_ZONE
/* Update extra overhead */
c
->
usize
=
OVERHEAD
;
c
->
state
=
M_STATE_BRK
;
chunk_checksum_set
(
c
);
n
->
usize
=
len
;
n
->
state
=
M_STATE_BRK
|
M_STATE_USED
;
chunk_checksum_set
(
n
);
#endif
__bin_chunk
(
c
);
return
new
;
}
weak_alias
(
__memalign
,
memalign
);
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录