为Linux 6.9.8新增文件复制系统调用时vfs_stat失败求助
排查mycopy系统调用"Failed to stat source file"错误的核心方向
1. 核对vfs_stat的内核调用规范
Linux 6.9.x中vfs_stat不能直接接收用户态路径指针,必须先通过内核安全API转换路径:
- 错误用法:直接传递用户态路径字符串给
vfs_stat,内核无法解析用户态地址空间的路径 - 正确流程:
long sys_mycopy(const char __user *src_path, const char __user *dest_path) { struct path src; struct kstat stat_buf; int ret; // 将用户态路径转为内核可识别的struct path ret = getname(src_path, &src); if (ret) return ret; // 调用vfs_stat ret = vfs_stat(&src, &stat_buf); path_put(&src); // 必须释放路径引用,避免内存泄漏 if (ret) return ret; // 后续复制逻辑... }
如果你的代码跳过了getname()步骤,这必然导致路径解析失败。
2. 验证系统调用参数传递的一致性
- 检查
syscall_64.tbl中mycopy的定义格式是否正确:463 64 mycopy sys_mycopy - 用户态测试代码的syscall参数类型必须和内核
sys_mycopy函数完全匹配,比如内核函数参数是const char __user *,用户态就要传递用户态字符串指针,不能出现类型不匹配导致的地址错乱。
3. 排查内核态权限与路径访问逻辑
即使目录设了777,也要注意:
vfs_stat会检查路径上每一级目录的执行权限(搜索权限),比如/usr/test/file.txt需要/、/usr、/usr/test都有执行权限,用getfacl /usr/test确认是否存在ACL限制。- 内核态不能直接访问用户态内存,必须用
copy_from_user()或getname()这类安全函数,否则会触发页错误,间接导致stat操作失败。
4. 打印内核错误码定位根因
在sys_mycopy中加入内核日志打印,获取vfs_stat的具体错误码:
ret = vfs_stat(&src, &stat_buf); if (ret) { pr_err("mycopy: vfs_stat failed, errno=%d\n", ret); path_put(&src); return ret; }
通过dmesg查看日志:
-ENOENT:源文件确实不存在-EACCES:权限不足(含目录搜索权限)-EFAULT:用户态路径指针无效
5. 验证路径本身的有效性
先在用户态执行stat /绝对路径/源文件确认文件存在,再将完全相同的路径传入mycopy系统调用,排除路径拼写错误或文件不存在的基础问题。
内容的提问来源于stack exchange,提问作者Konrad Gerrens
相关产品推荐
相关产品推荐

