security - 了解由未定义行为清理程序 (UBSan) 触发的运行时错误
问题描述
启用未定义的消毒剂时,我在 GNU 科学库 (GSL) 中发现运行时错误:
deque.c:58:11: runtime error: member access within misaligned address 0x0000024010f4 for type 'struct deque', which requires 8 byte alignment
0x0000024010f4: note: pointer points here
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
^
deque.c:59:11: runtime error: member access within misaligned address 0x0000024010f4 for type 'struct deque', which requires 8 byte alignment
0x0000024010f4: note: pointer points here
00 00 00 00 ff ff ff ff 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
^
deque.c:60:11: runtime error: member access within misaligned address 0x0000024010f4 for type 'struct deque', which requires 8 byte alignment
0x0000024010f4: note: pointer points here
00 00 00 00 ff ff ff ff 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
^
deque.c:61:12: runtime error: member access within misaligned address 0x0000024010f4 for type 'struct deque', which requires 8 byte alignment
0x0000024010f4: note: pointer points here
00 00 00 00 ff ff ff ff 00 00 00 00 05 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
^
但我不知道如何导致这些错误,或者如何修复它们。有人可以帮忙解释一下吗?此外,是否应该向开发人员提出一个重要的问题(例如,这种蜜蜂是否可以被用作安全攻击)?
源代码“deque.c”可以在这里找到,运行时错误的相关行如下所示(错误出现在第58、59、60、61行)。
deque 的定义在这里,在同一个文件中:
[添加]代码调用如下,在GSL 的 movstat 库中:deque_init
mmacc.c
static int
mmacc_init(const size_t n, void * vstate)
{
mmacc_state_t * state = (mmacc_state_t *) vstate;
state->n = n;
state->k = 0;
state->xprev = 0.0;
state->rbuf = (ringbuf *) ((unsigned char *) vstate + sizeof(mmacc_state_t));
state->minque = (deque *) ((unsigned char *) state->rbuf + ringbuf_size(n));
state->maxque = (deque *) ((unsigned char *) state->minque + deque_size(n + 1));
ringbuf_init(n, state->rbuf);
deque_init(n + 1, state->minque);
deque_init(n + 1, state->maxque);
return GSL_SUCCESS;
}
上面代码中的函数引用了GSL的movstat库中ringbuf_size
的以下代码。ringbuf.c
static size_t
ringbuf_size(const size_t n)
{
size_t size = 0;
size += sizeof(ringbuf);
size += n * sizeof(ringbuf_type_t); /* b->array */
return size;
}
解决方案
我对图书馆不太熟悉,但这就是您收到错误的原因。
deque.c:58:11: runtime error: member access within misaligned address 0x0000024010f4 for type 'struct deque', which requires 8 byte alignment
0x0000024010f4: note: pointer points here
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
^
我们可以看到,指针确实移动了 4。让我们找出原因。
指针来自
state->minque = (deque *) ((unsigned char *) state->rbuf + ringbuf_size(n));
由此我们可以判断state->rbuf
是未对齐或者ringbuf_size
返回的值未对齐到 8。通过快速测试,我们可以看到,确实ringbuf_size
返回了未对齐的值。我用一个简单的程序打印了n
,sizeof(ringbuf)
和n * sizeof(ringbuf_type_t)
最终结果。
0 24 + 0 = 24
1 24 + 4 = 28
2 24 + 8 = 32
3 24 + 12 = 36
4 24 + 16 = 40
5 24 + 20 = 44
6 24 + 24 = 48
7 24 + 28 = 52
8 24 + 32 = 56
9 24 + 36 = 60
10 24 + 40 = 64
11 24 + 44 = 68
12 24 + 48 = 72
13 24 + 52 = 76
14 24 + 56 = 80
15 24 + 60 = 84
如您所见,如果您使用奇数作为size
,那么您会得到未对齐的指针(在您的情况下是 5)。原因是:
sizeof(size_t) = 8
sizeof(ringbuf_type_t) = 4
示例修复可能是添加
size += (size % sizeof(size_t));
在ringbuf_size
功能上。这样,结果变为:
0 24 + 0 = 24
1 24 + 4 = 32
2 24 + 8 = 32
3 24 + 12 = 40
4 24 + 16 = 40
5 24 + 20 = 48
6 24 + 24 = 48
7 24 + 28 = 56
8 24 + 32 = 56
9 24 + 36 = 64
10 24 + 40 = 64
11 24 + 44 = 72
12 24 + 48 = 72
13 24 + 52 = 80
14 24 + 56 = 80
15 24 + 60 = 88
推荐阅读
- c# - 使用 SSRS 渲染扩展发送自定义 HTTP 标头
- node.js - 在我的 Node 应用程序中,请求参数在 Docker 容器外部按预期返回,但在容器内部读取为未定义。发生了什么?
- postgresql - 在 jOOQ 更新中使用 jsonb_set
- sql - 将 CHAR 字符串列中的所有值转换为 DATETIME?
- sql - 每周查询某一天,回溯一年
- sql - 在 Oracle 中显示 (01/01/2015) 到今天之间的所有日期
- c# - 在 C# 中使用 webhook 中的 JSON
- c# - 如何从代码中选择表单的背景颜色?
- python - 了解总值存储在递归函数中的位置 - Python
- javascript - SQL 查询使用 knexJS 在 DATE 字段上返回缓冲区