From b8a60b33ee6d45ff51dfbac33e79bd92d6c61195 Mon Sep 17 00:00:00 2001 From: Kurt Zeilenga Date: Sun, 6 May 2001 21:53:57 +0000 Subject: [PATCH] Import -llber hardening --- libraries/liblber/decode.c | 9 ++++++++- libraries/liblber/io.c | 14 ++++++++++++-- libraries/liblber/lber-int.h | 1 + libraries/liblber/sockbuf.c | 17 +++++++++++++++++ 4 files changed, 38 insertions(+), 3 deletions(-) diff --git a/libraries/liblber/decode.c b/libraries/liblber/decode.c index 6846377424..d2fbcdd357 100644 --- a/libraries/liblber/decode.c +++ b/libraries/liblber/decode.c @@ -137,6 +137,11 @@ ber_skip_tag( BerElement *ber, ber_len_t *len ) *len = lc; } + /* BER element should have enough data left */ + if( *len > ber_pvt_ber_remaining( ber ) ) { + return LBER_DEFAULT; + } + return tag; } @@ -252,7 +257,9 @@ ber_get_stringb( if ( (tag = ber_skip_tag( ber, &datalen )) == LBER_DEFAULT ) { return LBER_DEFAULT; } - if ( datalen > (*len - 1) ) { + + /* must fit within allocated space with termination */ + if ( datalen >= *len ) { return LBER_DEFAULT; } diff --git a/libraries/liblber/io.c b/libraries/liblber/io.c index 1e78515c4c..b04edb7890 100644 --- a/libraries/liblber/io.c +++ b/libraries/liblber/io.c @@ -77,7 +77,7 @@ ber_read( assert( BER_VALID( ber ) ); - nleft = ber->ber_end - ber->ber_ptr; + nleft = ber_pvt_ber_remaining( ber ); actuallen = nleft < len ? nleft : len; AC_MEMCPY( buf, ber->ber_ptr, actuallen ); @@ -524,15 +524,25 @@ get_lenbyte: ber->ber_rwptr += res; /* convert length. */ - ber->ber_len = 0; for( to_go = 0; to_go < res ; to_go++ ) { ber->ber_len <<= 8; ber->ber_len |= netlen[to_go]; } + if (PTR_IN_VAR(ber->ber_rwptr, ber->ber_len)) + return LBER_DEFAULT; } fill_buffer: /* now fill the buffer. */ + + /* make sure length is reasonable */ + if ( ber->ber_len == 0 || + ( sb->sb_max_incoming && ber->ber_len > sb->sb_max_incoming )) + { + errno = ERANGE; + return LBER_DEFAULT; + } + if (ber->ber_buf==NULL) { ber->ber_buf = (char *) LBER_MALLOC( ber->ber_len ); if (ber->ber_buf==NULL) { diff --git a/libraries/liblber/lber-int.h b/libraries/liblber/lber-int.h index 00a8f06a6c..ef34dfeb7d 100644 --- a/libraries/liblber/lber-int.h +++ b/libraries/liblber/lber-int.h @@ -74,6 +74,7 @@ struct sockbuf { ber_socket_t sb_fd; unsigned int sb_trans_needs_read:1; unsigned int sb_trans_needs_write:1; + ber_len_t sb_max_incoming; }; #define SOCKBUF_VALID( sb ) ( (sb)->sb_valid == LBER_VALID_SOCKBUF ) diff --git a/libraries/liblber/sockbuf.c b/libraries/liblber/sockbuf.c index 07627ba85c..bb3eb64c74 100644 --- a/libraries/liblber/sockbuf.c +++ b/libraries/liblber/sockbuf.c @@ -21,6 +21,10 @@ #include #endif /* HAVE_IO_H */ +#if defined( HAVE_FCNTL_H ) +#include +#endif + #if defined( HAVE_SYS_FILIO_H ) #include #elif defined( HAVE_SYS_IOCTL_H ) @@ -69,6 +73,7 @@ ber_sockbuf_ctrl( Sockbuf *sb, int opt, void *arg ) int ret = 0; assert( sb != NULL ); + assert( SOCKBUF_VALID( sb ) ); switch ( opt ) { case LBER_SB_OPT_HAS_IO: @@ -120,6 +125,18 @@ ber_sockbuf_ctrl( Sockbuf *sb, int opt, void *arg ) ret = ( sb->sb_trans_needs_write ? 1 : 0 ); break; + case LBER_SB_OPT_GET_MAX_INCOMING: + if ( arg != NULL ) { + *((ber_len_t *)arg) = sb->sb_max_incoming; + } + ret = 1; + break; + + case LBER_SB_OPT_SET_MAX_INCOMING: + sb->sb_max_incoming = *((ber_len_t *)arg); + ret = 1; + break; + default: ret = sb->sb_iod->sbiod_io->sbi_ctrl( sb->sb_iod, opt, arg );