Lorsque j'essaie d'écraser un fichier binaire qui est actuellement lancé, cp
ne parvient pas à l'écraser, mais il est alors possible de le rm
faire cp
. Par exemple:
user@poste:~$ cp binaryFile /tmp
user@poste:~$ sudo cp /tmp/binaryFile binaryFile
[sudo] password for user:
cp: cannot create regular file `binaryFile`: Text file busy
user@poste:~$ sudo rm binaryFile
user@poste:~$ sudo cp /tmp/binaryFile binaryFile
user@poste:~$ file binaryFile
binaryFile : ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.24, BuildID[sha1]=0x7ce005d9eb50e2574246b6a881e625802f7e49f2, not stripped
Une idée pourquoi?
Réponses:
Dans le premier cas, vous essayez de remplacer le contenu d'un fichier en cours d' exécution en tant que programme. Linux ne le permet pas - si c'était le cas, vous écraseriez le code juste au moment où l'OS l'exécutait; la première différence ferait planter le programme ou le rendrait défectueux.
Mais dans le deuxième cas, vous ne modifiez pas réellement le contenu de l'ancien fichier - vous créez un nouveau fichier à sa place, tandis que l'ancien perd simplement le nom de fichier mais conserve son contenu intact.
(N'oubliez
rm
pas que, techniquement, ne supprime pas les fichiers, il supprime simplement les liens de répertoire - comme pourln
ajouter plus de liens au même fichier. Ce n'est que lorsqu'un fichier n'a pas de liens et aucune référence de fichier ouvert, qu'il est automatiquement supprimé.)Le système fait référence aux fichiers en cours d'utilisation par leur inode, donc peu importe qu'ils aient le même nom de fichier - c'est toujours l' ancien fichier qui reste ouvert par le système, et même s'il n'a plus de liens, il ne sera supprimé une fois tous les programmes fermés.
la source
/proc/*/fd
pour y accéder, et éventuellement linkat () pour ajouter un nouveau lien vers le système de fichiers.linkat()
, pour des raisons de sécurité . (Exception à cette règle: sauf si elle a été créée avecopen(O_TMPFILE)
donc elle a commencé avec zéro lien.) Si vous essayez,linkat()
renvoie ENOENT, même en tant que root. Voir ma réponse à cette question pour qu'un script perl s'exécute réellementlinkat
et prouve qu'il ne fonctionne pas, même en tant que root: /