From 41584b12c0531a52a72f6591c8c7ce214916883b Mon Sep 17 00:00:00 2001 From: Cyrill Gorcunov Date: Wed, 6 Jun 2012 12:57:00 +0400 Subject: [PATCH] kvm tools: Use safe string handling functions Use str[n|l] functions to make sure destination is not overflowed. Seems socket path generation should be moved into a separate helper, but it's for another patch. Signed-off-by: Cyrill Gorcunov Signed-off-by: Pekka Enberg --- tools/kvm/include/kvm/strbuf.h | 1 + tools/kvm/kvm.c | 18 ++++++++++++------ tools/kvm/util/strbuf.c | 23 +++++++++++++++++++++++ 3 files changed, 36 insertions(+), 6 deletions(-) diff --git a/tools/kvm/include/kvm/strbuf.h b/tools/kvm/include/kvm/strbuf.h index 8fdef7e003af..2beefbc3f3fd 100644 --- a/tools/kvm/include/kvm/strbuf.h +++ b/tools/kvm/include/kvm/strbuf.h @@ -7,6 +7,7 @@ int prefixcmp(const char *str, const char *prefix); extern size_t strlcat(char *dest, const char *src, size_t count); +extern size_t strlcpy(char *dest, const char *src, size_t size); /* some inline functions */ diff --git a/tools/kvm/kvm.c b/tools/kvm/kvm.c index 99bcef44fedf..64d8b5157424 100644 --- a/tools/kvm/kvm.c +++ b/tools/kvm/kvm.c @@ -1,6 +1,7 @@ #include "kvm/kvm.h" #include "kvm/read-write.h" #include "kvm/util.h" +#include "kvm/strbuf.h" #include "kvm/mutex.h" #include "kvm/kvm-cpu.h" #include "kvm/kvm-ipc.h" @@ -142,11 +143,14 @@ static int kvm__create_socket(struct kvm *kvm) struct sockaddr_un local; int len, r; + /* This usually 108 bytes long */ + BUILD_BUG_ON(sizeof(local.sun_path) < 32); + if (!kvm->name) return -EINVAL; - sprintf(full_name, "%s/%s%s", kvm__get_dir(), kvm->name, - KVM_SOCK_SUFFIX); + snprintf(full_name, sizeof(full_name), "%s/%s%s", + kvm__get_dir(), kvm->name, KVM_SOCK_SUFFIX); if (access(full_name, F_OK) == 0) { pr_err("Socket file %s already exist", full_name); return -EEXIST; @@ -156,7 +160,7 @@ static int kvm__create_socket(struct kvm *kvm) if (s < 0) return s; local.sun_family = AF_UNIX; - strcpy(local.sun_path, full_name); + strlcpy(local.sun_path, full_name, sizeof(local.sun_path)); len = strlen(local.sun_path) + sizeof(local.sun_family); r = bind(s, (struct sockaddr *)&local, len); if (r < 0) @@ -177,7 +181,8 @@ void kvm__remove_socket(const char *name) { char full_name[PATH_MAX]; - sprintf(full_name, "%s/%s%s", kvm__get_dir(), name, KVM_SOCK_SUFFIX); + snprintf(full_name, sizeof(full_name), "%s/%s%s", + kvm__get_dir(), name, KVM_SOCK_SUFFIX); unlink(full_name); } @@ -187,11 +192,12 @@ int kvm__get_sock_by_instance(const char *name) char sock_file[PATH_MAX]; struct sockaddr_un local; - sprintf(sock_file, "%s/%s%s", kvm__get_dir(), name, KVM_SOCK_SUFFIX); + snprintf(sock_file, sizeof(sock_file), "%s/%s%s", + kvm__get_dir(), name, KVM_SOCK_SUFFIX); s = socket(AF_UNIX, SOCK_STREAM, 0); local.sun_family = AF_UNIX; - strcpy(local.sun_path, sock_file); + strlcpy(local.sun_path, sock_file, sizeof(local.sun_path)); len = strlen(local.sun_path) + sizeof(local.sun_family); r = connect(s, &local, len); diff --git a/tools/kvm/util/strbuf.c b/tools/kvm/util/strbuf.c index 6632a1449165..99d6b0c08fb4 100644 --- a/tools/kvm/util/strbuf.c +++ b/tools/kvm/util/strbuf.c @@ -37,3 +37,26 @@ size_t strlcat(char *dest, const char *src, size_t count) return res; } + +/** + * strlcpy - Copy a %NUL terminated string into a sized buffer + * @dest: Where to copy the string to + * @src: Where to copy the string from + * @size: size of destination buffer + * + * Compatible with *BSD: the result is always a valid + * NUL-terminated string that fits in the buffer (unless, + * of course, the buffer size is zero). It does not pad + * out the result like strncpy() does. + */ +size_t strlcpy(char *dest, const char *src, size_t size) +{ + size_t ret = strlen(src); + + if (size) { + size_t len = (ret >= size) ? size - 1 : ret; + memcpy(dest, src, len); + dest[len] = '\0'; + } + return ret; +} -- 2.39.5