Extend sshbuf validation
authortobias <tobias@openbsd.org>
Wed, 14 Aug 2024 15:40:30 +0000 (15:40 +0000)
committertobias <tobias@openbsd.org>
Wed, 14 Aug 2024 15:40:30 +0000 (15:40 +0000)
Multiple sshbuf structs can be linked through a parent/child relationship.
Make sure that a single sshbuf cannot be its own parent. If this would ever
happen, it would result in reference counting issues.

This is a cheap way of testing this with very little overhead. It does not
detect A->B->A linkages though for performance reason and the fact that it
takes a programming error for this to occur anyway.

Authored with Benny Baumann (BenBE at geshi dot org).

ok djm@

usr.bin/ssh/sshbuf.c

index 9756867..d0422d9 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: sshbuf.c,v 1.21 2024/08/14 15:37:11 tobias Exp $      */
+/*     $OpenBSD: sshbuf.c,v 1.22 2024/08/14 15:40:30 tobias Exp $      */
 /*
  * Copyright (c) 2011 Damien Miller
  *
@@ -55,6 +55,7 @@ sshbuf_check_sanity(const struct sshbuf *buf)
        SSHBUF_TELL("sanity");
        if (__predict_false(buf == NULL ||
            (!buf->readonly && buf->d != buf->cd) ||
+           buf->parent == buf ||
            buf->refcount < 1 || buf->refcount > SSHBUF_REFS_MAX ||
            buf->cd == NULL ||
            buf->max_size > SSHBUF_SIZE_MAX ||
@@ -130,7 +131,8 @@ sshbuf_set_parent(struct sshbuf *child, struct sshbuf *parent)
        if ((r = sshbuf_check_sanity(child)) != 0 ||
            (r = sshbuf_check_sanity(parent)) != 0)
                return r;
-       if (child->parent != NULL && child->parent != parent)
+       if ((child->parent != NULL && child->parent != parent) ||
+           child == parent)
                return SSH_ERR_INTERNAL_ERROR;
        child->parent = parent;
        child->parent->refcount++;