Linux 6.8 初探

Syscalls

listmount & statmount

列出 mount 信息的系统调用,效率不知道。

两个都依赖于 mnt_id_req

struct mnt_id_req {
	__u32 size;
	__u32 spare;
	__u64 mnt_id;
	__u64 param;
};

sizemnt_id_req 的大小,spare 置空,mnt_id 填新增的64位mountid,对于根文件系统的需要 statx 来询问。

paramlistmount 置空,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

正常编译。