aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLi RongQing <lirongqing@baidu.com>2019-04-03 22:58:01 -0400
committerDan Williams <dan.j.williams@intel.com>2019-04-07 17:36:04 -0400
commit9dc6488e84b0f64df17672271664752488cd6a25 (patch)
treeb72072d511728753fabada8b2b7cce287072b288
parentd2e5b6436c28e7ee4988497d31122e06217876fb (diff)
libnvdimm/pmem: fix a possible OOB access when read and write pmem
If offset is not zero and length is bigger than PAGE_SIZE, this will cause to out of boundary access to a page memory Fixes: 98cc093cba1e ("block, THP: make block_device_operations.rw_page support THP") Co-developed-by: Liang ZhiCheng <liangzhicheng@baidu.com> Signed-off-by: Liang ZhiCheng <liangzhicheng@baidu.com> Signed-off-by: Li RongQing <lirongqing@baidu.com> Reviewed-by: Ira Weiny <ira.weiny@intel.com> Reviewed-by: Jeff Moyer <jmoyer@redhat.com> Signed-off-by: Dan Williams <dan.j.williams@intel.com>
-rw-r--r--drivers/nvdimm/pmem.c8
1 files changed, 4 insertions, 4 deletions
diff --git a/drivers/nvdimm/pmem.c b/drivers/nvdimm/pmem.c
index bc2f700feef8..0279eb1da3ef 100644
--- a/drivers/nvdimm/pmem.c
+++ b/drivers/nvdimm/pmem.c
@@ -113,13 +113,13 @@ static void write_pmem(void *pmem_addr, struct page *page,
113 113
114 while (len) { 114 while (len) {
115 mem = kmap_atomic(page); 115 mem = kmap_atomic(page);
116 chunk = min_t(unsigned int, len, PAGE_SIZE); 116 chunk = min_t(unsigned int, len, PAGE_SIZE - off);
117 memcpy_flushcache(pmem_addr, mem + off, chunk); 117 memcpy_flushcache(pmem_addr, mem + off, chunk);
118 kunmap_atomic(mem); 118 kunmap_atomic(mem);
119 len -= chunk; 119 len -= chunk;
120 off = 0; 120 off = 0;
121 page++; 121 page++;
122 pmem_addr += PAGE_SIZE; 122 pmem_addr += chunk;
123 } 123 }
124} 124}
125 125
@@ -132,7 +132,7 @@ static blk_status_t read_pmem(struct page *page, unsigned int off,
132 132
133 while (len) { 133 while (len) {
134 mem = kmap_atomic(page); 134 mem = kmap_atomic(page);
135 chunk = min_t(unsigned int, len, PAGE_SIZE); 135 chunk = min_t(unsigned int, len, PAGE_SIZE - off);
136 rem = memcpy_mcsafe(mem + off, pmem_addr, chunk); 136 rem = memcpy_mcsafe(mem + off, pmem_addr, chunk);
137 kunmap_atomic(mem); 137 kunmap_atomic(mem);
138 if (rem) 138 if (rem)
@@ -140,7 +140,7 @@ static blk_status_t read_pmem(struct page *page, unsigned int off,
140 len -= chunk; 140 len -= chunk;
141 off = 0; 141 off = 0;
142 page++; 142 page++;
143 pmem_addr += PAGE_SIZE; 143 pmem_addr += chunk;
144 } 144 }
145 return BLK_STS_OK; 145 return BLK_STS_OK;
146} 146}