如何修复proxify中cannot initialize proxy_sock map报错?
修复proxify工具eBPF模式启动时的"socket operation on non-socket"错误
问题背景
使用Go开发的proxify工具,通过make proxify编译后执行sudo ./proxify -b启用eBPF steering模式时,出现如下报错:
2024/04/17 11:35:34 cannot initialize proxy_sock map: update: socket operation on non-socket:
该错误关联代码第99行:
fdString := strings.Split(pidFD[1], "f")[0]
问题分析
这段代码用于从进程FD信息中提取文件描述符的数字部分,但存在两个核心问题:
- 未校验
pidFD数组的格式是否符合预期,若数组长度不足2或第二个元素不含"f"分隔符,会导致拆分失败或得到无效的FD字符串 - 未验证提取出的FD是否为socket类型,直接传入eBPF map更新操作,当FD对应非socket资源时就会触发"socket operation on non-socket"错误
修复方案
对代码添加格式校验、FD有效性检查,过滤无效条目后再执行eBPF操作,修改后的代码示例如下:
import ( "strconv" "syscall" "strings" "log" ) // 替换原第99行附近的逻辑 if len(pidFD) < 2 { log.Printf("skip invalid pidFD entry: %v", pidFD) continue } fdPart := pidFD[1] if !strings.Contains(fdPart, "f") { log.Printf("skip unexpected fd format: %v", pidFD) continue } fdString := strings.Split(fdPart, "f")[0] fd, err := strconv.Atoi(fdString) if err != nil { log.Printf("skip invalid fd string %s: %v", fdString, err) continue } // 检查FD是否为socket类型 var stat syscall.Stat_t if err := syscall.Fstat(fd, &stat); err != nil { log.Printf("skip unstatable fd %d: %v", fd, err) continue } if (stat.Mode & syscall.S_IFMT) != syscall.S_IFSOCK { log.Printf("skip non-socket fd %d", fd) continue } // 继续执行原有的eBPF proxy_sock map更新逻辑
修复说明
- 格式校验:确保
pidFD数组长度足够且包含预期的分隔符,避免索引越界或拆分出无效内容 - FD有效性验证:通过
syscall.Fstat检查FD的类型,仅保留socket类型的FD - 异常处理:对所有校验失败的情况记录日志并跳过,不中断整个初始化流程,保证工具能正常启动并处理有效socket
内容的提问来源于stack exchange,提问作者NobinPegasus
相关产品推荐
相关产品推荐

