summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMark Salyzyn2016-10-27 10:04:48 -0500
committerMark Salyzyn2016-11-03 15:34:13 -0500
commit547e0dc45a6f2eca161b29b34a7f5ebbbc8d4b01 (patch)
treea00b6d307733777770fe668fd88a0da61a6635d4 /libcutils/sockets.cpp
parent5febc5131899402e983c319af9c38596ee9a56a2 (diff)
downloadplatform-system-core-547e0dc45a6f2eca161b29b34a7f5ebbbc8d4b01.tar.gz
platform-system-core-547e0dc45a6f2eca161b29b34a7f5ebbbc8d4b01.tar.xz
platform-system-core-547e0dc45a6f2eca161b29b34a7f5ebbbc8d4b01.zip
libcutils: add android_get_control_socket() test
android_get_control_socket() checks if the resulting file descriptor is valid, open and matches the socket bound name reference, which on purpose will fail if a symbolic link is in the path rather than using a fully qualified path. If there are any non-alpha and non-numeric characters in the name, they are replaced with _. Add unit test. Test: gTest libcutils_test --gtest_filter=SocketTest.android_get_control_socket Bug: 32450474 Change-Id: I27a6419012033ef8bd6ca04f3e479d01264d8c49
Diffstat (limited to 'libcutils/sockets.cpp')
-rw-r--r--libcutils/sockets.cpp84
1 files changed, 69 insertions, 15 deletions
diff --git a/libcutils/sockets.cpp b/libcutils/sockets.cpp
index bba63ac16..63761a2c5 100644
--- a/libcutils/sockets.cpp
+++ b/libcutils/sockets.cpp
@@ -28,12 +28,32 @@
28 28
29// This file contains socket implementation that can be shared between 29// This file contains socket implementation that can be shared between
30// platforms as long as the correct headers are included. 30// platforms as long as the correct headers are included.
31#define _GNU_SOURCE 1 // For asprintf
31 32
32#include <cutils/sockets.h> 33#include <ctype.h>
33 34#include <errno.h>
35#include <fcntl.h>
36#include <limits.h>
34#if !defined(_WIN32) 37#if !defined(_WIN32)
35#include <netinet/in.h> 38#include <netinet/in.h>
36#endif 39#endif
40#include <stdio.h>
41#include <stdlib.h>
42#include <string.h>
43#include <sys/stat.h>
44#include <sys/types.h>
45#if !defined(_WIN32)
46#include <sys/un.h>
47#endif
48#include <unistd.h>
49
50#include <string>
51
52#include <cutils/sockets.h>
53
54#ifndef TEMP_FAILURE_RETRY // _WIN32 does not define
55#define TEMP_FAILURE_RETRY(exp) (exp)
56#endif
37 57
38int socket_get_local_port(cutils_socket_t sock) { 58int socket_get_local_port(cutils_socket_t sock) {
39 sockaddr_storage addr; 59 sockaddr_storage addr;
@@ -47,22 +67,56 @@ int socket_get_local_port(cutils_socket_t sock) {
47} 67}
48 68
49int android_get_control_socket(const char* name) { 69int android_get_control_socket(const char* name) {
50 char key[64]; 70 char *key = NULL;
51 snprintf(key, sizeof(key), ANDROID_SOCKET_ENV_PREFIX "%s", name); 71 if (asprintf(&key, ANDROID_SOCKET_ENV_PREFIX "%s", name) < 0) return -1;
72 if (!key) return -1;
52 73
53 const char* val = getenv(key); 74 char *cp = key;
54 if (!val) { 75 while (*cp) {
55 return -1; 76 if (!isalnum(*cp)) *cp = '_';
77 ++cp;
56 } 78 }
57 79
80 const char* val = getenv(key);
81 free(key);
82 if (!val) return -1;
83
58 errno = 0; 84 errno = 0;
59 long ret = strtol(val, NULL, 10); 85 long fd = strtol(val, NULL, 10);
60 if (errno) { 86 if (errno) return -1;
61 return -1; 87
62 } 88 // validity checking
63 if (ret < 0 || ret > INT_MAX) { 89 if ((fd < 0) || (fd > INT_MAX)) return -1;
64 return -1; 90#if defined(_SC_OPEN_MAX)
65 } 91 if (fd >= sysconf(_SC_OPEN_MAX)) return -1;
92#elif defined(OPEN_MAX)
93 if (fd >= OPEN_MAX) return -1;
94#elif defined(_POSIX_OPEN_MAX)
95 if (fd >= _POSIX_OPEN_MAX) return -1;
96#endif
97
98#if defined(F_GETFD)
99 if (TEMP_FAILURE_RETRY(fcntl(fd, F_GETFD)) < 0) return -1;
100#elif defined(F_GETFL)
101 if (TEMP_FAILURE_RETRY(fcntl(fd, F_GETFL)) < 0) return -1;
102#else
103 struct stat s;
104 if (TEMP_FAILURE_RETRY(fstat(fd, &s)) < 0) return -1;
105#endif
106
107#if !defined(_WIN32)
108 struct sockaddr_un addr;
109 socklen_t addrlen = sizeof(addr);
110 int ret = TEMP_FAILURE_RETRY(getsockname(fd, (struct sockaddr *)&addr, &addrlen));
111 if (ret < 0) return -1;
112 char *path = NULL;
113 if (asprintf(&path, ANDROID_SOCKET_DIR"/%s", name) < 0) return -1;
114 if (!path) return -1;
115 int cmp = strcmp(addr.sun_path, path);
116 free(path);
117 if (cmp != 0) return -1;
118#endif
66 119
67 return static_cast<int>(ret); 120 // It is what we think it is
121 return static_cast<int>(fd);
68} 122}