这篇文章上次修改于 274 天前,可能其部分内容已经发生变化,如有疑问可询问作者。
Linux 6.8 初探
Syscalls
listmount & statmount
列出 mount
信息的系统调用,效率不知道。
两个都依赖于 mnt_id_req
。
struct mnt_id_req {
__u32 size;
__u32 spare;
__u64 mnt_id;
__u64 param;
};
size
为 mnt_id_req
的大小,spare
置空,mnt_id
填新增的64位mountid
,对于根文件系统的需要 statx
来询问。
param
对 listmount
置空,statmount
写成需要的参数。
#include <sys/syscall.h>
#include <linux/mount.h>
#include <sys/types.h>
#include <linux/stat.h>
#include <unistd.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
typedef unsigned long long u64;
u64 buf[100005];
long statmount(const struct mnt_id_req *req,struct statmount *buf, size_t bufsize,unsigned int flags){
return syscall(__NR_statmount,req,buf,bufsize,flags);
}
long listmount(const struct mnt_id_req *req,u64 *mnt_ids, size_t nr_mnt_ids,unsigned int flags){
return syscall(__NR_listmount,req,mnt_ids,nr_mnt_ids,flags);
}
unsigned char buf3[100005];
int main(){
struct statx statxbuf={0};
unsigned long long rootmntid=statxbuf.stx_mnt_id;
struct mnt_id_req req={0};
req.size=sizeof(struct mnt_id_req);
int ret=statx(0,"/",0,STATX_MNT_ID_UNIQUE,&statxbuf);
if(ret<0){
printf("statx error:%d",ret);
return -1;
}
rootmntid=statxbuf.stx_mnt_id;
req.param=0;
req.mnt_id=rootmntid;
ret=listmount(&req,buf,sizeof(buf)/sizeof(u64),0);
if(ret<=0){
printf("listmount error:%d",ret);
return -2;
}
int n=ret;
struct statmount *buf2=buf3;
for(int i=0;i<n;i++){
req.mnt_id=buf[i];
req.param=STATMOUNT_MNT_ROOT|STATMOUNT_MNT_POINT|STATMOUNT_FS_TYPE|STATMOUNT_MNT_BASIC;
ret=statmount(&req,buf2,sizeof(buf),0);
if(ret<0){
printf("statmount error :%d",ret);
return -3;
}
printf("mnt_root:%s mnt_point:%s fs_type:%s mnt_parent_id:%lld\n",buf2->str+buf2->mnt_root,buf2->str+buf2->mnt_point,buf2->str+buf2->fs_type,buf2->mnt_parent_id);
}
return 0;
}
输出:
mnt_root:/ mnt_point:/sys fs_type:sysfs mnt_parent_id:4294967324
mnt_root:/ mnt_point:/proc fs_type:proc mnt_parent_id:4294967324
mnt_root:/ mnt_point:/dev fs_type:devtmpfs mnt_parent_id:4294967324
mnt_root:/ mnt_point:/dev/pts fs_type:devpts mnt_parent_id:4294967320
mnt_root:/ mnt_point:/run fs_type:tmpfs mnt_parent_id:4294967324
mnt_root:/ mnt_point:/sys/kernel/security fs_type:securityfs mnt_parent_id:4294967318
mnt_root:/ mnt_point:/dev/shm fs_type:tmpfs mnt_parent_id:4294967320
mnt_root:/ mnt_point:/run/lock fs_type:tmpfs mnt_parent_id:4294967322
mnt_root:/ mnt_point:/sys/fs/cgroup fs_type:cgroup2 mnt_parent_id:4294967318
mnt_root:/ mnt_point:/sys/fs/pstore fs_type:pstore mnt_parent_id:4294967318
mnt_root:/ mnt_point:/sys/fs/bpf fs_type:bpf mnt_parent_id:4294967318
mnt_root:/ mnt_point:/proc/sys/fs/binfmt_misc fs_type:autofs mnt_parent_id:4294967319
mnt_root:/ mnt_point:/dev/mqueue fs_type:mqueue mnt_parent_id:4294967320
mnt_root:/ mnt_point:/dev/hugepages fs_type:hugetlbfs mnt_parent_id:4294967320
mnt_root:/ mnt_point:/sys/kernel/debug fs_type:debugfs mnt_parent_id:4294967318
mnt_root:/ mnt_point:/sys/kernel/tracing fs_type:tracefs mnt_parent_id:4294967318
mnt_root:/ mnt_point:/sys/fs/fuse/connections fs_type:fusectl mnt_parent_id:4294967318
mnt_root:/ mnt_point:/sys/kernel/config fs_type:configfs mnt_parent_id:4294967318
mnt_root:/ mnt_point:/run/credentials/systemd-sysusers.service fs_type:ramfs mnt_parent_id:4294967322
mnt_root:/ mnt_point:/boot fs_type:ext4 mnt_parent_id:4294967324
mnt_root:/ mnt_point:/proc/sys/fs/binfmt_misc fs_type:binfmt_misc mnt_parent_id:4294967333
mnt_root:/ mnt_point:/run/user/1000 fs_type:tmpfs mnt_parent_id:4294967322
LSM(安全模块)
不是很懂,写了个可以全部列出来的。
还是很简单,但是SELinux飞哪里去了我就不知道了。
#include <sys/syscall.h>
#include <linux/mount.h>
#include <sys/types.h>
#include <linux/stat.h>
#include <unistd.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <map>
#include <string>
#include <linux/lsm.h>
typedef unsigned long long u64;
typedef unsigned u32;
long lsm_list_modules(u64 *ids, size_t *size, u32 flags){
return syscall(__NR_lsm_list_modules,ids,size,flags);
}
std::map<u64,std::string>mp;
u64 buf[1000005];
int main(){
size_t size;
mp[LSM_ID_UNDEF]="UNDEF";
mp[LSM_ID_CAPABILITY]="CAPABILITY";
mp[LSM_ID_SELINUX]="SELINUX";
mp[LSM_ID_SMACK]="SMACK";
mp[LSM_ID_TOMOYO]="TOMOYO";
mp[LSM_ID_APPARMOR]="APPARMOR";
mp[LSM_ID_YAMA]="YAMA";
mp[LSM_ID_LOADPIN]="LOADPIN";
mp[LSM_ID_SAFESETID]="SAFESETID";
mp[LSM_ID_LOCKDOWN]="LOCKDOWN";
mp[LSM_ID_BPF]="BPF";
mp[LSM_ID_LANDLOCK]="LANDLOCK";
int ret=lsm_list_modules(buf,&size,0);
int cnt=0;
for(int i=0;i<size;i++){
if(buf[i]==LSM_ID_UNDEF){
continue;
}
printf("LSM%d:%s\n",++cnt,mp[buf[i]].c_str());
}
return 0;
}
输出:
LSM1:CAPABILITY
LSM2:LANDLOCK
LSM3:LOCKDOWN
LSM4:YAMA
LSM5:BPF
Nvidia
正常编译。