USER6 SNMP 把测试 AC 的 auth 打崩了
TL;DR
摸 IPv6 用户表索引时,对 WLSX-USER6-MIB 做了带 IPv6 字面量的 SNMPv2c GET。测试 AC 10.123.x.x(Aruba A72xx)的 /mswitch/bin/auth 连续 SIGSEGV 6 次,User-ID 表被清空,AP 心跳超时掉线。
表头 GETNEXT 单独复现不会崩——这是 keyed GET 自己处理的 bug,不是扫表。core 里 $s2 / BadVA 是 OID 里的 IPv6 字节被当成指针(in6_addr *)。
airpin 因此对 IPv6 查询直接返回 400——不要对 USER6 / user6* 做 GET、GETNEXT、walk、GETBULK。
现场
- 测试 AC:
10.123.x.x(Aruba A72xx,communitypublic) - 企业根:
1.3.6.1.4.1.14823.2.2.1(wlsxEnterpriseMibModules) - MIB:
<aruba-mib path>/aruba-user6.my - crash dump:
<crash.tar>→flash/crash/process/8-31-2026@15-* - plog:
<plog.csv>
⚠️ 不要在这台 AC 上重放下面的 GET。
OID 节点
wlsxUser6MIB = { wlsxEnterpriseMibModules 14 } = .1.3.6.1.4.1.14823.2.2.1.14wlsxUser6InfoGroup = { wlsxSwitchMIB 4 } = .1.3.6.1.4.1.14823.2.2.1.1.4
SWITCH 侧 wlsxSwitchUser6Table(按 IPv6 字符串索引)
索引:user6IpAddress(DisplayString)。列是 wlsxSwitchUser6Entry 下的子节点。
| 节点 | OID | SYNTAX | 索引 |
|---|---|---|---|
wlsxUser6InfoGroup | .1.3.6.1.4.1.14823.2.2.1.1.4 | — | — |
wlsxSwitchUser6Table | .1.4.1 | SEQUENCE OF | — |
wlsxSwitchUser6Entry | .1.4.1.1 | — | { user6IpAddress } |
user6IpAddress | .1.4.1.1.1 | DisplayString,not-accessible | 索引本身 |
user6PhyAddress | .1.4.1.1.2 | MacAddress | { user6IpAddress } |
user6Name | .1.4.1.1.3 | DisplayString | 同上 |
完整:user6PhyAddress = .1.3.6.1.4.1.14823.2.2.1.1.4.1.1.2
USER6 侧 wlsxUser6Table(按 MAC + IPv6 字符串索引)
索引:{ nUser6PhyAddress, nUser6IpAddress }。列是 wlsxUser6Entry 下的子节点。
| 节点 | OID | SYNTAX | 索引 |
|---|---|---|---|
wlsxUser6AllInfoGroup | .14.1 | — | — |
wlsxTotalNumOfUsers6 | .14.1.1 | Unsigned32 | 无 |
wlsxUser6Table | .14.1.2 | SEQUENCE OF | — |
wlsxUser6Entry | .14.1.2.1 | — | { nUser6PhyAddress, nUser6IpAddress } |
nUser6PhyAddress | .14.1.2.1.1 | MacAddress,not-accessible | 索引 |
nUser6IpAddress | .14.1.2.1.2 | DisplayString(0…128),not-accessible | 索引 |
nUser6Name | .14.1.2.1.3 | DisplayString | { mac, ipv6-string } |
nUser6ApLocation | .14.1.2.1.10 | DisplayString | 同上 |
nUser6IsWired | .14.1.2.1.23 | TruthValue | 同上 |
完整前缀:.1.3.6.1.4.1.14823.2.2.1.14.1.2.1.{列}.{mac 6 字节}.{ipv6 DisplayString}
打崩 auth 的 GET(寄存器对得上)
样本地址:2001:da8:215:230c::d69f。
MIB 写的是 DisplayString,当时试了长度前缀 ASCII 和 16 字节二进制两种拼法。
1. 15:32:25 第一次 SIGSEGV(pid 3714)
BadVA / $s2 = 0x32303031 = ASCII "2001",邻寄存器 :215 :230。
PDU 一次 GET 四列,IPv6 都按 DisplayString:长度 23 + 各字符 ASCII:
1 | 23.50.48.48.49.58.100.97.56.58.50.49.53.58.50.51.48.99.58.58.100.54.57.102 |
1 | snmpget -v2c -c public -t 2 -r 1 -On 10.123.x.x \ |
| OID | 节点 | 索引 |
|---|---|---|
…1.1.4.1.1.2 + DisplayString | WLSX-SWITCH-MIB::user6PhyAddress(挂在 USER6 MIB 的 wlsxUser6InfoGroup) | { user6IpAddress } |
…14.1.2.1.3 + 02:81:45:72:83:e3 + DisplayString | WLSX-USER6-MIB::nUser6Name | { nUser6PhyAddress, nUser6IpAddress } |
…14.1.2.1.10 + 同上 MAC | nUser6ApLocation | 同上 |
…14.1.2.1.23 + 同上 MAC | nUser6IsWired | 同上 |
SNMP 客户端当时回 noSuchInstance。15:32:18 起 snmp 对 auth PAPI 127.0.0.1:8214 已 Connection refused。15:32:25 kernel 记 SIGSEGV。
同批还试过 IMPLIED(无长度前缀)的 user6PhyAddress,同样回 noSuchInstance。core 对上的是带长度的 "2001…" 那条。
2. 15:33:23 第二次 SIGSEGV(pid 19122)
BadVA = 0x20010da8,邻寄存器 0xd69f = 2001:0da8:…:d69f 的前 4 字节和末 hextet。
1 | snmpget -v2c -c public -t 2 -r 1 -On 10.123.x.x \ |
user6PhyAddress + 16 字节 InetAddress(2001:da8:215:230c::d69f.packed)。MIB 并不这么编索引。
没打崩的 GETNEXT(单独复现失败是对的)
表头 GETNEXT,没有实例索引,$s2 里不会出现 "2001"。空表回 genError,不是 endOfMibView。
1 | snmpgetnext -v2c -c public -t 3 -r 1 -On 10.123.x.x 1.3.6.1.4.1.14823.2.2.1.1.4.1.1.2 |
| OID | 节点 |
|---|---|
…1.1.4.1.1.2 | user6PhyAddress 列头 |
…14.1.2.1.3 | nUser6Name 列头 |
…14.1.2.1.1 | nUser6PhyAddress 列头(not-accessible) |
随后又对 nUser6Name 加了 MAC 前缀再 GETNEXT(02:81:45:72:83:e3、28:95:29:7d:8b:0b),同样 genError。时间上夹在两次崩之间,但 core 对上的是带 IPv6 的 GET。
crash 摘要
六次同一 PC:auth+0x55e5cc,ldl $5, 0($s2),从 $s2 拷 16 字节。$s2 是 IPv6 字面量,不是合法指针。
| 时间 | pid | BadVA | 解码 |
|---|---|---|---|
| 15:32:25 | 3714 | 0x32303031 | ASCII "2001" |
| 15:33:23 | 19122 | 0x20010da8 | 二进制 2001:0da8 |
| 15:38:39 | 20736 | 0x32303031 | "2001"(继续试 ASCII GET) |
| 15:40:05 | 24984 | 同上 | 同上 |
| 15:45:30 | 27198 | 同上 | 同上 |
| 15:46:26 | 31775 | "2001" + "8:02" "15:2" | exploded 2001:0da8:0215:… |
crash.tar 只留了后 4 次 core;process_crashinfo.log 里 6 次都在。后续几次有 nanny 拉起后再崩的成分,但 BadVA 仍是当时 GET 的 IPv6 编码。
后果:每次重启 Clear User-ID Table with 0 entries;15:47 AP-West / AP-North / AP-Middle heartbeat timeout。
结论
Aruba USER6 这条 SNMP 路径把 OID 里的 IPv6 索引字节当成了 in6_addr *。DisplayString 和 16 字节二进制都会中。这是控制器 bug,不是 GETNEXT 扫表。