Freigeben über


Desafio da Semana #12


Por: Roberto Alexis Farah

Olá pessoal!

Tenho demorado para publicar novos artigos porque tenho usado meu tempo livre no desenvolvimento de duas ferramentas, uma delas pública que, em breve, vocês tomarão conhecimento através desse blog. ;)

No desafio de hoje abordarei dois problemas que estão entre os mais comuns que encontro em códigos VB.NET, C# e ASP.NET.

Embora ambos são abordados juntos aqui, na prática são problemas independentes.

CENÁRIO

Eis o código fonte. Pode ser traduzido para VB.NET, optei por fazer em C# simplesmente porque conheço mais:

namespace Demo

{

          class Program

          {

                   static void Main(string[] args)

                   {

                             string str = "Abcd";

                            

                             DoSomething(str);

                            

                   }

                  

                   static bool DoSomething(string str)

                   {

                             // Checa se string é nula/vazia.

                             if(0 == str.Length)

                             {

                                      return false;

                             }

                            

                             str = str.ToUpper();

                                     

                             Microsoft.Office.Interop.Word.Application msWord = null;

                                                                            

                             try

                             {

                                      msWord = new Microsoft.Office.Interop.Word.Application();

                                      object saveChanges = false;

                                      object missing = null;

                            

                                      msWord.Quit(ref saveChanges, ref missing, ref missing);

                             }

                             catch(OutOfMemoryException ex)

                             {

                                      Console.WriteLine("Não há memória disponível...");

                             }

                             finally

                             {

                                      // Como liberar o objeto COM?

                             }

                            

                             return true;

                   }

          }

}

SINTOMA

Temos dois problemas e dois sintomas no código acima.

Primeiro Sintoma:

Algumas vezes o código acima pode sofrer um crash por NullReferenceException quando o parâmetro ‘str’ é utilizado, como na comparação com str.Length.

Caso real: Em incidentes que trabalhei esse tipo de exceção costuma surpreender os desenvolvedores que assumem erroneamente que os parâmetros de métodos estão sendo testados antes do uso.

Segundo Sintoma:

Sempre que o componente Word é utilizado ele nunca é liberado da memória.

Caso real: Em incidentes que trabalhei esse foi o problema número um relacionado a contador de instância de componentes no COM+ usados via .NET nunca decrementarem quando supostamente liberados da memória!

OBJETIVO

Identifique ambos PROBLEMAS e proponha uma SOLUÇÃO para cada um deles.

Até semana que vem!

Comments

  • Anonymous
    November 04, 2006
    The comment has been removed

  • Anonymous
    November 09, 2006
    Oi Marcondes! Muito completo e didático seu post! Estou me perguntando se ainda preciso publicar a resposta. :) Obrigado

  • Anonymous
    November 27, 2006
    Olá Marcondes, td bem ? Da forma que vc definiu "str", ela estaria vulnerável a ataques de Buffer Overflow. Correto ? []'s ! Weber Ress

  • Anonymous
    November 27, 2006
    Olá Weber, tudo bem? a definição da variável str é do tipo string, um objeto gerenciado dentro do CLR. Como o parâmetro do método DoSomethind é do tipo string, e este é o único ponto de entrada para o método, não estamos permitindo que haja qualquer tipo de acesso direto ao endereçamento do objeto string, o valor lido do parâmetro (não importa o que seja) será interpretado como o tamanho total da string. Não vamos ter problema de buffer overflow. []´s

  • Anonymous
    January 02, 2007
    Olá ! Feliz 2007 !! :-) O código abaixo é suscetível a Buffer Overflow, pois não estou verificando qual o tamanho de Name antes de copiar para NameBuffer, que possui um tamanho limitado. void SayHello(char * Name) { char NameBuffer[256]; strcpy(NameBuffer,Name); printf("Hello %s",NameBuffer); } Da forma que vc colocou no comentário anterior, como um ambiente CLR se protegeria de uma situação como esta ? Entendi que o acesso direto a memória é impedido através do CLR, mas este novo cenário seria tratado pelo CLR ? []'s !! Weber Ress

  • Anonymous
    January 02, 2007
    Olá Weber, O código que você colocou é suscetível a buffer overflow sim. No ambiente CLR o risco de buffer overflow é bastante minimizado, entretanto, se você fizer chamadas para código não gerenciado via, por exemplo, C# ou VB.NET, você fica sujeito aos problemas típicos de código nativo. Esse artigo esclarece bem isso: http://msdn.microsoft.com//msdnmag/issues/04/04/securitybriefs/ Em relação a Buffer Overflow em código nativo, como no exemplo que você colocou, há dois artigos meus falando sobre isso: Desafio Da Semana #8 - Crash - Buffer Overflow http://blogs.technet.com/latam/archive/2006/07/24/443173.aspx Desafio Da Semana #9 - Como explorar um Buffer Overflow http://blogs.technet.com/latam/archive/2006/08/11/446117.aspx []s, Roberto