CVE-2019-19927 (published 2019-12-31T02:15Z)

In the Linux kernel 5.0.0-rc7 (as distributed in ubuntu/linux.git on kernel.ubuntu.com), mounting a crafted f2fs filesystem image and performing some operations can lead to slab-out-of-bounds read access in ttm_put_pages in drivers/gpu/drm/ttm/ttm_page_alloc.c. This is related to the vmwgfx or ttm module.

Severity: LOW
CVSS v2 base score: 3.6 (AV:L/AC:L/Au:N/C:P/I:N/A:P)
CVSS v3 base score: 6.0, MEDIUM (CVSS:3.1/AV:L/AC:L/PR:H/UI:N/S:U/C:H/I:N/A:H)

Weakness information:
cwe_id: CWE-125
cwe_name: Out-of-bounds Read
description: The product reads data past the end, or before the beginning, of the intended buffer.
extended_description: 
            
            
             
			 
         
         

Fix information:
repo_url: https://github.com/torvalds/linux
commit_details: repo_url: https://github.com/torvalds/linux
author: Christian König
author_date: 2019-04-02 09:29:35+02:00
msg: drm/ttm: fix start page for huge page check in ttm_put_pages()

The first page entry is always the same with itself.

Signed-off-by: Christian König <christian.koenig@amd.com>
Reviewed-by: Michel Dänzer <michel.daenzer@amd.com>
Reviewed-by: Junwei Zhang <Jerry.Zhang@amd.com>
Reviewed-by: Huang Rui <ray.huang@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
repository: repo_url: https://github.com/torvalds/linux
repo_name: torvalds/linux
description: Linux kernel source tree
repo_language: C
owner: torvalds
file_changes: filename: ttm_page_alloc.c
change_type: ModificationType.MODIFY
diff: @@ -732,7 +732,7 @@ static void ttm_put_pages(struct page **pages, unsigned npages, int flags,
 #ifdef CONFIG_TRANSPARENT_HUGEPAGE
 			if (!(flags & TTM_PAGE_FLAG_DMA32) &&
 			    (npages - i) >= HPAGE_PMD_NR) {
-				for (j = 0; j < HPAGE_PMD_NR; ++j)
+				for (j = 1; j < HPAGE_PMD_NR; ++j)
 					if (p++ != pages[i + j])
 					    break;
 
@@ -767,7 +767,7 @@ static void ttm_put_pages(struct page **pages, unsigned npages, int flags,
 			if (!p)
 				break;
 
-			for (j = 0; j < HPAGE_PMD_NR; ++j)
+			for (j = 1; j < HPAGE_PMD_NR; ++j)
 				if (p++ != pages[i + j])
 				    break;
 

programming_language: C
repo_url: https://github.com/torvalds/linux
commit_details: repo_url: https://github.com/torvalds/linux
author: Christian König
author_date: 2019-04-10 11:43:43+02:00
msg: drm/ttm: fix incrementing the page pointer for huge pages

When we increment the counter we need to increment the pointer as well.

Signed-off-by: Christian König <christian.koenig@amd.com>
Fixes: e16858a7e6e7 drm/ttm: fix start page for huge page check in ttm_put_pages()
Reviewed-by: Michel Dänzer <michel.daenzer@amd.com>
Acked-by: Huang Rui <ray.huang@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
repository: repo_url: https://github.com/torvalds/linux
repo_name: torvalds/linux
description: Linux kernel source tree
repo_language: C
owner: torvalds
file_changes: filename: ttm_page_alloc.c
change_type: ModificationType.MODIFY
diff: @@ -733,7 +733,7 @@ static void ttm_put_pages(struct page **pages, unsigned npages, int flags,
 			if (!(flags & TTM_PAGE_FLAG_DMA32) &&
 			    (npages - i) >= HPAGE_PMD_NR) {
 				for (j = 1; j < HPAGE_PMD_NR; ++j)
-					if (p++ != pages[i + j])
+					if (++p != pages[i + j])
 					    break;
 
 				if (j == HPAGE_PMD_NR)
@@ -768,7 +768,7 @@ static void ttm_put_pages(struct page **pages, unsigned npages, int flags,
 				break;
 
 			for (j = 1; j < HPAGE_PMD_NR; ++j)
-				if (p++ != pages[i + j])
+				if (++p != pages[i + j])
 				    break;
 
 			if (j != HPAGE_PMD_NR)

programming_language: C
repo_url: https://github.com/torvalds/linux
commit_details: repo_url: https://github.com/torvalds/linux
author: Christian König
author_date: 2019-04-02 09:26:52+02:00
msg: drm/ttm: fix out-of-bounds read in ttm_put_pages() v2

When ttm_put_pages() tries to figure out whether it's dealing with
transparent hugepages, it just reads past the bounds of the pages array
without a check.

v2: simplify the test if enough pages are left in the array (Christian).

Signed-off-by: Jann Horn <jannh@google.com>
Signed-off-by: Christian König <christian.koenig@amd.com>
Fixes: 5c42c64f7d54 ("drm/ttm: fix the fix for huge compound pages")
Cc: stable@vger.kernel.org
Reviewed-by: Michel Dänzer <michel.daenzer@amd.com>
Reviewed-by: Junwei Zhang <Jerry.Zhang@amd.com>
Reviewed-by: Huang Rui <ray.huang@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
repository: repo_url: https://github.com/torvalds/linux
repo_name: torvalds/linux
description: Linux kernel source tree
repo_language: C
owner: torvalds
file_changes: filename: ttm_page_alloc.c
change_type: ModificationType.MODIFY
diff: @@ -730,7 +730,8 @@ static void ttm_put_pages(struct page **pages, unsigned npages, int flags,
 			}
 
 #ifdef CONFIG_TRANSPARENT_HUGEPAGE
-			if (!(flags & TTM_PAGE_FLAG_DMA32)) {
+			if (!(flags & TTM_PAGE_FLAG_DMA32) &&
+			    (npages - i) >= HPAGE_PMD_NR) {
 				for (j = 0; j < HPAGE_PMD_NR; ++j)
 					if (p++ != pages[i + j])
 					    break;
@@ -759,7 +760,7 @@ static void ttm_put_pages(struct page **pages, unsigned npages, int flags,
 		unsigned max_size, n2free;
 
 		spin_lock_irqsave(&huge->lock, irq_flags);
-		while (i < npages) {
+		while ((npages - i) >= HPAGE_PMD_NR) {
 			struct page *p = pages[i];
 			unsigned j;
 

programming_language: C