【问题标题】:Kernel address poising by clearing upper bits?通过清除高位来准备内核地址?
【发布时间】:2017-07-06 17:45:15
【问题描述】:

Linux 中是否有某种机制通过将高 16 位归零来毒化地址?

我正在调试 Intel x86-64 机器上的内核崩溃。导致崩溃的指令尝试访问0x880139f3da00的地址:

crash> bt
R10: 0000000000000001  R11: 0000000000000001  R12: 0000880139f3da00
                                              ~~~~~~~~~~~~~~~~~~~~~

crash> p arp_tbl.nht->hash_buckets[255]
$66 = (struct neighbour *) 0x880139f3da00

crash> p *arp_tbl.nht->hash_buckets[255]
Cannot access memory at address 0x880139f3da00

hash_buckets 表有效:

crash> p arp_tbl.nht->hash_buckets[253]
$70 = (struct neighbour *) 0xffff88007325ae00
$71 = {
  next = 0x0, 
  tbl = 0xffffffff81abbf20 <arp_tbl>, 

将高位字设置为0xffff 使地址有效并返回有效的数据结构:

crash> p *((struct neighbour *)0xffff880139f3da00)
$73 = {
  next = 0xffff88006de69a00, 
  tbl = 0xffffffff81abbf20 <arp_tbl>, 
  ... rest looks reasonable too ...

结构由 RCU 操作更新(例如,很可能由 neigh_flush_dev() 中的这些操作)。那么,地址以这种方式变为无效的原因可能是什么?

我可以排除硬件缺陷(在两台机器上和不同的地址上看到)。系统运行 CentOS 7,内核 3.10.0-514.6.1.el7.centos.plus.x86_64 到 3.10.0-514.21.2.el7.centos.plus.x86_64。

更新

从另一个故障转储中,我看到一个带有

的 IPv6 数据包的 skb
crash> p *((struct sk_buff *)0xffff880070e25e00)
$57 = {
  transport_header = 54, 
  network_header = 14, 
  mac_header = 0, 
  ...
  head = 0xffff880138e28000 "", 
  data = 0xffff880138e2800e "`", 
  ...
}

在写入前 0x8 个字节时会崩溃

#define HH_DATA_MOD 16

static inline int neigh_hh_output(const struct hh_cache *hh, struct sk_buff *skb)
{
                if (likely(hh_len <= HH_DATA_MOD)) {
                        memcpy(skb->data - HH_DATA_MOD, hh->hh_data, HH_DATA_MOD);   <<<<<

这可以解释为什么两个字节被覆盖 (16 - 14)。

【问题讨论】:

    标签: linux-kernel crash x86-64 centos7 rcu


    【解决方案1】:

    你能检查读取这个地址的内存位置吗?通常这种“部分零”读取是在该区域上运行 memset 的结果。在这个 cpu 触发崩溃之后,可能有足够的时间让其他正在修改该区域的人完成归零,甚至可能用其他数据填充它。

    到目前为止,没有理由怀疑 rcu 在这里扮演任何角色

    这绝对不是内核所做的“中毒”(以这种方式做会很奇怪)。但是,如果崩溃是可重现的(你说它发生在至少 2 台不同的机器上?)那么运行调试内核可能会有所帮助,尤其是在启用了平板调试的情况下。

    【讨论】:

    • 我想 KASAN 是这里追踪它的最佳选择。
    • 感谢您的建议;不幸的是,“可重现”的意思是“每周一次”:(它发生在我无法运行开发内核的生产机器上。但我得到了另一个线索。
    • 0andriy,这个内核中没有 kasan,这很容易检查。我怀疑你的反对意见是来自你,我再次发现自己对你的反应感到困惑。
    • @employeeofthemonth 不,我没有投反对票。你在这里的回答对我来说听起来很理智。
    • 那么抱歉。这些不加解释的投票让我真的很难过。
    猜你喜欢
    • 1970-01-01
    • 2015-03-26
    • 2020-10-06
    • 2017-08-29
    • 1970-01-01
    • 2018-04-12
    • 2011-12-05
    • 2018-07-06
    • 1970-01-01
    相关资源
    最近更新 更多