Erreurs lors du référencement d’adresses User-Space
Tout pilote, qu’il s’agisse de prendre en charge des irps ou des opérations d’E/S rapides, doit valider n’importe quelle adresse dans l’espace utilisateur avant d’essayer de l’utiliser. Le gestionnaire d’E/S ne valide pas ces adresses, ni les pointeurs incorporés dans les mémoires tampons passées aux pilotes.
Échec de la validation des adresses passées dans METHOD_NEITHER IOCTL et FSCTL
Le gestionnaire d’E/S n’effectue aucune validation pour METHOD_NEITHER IOCTL et FSCTL. Pour s’assurer que les adresses d’espace utilisateur sont valides, le pilote doit utiliser les routines ProbeForRead et ProbeForWrite , en plaçant toutes les références de mémoire tampon dans des blocs try/except .
Dans l’exemple suivant, le pilote suppose que la valeur passée dans type3InputBuffer représente une adresse valide.
case IOCTL_GET_HANDLER:
{
PULONG EntryPoint;
EntryPoint =
IrpSp->Parameters.DeviceIoControl.Type3InputBuffer;
*EntryPoint = (ULONG)DriverEntryPoint;
...
}
Le code suivant évite ce problème :
case IOCTL_GET_HANDLER:
{
PULONG_PTR EntryPoint;
EntryPoint =
IrpSp->Parameters.DeviceIoControl.Type3InputBuffer;
try
{
if (Irp->RequestorMode != KernelMode)
{
ProbeForWrite(EntryPoint,
sizeof(ULONG_PTR),
TYPE_ALIGNMENT(ULONG_PTR));
}
*EntryPoint = (ULONG_PTR)DriverEntryPoint;
}
except(EXCEPTION_EXECUTE_HANDLER)
{
...
}
...
}
Notez également que le code correct caste DriverEntryPoint en ULONG_PTR, au lieu d’un ULONG. Cette modification permet une utilisation dans un environnement Windows 64 bits.
Échec de la validation des pointeurs incorporés dans les demandes d’E/S mises en mémoire tampon
Souvent, les pilotes incorporent des pointeurs dans des requêtes mises en mémoire tampon, comme dans l’exemple suivant :
struct ret_buf
{
void *arg; // Pointer embedded in request
int rval;
};
pBuf = Irp->AssociatedIrp.SystemBuffer;
...
arg = pBuf->arg; // Fetch the embedded pointer
...
// If the arg pointer is not valid, the following
// statement can corrupt the system:
RtlMoveMemory(arg, &info, sizeof(info));
Dans cet exemple, le pilote doit valider le pointeur incorporé à l’aide des routines Probe Xxx placées dans un bloc try/except de la même façon que pour les METHOD_NEITHER IOCTL décrites précédemment. Bien que l’incorporation d’un pointeur permette à un pilote de retourner des informations supplémentaires, un pilote peut obtenir plus efficacement le même résultat à l’aide d’un décalage relatif ou d’une mémoire tampon de longueur variable.
Pour plus d’informations sur l’utilisation de blocs try/except pour gérer des adresses non valides, consultez Gestion des exceptions.
Commentaires
https://aka.ms/ContentUserFeedback.
Bientôt disponible : Tout au long de 2024, nous allons supprimer progressivement GitHub Issues comme mécanisme de commentaires pour le contenu et le remplacer par un nouveau système de commentaires. Pour plus d’informations, consultezEnvoyer et afficher des commentaires pour