bug-gnulib
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

res_nmkquery - duplicate transaction-id across fork


From: Martin Waite
Subject: res_nmkquery - duplicate transaction-id across fork
Date: Mon, 19 May 2008 13:53:48 +0100
User-agent: Thunderbird 2.0.0.14 (Windows/20080421)

Hi,

I'm using a debian Etch system with glibc-2.3.6 installed.

Our application is a daemon process that forks a new process to handle incoming connections.  We have found that the DNS transaction-id for the first DNS query issued by each child process has the same DNS transaction-id.  This poses a minor security problem for naive forking applications (like ours) in that an attacker can accurately guess what the first transaction-id will be following a fork.  

In function res_nmkquery, the following code generates the transaction-id:

        hp = (HEADER *) buf;
        /* We randomize the IDs every time.  The old code just
           incremented by one after the initial randomization which
           still predictable if the application does multiple
           requests.  */
#if 0
        hp->id = htons(++statp->id);
#else
        hp->id = htons(statp->id);
        int randombits;
        do
          {
#ifdef RANDOM_BITS
            RANDOM_BITS (randombits);
#else
            struct timeval tv;
            __gettimeofday (&tv, NULL);
            randombits = (tv.tv_sec << 8) ^ tv.tv_usec;
#endif
          }
        while ((randombits & 0xffff) == 0);
        statp->id = (statp->id + randombits) & 0xffff;
#endif
        hp->opcode = op;


The line "hp->id = htons(statp->id);" consumes the transaction-id before generating a new one for the next call.

A better solution would be if the transaction-id was consumed after a new one is generated, ie. just after the assignment to statp->id after the while loop.   This would be more in the spirit of the old behaviour where the transaction-id is incremented and then used - "hp->id = htons(++statp->id); ".

In short, I suggest that the code is changed to the following:
        hp = (HEADER *) buf;
        /* We randomize the IDs every time.  The old code just
           incremented by one after the initial randomization which
           still predictable if the application does multiple
           requests.  */
#if 0
        hp->id = htons(++statp->id);
#else
        int randombits;
        do
          {
#ifdef RANDOM_BITS
            RANDOM_BITS (randombits);
#else
            struct timeval tv;
            __gettimeofday (&tv, NULL);
            randombits = (tv.tv_sec << 8) ^ tv.tv_usec;
#endif
          }
        while ((randombits & 0xffff) == 0);
        statp->id = (statp->id + randombits) & 0xffff;
        hp->id = htons(statp->id);
#endif
        hp->opcode = op;


--
Martin Waite
Solutions Architect
DataCash

Tel (Direct): +44 (0)131 538 8431
Mobile: +44 (0)7866 750509

DataCash Ltd, Suite 3/1 Great Michael House,
14 Links Place, Edinburgh, EH6 7EZ, United Kingdom.

Tel: +44 (0)870 7274 762
Fax: +44 (0)870 7274 782

www.datacash.com

DISCLAIMER: This email and any files transmitted with it are confidential to DataCash Group plc and its group companies. It is intended only for the person to whom it is addressed. If you have received this email in error, please forward it to address@hidden with the subject line "Received in Error". If you are not the intended recipient you must not use, disclose, copy, print, distribute or rely on this email or any transmitted files. DataCash Ltd is registered in England and Wales no. 3430157. DataCash Ltd is part of the DataCash Group plc. DataCash Group plc is registered in England and Wales no. 3168091. DataCash Ltd and DataCash Group plc registered address is Descartes House, 8 Gate Street, London, WC2A 3HP, United Kingdom.

Save a tree...Please only print this page if essential

reply via email to

[Prev in Thread] Current Thread [Next in Thread]