#1 Le 09/06/2011, à 16:17
- guendalf
[Résolu] Refus de création d'un hardlink par ln
Bonjour à tous,
Voici la suite de commande qui provoque un refus de la part de ln pour créer un lien (en dur) vers un fichier appartenant en root en lecture seule:
$ sudo touch f
$ ln f g
ln: creating hard link `g' => `f': Operation not permitted
Je ne comprends pas pourquoi il est nécessaire d'avoir les droits en écriture pour créer un hardlink ?
Note: il est tout à fait possible de supprimer un hardlink sans avoir les droits en écriture.
Dernière modification par guendalf (Le 09/06/2011, à 22:42)
Hors ligne
#2 Le 09/06/2011, à 18:50
- pode
Re : [Résolu] Refus de création d'un hardlink par ln
Parce que c'est le même fichier (l'i-node est identique). Les hard link ne sont que des alias vers les mêmes données.
Note: il est tout à fait possible de supprimer un hardlink sans avoir les droits en écriture.
Comme pour les fichiers normaux.
Dernière modification par pode (Le 09/06/2011, à 18:51)
Hors ligne
#3 Le 09/06/2011, à 19:57
- guendalf
Re : [Résolu] Refus de création d'un hardlink par ln
Merci pode pour la réponse rapide mais ça ne répond qu'à moitié à ma question.
Je suis d'accord avec toi sur le fait qu'il soit normal de supprimer un hardlink comme n'importe quel fichier à partir du moment où on a les droits sur le répertoire qui le contient.
Par contre, il devrait être possible de réaliser la commande suivante:
sudo touch foo; ln foo bar
Cette commande fonctionne d'ailleurs très bien sur Debian et sur OpenBSD.
Il doit s'agir d'un problème lié avec Ubuntu mais je ne sais pas lequel. J'ai signalé ce comportement étrange auprès de GNU/coreutils.
Hors ligne
#4 Le 09/06/2011, à 20:07
- aduxas
Re : [Résolu] Refus de création d'un hardlink par ln
Cette commande fonctionne d'ailleurs très bien sur Debian et sur OpenBSD.
D'accord avec toi. Sous Suse, pas de problème non plus. Ensuite:
~> touch f
~> chmod u-w f
~> ls -l f
-r--r----- 1 titus titus 0 2011-06-09 14:56 f
~> rm f
rm: remove write-protected regular empty file `f'?
La suppression n'est pas automatique, et si je n'étais pas le propriétaire, elle échouerait.
Edit: est-ce qu'il ya qq chose de spécial avec ta partition ou ton disque?
Dernière modification par aduxas (Le 09/06/2011, à 20:10)
Hors ligne
#5 Le 09/06/2011, à 20:52
- guendalf
Re : [Résolu] Refus de création d'un hardlink par ln
Ensuite:
~> touch f ~> chmod u-w f ~> ls -l f -r--r----- 1 titus titus 0 2011-06-09 14:56 f ~> rm f rm: remove write-protected regular empty file `f'?
La suppression n'est pas automatique, et si je n'étais pas le propriétaire, elle échouerait.
Il suffit d'être propriétaire du répertoire et non du fichier. Donc:
~> sudo touch f
~> rm f
rm: remove write-protected regular empty file `f'? y
fonctionne parfaitement.
Edit: est-ce qu'il ya qq chose de spécial avec ta partition ou ton disque?
Non rien de spécial, j'ai une install par défaut d'Ubuntu 10.10 32bits, donc une partition ext4.
Hors ligne
#6 Le 09/06/2011, à 20:55
- pode
Re : [Résolu] Refus de création d'un hardlink par ln
Par contre, il devrait être possible de réaliser la commande suivante:
sudo touch foo; ln foo bar
Cette commande fonctionne d'ailleurs très bien sur Debian et sur OpenBSD.
Ça m'étonne parce que les deux fichiers ont le même inode.
Donc, le fichier foo et le fichier bar auront des droits, compte et groupe propriétaires identiques.
Or, le premier fichier foo appartient à root et un compte non root ne peut pas créer de fichier appartenant à root.
Ce n'était pas toujours vrai sur des anciens systèmes Unix (en tout cas, on pouvait donner un fichier à un autre compte via chown), mais sur Linux c'est le cas.
D'accord avec toi. Sous Suse, pas de problème non plus. Ensuite:
~> touch f ~> chmod u-w f ~> ls -l f -r--r----- 1 titus titus 0 2011-06-09 14:56 f ~> rm f rm: remove write-protected regular empty file `f'?
La suppression n'est pas automatique, et si je n'étais pas le propriétaire, elle échouerait.
Il suffit de faire un rm -f. On peut donc supprimer un fichier même s'il n'est qu'en lecture seule.
Ce qui est important, ce sont effectivement les droits sur le répertoire. Il faut qu'il soit en x (pour pouvoir être traversé) et en w pour que la correspondance entre l'inode du fichier et le nom du fichier (correspondance stockée dans la structure interne du répertoire) puisse être supprimée.
Hors ligne
#7 Le 09/06/2011, à 21:04
- guendalf
Re : [Résolu] Refus de création d'un hardlink par ln
guendalf a écrit :Par contre, il devrait être possible de réaliser la commande suivante:
sudo touch foo; ln foo bar
Cette commande fonctionne d'ailleurs très bien sur Debian et sur OpenBSD.
Ça m'étonne parce que les deux fichiers ont le même inode.
Donc, le fichier foo et le fichier bar auront des droits, compte et groupe propriétaires identiques.
Or, le premier fichier foo appartient à root et un compte non root ne peut pas créer de fichier appartenant à root.
Ce n'était pas toujours vrai sur des anciens systèmes Unix (en tout cas, on pouvait donner un fichier à un autre compte via chown), mais sur Linux c'est le cas.
Ben du coup ln ne crée pas un fichier appartenant à root mais seulement un pointeur supplémentaire vers le fichier existant (qui peut appartenir à n'importe qui). Je ne vois vraiment pas quel problème de sécurité ça pourrait poser.
Sinon, je suis étonné que le comportement soit différent entre Ubuntu et Debian. Moi qui pensait qu'Ubuntu n'était plus ou moins qu'une Debian avec un tas de logiciels préinstallés...
Hors ligne
#8 Le 09/06/2011, à 21:51
- pode
Re : [Résolu] Refus de création d'un hardlink par ln
Ben du coup ln ne crée pas un fichier appartenant à root mais seulement un pointeur supplémentaire vers le fichier existant (qui peut appartenir à n'importe qui).
Si tu as réussi à créer un fichier avec des droits différents, à mon avis, cela signifie que tu n'as pas réellement créé un hard link mais que ce que tu as fait correspond à un simple cp.
Sinon, avec ton compte non root, tu pourrais modifier un fichier appartenant à root...
Pour vérifier cela, il faut regarder le numéro d'inode des 2 fichiers avec l'option -i de la commande ls ou avec la commande stat
Ou tu vois si la modification du fichier appartenant au compte non root a un impact sur le fichier appartenant à root.
Sinon, le message d'erreur ne vient pas, à l'origine, du code source de ln (vérifié avec apt-get source coreutils).
C'est l'appel système linkat qui échoue :
$ cat src/ln.c
[...]
ok = ((symbolic_link ? symlink (source, dest)
: linkat (AT_FDCWD, source, AT_FDCWD, dest,
logical ? AT_SYMLINK_FOLLOW : 0))
== 0);
[...]
if (ok)
[...]
}
else
{
error (0, errno,
[...]
: _("creating hard link %s => %s"))),
$ LANG=C strace ln /tmp/azerty /tmp/uiop &>/tmp/ln.out
[...]
linkat(AT_FDCWD, "/tmp/azerty", AT_FDCWD, "/tmp/uiop", 0) = -1 EPERM (Operation not permitted)
La différence entre le comportement de Debian et celui d'Ubuntu est donc certainement une modification du noyau Linux (et plus précisément de l'appel système linkat) apportée par les ingénieurs d'Ubuntu.
Hors ligne
#9 Le 09/06/2011, à 22:16
- guendalf
Re : [Résolu] Refus de création d'un hardlink par ln
Si tu as réussi à créer un fichier avec des droits différents, à mon avis, cela signifie que tu n'as pas réellement créé un hard link mais que ce que tu as fait correspond à un simple cp.
Sinon, avec ton compte non root, tu pourrais modifier un fichier appartenant à root...
Non non, je n'ai créé aucun fichier. La seule commande exécuté est celle indiquée au début du thread, à savoir
ln rootFile f
Le fait de créé un hardlink ne change pas les permissions du fichier, donc le fait de pouvoir créer avec un compte non root un hardlink sur un fichier appartenant à root ne permet pas de modifier ce fichier (sauf si bien sûr root nous en donne les droits).
Pour vérifier cela, il faut regarder le numéro d'inode des 2 fichiers avec l'option -i de la commande ls ou avec la commande stat
Ou tu vois si la modification du fichier appartenant au compte non root a un impact sur le fichier appartenant à root.
Oui les deux "fichiers" ont le même inode et donc pointent sur le même fichier. La seule différence après création du hardlink est que le compteur du nombre de références au fichier est augmenté de 1.
Sinon, le message d'erreur ne vient pas, à l'origine, du code source de ln (vérifié avec apt-get source coreutils).
C'est l'appel système linkat qui échoue :$ LANG=C strace ln /tmp/azerty /tmp/uiop &>/tmp/ln.out [...] linkat(AT_FDCWD, "/tmp/azerty", AT_FDCWD, "/tmp/uiop", 0) = -1 EPERM (Operation not permitted)
La différence entre le comportement de Debian et celui d'Ubuntu est donc certainement une modification du noyau Linux (et plus précisément de l'appel système linkat) apportée par les ingénieurs d'Ubuntu.
Bonne remarque ! J'avais fait le test avec un appel à link à partir d'un fichier C et j'obtiens la même erreur. Je n'avais pas pensé à utiliser strace ! Mais tu as raison, il doit s'agir d'une modification apportée au kernel par les dev d'Ubuntu. Je vais donc reporter cette "anomalie" auprès des gens d'Ubuntu.
Merci.
Hors ligne
#10 Le 09/06/2011, à 22:29
- guendalf
Re : [Résolu] Refus de création d'un hardlink par ln
Bon les responsables de coreutils m'ont indiqué l'explication:
https://wiki.ubuntu.com/SecurityTeam/Ro … Protection
C'est un choix délibéré d'Ubuntu pour limiter un éventuel DoS. Je marque le sujet comme clos.
Hors ligne
#11 Le 10/06/2011, à 04:04
- aduxas
Re : [Résolu] Refus de création d'un hardlink par ln
Sous kubuntu Lucid:
~$ sudo touch f
~$ ln f g
~$ ls -l f g
-rw-r--r-- 2 root root 0 2011-06-09 23:01 f
-rw-r--r-- 2 root root 0 2011-06-09 23:01 g
Et voilà. f et g appartiennent à root, même si g a été créé par moi.
Hors ligne