Aracılığıyla paylaş


User-Space Adreslerine Referans Verme Hataları

IRP'leri veya hızlı G/Ç işlemlerini destekleyen herhangi bir sürücü, kullanmaya çalışmadan önce kullanıcı alanında herhangi bir adresi doğrulamalıdır. G/Ç yöneticisi bu tür adresleri doğrulamaz ve sürücülere geçirilen arabelleklere gömülü işaretçileri doğrulamaz.

METHOD_NEITHER IOCTL'lerde ve FSCTL'lerde Geçirilen Adreslerin Doğrulanmaması

G/Ç yöneticisi, METHOD_NEITHER IOCTL'ler ve FSCTL'ler için hiçbir doğrulama yapmaz. Kullanıcı alanı adreslerinin geçerli olduğundan emin olmak için sürücü, ProbeForRead ve ProbeForWrite rutinlerini kullanmalı ve tüm arabellek başvurularını try/except bloklarına almalıdır.

Aşağıdaki örnekte, sürücü Type3InputBuffer içinde geçirilen değerin geçerli bir adresi temsil ettiğini varsayar.

   case IOCTL_GET_HANDLER:
   {
      PULONG EntryPoint;

      EntryPoint =
         IrpSp->Parameters.DeviceIoControl.Type3InputBuffer; 
      *EntryPoint = (ULONG)DriverEntryPoint; 
      ...
   }

Aşağıdaki kod bu sorunu önler:

   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)
      {
        ...
      }
      ...
   }

Ayrıca doğru kodun DriverEntryPoint'i ULONG yerine bir ULONG_PTR dönüştürdüğünü unutmayın. Bu değişiklik, 64 bit Windows ortamında kullanıma olanak tanır.

Arabelleğe alınan G/Ç isteklerine eklenen işaretçilerin doğrulanamaması durumu

Sürücüler genellikle aşağıdaki örnekte olduğu gibi arabelleğe alınan isteklere işaretçiler ekler:

   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));

Bu örnekte, sürücü, daha önce açıklanan METHOD_NEITHER IOCTL'lerle aynı şekilde try/except bloğunda yer alan ProbeXxx rutinlerini kullanarak gömülü işaretçiyi doğrulamalıdır. İşaretçi eklemek bir sürücünün ek bilgi döndürmesine olanak sağlasa da, bir sürücü göreli uzaklık veya değişken uzunluk arabelleği kullanarak aynı sonucu daha verimli bir şekilde elde edebilir.

Geçersiz adresleri işlemek için try/except bloklarını kullanma hakkında daha fazla bilgi için bkz. Özel Durumları İşleme.