Check read() and write() for offset + count wraparound
authorBarret Rhoden <brho@cs.berkeley.edu>
Sat, 2 Mar 2019 00:50:43 +0000 (19:50 -0500)
committerBarret Rhoden <brho@cs.berkeley.edu>
Sat, 2 Mar 2019 00:50:43 +0000 (19:50 -0500)
If you gave a file a very large count and the sum offset + count wrapped
around, you could confuse the system into thinking you had a smaller
file.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
kern/src/ns/fs_file.c
kern/src/ns/sysfile.c

index 2605055..09aa073 100644 (file)
@@ -360,6 +360,8 @@ size_t fs_file_read(struct fs_file *f, uint8_t *buf, size_t count,
        /* These errors should have been caught by higher level code */
        if ((uintptr_t)buf + count < (uintptr_t)buf)
                panic("Bad buf %p + count %p", buf, count);
+       if (offset + count < offset)
+               panic("Bad offset %p + count %p", offset, count);
        if (waserror()) {
                if (so_far) {
                        poperror();
@@ -409,6 +411,8 @@ size_t fs_file_write(struct fs_file *f, const uint8_t *buf, size_t count,
        /* These errors should have been caught by higher level code */
        if ((uintptr_t)buf + count < (uintptr_t)buf)
                panic("Bad buf %p + count %p", buf, count);
+       if (offset + count < offset)
+               panic("Bad offset %p + count %p", offset, count);
        if (waserror()) {
                if (so_far) {
                        write_metadata(f, offset + so_far, false);
index ad13b8b..34e65f0 100644 (file)
@@ -752,6 +752,8 @@ static long rread(int fd, void *va, long n, int64_t * offp)
                        off = *offp;
                if (off < 0)
                        error(EINVAL, ERROR_FIXME);
+               if ((off64_t)off + (size_t)n < (off64_t)off)
+                       error(EINVAL, "bad offset %p + count %p", off, n);
                if (off == 0) {
                        if (offp == NULL) {
                                spin_lock(&c->lock);
@@ -1121,6 +1123,8 @@ static long rwrite(int fd, void *va, long n, int64_t * offp)
        }
        if (off < 0)
                error(EINVAL, ERROR_FIXME);
+       if ((off64_t)off + (size_t)n < (off64_t)off)
+               error(EINVAL, "bad offset %p + count %p", off, n);
        m = devtab[c->type].write(c, va, n, off);
        poperror();