Commits

iru  committed 91c5000

Sanitize I/O lengths. Update TODO

  • Participants
  • Parent commits 1251020

Comments (0)

Files changed (8)

 - Unmount only works when forced.
-- Readdir doesn't return dot and dotdot
-- Implement wstat
+- Readdir doesn't return dot and dotdot.
+- Open with truncation does not work.
+- Implement wstat.
 - Add options to mount: noauth, auth as other user, port, aname
 
 - v9fs pass the fcall up to the functions instead of bcopying data (as in Tread) like us
 	Offtag	= 5,
 
 	Minhd	= Offtag + 2,		/* Minimum 9P header size, independent of message type */
-	Maxhd	= 23,				/* Maximum 9P header size */
+	Maxhd	= 24,				/* Maximum 9P header size */
 };
 
 struct o9fs {
 	struct	mount *mp;
 	struct	vnode *vroot;		/* Local root of the tree */
 	struct	file *servfp;		/* File pointing to the server */
-	long	msize;				/* Maximum size of our payload */
+	long	msize;				/* Maximum 9P message size */
 	
 	/* 
      * Buffers for I/O
 
 #define	O9FS_NOTAG		(u_short)~0U	/* Dummy tag */
 #define	O9FS_NOFID		(uint32_t)~0U	/* Dummy fid */
-#define	O9FS_IOHDRSZ	24				/* ample room for Twrite/Rread header (iounit) */
 
 #define O9FS_GBIT8(p)	((p)[0])
 #define O9FS_GBIT16(p)	((p)[0]|((p)[1]<<8))
 	DRET();
 	return stat;
 }
-	
+
+
+/*
+ * Assume len is a sanitized length
+ */
 uint32_t
 o9fs_rdwr(struct o9fs *fs, struct o9fid *f, uint8_t type, uint32_t len, uint64_t off)
 {
 	O9FS_PBIT16(p + Offtag, o9fs_tag());
 	O9FS_PBIT32(p + Minhd, f->fid);
 	O9FS_PBIT64(p + Minhd + 4, off);
-	if (f->iounit > 0 && len > f->iounit)
-		len = f->iounit;
-	if (len > fs->msize)
-		len = fs->msize - O9FS_IOHDRSZ;
+	O9FS_PBIT32(p + Minhd + 4 + 8, len);
 
-	O9FS_PBIT32(p + Minhd + 4 + 8, len);
 	p += Minhd + 4 + 8 + 4;
 	if (type == O9FS_TWRITE)
 		p += len;

File o9fs_extern.h

 void	_printvp(struct vnode *);
 long	o9fs_mio(struct o9fs *, u_long);
 uint16_t	o9fs_tag(void);
+uint32_t	o9fs_sanelen(struct o9fs *, uint32_t);
 
 /* o9fs_9p.c */
 uint32_t	o9fs_rdwr(struct o9fs *, struct o9fid *, uint8_t, uint32_t, uint64_t);
 	return (uint16_t)arc4random()%0xFFFF;
 }
 
+uint32_t
+o9fs_sanelen(struct o9fs *fs, uint32_t n)
+{
+	if (n > fs->msize - Maxhd)
+		n = fs->msize - Maxhd;
+	return n;
+}

File o9fs_vfsops.c

 
 		
 	
-static long
+static uint32_t
 o9fs_version(struct o9fs *fs, uint32_t msize)
 {
 	long n;
 	u_char *p;
 
 	if (fs == NULL)
-		return -1;
+		return 0;
 
 	p = fs->outbuf;
 
 
 	n = o9fs_mio(fs, 19);
 	if (n <= 0)
-		return -1;
-	return fs->msize = O9FS_GBIT16(fs->inbuf + Minhd);
+		return 0;
+	return O9FS_GBIT16(fs->inbuf + Minhd);
 }	
 
 struct o9fid *
 	struct o9fs *fs;
 	struct vnode *rvp;
 	struct o9fid *fid;
+	uint32_t msize;
 
 	fs = (struct o9fs *) malloc(sizeof(struct o9fs), M_MISCFSMNT, M_WAITOK | M_ZERO);
 	fs->mp = mp;
 	TAILQ_INIT(&fs->freeq);
 	fs->nextfid = 0;	
 
-	if(o9fs_version(fs, 8192+O9FS_IOHDRSZ) < 0)
+	msize = o9fs_version(fs, 8192+Maxhd);
+	if (msize < Maxhd)
 		return EIO;
+	fs->msize = msize;
 
 	fid = o9fs_attach(fs, o9fs_auth(fs, "none", ""), "iru", "");
 	if (fid == NULL)
-		return EIO;	
+		return EIO;
 
 	return o9fs_allocvp(fs->mp, fid, &fs->vroot, VROOT);
 }

File o9fs_vnops.c

 	if (uio->uio_resid == 0)
 		return 0;
 
-	n = o9fs_rdwr(fs, f, O9FS_TREAD, uio->uio_resid, uio->uio_offset);
+	n = o9fs_rdwr(fs, f, O9FS_TREAD, o9fs_sanelen(fs, uio->uio_resid), uio->uio_offset);
 	if (n > 0)
 		return uiomove(fs->inbuf + Minhd + 4, n, uio);
 	return n;
 	buf = malloc(O9FS_DIRMAX, M_O9FS, M_WAITOK);
 
 	for (;;) {
+		len = o9fs_sanelen(fs, len);
 		nbuf = o9fsrealloc(buf, ts+O9FS_DIRMAX-n, ts+O9FS_DIRMAX);
 		buf = nbuf;
 		n = o9fs_rdwr(fs, f, O9FS_TREAD, len, f->offset);
 	struct uio *uio;
 	struct o9fid *f;
 	struct o9fs *fs;
-	int ioflag, error, msize;
+	int ioflag, error;
 	uint32_t n;
-	int64_t len;
 	off_t offset;
 	DIN();
 
 		return EINVAL;
 	}
 
-	if (uio->uio_resid == 0)
+	if (uio->uio_resid == 0) {
+		DRET();
 		return 0;
+	}
 
 	offset = uio->uio_offset;
 	if (ioflag & IO_APPEND) {
 			offset = st.st_size;
 	}
 
-	len = uio->uio_resid;
-	error = uiomove(fs->outbuf + Minhd + 4 + 8 + 4, len, uio);
-	n = o9fs_rdwr(fs, f, O9FS_TWRITE, len, offset);
+	n = o9fs_sanelen(fs, uio->uio_resid);
+	error = uiomove(fs->outbuf + Minhd + 4 + 8 + 4, n, uio);
+	if (error) {
+		DRET();
+		return -1;
+	}
+
+	n = o9fs_rdwr(fs, f, O9FS_TWRITE, n, offset);
 	if (n < 0) {
 		DRET();
 		return -1;
 	}
+
 	f->offset = offset + n;
 	DRET();
-	return error;
+	return n;
 }
 
 int

File simple-test.sh

-#!/bin/sh
-
-if [[ $1 == "-v" ]]; then
-	try() {
-		$* || exit $?
-    }
-	shift
-else
-	try() {
-		$* >/dev/null 2>&1 || exit $?
-    }
-fi
-
+#!/bin/ksh
 
 [[ -z $1 ]] && mtpt=/mnt || mtpt="$1"
 
 testdir=$mtpt/tmp/testdir
-testfile=$testdir/test0
+testfile=$testdir/file0
+
+try() {
+	$* || exit 1 
+}
 
 domount() {
 	try mount/mount_o9fs '10.0.2.1!5648' $mtpt
 }
 
 domount
-mkdir
-create
-readdir
-lreaddir
-xwrite
-xread
-remove
-readdir
-lreaddir
-rmdir
-dounmount
+#mkdir
+#create
+#readdir
+#lreaddir
+#xwrite
+#xread
+#remove
+#readdir
+#lreaddir
+#rmdir
+#dounmount