Старый 06.05.2014, 10:33   #1
SynQ
 
Регистрация: 11.07.2010
Сообщений: 953
Репутация: 352
По умолчанию CVE-2014-2851 Linux (<=3.14.1) group_info refcounter overflow use afer free

CVE-2014-2851

commit (внесен 2014-04-14): https://git.kernel.org/cgit/linux/ke...3102137b7f6cac

Код:
There is a memory leak in ping. Current group_info had been got in 
ping_init_sock and group_info->usage increased. 
But the usage hasn't decreased anywhere in ping.
This will make this group_info never freed and cause memory leak.

 net/ipv4/ping.c |   11 ++++++++---
 1 files changed, 8 insertions(+), 3 deletions(-)
diff --git a/net/ipv4/ping.c b/net/ipv4/ping.c
index f4b19e5..2af7b1f 100644
--- a/net/ipv4/ping.c
+++ b/net/ipv4/ping.c
@@ -255,23 +255,28 @@ int ping_init_sock(struct sock *sk)
 	struct group_info *group_info = get_current_groups();
 	int i, j, count = group_info->ngroups;
 	kgid_t low, high;
+	int ret = 0;
 
 	inet_get_ping_group_range_net(net, &low, &high);
 	if (gid_lte(low, group) && gid_lte(group, high))
-		return 0;
+		goto out_release_group;
 
 	for (i = 0; i < group_info->nblocks; i++) {
 		int cp_count = min_t(int, NGROUPS_PER_BLOCK, count);
 		for (j = 0; j < cp_count; j++) {
 			kgid_t gid = group_info->blocks[i][j];
 			if (gid_lte(low, gid) && gid_lte(gid, high))
-				return 0;
+				goto out_release_group;
 		}
 
 		count -= cp_count;
 	}
 
-	return -EACCES;
+	ret = -EACCES;
+
+out_release_group:
+	put_group_info(group_info);
+	return ret;
 }
 EXPORT_SYMBOL_GPL(ping_init_sock);
При вызове ping_init_sock() увеличивается счетчик ссылок на group_info, но после никогда не уменьшается. Достигнув 0xffffffff, следующим можно переполнить счетчик в ноль и тогда структура будет освобождена из памяти. На ее месте после этого может оказаться другая память.

poc: https://github.com/thomaxxl/group_info

Автор после освобождения group_info (которая на его 32-битной системе выделяется в слабе kmalloc-192), открывает множество файловых дескрипторов (которые создаются в том же слабе) и т.о. может продолжать инкрементировать первые 4 байта памяти на месте старого счетчика ссылок, но уже в struct file.

Код:
include/linux/cred.h
32 struct group_info {
33         atomic_t        usage;            // refcounter
34         int             ngroups;          // return value of getgroups
35         int             nblocks;
36         kgid_t          small_block[NGROUPS_SMALL];
37         kgid_t          *blocks[0];
38 };
Если найти структуру размером 192<x<128 байт, которая тоже окажется в kmalloc-192, и которую легко выделить в большом количестве, можно будет свободно менять ее первые 4 байта (желательно. чтобы эти 4 байта были указателем ).
SynQ вне форума   Ответить с цитированием
Старый 02.01.2016, 13:08   #2
SynQ
 
Регистрация: 11.07.2010
Сообщений: 953
Репутация: 352
По умолчанию

Статья Виталия Николенко:
https://cyseclabs.com/page?n=02012016
SynQ вне форума   Ответить с цитированием
Ответ

Метки
linux kernel, privilege escalation

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.

Быстрый переход



Powered by vBulletin® Version 3.8.5
Copyright ©2000 - 2019, Jelsoft Enterprises Ltd. Перевод: zCarot