Random IRC quote :      <ggonzalez> un pal?ndromo es un bicho desos que ponen webos

¿Donde esta el bug?

#include <Windows.h>

//
// ¿Por qué se da el bug en este código?
// ¿De quien consideramos que es el bug en este caso?
//
void main()
{
  SC_HANDLE ScManager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);

  if (ScManager != NULL)
  {
    SC_HANDLE ScService = OpenServiceW(ScManager, L"ACPI", SERVICE_ALL_ACCESS);

    if (ScService != NULL)
    {
      DWORD bufsize = 0;

      if (QueryServiceConfigW(ScService, NULL, 0, &bufsize) == 0)
      {
        if (GetLastError() == ERROR_INSUFFICIENT_BUFFER)
        {
          BYTE * buffer = (BYTE*)calloc(1, bufsize + 1);

          if (buffer != NULL)
          {
            QUERY_SERVICE_CONFIGW * query = (QUERY_SERVICE_CONFIGW *)(buffer + 1);

            QueryServiceConfigW(ScService, query, bufsize, &bufsize);

            free(buffer);
          }
        }
      }
      CloseServiceHandle(ScService);
    }
    CloseServiceHandle(ScManager);
  }
}
 

Os recomendamos compilar y ejecutar el codigo 🙂

8 Comentarios para “¿Donde esta el bug?”

  1. Comment por Newlog | 02/27/11 at 4:11 am

    Puede ser que el problema esté en el free(buffer)? Quiero decir que si después se quisieran leer los datos de la estructura query, la cosa petaría ya que esa zona de memoria ya se habría liberado. (Aunque ya soy consciente de que en vuestro código no se vuelve a utilizar la variable query).

    Por otro lado, esos ‘+1’ me mosquean un poco, aunque después de pensarlo un poco, no creo que haya ningún problema. Por otro lado, utilizar las mismas variables bufsize como variables ‘in’ y ‘out’ también me parecía problemático, por si la variable ‘out’ bufsize se modificaba antes de que se utilizaran los datos de la variable ‘in’ bufsize, pero después de pensarlo un poco (también) no creo que haya problema ya que de la variable ‘in’ bufsize se hace una cópia (var. pasada por valor) así que no se pierde su valor por más que el valor original de la variable bufsize se modifique.

    En fin, espero no haber metido mucho la gamba ^^’ Y también me parece que me he explicado un poco mal… Son las 3 de la noche ^^’ ¡Y SÁBADO! No se que coño hago aquí xD

    P.D.: No he podido compilar.

  2. Comment por Bubu | 02/28/11 at 9:37 am

    Eres un crack !!!

    No veo en la documentación de Microsoft que el buffer deba estar alineado a doble palabra, así que el bug es claramente to del QueryServiceConfig.

    Si lo has descubierto por casualidad, te acompaño en el sentimiento.

    Saludos …..

  3. Comment por Anonymous Researcher | 02/28/11 at 9:49 am

    That’s Not a Bug, It’s a Feature.

  4. Comment por nergeia | 02/28/11 at 1:25 pm

    //QUERY_SERVICE_CONFIGW * query = (QUERY_SERVICE_CONFIGW *)(buffer + 1);

    QUERY_SERVICE_CONFIGW * query = (QUERY_SERVICE_CONFIGW *)(buffer);

  5. Comment por La nuri | 03/02/11 at 11:10 pm

    Para bugs los que me suelen salir entre pata y pata.
    Y como pican los mamones!!

  6. jj
    Comment por jj | 03/03/11 at 11:13 am

    Da igual lo que ponga en la documentación (aunque debería ponerlo), pero la función (si es una función documentada) DEBE devolver un código de error si el buffer no está lineado (es decir, si el puntero pasado, bla, bla, …).

    Culpa de quien escribió la función.

    PD: obviamente existen otras alternativas.

  7. Comment por Juan | 03/29/11 at 3:39 pm

    La llamada a la función OpenServiceW tiene el segundo parametro erroneo:

    SC_HANDLE ScService = OpenServiceW(ScManager, L»ACPI», SERVICE_ALL_ACCESS);

    La L ¿Que es? ¿Una constante? ¿Donde esta definida? y por que va pegada al culo de un string sin un «+»

  8. Comment por erg0t | 04/02/11 at 3:30 am

    @Juan la L seguida de una cadena (o de un char) es porque su tipo es wchar_t. Es totalmente normal y ahora a partir de C++0x puedes esperarte encontar tambien u»cadena» o U»cadena» para los tipos char16_t y char32_t respectivamente.

Se han cerrado los comentarios