我的程序在已写入用户指定目录的二进制文件上调用exec()。如果目录位于以“noexec”挂载的树中,则exec()将失败并显示EACCES。
我希望能够找出一个目录是否使用noexec挂载,而不是fcntl(),stat()或mount()都没有返回此信息(来自阅读联机帮助页) )。查看exec系统调用的内核源代码,看起来此信息存储在inode的元数据中,我看不到任何系统调用返回此信息。
673 struct nameidata nd;
(..)
677 err = path_lookup_open(AT_FDCWD, name, LOOKUP_FOLLOW, &nd, FMODE_READ|FMODE_EXEC);
678 file = ERR_PTR(err);
(..)
682 file = ERR_PTR(-EACCES);
683 if (!(nd.mnt->mnt_flags & MNT_NOEXEC) &&
684 S_ISREG(inode->i_mode)) {
有谁知道这样做的方法?
感谢。
答案 0 :(得分:1)
您可以使用statvfs()
struct statvfs st;
inr rc = statvfs("/mnt/foo", &st);
if (rc == -1)
error();
if (st.f_flag & ST_NOEXEC) {
//no exec flags was set
}
答案 1 :(得分:0)
您是否考虑阅读/proc/mounts
然后确定您的程序二进制文件所在的文件系统,可能使用statfs(2)和/或realpath(3)?
但是你总是应该关心并处理execve(2)和相关exec
函数的失败,这些函数可能由于各种原因而失败。
execve
可能失败的方式很多,其中一些不易重现;同样是因为fork
或任何其他系统调用失败。
我会离开并报告EACCESS
错误(execve
),或者,如果你绝对想要抓住&解释更多noexec
挂载选项,执行更复杂的事情(statfs
和/或realpath
以及扫描/proc/mounts
或/proc/self/mounts
)之后EACCESS
失败。
在execve
之前测试二进制路径没有多大意义......只需在...之后报告错误