From dafc98aaa282126d5a6061eb50d84308332d7806 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Sat, 30 Dec 2017 15:15:44 +0100 Subject: [PATCH] socket-util: slight rework of getpeersec() Let's call getsockopt() in a loop, so that we can deal correctly with the label changing while we are trying to read it. (also, while we are at it, let's make sure that there's always one trailing NUL byte at the end of the buffer, after all SO_PEERSEC has zero documentation, and multiple implementing backends, hence let's better be safe than sorry) --- src/basic/socket-util.c | 31 +++++++++++-------------------- 1 file changed, 11 insertions(+), 20 deletions(-) diff --git a/src/basic/socket-util.c b/src/basic/socket-util.c index 860c8fbfc..c89e5c8c7 100644 --- a/src/basic/socket-util.c +++ b/src/basic/socket-util.c @@ -987,41 +987,32 @@ int getpeercred(int fd, struct ucred *ucred) { } int getpeersec(int fd, char **ret) { + _cleanup_free_ char *s = NULL; socklen_t n = 64; - char *s; - int r; assert(fd >= 0); assert(ret); - s = new0(char, n); - if (!s) - return -ENOMEM; + for (;;) { + s = new0(char, n+1); + if (!s) + return -ENOMEM; - r = getsockopt(fd, SOL_SOCKET, SO_PEERSEC, s, &n); - if (r < 0) { - free(s); + if (getsockopt(fd, SOL_SOCKET, SO_PEERSEC, s, &n) >= 0) + break; if (errno != ERANGE) return -errno; - s = new0(char, n); - if (!s) - return -ENOMEM; - - r = getsockopt(fd, SOL_SOCKET, SO_PEERSEC, s, &n); - if (r < 0) { - free(s); - return -errno; - } + s = mfree(s); } - if (isempty(s)) { - free(s); + if (isempty(s)) return -EOPNOTSUPP; - } *ret = s; + s = NULL; + return 0; } -- 2.30.2