From a0bda4cce16da09fed44d70c1eaa5e56516024fa Mon Sep 17 00:00:00 2001
From: Michael Vogt <mvo@ubuntu.com>
Date: Fri, 15 Jan 2021 20:59:53 +0100
Subject: [PATCH] cmd: make string/error code more robust against errno leaking

The i386 sid sbuild fails because apparently some sbuild code
is calling functions that are not implemented so errno is set
during the tests when it is not expected. This leads to test
failures because the die() code will append errno status if
errno is set. This commit fixes this and makes the nightly
test also run on i386.
---
 cmd/libsnap-confine-private/error.c        | 10 ++++++++++
 cmd/libsnap-confine-private/string-utils.c |  6 ++++++
 tests/nightly/sbuild/task.yaml             | 15 +++++++++++----
 3 files changed, 27 insertions(+), 4 deletions(-)

diff --git a/cmd/libsnap-confine-private/error.c b/cmd/libsnap-confine-private/error.c
index 17a9676a2ef..5d4ce082343 100644
--- a/cmd/libsnap-confine-private/error.c
+++ b/cmd/libsnap-confine-private/error.c
@@ -29,6 +29,8 @@
 static sc_error *sc_error_initv(const char *domain, int code,
 				const char *msgfmt, va_list ap)
 {
+	// Set errno in case we die.
+	errno = 0;
 	sc_error *err = calloc(1, sizeof *err);
 	if (err == NULL) {
 		die("cannot allocate memory for error object");
@@ -81,6 +83,8 @@ sc_error *sc_error_init_api_misuse(const char *msgfmt, ...)
 
 const char *sc_error_domain(sc_error * err)
 {
+	// Set errno in case we die.
+	errno = 0;
 	if (err == NULL) {
 		die("cannot obtain error domain from NULL error");
 	}
@@ -89,6 +93,8 @@ const char *sc_error_domain(sc_error * err)
 
 int sc_error_code(sc_error * err)
 {
+	// Set errno in case we die.
+	errno = 0;
 	if (err == NULL) {
 		die("cannot obtain error code from NULL error");
 	}
@@ -97,6 +103,8 @@ int sc_error_code(sc_error * err)
 
 const char *sc_error_msg(sc_error * err)
 {
+	// Set errno in case we die.
+	errno = 0;
 	if (err == NULL) {
 		die("cannot obtain error message from NULL error");
 	}
@@ -143,6 +151,8 @@ int sc_error_forward(sc_error ** recipient, sc_error * error)
 
 bool sc_error_match(sc_error * error, const char *domain, int code)
 {
+	// Set errno in case we die.
+	errno = 0;
 	if (domain == NULL) {
 		die("cannot match error to a NULL domain");
 	}
diff --git a/cmd/libsnap-confine-private/string-utils.c b/cmd/libsnap-confine-private/string-utils.c
index ceea7b8cdd2..62c18c27f7a 100644
--- a/cmd/libsnap-confine-private/string-utils.c
+++ b/cmd/libsnap-confine-private/string-utils.c
@@ -74,6 +74,8 @@ bool sc_startswith(const char *str, const char *prefix)
 
 char *sc_strdup(const char *str)
 {
+	// Set errno in case we die.
+	errno = 0;
 	size_t len;
 	char *copy;
 	if (str == NULL) {
@@ -90,6 +92,8 @@ char *sc_strdup(const char *str)
 
 int sc_must_snprintf(char *str, size_t size, const char *format, ...)
 {
+	// Set errno in case we die.
+	errno = 0;
 	int n;
 
 	va_list va;
@@ -196,6 +200,8 @@ void sc_string_init(char *buf, size_t buf_size)
 
 void sc_string_quote(char *buf, size_t buf_size, const char *str)
 {
+	// Set errno in case we die.
+	errno = 0;
 	if (str == NULL) {
 		die("cannot quote string: string is NULL");
 	}
diff --git a/tests/nightly/sbuild/task.yaml b/tests/nightly/sbuild/task.yaml
index 6c2391ca7a8..86c88da12dc 100644
--- a/tests/nightly/sbuild/task.yaml
+++ b/tests/nightly/sbuild/task.yaml
@@ -4,14 +4,21 @@ summary: Ensure snapd builds correctly in sbuild
 priority: 500
 
 environment:
+    # amd64 normal build
     BUILD_MODE/normal: normal
+    ARCH/normal: amd64
+    # i386 normal build
+    BUILD_MODE/i386: normal
+    ARCH/i386: i386
+    # Only build arch:any
     BUILD_MODE/any: any
+    ARCH/any: amd64
 
 systems: [debian-sid-*]
 
 execute: |
     echo "Create a sid sbuild env"
-    eatmydata sbuild-createchroot --include=eatmydata,ccache,gnupg sid /srv/chroot/sid-amd64-sbuild http://deb.debian.org/debian
+    eatmydata sbuild-createchroot --include=eatmydata,ccache,gnupg --arch="$ARCH" sid /srv/chroot/"sid-$ARCH-sbuild" http://deb.debian.org/debian
 
     echo "Allow test user to run sbuild"
     sbuild-adduser test
@@ -22,11 +29,11 @@ execute: |
     fi
 
     echo "Build mode: $BUILD_MODE"
-    su -c "sbuild $BUILD_PARAM -d sid --run-autopkgtest $SPREAD_PATH/../*.dsc" test
+    su -c "sbuild $BUILD_PARAM --arch=$ARCH -d sid --run-autopkgtest $SPREAD_PATH/../*.dsc" test
 
 restore: |
-    rm --recursive --one-file-system /srv/chroot/sid-amd64-sbuild
-    rm -f /etc/schroot/chroot.d/sid-amd64-sbuild-*
+    rm --recursive --one-file-system /srv/chroot/"sid-$ARCH-sbuild"
+    rm -f /etc/schroot/chroot.d/"sid-$ARCH-sbuild-"*
 
 debug: |
     # Test that there's a log file and a symbolic link pointing to it.
