summaryrefslogtreecommitdiffstats
path: root/source/lib/util.c
diff options
context:
space:
mode:
Diffstat (limited to 'source/lib/util.c')
-rw-r--r--source/lib/util.c83
1 files changed, 83 insertions, 0 deletions
diff --git a/source/lib/util.c b/source/lib/util.c
index 45d3916ebe6..f49af133adb 100644
--- a/source/lib/util.c
+++ b/source/lib/util.c
@@ -3112,3 +3112,86 @@ int this_is_smp(void)
return 0;
#endif
}
+
+/****************************************************************
+ Check if an offset into a buffer is safe.
+ If this returns True it's safe to indirect into the byte at
+ pointer ptr+off.
+****************************************************************/
+
+BOOL is_offset_safe(const char *buf_base, size_t buf_len, char *ptr, size_t off)
+{
+ const char *end_base = buf_base + buf_len;
+ char *end_ptr = ptr + off;
+
+ if (!buf_base || !ptr) {
+ return False;
+ }
+
+ if (end_base < buf_base || end_ptr < ptr) {
+ return False; /* wrap. */
+ }
+
+ if (end_ptr < end_base) {
+ return True;
+ }
+ return False;
+}
+
+/****************************************************************
+ Return a safe pointer into a buffer, or NULL.
+****************************************************************/
+
+char *get_safe_ptr(const char *buf_base, size_t buf_len, char *ptr, size_t off)
+{
+ return is_offset_safe(buf_base, buf_len, ptr, off) ?
+ ptr + off : NULL;
+}
+
+/****************************************************************
+ Return a safe pointer into a string within a buffer, or NULL.
+****************************************************************/
+
+char *get_safe_str_ptr(const char *buf_base, size_t buf_len, char *ptr, size_t off)
+{
+ if (!is_offset_safe(buf_base, buf_len, ptr, off)) {
+ return NULL;
+ }
+ /* Check if a valid string exists at this offset. */
+ if (skip_string(buf_base,buf_len, ptr + off) == NULL) {
+ return NULL;
+ }
+ return ptr + off;
+}
+
+/****************************************************************
+ Return an SVAL at a pointer, or failval if beyond the end.
+****************************************************************/
+
+int get_safe_SVAL(const char *buf_base, size_t buf_len, char *ptr, size_t off, int failval)
+{
+ /*
+ * Note we use off+1 here, not off+2 as SVAL accesses ptr[0] and ptr[1],
+ * NOT ptr[2].
+ */
+ if (!is_offset_safe(buf_base, buf_len, ptr, off+1)) {
+ return failval;
+ }
+ return SVAL(ptr,off);
+}
+
+/****************************************************************
+ Return an IVAL at a pointer, or failval if beyond the end.
+****************************************************************/
+
+int get_safe_IVAL(const char *buf_base, size_t buf_len, char *ptr, size_t off, int failval)
+{
+ /*
+ * Note we use off+3 here, not off+4 as IVAL accesses
+ * ptr[0] ptr[1] ptr[2] ptr[3] NOT ptr[4].
+ */
+ if (!is_offset_safe(buf_base, buf_len, ptr, off+3)) {
+ return failval;
+ }
+ return IVAL(ptr,off);
+}