From 6b146c70c2863bf1e9d5c4a35cbd8426c5a161e7 Mon Sep 17 00:00:00 2001 From: cinap_lenrek Date: Sat, 8 Feb 2014 03:50:41 +0100 Subject: [PATCH] pc64: handle negative file offsets when accessing kernel memory with devproc file offset is 64 bit signed integer, negative offsets are invalid and rejected by the kernel. to still access kernel memory on amd64, we unconditionally clear the sign bit of the 64 bit offset in libmach and devproc sign extends the offset back to a 64 bit address. --- sys/src/9/port/devproc.c | 4 ++++ sys/src/libmach/access.c | 12 +++++++++++- 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/sys/src/9/port/devproc.c b/sys/src/9/port/devproc.c index 57ebebb1a..c49f5f677 100644 --- a/sys/src/9/port/devproc.c +++ b/sys/src/9/port/devproc.c @@ -708,6 +708,10 @@ procread(Chan *c, void *va, long n, vlong off) Waitq *wq; a = va; + + /* sign extend 63 bit to 64 bit */ + off <<= 1; + off >>= 1; offset = off; if(c->qid.type & QTDIR) diff --git a/sys/src/libmach/access.c b/sys/src/libmach/access.c index 784ee6158..6d8ed1f3e 100644 --- a/sys/src/libmach/access.c +++ b/sys/src/libmach/access.c @@ -263,7 +263,17 @@ reloc(Map *map, uvlong addr, vlong *offp) for (i = 0; i < map->nsegs; i++) { if (map->seg[i].inuse) if (map->seg[i].b <= addr && addr < map->seg[i].e) { - *offp = addr + map->seg[i].f - map->seg[i].b; + addr += map->seg[i].f - map->seg[i].b; + + /* + * avoid negative file offsets for kernel + * addresses by clearing the sign bit. + * devproc sign extends back to 64 bit. + */ + addr <<= 1; + addr >>= 1; + + *offp = addr; return &map->seg[i]; } }