2013-08-24 2 views
2

Интерфейс внешних функций позволяет haskell работать с миром C. Теперь сторона Haskell позволяет работать с указателями, используя Storable экземпляров. Так, например, если у меня есть массив целых чисел в мире C, вероятным представлением этого в мире haskell будет Ptr Int. Теперь предположим, что я хочу перевести выражение C a[0] = a[0] + 1. Единственный способ сделать это на стороне haskell - это заглянуть внутрь, а затем подсунуть результат добавления. В результате этого возникает проблема с этим подходом. (Я не уверен, что оптимизирующий компилятор всегда может избежать этого)Низкоуровневые указатели в haskell

Теперь большинство людей могут считать этот эффект безвредным, но подумайте о ситуации, когда объект указателя содержит некоторые конфиденциальные данные. Я создал этот указатель на стороне c так, чтобы он всегда гарантировал, что его содержимое никогда не будет выгружено из памяти (используя системный вызов mlock). Теперь просмотр результатов на стороне haskell больше не гарантирует безопасность конфиденциальных данных.

Итак, каким должен быть лучший способ избежать этого в мире haskell? Кто-то сталкивался с аналогичными проблемами с манипуляторами с низким уровнем указателя в haskell.

+1

Можете ли вы пояснить, как обкатка вредно? Если вы имеете в виду, что кто-то может впоследствии сканировать диск, чтобы найти значение swapped, то то же самое можно сказать и о других вещах на стороне C. После того, как вы начнете использовать это «чувствительное значение», вы не можете предсказать, где он закончится - даже стек, локальные переменные, регистры в состоянии задачи, .... все могут перейти на диск. Я ожидал бы, что области памяти заблокированы по соображениям производительности - например, не заменяйте Java-кучу, потому что замена редко загружаемых страниц кучи может сделать GC медленным. –

+0

Вы можете заблокировать память, используя системный вызов mlock. Так, например, если вы заблокируете вышеупомянутый массив, он никогда не будет заменен. libgcrypt, который используется такими программами, как gnupg, для блокировки конфиденциальной информации в памяти по соображениям безопасности. – Satvik

+0

Поскольку я не могу заблокировать чистые значения haskell, поскольку они могут быть перемещены сборщиком мусора, я должен работать с защищенной памятью, выделенной на стороне c (используя ForeignPtr в моем случае). – Satvik

ответ

3

Я только что построил тестовый пример с кодом:

foo :: Ptr CInt -> IO() 
foo p = peek p >>= poke p ∘ (+1) 

и используя GHC 7.6.3 -fllvm -O2 -ddump-asm Я вижу соответствующие инструкции:

0x0000000000000061 <+33>: mov 0x7(%r14),%rax 
0x0000000000000065 <+37>: incl (%rax) 

Так он загружает адрес в rax и приращение память по этому адресу. Кажется, это то, что вы получите на других языках, но давайте посмотрим.

С С, я думаю, что справедливо сравнение:

void foo(int *p) 
{ 
    p[0]++; 
} 

Какие результаты в:

0x0000000000000000 <+0>:  addl $0x1,(%rdi) 

Все это говорит, я свободно признаю, что это не для меня ясно, что вы обеспокоены тем, поэтому я, возможно, пропустил вашу мысль, и при этом обратился к неправильной вещи.

+0

Предположим, что я делаю 'a <- peek p'. Теперь '' 'выделяет отдельную память, которая обрабатывается сборщиком мусора? В вашем случае я полагаю, что компилятор оптимизирован для обмена одной и той же памятью, но всегда будет так. – Satvik

+0

Нет ничего гарантирующего, что это всегда будет иметь место. Если вы должны контролировать то, что находится в регистрах, а что нет, или то, что выделяется и потенциально хранится в куче, а что нет, то у меня нет убедительного решения для вас, кроме создания или записи на каком-то языке и использования соответствующего компилятор, который дает вам эти гарантии, а затем создает внешние привязки для доступа к функциям в Haskell. Это крипто-ключ, который вы так старательно защищаете? –

+0

Кроме того, возможно, стоит отметить, что C не дает такого обещания. Вероятно, вы можете согласиться с тем, что это приведет к инструкции по наращиванию памяти, но нет обещаний, что он не будет сначала перенесен в регистр (и, возможно, контекст переключится, будет сохранен в памяти и заменен на жесткий диск). Если это относится и к вам, то сборка или выделенное оборудование, по-видимому, являются вашими основными опциями. –

Смежные вопросы