Ich hatte gehofft, jemand könnte die Nuancen des in der Linux-Kernel-Quelle verwendeten __user-Makros erklären.
Zunächst das Makro:
# define __user __attribute__((noderef, address_space(1)))
Nach einigem googeln habe ich nun gelesen, dass man mit diesem Makro einen Zeiger als zum Benutzeradressraum gehörend festlegen kann und dass er nicht dereferenziert werden sollte.
Ich vermisse vielleicht einige offensichtliche Fakten, aber könnte jemand bitte die Auswirkungen eines solchen Makros erklären? Was ist zum Beispiel ein gutes Beispiel dafür, wo dieses Makro von Nutzen sein würde? Nochmals, vergib mir, wenn mir etwas Offensichtliches fehlt.
Um dies in einen Zusammenhang zu bringen, bin ich beim Untersuchen eines USB-Codes (linux / usbdevice_fs.h) auf das Makro gestoßen. Ich suche nur nach einem allgemeinen Verständnis dieser Makros (oder ähnlicher), die im Kernel verwendet werden.
Danke fürs schauen!
quelle
Antworten:
Tools wie sparse können Kernel-Entwicklern mitteilen, dass sie möglicherweise einen nicht vertrauenswürdigen Zeiger (oder einen Zeiger, der in der aktuellen Zuordnung virtueller Adressen ungültig ist) nicht ordnungsgemäß verwenden.
quelle
__attribute__()
kann jeden beliebigen Text als ein „Attribut“ verwenden? Es ist nicht auf einen festen Satz beschränkt, der für GCC selbst von Bedeutung ist?An attribute specifier is of the form __attribute__ ((attribute-list)). An attribute list is a possibly empty comma-separated sequence of attributes, where each attribute is one of the following: 1. Empty. Empty attributes are ignored. **2. An attribute name (which may be an identifier such as unused, or a reserved word such as const).** (...)
. Es scheint, als könnte es sich um einen beliebigen Bezeichner handeln (unter Verwendung von Bezeichner-Namenskonventionen).Ich denke, __user markiert User-Space-Zeiger und weist den Entwickler / das System an, ihm nicht zu vertrauen. Wenn der Benutzer Ihnen einen "ungültigen" Zeiger gibt, versucht der Kernel, darauf zu verweisen (beachten Sie, dass der Kernel überall verweisen kann), und er kann seinen eigenen Speicherplatz beschädigen.
Zum Beispiel sollte in "read" (in you usbdevice_fs.h) ein (__user) Puffer bereitgestellt werden, in den das Ergebnis geschrieben werden kann. Sie müssen also copy_to_user verwenden, aber nicht memcopy, strcpy oder ähnliches.
Hinweis: Dies ist keine formale Definition / Beschreibung, sondern der einzige Teil, den ich kenne.
quelle
Das
__user
Makro wird mit einigen anderen Makros wie__force
/__kernel
etc in der Header-Datei compiler.h definiert. Sie sind für herkömmliche Compiler, einschließlich GCC / ICC usw., eigentlich nicht von Nutzen. Sie sind jedoch nützlich für statische Kernel-Analysetools wie Sparse (weitere Informationen hier: Sparse - Linux Kernel Newbies). Wenn Sie Makros wie__user
/__kernel
/__force
etc erwähnen , hat dies eine besondere Bedeutung für Sparse. In der Linux-Kernel-Mailingliste erklärt Linus Torvalds die Verwendung folgendermaßen:quelle