2013-08-24 4 views
2

L'interface de fonction étrangère permet au haskell de fonctionner avec le monde C. Maintenant, côté Haskell permet de travailler avec les pointeurs en utilisant Storable instances. Par exemple, si j'ai un tableau d'entiers dans le monde C, une représentation plausible de cela dans le monde de haskell serait Ptr Int. Supposons maintenant que je souhaite traduire l'expression C a[0] = a[0] + 1. La seule façon de faire cela du côté du haskell est de jeter un coup d'œil sur le résultat et de remonter le résultat de l'addition. Le problème avec cette approche est qu'une valeur temporaire est créée à la suite de cela. (Je ne suis pas sûr qu'un compilateur d'optimisation puisse toujours éviter cela)Pointeurs de bas niveau dans le haskell

Maintenant, la plupart des gens peuvent penser que cet effet est inoffensif, mais pensez à une situation où l'objet Pointer contient des données sensibles. J'ai créé ce pointeur sur le côté c de manière à toujours garantir que son contenu ne sera jamais transféré de la mémoire (en utilisant l'appel système mlock). Maintenant, jeter un coup d'œil sur le résultat du côté haskell ne garantit plus la sécurité des données sensibles.

Alors, quel devrait être le meilleur moyen d'éviter cela dans le monde du haskell? Est-ce que quelqu'un d'autre a rencontré des problèmes similaires avec des manipulations de bas niveau de pointeur dans haskell.

+1

Pouvez-vous préciser en quoi l'échange est nocif? Si vous voulez dire que quelqu'un peut ensuite scanner le disque pour trouver la valeur permutée, alors la même chose peut être dite à propos d'autres choses du côté C. Une fois que vous commencez à utiliser cette "valeur sensible", vous ne pouvez pas prédire où elle finira - même la pile, les variables locales, les registres dans l'état de la tâche, .... peuvent tous se déplacer sur le disque. Je m'attendrais à ce que les régions de mémoire soient verrouillées pour des raisons de performance - par exemple, n'échangez pas Java Heap, car l'échange de pages de tas rarement accédées peut ralentir GC. –

+0

Vous pouvez verrouiller une mémoire en utilisant l'appel système mlock. Ainsi, par exemple, si vous verrouillez le tableau ci-dessus, il est garanti qu'il ne sera jamais échangé. libgcrypt qui est utilisé par des programmes comme gnupg l'utilise pour verrouiller des informations sensibles dans la mémoire pour des raisons de sécurité. – Satvik

+0

Comme je ne peux pas verrouiller les valeurs de haskell pur car elles peuvent être déplacées par le garbage collector, je dois travailler avec la mémoire sécurisée allouée du côté c (en utilisant ForeignPtr dans mon cas). – Satvik

Répondre

3

Je viens de construire un test avec le code:

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

Et en utilisant GHC 7.6.3 -fllvm -O2 -ddump-asm Je vois les instructions pertinentes:

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

Il charge une adresse dans rax et incréments la mémoire à cette adresse. Semble être ce que vous auriez dans d'autres langues, mais voyons.

Avec C, je pense que la comparaison équitable est:

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

qui se traduit par:

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

Tout cela dit, je reconnais volontiers qu'il ne soit pas clair pour moi ce que vous êtes préoccupé par à propos de si j'ai peut-être manqué votre point de vue et, ce faisant, adressé la mauvaise chose.

+0

Supposons que je fasse 'a <- peek p'. Maintenant, 'a' est-il attribué une mémoire séparée qui est gérée par le garbage collector? Dans votre cas je suppose que le compilateur a optimisé pour partager la même mémoire, mais ce sera toujours le cas. – Satvik

+0

Rien ne garantit que ce sera toujours le cas. Si vous devez contrôler ce qui est dans les registres et ce qui ne l'est pas, ou ce qui est alloué et potentiellement stocké dans un tas et ce qui ne l'est pas, je n'ai pas de solution convaincante pour vous en plus de générer ou d'écrire dans un langage. compilateur qui vous donne ces garanties, puis faire des liaisons étrangères pour accéder à la fonctionnalité dans Haskell. Est-ce une clé de cryptage que vous travaillez si dur à protéger? –

+0

En outre, il est probablement intéressant de noter que C ne donne pas une telle promesse. Vous pouvez probablement accepter qu'il en résultera une instruction d'incrémentation de mémoire, mais il n'y a aucune promesse qu'il ne sera pas déplacé d'abord dans un registre (et peut-être que le contexte soit changé, stocké dans la mémoire, et échangé sur le disque dur). Si cela vous concerne aussi, l'assemblage ou le matériel dédié semble être votre principale option. –