mirror of
https://github.com/OpenVPN/openvpn.git
synced 2026-06-11 09:50:26 -04:00
Added additional defensive programming to buffer.[ch] functions.
git-svn-id: http://svn.openvpn.net/projects/openvpn/branches/BETA21/openvpn@3128 e7ae566f-a301-0410-adde-c780ea21d3b5
This commit is contained in:
parent
70899be8dd
commit
b551bec9bc
2 changed files with 118 additions and 26 deletions
8
buffer.c
8
buffer.c
|
|
@ -42,6 +42,12 @@ array_mult_safe (const size_t m1, const size_t m2)
|
|||
return (size_t) res;
|
||||
}
|
||||
|
||||
void
|
||||
buf_size_error (size_t size)
|
||||
{
|
||||
msg (M_FATAL, "fatal buffer size error, size=%lu", (unsigned long)size);
|
||||
}
|
||||
|
||||
struct buffer
|
||||
#ifdef DMALLOC
|
||||
alloc_buf_debug (size_t size, const char *file, int line)
|
||||
|
|
@ -64,6 +70,8 @@ alloc_buf_gc (size_t size, struct gc_arena *gc)
|
|||
#endif
|
||||
{
|
||||
struct buffer buf;
|
||||
if (!buf_size_valid (size))
|
||||
buf_size_error (size);
|
||||
buf.capacity = (int)size;
|
||||
buf.offset = 0;
|
||||
buf.len = 0;
|
||||
|
|
|
|||
136
buffer.h
136
buffer.h
|
|
@ -28,6 +28,8 @@
|
|||
#include "basic.h"
|
||||
#include "thread.h"
|
||||
|
||||
#define BUF_SIZE_MAX 1000000
|
||||
|
||||
/*
|
||||
* Define verify_align function, otherwise
|
||||
* it will be a noop.
|
||||
|
|
@ -74,12 +76,12 @@ struct gc_arena
|
|||
struct gc_entry *list;
|
||||
};
|
||||
|
||||
#define BPTR(buf) ((buf)->data + (buf)->offset)
|
||||
#define BEND(buf) (BPTR(buf) + (buf)->len)
|
||||
#define BLAST(buf) (((buf)->data && (buf)->len) ? (BPTR(buf) + (buf)->len - 1) : NULL)
|
||||
#define BLEN(buf) ((buf)->len)
|
||||
#define BDEF(buf) ((buf)->data != NULL)
|
||||
#define BSTR(buf) ((char *)BPTR(buf))
|
||||
#define BPTR(buf) (buf_bptr(buf))
|
||||
#define BEND(buf) (buf_bend(buf))
|
||||
#define BLAST(buf) (buf_blast(buf))
|
||||
#define BLEN(buf) (buf_len(buf))
|
||||
#define BDEF(buf) (buf_defined(buf))
|
||||
#define BSTR(buf) (buf_str(buf))
|
||||
#define BCAP(buf) (buf_forward_capacity (buf))
|
||||
|
||||
void buf_clear (struct buffer *buf);
|
||||
|
|
@ -97,6 +99,8 @@ size_t array_mult_safe (const size_t m1, const size_t m2);
|
|||
#define PA_BRACKET (1<<0)
|
||||
char *print_argv (const char **p, struct gc_arena *gc, const unsigned int flags);
|
||||
|
||||
void buf_size_error (const size_t size);
|
||||
|
||||
/* for dmalloc debugging */
|
||||
|
||||
#ifdef DMALLOC
|
||||
|
|
@ -136,6 +140,69 @@ bool buf_init_debug (struct buffer *buf, int offset, const char *file, int line)
|
|||
|
||||
/* inline functions */
|
||||
|
||||
static inline bool
|
||||
buf_defined (const struct buffer *buf)
|
||||
{
|
||||
return buf->data != NULL;
|
||||
}
|
||||
|
||||
static inline bool
|
||||
buf_valid (const struct buffer *buf)
|
||||
{
|
||||
return likely (buf->data != NULL) && likely (buf->len >= 0);
|
||||
}
|
||||
|
||||
static inline uint8_t *
|
||||
buf_bptr (const struct buffer *buf)
|
||||
{
|
||||
if (buf_valid (buf))
|
||||
return buf->data + buf->offset;
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int
|
||||
buf_len (const struct buffer *buf)
|
||||
{
|
||||
if (buf_valid (buf))
|
||||
return buf->len;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline uint8_t *
|
||||
buf_bend (const struct buffer *buf)
|
||||
{
|
||||
return buf_bptr (buf) + buf_len (buf);
|
||||
}
|
||||
|
||||
static inline uint8_t *
|
||||
buf_blast (const struct buffer *buf)
|
||||
{
|
||||
if (buf_len (buf) > 0)
|
||||
return buf_bptr (buf) + buf_len (buf) - 1;
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static inline bool
|
||||
buf_size_valid (const size_t size)
|
||||
{
|
||||
return likely (size < BUF_SIZE_MAX);
|
||||
}
|
||||
|
||||
static inline bool
|
||||
buf_size_valid_signed (const int size)
|
||||
{
|
||||
return likely (size >= -BUF_SIZE_MAX) && likely (size < BUF_SIZE_MAX);
|
||||
}
|
||||
|
||||
static inline char *
|
||||
buf_str (const struct buffer *buf)
|
||||
{
|
||||
return (char *)buf_bptr(buf);
|
||||
}
|
||||
|
||||
static inline void
|
||||
buf_reset (struct buffer *buf)
|
||||
{
|
||||
|
|
@ -162,15 +229,11 @@ buf_init_dowork (struct buffer *buf, int offset)
|
|||
return true;
|
||||
}
|
||||
|
||||
static inline bool
|
||||
buf_defined (struct buffer *buf)
|
||||
{
|
||||
return buf->data != NULL;
|
||||
}
|
||||
|
||||
static inline void
|
||||
buf_set_write (struct buffer *buf, uint8_t *data, int size)
|
||||
{
|
||||
if (!buf_size_valid (size))
|
||||
buf_size_error (size);
|
||||
buf->len = 0;
|
||||
buf->offset = 0;
|
||||
buf->capacity = size;
|
||||
|
|
@ -182,6 +245,8 @@ buf_set_write (struct buffer *buf, uint8_t *data, int size)
|
|||
static inline void
|
||||
buf_set_read (struct buffer *buf, const uint8_t *data, int size)
|
||||
{
|
||||
if (!buf_size_valid (size))
|
||||
buf_size_error (size);
|
||||
buf->len = buf->capacity = size;
|
||||
buf->offset = 0;
|
||||
buf->data = (uint8_t *)data;
|
||||
|
|
@ -322,38 +387,57 @@ struct buffer buf_sub (struct buffer *buf, int size, bool prepend);
|
|||
static inline bool
|
||||
buf_safe (const struct buffer *buf, int len)
|
||||
{
|
||||
return len >= 0 && buf->offset + buf->len + len <= buf->capacity;
|
||||
return buf_valid (buf) && buf_size_valid (len)
|
||||
&& buf->offset + buf->len + len <= buf->capacity;
|
||||
}
|
||||
|
||||
static inline bool
|
||||
buf_safe_bidir (const struct buffer *buf, int len)
|
||||
{
|
||||
const int newlen = buf->len + len;
|
||||
return newlen >= 0 && buf->offset + newlen <= buf->capacity;
|
||||
if (buf_valid (buf) && buf_size_valid_signed (len))
|
||||
{
|
||||
const int newlen = buf->len + len;
|
||||
return newlen >= 0 && buf->offset + newlen <= buf->capacity;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
static inline int
|
||||
buf_forward_capacity (const struct buffer *buf)
|
||||
{
|
||||
int ret = buf->capacity - (buf->offset + buf->len);
|
||||
if (ret < 0)
|
||||
ret = 0;
|
||||
return ret;
|
||||
if (buf_valid (buf))
|
||||
{
|
||||
int ret = buf->capacity - (buf->offset + buf->len);
|
||||
if (ret < 0)
|
||||
ret = 0;
|
||||
return ret;
|
||||
}
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int
|
||||
buf_forward_capacity_total (const struct buffer *buf)
|
||||
{
|
||||
int ret = buf->capacity - buf->offset;
|
||||
if (ret < 0)
|
||||
ret = 0;
|
||||
return ret;
|
||||
if (buf_valid (buf))
|
||||
{
|
||||
int ret = buf->capacity - buf->offset;
|
||||
if (ret < 0)
|
||||
ret = 0;
|
||||
return ret;
|
||||
}
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int
|
||||
buf_reverse_capacity (const struct buffer *buf)
|
||||
{
|
||||
return buf->offset;
|
||||
if (buf_valid (buf))
|
||||
return buf->offset;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline bool
|
||||
|
|
@ -373,7 +457,7 @@ buf_inc_len (struct buffer *buf, int inc)
|
|||
static inline uint8_t *
|
||||
buf_prepend (struct buffer *buf, int size)
|
||||
{
|
||||
if (size < 0 || size > buf->offset)
|
||||
if (!buf_valid (buf) || size < 0 || size > buf->offset)
|
||||
return NULL;
|
||||
buf->offset -= size;
|
||||
buf->len += size;
|
||||
|
|
@ -383,7 +467,7 @@ buf_prepend (struct buffer *buf, int size)
|
|||
static inline bool
|
||||
buf_advance (struct buffer *buf, int size)
|
||||
{
|
||||
if (size < 0 || buf->len < size)
|
||||
if (!buf_valid (buf) || size < 0 || buf->len < size)
|
||||
return false;
|
||||
buf->offset += size;
|
||||
buf->len -= size;
|
||||
|
|
|
|||
Loading…
Reference in a new issue