summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'libcutils')
-rw-r--r--libcutils/Android.bp26
-rw-r--r--libcutils/include/private/android_filesystem_config.h8
-rw-r--r--libcutils/uevent.cpp (renamed from libcutils/uevent.c)90
3 files changed, 97 insertions, 27 deletions
diff --git a/libcutils/Android.bp b/libcutils/Android.bp
index b30336ddd..8fb3a52d7 100644
--- a/libcutils/Android.bp
+++ b/libcutils/Android.bp
@@ -112,25 +112,34 @@ cc_library {
112 "properties.cpp", 112 "properties.cpp",
113 "qtaguid.cpp", 113 "qtaguid.cpp",
114 "trace-dev.c", 114 "trace-dev.c",
115 "uevent.c", 115 "uevent.cpp",
116 ], 116 ],
117 sanitize: {
118 misc_undefined: ["integer"],
119 },
120 }, 117 },
121 118
122 android_arm: { 119 android_arm: {
123 srcs: ["arch-arm/memset32.S"], 120 srcs: ["arch-arm/memset32.S"],
121 sanitize: {
122 misc_undefined: ["integer"],
123 },
124 }, 124 },
125 android_arm64: { 125 android_arm64: {
126 srcs: ["arch-arm64/android_memset.S"], 126 srcs: ["arch-arm64/android_memset.S"],
127 sanitize: {
128 misc_undefined: ["integer"],
129 },
127 }, 130 },
128 131
129 android_mips: { 132 android_mips: {
130 srcs: ["arch-mips/android_memset.c"], 133 srcs: ["arch-mips/android_memset.c"],
134 sanitize: {
135 misc_undefined: ["integer"],
136 },
131 }, 137 },
132 android_mips64: { 138 android_mips64: {
133 srcs: ["arch-mips/android_memset.c"], 139 srcs: ["arch-mips/android_memset.c"],
140 sanitize: {
141 misc_undefined: ["integer"],
142 },
134 }, 143 },
135 144
136 android_x86: { 145 android_x86: {
@@ -138,6 +147,12 @@ cc_library {
138 "arch-x86/android_memset16.S", 147 "arch-x86/android_memset16.S",
139 "arch-x86/android_memset32.S", 148 "arch-x86/android_memset32.S",
140 ], 149 ],
150 // TODO: This is to work around b/29412086.
151 // Remove once __mulodi4 is available and move the "sanitize" block
152 // to the android target.
153 sanitize: {
154 misc_undefined: [],
155 },
141 }, 156 },
142 157
143 android_x86_64: { 158 android_x86_64: {
@@ -145,6 +160,9 @@ cc_library {
145 "arch-x86_64/android_memset16.S", 160 "arch-x86_64/android_memset16.S",
146 "arch-x86_64/android_memset32.S", 161 "arch-x86_64/android_memset32.S",
147 ], 162 ],
163 sanitize: {
164 misc_undefined: ["integer"],
165 },
148 }, 166 },
149 }, 167 },
150 168
diff --git a/libcutils/include/private/android_filesystem_config.h b/libcutils/include/private/android_filesystem_config.h
index 55ece54a5..2ecf5bce6 100644
--- a/libcutils/include/private/android_filesystem_config.h
+++ b/libcutils/include/private/android_filesystem_config.h
@@ -170,6 +170,14 @@
170#define AID_SHARED_GID_START 50000 /* start of gids for apps in each user to share */ 170#define AID_SHARED_GID_START 50000 /* start of gids for apps in each user to share */
171#define AID_SHARED_GID_END 59999 /* end of gids for apps in each user to share */ 171#define AID_SHARED_GID_END 59999 /* end of gids for apps in each user to share */
172 172
173/*
174 * This is a magic number in the kernel and not something that was picked
175 * arbitrarily. This value is returned whenever a uid that has no mapping in the
176 * user namespace is returned to userspace:
177 * https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/include/linux/highuid.h?h=v4.4#n40
178 */
179#define AID_OVERFLOWUID 65534 /* unmapped user in the user namespace */
180
173#define AID_ISOLATED_START 99000 /* start of uids for fully isolated sandboxed processes */ 181#define AID_ISOLATED_START 99000 /* start of uids for fully isolated sandboxed processes */
174#define AID_ISOLATED_END 99999 /* end of uids for fully isolated sandboxed processes */ 182#define AID_ISOLATED_END 99999 /* end of uids for fully isolated sandboxed processes */
175 183
diff --git a/libcutils/uevent.c b/libcutils/uevent.cpp
index f548dca2f..a84e5b000 100644
--- a/libcutils/uevent.c
+++ b/libcutils/uevent.cpp
@@ -17,7 +17,8 @@
17#include <cutils/uevent.h> 17#include <cutils/uevent.h>
18 18
19#include <errno.h> 19#include <errno.h>
20#include <stdbool.h> 20#include <stdint.h>
21#include <stdio.h>
21#include <string.h> 22#include <string.h>
22#include <strings.h> 23#include <strings.h>
23#include <sys/socket.h> 24#include <sys/socket.h>
@@ -26,11 +27,60 @@
26 27
27#include <linux/netlink.h> 28#include <linux/netlink.h>
28 29
30#include <fstream>
31
32#include <private/android_filesystem_config.h>
33
34namespace {
35
36// Returns the uid of root in the current user namespace.
37// Returns AID_OVERFLOWUID if the root user is not mapped in the current
38// namespace.
39// Returns 0 if the kernel is not user namespace-aware (for backwards
40// compatibility) or if AID_OVERFLOWUID could not be validated to match what the
41// kernel would return.
42uid_t GetRootUid() {
43 constexpr uid_t kParentRootUid = 0;
44
45 std::ifstream uid_map_file("/proc/self/uid_map");
46 if (!uid_map_file) {
47 // The kernel does not support user namespaces.
48 return kParentRootUid;
49 }
50
51 uid_t current_namespace_uid, parent_namespace_uid;
52 uint32_t length;
53 while (uid_map_file >> current_namespace_uid >> parent_namespace_uid >> length) {
54 // Since kParentRootUid is 0, it should be the first entry in the mapped
55 // range.
56 if (parent_namespace_uid != kParentRootUid || length < 1) continue;
57 return current_namespace_uid;
58 }
59
60 // Sanity check: verify that the overflow UID is the one to be returned by
61 // the kernel.
62 std::ifstream overflowuid_file("/proc/sys/kernel/overflowuid");
63 if (!overflowuid_file) {
64 // It's better to return 0 in case we cannot make sure that the overflow
65 // UID matches.
66 return kParentRootUid;
67 }
68 uid_t kernel_overflow_uid;
69 if (!(overflowuid_file >> kernel_overflow_uid) || kernel_overflow_uid != AID_OVERFLOWUID)
70 return kParentRootUid;
71
72 // root is unmapped, use the kernel "overflow" uid.
73 return AID_OVERFLOWUID;
74}
75
76} // namespace
77
78extern "C" {
79
29/** 80/**
30 * Like recv(), but checks that messages actually originate from the kernel. 81 * Like recv(), but checks that messages actually originate from the kernel.
31 */ 82 */
32ssize_t uevent_kernel_multicast_recv(int socket, void *buffer, size_t length) 83ssize_t uevent_kernel_multicast_recv(int socket, void* buffer, size_t length) {
33{
34 uid_t uid = -1; 84 uid_t uid = -1;
35 return uevent_kernel_multicast_uid_recv(socket, buffer, length, &uid); 85 return uevent_kernel_multicast_uid_recv(socket, buffer, length, &uid);
36} 86}
@@ -44,25 +94,19 @@ ssize_t uevent_kernel_multicast_recv(int socket, void *buffer, size_t length)
44 * returns -1, sets errno to EIO, and sets "user" to the UID associated with the 94 * returns -1, sets errno to EIO, and sets "user" to the UID associated with the
45 * message. If the peer UID cannot be determined, "user" is set to -1." 95 * message. If the peer UID cannot be determined, "user" is set to -1."
46 */ 96 */
47ssize_t uevent_kernel_multicast_uid_recv(int socket, void *buffer, size_t length, uid_t *uid) 97ssize_t uevent_kernel_multicast_uid_recv(int socket, void* buffer, size_t length, uid_t* uid) {
48{
49 return uevent_kernel_recv(socket, buffer, length, true, uid); 98 return uevent_kernel_recv(socket, buffer, length, true, uid);
50} 99}
51 100
52ssize_t uevent_kernel_recv(int socket, void *buffer, size_t length, bool require_group, uid_t *uid) 101ssize_t uevent_kernel_recv(int socket, void* buffer, size_t length, bool require_group, uid_t* uid) {
53{ 102 static const uid_t root_uid = GetRootUid();
54 struct iovec iov = { buffer, length }; 103 struct iovec iov = {buffer, length};
55 struct sockaddr_nl addr; 104 struct sockaddr_nl addr;
56 char control[CMSG_SPACE(sizeof(struct ucred))]; 105 char control[CMSG_SPACE(sizeof(struct ucred))];
57 struct msghdr hdr = { 106 struct msghdr hdr = {
58 &addr, 107 &addr, sizeof(addr), &iov, 1, control, sizeof(control), 0,
59 sizeof(addr),
60 &iov,
61 1,
62 control,
63 sizeof(control),
64 0,
65 }; 108 };
109 struct ucred* cred;
66 110
67 *uid = -1; 111 *uid = -1;
68 ssize_t n = recvmsg(socket, &hdr, 0); 112 ssize_t n = recvmsg(socket, &hdr, 0);
@@ -70,15 +114,15 @@ ssize_t uevent_kernel_recv(int socket, void *buffer, size_t length, bool require
70 return n; 114 return n;
71 } 115 }
72 116
73 struct cmsghdr *cmsg = CMSG_FIRSTHDR(&hdr); 117 struct cmsghdr* cmsg = CMSG_FIRSTHDR(&hdr);
74 if (cmsg == NULL || cmsg->cmsg_type != SCM_CREDENTIALS) { 118 if (cmsg == NULL || cmsg->cmsg_type != SCM_CREDENTIALS) {
75 /* ignoring netlink message with no sender credentials */ 119 /* ignoring netlink message with no sender credentials */
76 goto out; 120 goto out;
77 } 121 }
78 122
79 struct ucred *cred = (struct ucred *)CMSG_DATA(cmsg); 123 cred = (struct ucred*)CMSG_DATA(cmsg);
80 *uid = cred->uid; 124 *uid = cred->uid;
81 if (cred->uid != 0) { 125 if (cred->uid != root_uid) {
82 /* ignoring netlink message from non-root user */ 126 /* ignoring netlink message from non-root user */
83 goto out; 127 goto out;
84 } 128 }
@@ -101,8 +145,7 @@ out:
101 return -1; 145 return -1;
102} 146}
103 147
104int uevent_open_socket(int buf_sz, bool passcred) 148int uevent_open_socket(int buf_sz, bool passcred) {
105{
106 struct sockaddr_nl addr; 149 struct sockaddr_nl addr;
107 int on = passcred; 150 int on = passcred;
108 int s; 151 int s;
@@ -113,8 +156,7 @@ int uevent_open_socket(int buf_sz, bool passcred)
113 addr.nl_groups = 0xffffffff; 156 addr.nl_groups = 0xffffffff;
114 157
115 s = socket(PF_NETLINK, SOCK_DGRAM | SOCK_CLOEXEC, NETLINK_KOBJECT_UEVENT); 158 s = socket(PF_NETLINK, SOCK_DGRAM | SOCK_CLOEXEC, NETLINK_KOBJECT_UEVENT);
116 if(s < 0) 159 if (s < 0) return -1;
117 return -1;
118 160
119 /* buf_sz should be less than net.core.rmem_max for this to succeed */ 161 /* buf_sz should be less than net.core.rmem_max for this to succeed */
120 if (setsockopt(s, SOL_SOCKET, SO_RCVBUF, &buf_sz, sizeof(buf_sz)) < 0) { 162 if (setsockopt(s, SOL_SOCKET, SO_RCVBUF, &buf_sz, sizeof(buf_sz)) < 0) {
@@ -124,10 +166,12 @@ int uevent_open_socket(int buf_sz, bool passcred)
124 166
125 setsockopt(s, SOL_SOCKET, SO_PASSCRED, &on, sizeof(on)); 167 setsockopt(s, SOL_SOCKET, SO_PASSCRED, &on, sizeof(on));
126 168
127 if(bind(s, (struct sockaddr *) &addr, sizeof(addr)) < 0) { 169 if (bind(s, (struct sockaddr*)&addr, sizeof(addr)) < 0) {
128 close(s); 170 close(s);
129 return -1; 171 return -1;
130 } 172 }
131 173
132 return s; 174 return s;
133} 175}
176
177} // extern "C"