From: Jeff Mahoney <jeffm@suse.com>
Subject: nfs: fix memory corruption rooted in get_ih_name pointer math
References: bsc#984107
Patch-mainline: Never, fix for patches.fixes/nfs-idmap-mem-usages.fix

The suse-only patch patches.fixes/nfs-idmap-mem-usages.fix introduced a random
memory corruption due to wrong pointer arithmetic in the new get_ih_name()
function. It has manifested e.g. by page tables overwritten by idmap names.
Correct the pointer arithmetic by following the normal page index / page
offset pattern used elsewhere.

Based on an earlier fix by Vlastimil Babka <vbabka@suse.com>.

Signed-off-by: Jeff Mahoney <jeffm@suse.com>
---
 fs/nfs/idmap.c |   11 +++++++----
 1 file changed, 7 insertions(+), 4 deletions(-)

--- a/fs/nfs/idmap.c
+++ b/fs/nfs/idmap.c
@@ -429,10 +429,13 @@ idmap_name_hash(struct idmap_hashtable*
 
 static char *get_ih_name(struct idmap_hashtable *h, struct idmap_hashent *he)
 {
-	int i = he - h->h_entries;
-	int p = (i * IDMAP_NAMESZ) / PAGE_SIZE;
-	i -= p * PAGE_SIZE;
-	return h->h_names[p] + i * IDMAP_NAMESZ;
+	unsigned int i = he - h->h_entries;
+	unsigned int offset = i * IDMAP_NAMESZ;
+	unsigned int p = offset >> PAGE_SHIFT;
+
+	offset &= (PAGE_SIZE - 1);
+
+	return h->h_names[p] + offset;
 }
 
 static struct idmap_hashent *
