Path: csiph.com!xmission!news.snarked.org!news.linkpendium.com!news.linkpendium.com!panix!usenet.stanford.edu!not-for-mail From: Jessica Clarke Newsgroups: gnu.bash.bug Subject: [PATCH] unwind_prot.c: Avoid buffer overflow Date: Sat, 27 Jun 2020 22:14:38 +0100 Lines: 35 Approved: bug-bash@gnu.org Message-ID: References: <20200627211438.40013-1-jrtc27@jrtc27.com> NNTP-Posting-Host: lists.gnu.org Mime-Version: 1.0 Content-Transfer-Encoding: 8bit X-Trace: usenet.stanford.edu 1593295308 7490 209.51.188.17 (27 Jun 2020 22:01:48 GMT) X-Complaints-To: action@cs.stanford.edu Cc: Jessica Clarke To: bug-bash@gnu.org Envelope-to: bug-bash@gnu.org DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=jrtc27.com; s=gmail.jrtc27.user; h=from:to:cc:subject:date:message-id:mime-version :content-transfer-encoding; bh=/0STzMfhOoQ3B2pRiYjq3GL7bj0V5ERQEwTA0okP7QY=; b=n9q4bAbe8efWAz7h6BLJRX/po3gjShLIvE8zCVKmGCnjzUx8j87NORW/nQtSnBdIlC m0j4hLGD8jw2M+/BT1Q9O4yCzqlug+xX1mjrj8dTBJjg6kZcV4o9CrwQZwaqNVOGa3Se wNSnZ1RKe48F4TslJtUHBd4Sdg8bh/n32TlQ9SN7OVs5R91sHmiP0bJuMMTmNcJsLd1D o6vaecoeaIZSowW5WHZlUWMIHSXRXNJ5HdxvDpp55BAaZoxx65v0c9gUw3PlETN4Rd6s wgSCD8IrRlfOMSjaRBfT2U6aUthK+hgW+XNGWLGP2PFGbJEJTzMNl+2b7Vv031It3WaG OURg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:mime-version :content-transfer-encoding; bh=/0STzMfhOoQ3B2pRiYjq3GL7bj0V5ERQEwTA0okP7QY=; b=CTi+Md42zFCVBACTTLraKqsaobAP7BMIcaIxlrcHpUMI7MjR0YPBVyQh4hzT59SWSG z73VAj11VHJ0t6q/0YA4g1CBpQDDURhh3nmYtV43+43tnVI14Xsu5F2ZVqfmq3hVlSC3 F0DQNqDTbfLW8ApnbPpnyqvjrpUjQae0VQ18mId7kmlvZpGvRFdr0UKa1Mwa7Qn3esxg H6LH9qbnV4ibIxWPOAv71RhMbYFmKp4OVmkOKi54qhFZ9oaRnf1o5t5nRFvWoaqij6WX UxCPWPAf5nrIj++8VxfBJE/V/xo7I44Vv39yFTKWn3YA5IH0zdbBTBw7YbZ4Y8OvCW40 8yig== X-Gm-Message-State: AOAM531U81iGAA5kj/25rhmSrwvMgDCoogCQfakLiDgBHm1VAtfb6UXD kALob2eKOCXUJGQoIY+zkohpmWcdJSc= X-Google-Smtp-Source: ABdhPJyko2egfuRAQOfCUX3T8Tzio7oqzIUXtCoPmS0ZvdjPkpWD+yYSpNh10T2itquvh7ZQUT0mBA== X-Received: by 2002:a7b:c84d:: with SMTP id c13mr9732196wml.170.1593292480911; Sat, 27 Jun 2020 14:14:40 -0700 (PDT) X-Mailer: git-send-email 2.20.1 Received-SPF: pass client-ip=2a00:1450:4864:20::342; envelope-from=jrtc27@jrtc27.com; helo=mail-wm1-x342.google.com X-detected-operating-system: by eggs.gnu.org: No matching host in p0f cache. That's all we know. X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, URIBL_BLOCKED=0.001 autolearn=_AUTOLEARN X-Spam_action: no action X-Mailman-Approved-At: Sat, 27 Jun 2020 18:01:45 -0400 X-BeenThere: bug-bash@gnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Bug reports for the GNU Bourne Again SHell List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Mailman-Original-Message-ID: <20200627211438.40013-1-jrtc27@jrtc27.com> Xref: csiph.com gnu.bash.bug:16460 In unwind_protect_mem_internal, we must make sure to allocate at least a full UNWIND_ELT, even if the required size for desired_setting is less than the remaining padding in UNWIND_ELT. Otherwise when we come to memset it with 0xdf in unwind_frame_discard_internal we will overflow the allocation. On existing 32-bit and 64-bit architectures, this padding happens to be only 4 bytes, and no users of this function call it with a size smaller than 4 (unwind_protect_short and unwind_protect_string are both currently unused). However, we should not rely on this as this could change in future. Moreover on CHERI-RISC-V, pointers are replaced with capabilities, 16-byte fat pointers, and the padding now ends up being 12 bytes, violating this assumption, but also trapping on this detected buffer overflow by virtue of its fine-grained bounds. --- unwind_prot.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/unwind_prot.c b/unwind_prot.c index c9196dc1..37429924 100644 --- a/unwind_prot.c +++ b/unwind_prot.c @@ -349,6 +349,8 @@ unwind_protect_mem_internal (var, psize) size = *(int *) psize; allocated = size + offsetof (UNWIND_ELT, sv.v.desired_setting[0]); + if (allocated < sizeof (UNWIND_ELT)) + allocated = sizeof (UNWIND_ELT); elt = (UNWIND_ELT *)xmalloc (allocated); elt->head.next = unwind_protect_list; elt->head.cleanup = (Function *) restore_variable; -- 2.20.1