[systemd-devel] [PATCH] always check asprintf return code

Karel Zak kzak at redhat.com
Fri Jul 25 06:38:31 PDT 2014


There is a small number of the places in sources where we don't check
asprintf() return code and assume that after error the function
returns NULL pointer via the first argument. That's wrong, after
error the content of pointer is undefined.
---
 src/core/unit-printf.c                              |  8 +++++---
 src/cryptsetup/cryptsetup.c                         | 11 ++++++++---
 src/journal/coredump.c                              |  5 ++---
 src/journal/journalctl.c                            | 16 +++++++++++-----
 src/run/run.c                                       | 16 ++++++++--------
 src/shared/install.c                                | 15 +++++++++------
 src/systemctl/systemctl.c                           | 14 ++++++++------
 src/tty-ask-password-agent/tty-ask-password-agent.c |  5 +++--
 8 files changed, 54 insertions(+), 36 deletions(-)

diff --git a/src/core/unit-printf.c b/src/core/unit-printf.c
index 5bd30f0..8ac2081 100644
--- a/src/core/unit-printf.c
+++ b/src/core/unit-printf.c
@@ -208,7 +208,9 @@ static int specifier_user_name(char specifier, void *data, void *userdata, char
                                 if (r < 0)
                                         return -ENODATA;
 
-                                asprintf(&printed, UID_FMT, uid);
+                                r = asprintf(&printed, UID_FMT, uid);
+                                if (r < 0)
+                                        return -ENOMEM;
                         }
                 }
 
@@ -230,8 +232,8 @@ static int specifier_user_name(char specifier, void *data, void *userdata, char
 
                 if (specifier == 'u')
                         printed = strdup(username);
-                else
-                        asprintf(&printed, UID_FMT, uid);
+                else (asprintf(&printed, UID_FMT, uid) < 0)
+                        return -ENOMEM;
         }
 
         if (!printed)
diff --git a/src/cryptsetup/cryptsetup.c b/src/cryptsetup/cryptsetup.c
index a67d85e..67dc88f 100644
--- a/src/cryptsetup/cryptsetup.c
+++ b/src/cryptsetup/cryptsetup.c
@@ -549,13 +549,18 @@ int main(int argc, char *argv[]) {
                         description = NULL;
                 }
 
+                k = 0;
                 if (mount_point && description)
-                        asprintf(&name_buffer, "%s (%s) on %s", description, argv[2], mount_point);
+                        k = asprintf(&name_buffer, "%s (%s) on %s", description, argv[2], mount_point);
                 else if (mount_point)
-                        asprintf(&name_buffer, "%s on %s", argv[2], mount_point);
+                        k = asprintf(&name_buffer, "%s on %s", argv[2], mount_point);
                 else if (description)
-                        asprintf(&name_buffer, "%s (%s)", description, argv[2]);
+                        k = asprintf(&name_buffer, "%s (%s)", description, argv[2]);
 
+                if (k < 0) {
+                        log_oom();
+                        goto finish;
+                }
                 name = name_buffer ? name_buffer : argv[2];
 
                 k = crypt_init(&cd, argv[3]);
diff --git a/src/journal/coredump.c b/src/journal/coredump.c
index 182c2b1..9f28eed 100644
--- a/src/journal/coredump.c
+++ b/src/journal/coredump.c
@@ -591,9 +591,8 @@ int main(int argc, char* argv[]) {
         }
 
         if (sd_pid_get_owner_uid(pid, &owner_uid) >= 0) {
-                asprintf(&core_owner_uid, "COREDUMP_OWNER_UID=" UID_FMT, owner_uid);
-
-                if (core_owner_uid)
+                if (asprintf(&core_owner_uid, "COREDUMP_OWNER_UID=" UID_FMT,
+                             owner_uid) > 0)
                         IOVEC_SET_STRING(iovec[j++], core_owner_uid);
         }
 
diff --git a/src/journal/journalctl.c b/src/journal/journalctl.c
index 7aedbf0..5a59a3a 100644
--- a/src/journal/journalctl.c
+++ b/src/journal/journalctl.c
@@ -746,11 +746,17 @@ static int add_matches(sd_journal *j, char **args) {
                                         }
                                 } else
                                         t = strappend("_EXE=", path);
-                        } else if (S_ISCHR(st.st_mode))
-                                asprintf(&t, "_KERNEL_DEVICE=c%u:%u", major(st.st_rdev), minor(st.st_rdev));
-                        else if (S_ISBLK(st.st_mode))
-                                asprintf(&t, "_KERNEL_DEVICE=b%u:%u", major(st.st_rdev), minor(st.st_rdev));
-                        else {
+                        } else if (S_ISCHR(st.st_mode)) {
+                                if (asprintf(&t, "_KERNEL_DEVICE=c%u:%u",
+                                             major(st.st_rdev),
+                                             minor(st.st_rdev)) < 0)
+                                        return -ENOMEM;
+                        } else if (S_ISBLK(st.st_mode)) {
+                                if (asprintf(&t, "_KERNEL_DEVICE=b%u:%u",
+                                             major(st.st_rdev),
+                                             minor(st.st_rdev)) < 0)
+                                        return -ENOMEM;
+                        } else {
                                 log_error("File is neither a device node, nor regular file, nor executable: %s", *i);
                                 return -EINVAL;
                         }
diff --git a/src/run/run.c b/src/run/run.c
index 9d5527b..b9be145 100644
--- a/src/run/run.c
+++ b/src/run/run.c
@@ -335,11 +335,11 @@ static int start_transient_service(
         _cleanup_free_ char *name = NULL;
         int r;
 
-        if (arg_unit)
+        if (arg_unit) {
                 name = unit_name_mangle_with_suffix(arg_unit, MANGLE_NOGLOB, ".service");
-        else
-                asprintf(&name, "run-"PID_FMT".service", getpid());
-        if (!name)
+                if (!name)
+                        return log_oom();
+        } else if (asprintf(&name, "run-"PID_FMT".service", getpid()) < 0)
                 return log_oom();
 
         r = message_start_transient_unit_new(bus, name, &m);
@@ -471,11 +471,11 @@ static int start_transient_scope(
 
         assert(bus);
 
-        if (arg_unit)
+        if (arg_unit) {
                 name = unit_name_mangle_with_suffix(arg_unit, MANGLE_NOGLOB, ".scope");
-        else
-                asprintf(&name, "run-"PID_FMT".scope", getpid());
-        if (!name)
+                if (!name)
+                        return log_oom();
+        } else if (asprintf(&name, "run-"PID_FMT".scope", getpid()) < 0)
                 return log_oom();
 
         r = message_start_transient_unit_new(bus, name, &m);
diff --git a/src/shared/install.c b/src/shared/install.c
index a2f84f8..e957c33 100644
--- a/src/shared/install.c
+++ b/src/shared/install.c
@@ -88,13 +88,16 @@ static int get_config_path(UnitFileScope scope, bool runtime, const char *root_d
 
         case UNIT_FILE_SYSTEM:
 
-                if (root_dir && runtime)
-                        asprintf(&p, "%s/run/systemd/system", root_dir);
-                else if (runtime)
+                if (root_dir && runtime) {
+                        if (asprintf(&p, "%s/run/systemd/system", root_dir) < 0)
+                                return -ENOMEM;
+                } else if (runtime)
                         p = strdup("/run/systemd/system");
-                else if (root_dir)
-                        asprintf(&p, "%s/%s", root_dir, SYSTEM_CONFIG_UNIT_PATH);
-                else
+                else if (root_dir) {
+                        if (asprintf(&p, "%s/%s", root_dir,
+                                     SYSTEM_CONFIG_UNIT_PATH) < 0)
+                                return -ENOMEM;
+                } else
                         p = strdup(SYSTEM_CONFIG_UNIT_PATH);
 
                 break;
diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c
index fc32509..214b53f 100644
--- a/src/systemctl/systemctl.c
+++ b/src/systemctl/systemctl.c
@@ -4999,14 +4999,15 @@ static int enable_sysv_units(const char *verb, char **args) {
                         _cleanup_free_ char *path = NULL;
 
                         if (!isempty(arg_root))
-                                asprintf(&path, "%s/%s/%s", arg_root, *k, name);
+                                r = asprintf(&path, "%s/%s/%s", arg_root, *k, name);
                         else
-                                asprintf(&path, "%s/%s", *k, name);
+                                r = asprintf(&path, "%s/%s", *k, name);
 
-                        if (!path) {
+                        if (r < 0) {
                                 r = log_oom();
                                 goto finish;
                         }
+                        r = 0;
 
                         found_native = access(path, F_OK) >= 0;
                         if (found_native)
@@ -5017,13 +5018,14 @@ static int enable_sysv_units(const char *verb, char **args) {
                         continue;
 
                 if (!isempty(arg_root))
-                        asprintf(&p, "%s/" SYSTEM_SYSVINIT_PATH "/%s", arg_root, name);
+                        r = asprintf(&p, "%s/" SYSTEM_SYSVINIT_PATH "/%s", arg_root, name);
                 else
-                        asprintf(&p, SYSTEM_SYSVINIT_PATH "/%s", name);
-                if (!p) {
+                        r = asprintf(&p, SYSTEM_SYSVINIT_PATH "/%s", name);
+                if (r < 0) {
                         r = log_oom();
                         goto finish;
                 }
+                r = 0;
 
                 p[strlen(p) - strlen(".service")] = 0;
                 found_sysv = access(p, F_OK) >= 0;
diff --git a/src/tty-ask-password-agent/tty-ask-password-agent.c b/src/tty-ask-password-agent/tty-ask-password-agent.c
index a7fce51..2c540ba 100644
--- a/src/tty-ask-password-agent/tty-ask-password-agent.c
+++ b/src/tty-ask-password-agent/tty-ask-password-agent.c
@@ -102,8 +102,9 @@ static int ask_password_plymouth(
         if (accept_cached) {
                 packet = strdup("c");
                 n = 1;
-        } else
-                asprintf(&packet, "*\002%c%s%n", (int) (strlen(message) + 1), message, &n);
+        } else if (asprintf(&packet, "*\002%c%s%n", (int) (strlen(message) + 1),
+                            message, &n) < 0)
+                packet = NULL;
 
         if (!packet) {
                 r = -ENOMEM;
-- 
1.9.3



More information about the systemd-devel mailing list