1 /* 2 * Copyright (C) 2012 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #include <gtest/gtest.h> 18 #include "ScopedSignalHandler.h" 19 #include "TemporaryFile.h" 20 21 #include <errno.h> 22 #include <fcntl.h> 23 #include <limits.h> 24 #include <stdint.h> 25 #include <unistd.h> 26 #include <sys/syscall.h> 27 #include <sys/types.h> 28 #include <sys/wait.h> 29 30 TEST(unistd, sysconf_SC_MONOTONIC_CLOCK) { 31 ASSERT_GT(sysconf(_SC_MONOTONIC_CLOCK), 0); 32 } 33 34 static void* get_brk() { 35 return sbrk(0); 36 } 37 38 static void* page_align(uintptr_t addr) { 39 uintptr_t mask = sysconf(_SC_PAGE_SIZE) - 1; 40 return reinterpret_cast<void*>((addr + mask) & ~mask); 41 } 42 43 TEST(unistd, brk) { 44 void* initial_break = get_brk(); 45 46 // The kernel aligns the break to a page. 47 void* new_break = reinterpret_cast<void*>(reinterpret_cast<uintptr_t>(initial_break) + 1); 48 ASSERT_EQ(0, brk(new_break)); 49 ASSERT_GE(get_brk(), new_break); 50 51 new_break = page_align(reinterpret_cast<uintptr_t>(initial_break) + sysconf(_SC_PAGE_SIZE)); 52 ASSERT_EQ(0, brk(new_break)); 53 ASSERT_EQ(get_brk(), new_break); 54 } 55 56 TEST(unistd, brk_ENOMEM) { 57 ASSERT_EQ(-1, brk(reinterpret_cast<void*>(-1))); 58 ASSERT_EQ(ENOMEM, errno); 59 } 60 61 #if defined(__GLIBC__) 62 #define SBRK_MIN INTPTR_MIN 63 #define SBRK_MAX INTPTR_MAX 64 #else 65 #define SBRK_MIN PTRDIFF_MIN 66 #define SBRK_MAX PTRDIFF_MAX 67 #endif 68 69 TEST(unistd, sbrk_ENOMEM) { 70 #if defined(__BIONIC__) && !defined(__LP64__) 71 // There is no way to guarantee that all overflow conditions can be tested 72 // without manipulating the underlying values of the current break. 73 extern void* __bionic_brk; 74 75 class ScopedBrk { 76 public: 77 ScopedBrk() : saved_brk_(__bionic_brk) {} 78 virtual ~ScopedBrk() { __bionic_brk = saved_brk_; } 79 80 private: 81 void* saved_brk_; 82 }; 83 84 ScopedBrk scope_brk; 85 86 // Set the current break to a point that will cause an overflow. 87 __bionic_brk = reinterpret_cast<void*>(static_cast<uintptr_t>(PTRDIFF_MAX) + 2); 88 89 // Can't increase by so much that we'd overflow. 90 ASSERT_EQ(reinterpret_cast<void*>(-1), sbrk(PTRDIFF_MAX)); 91 ASSERT_EQ(ENOMEM, errno); 92 93 // Set the current break to a point that will cause an overflow. 94 __bionic_brk = reinterpret_cast<void*>(static_cast<uintptr_t>(PTRDIFF_MAX)); 95 96 ASSERT_EQ(reinterpret_cast<void*>(-1), sbrk(PTRDIFF_MIN)); 97 ASSERT_EQ(ENOMEM, errno); 98 99 __bionic_brk = reinterpret_cast<void*>(static_cast<uintptr_t>(PTRDIFF_MAX) - 1); 100 101 ASSERT_EQ(reinterpret_cast<void*>(-1), sbrk(PTRDIFF_MIN + 1)); 102 ASSERT_EQ(ENOMEM, errno); 103 #else 104 class ScopedBrk { 105 public: 106 ScopedBrk() : saved_brk_(get_brk()) {} 107 virtual ~ScopedBrk() { brk(saved_brk_); } 108 109 private: 110 void* saved_brk_; 111 }; 112 113 ScopedBrk scope_brk; 114 115 uintptr_t cur_brk = reinterpret_cast<uintptr_t>(get_brk()); 116 if (cur_brk < static_cast<uintptr_t>(-(SBRK_MIN+1))) { 117 // Do the overflow test for a max negative increment. 118 ASSERT_EQ(reinterpret_cast<void*>(-1), sbrk(SBRK_MIN)); 119 #if defined(__BIONIC__) 120 // GLIBC does not set errno in overflow case. 121 ASSERT_EQ(ENOMEM, errno); 122 #endif 123 } 124 125 uintptr_t overflow_brk = static_cast<uintptr_t>(SBRK_MAX) + 2; 126 if (cur_brk < overflow_brk) { 127 // Try and move the value to PTRDIFF_MAX + 2. 128 cur_brk = reinterpret_cast<uintptr_t>(sbrk(overflow_brk)); 129 } 130 if (cur_brk >= overflow_brk) { 131 ASSERT_EQ(reinterpret_cast<void*>(-1), sbrk(SBRK_MAX)); 132 #if defined(__BIONIC__) 133 // GLIBC does not set errno in overflow case. 134 ASSERT_EQ(ENOMEM, errno); 135 #endif 136 } 137 #endif 138 } 139 140 TEST(unistd, truncate) { 141 TemporaryFile tf; 142 ASSERT_EQ(0, close(tf.fd)); 143 ASSERT_EQ(0, truncate(tf.filename, 123)); 144 145 struct stat sb; 146 ASSERT_EQ(0, stat(tf.filename, &sb)); 147 ASSERT_EQ(123, sb.st_size); 148 } 149 150 TEST(unistd, truncate64) { 151 TemporaryFile tf; 152 ASSERT_EQ(0, close(tf.fd)); 153 ASSERT_EQ(0, truncate64(tf.filename, 123)); 154 155 struct stat sb; 156 ASSERT_EQ(0, stat(tf.filename, &sb)); 157 ASSERT_EQ(123, sb.st_size); 158 } 159 160 TEST(unistd, ftruncate) { 161 TemporaryFile tf; 162 ASSERT_EQ(0, ftruncate(tf.fd, 123)); 163 ASSERT_EQ(0, close(tf.fd)); 164 165 struct stat sb; 166 ASSERT_EQ(0, stat(tf.filename, &sb)); 167 ASSERT_EQ(123, sb.st_size); 168 } 169 170 TEST(unistd, ftruncate64) { 171 TemporaryFile tf; 172 ASSERT_EQ(0, ftruncate64(tf.fd, 123)); 173 ASSERT_EQ(0, close(tf.fd)); 174 175 struct stat sb; 176 ASSERT_EQ(0, stat(tf.filename, &sb)); 177 ASSERT_EQ(123, sb.st_size); 178 } 179 180 static bool g_pause_test_flag = false; 181 static void PauseTestSignalHandler(int) { 182 g_pause_test_flag = true; 183 } 184 185 TEST(unistd, pause) { 186 ScopedSignalHandler handler(SIGALRM, PauseTestSignalHandler); 187 188 alarm(1); 189 ASSERT_FALSE(g_pause_test_flag); 190 ASSERT_EQ(-1, pause()); 191 ASSERT_TRUE(g_pause_test_flag); 192 } 193 194 TEST(unistd, read) { 195 int fd = open("/proc/version", O_RDONLY); 196 ASSERT_TRUE(fd != -1); 197 198 char buf[5]; 199 ASSERT_EQ(5, read(fd, buf, 5)); 200 ASSERT_EQ(buf[0], 'L'); 201 ASSERT_EQ(buf[1], 'i'); 202 ASSERT_EQ(buf[2], 'n'); 203 ASSERT_EQ(buf[3], 'u'); 204 ASSERT_EQ(buf[4], 'x'); 205 close(fd); 206 } 207 208 TEST(unistd, read_EBADF) { 209 // read returns ssize_t which is 64-bits on LP64, so it's worth explicitly checking that 210 // our syscall stubs correctly return a 64-bit -1. 211 char buf[1]; 212 ASSERT_EQ(-1, read(-1, buf, sizeof(buf))); 213 ASSERT_EQ(EBADF, errno); 214 } 215 216 TEST(unistd, syscall_long) { 217 // Check that syscall(3) correctly returns long results. 218 // https://code.google.com/p/android/issues/detail?id=73952 219 // We assume that the break is > 4GiB, but this is potentially flaky. 220 uintptr_t p = reinterpret_cast<uintptr_t>(sbrk(0)); 221 ASSERT_EQ(p, static_cast<uintptr_t>(syscall(__NR_brk, 0))); 222 } 223 224 TEST(unistd, alarm) { 225 ASSERT_EQ(0U, alarm(0)); 226 } 227 228 TEST(unistd, _exit) { 229 int pid = fork(); 230 ASSERT_NE(-1, pid) << strerror(errno); 231 232 if (pid == 0) { 233 _exit(99); 234 } 235 236 int status; 237 ASSERT_EQ(pid, waitpid(pid, &status, 0)); 238 ASSERT_TRUE(WIFEXITED(status)); 239 ASSERT_EQ(99, WEXITSTATUS(status)); 240 } 241 242 TEST(unistd, getenv_unsetenv) { 243 ASSERT_EQ(0, setenv("test-variable", "hello", 1)); 244 ASSERT_STREQ("hello", getenv("test-variable")); 245 ASSERT_EQ(0, unsetenv("test-variable")); 246 ASSERT_TRUE(getenv("test-variable") == NULL); 247 } 248 249 TEST(unistd, unsetenv_EINVAL) { 250 EXPECT_EQ(-1, unsetenv(NULL)); 251 EXPECT_EQ(EINVAL, errno); 252 EXPECT_EQ(-1, unsetenv("")); 253 EXPECT_EQ(EINVAL, errno); 254 EXPECT_EQ(-1, unsetenv("a=b")); 255 EXPECT_EQ(EINVAL, errno); 256 } 257 258 TEST(unistd, setenv_EINVAL) { 259 EXPECT_EQ(-1, setenv(NULL, "value", 0)); 260 EXPECT_EQ(EINVAL, errno); 261 EXPECT_EQ(-1, setenv(NULL, "value", 1)); 262 EXPECT_EQ(EINVAL, errno); 263 EXPECT_EQ(-1, setenv("", "value", 0)); 264 EXPECT_EQ(EINVAL, errno); 265 EXPECT_EQ(-1, setenv("", "value", 1)); 266 EXPECT_EQ(EINVAL, errno); 267 EXPECT_EQ(-1, setenv("a=b", "value", 0)); 268 EXPECT_EQ(EINVAL, errno); 269 EXPECT_EQ(-1, setenv("a=b", "value", 1)); 270 EXPECT_EQ(EINVAL, errno); 271 } 272 273 TEST(unistd, setenv) { 274 ASSERT_EQ(0, unsetenv("test-variable")); 275 276 char a[] = "a"; 277 char b[] = "b"; 278 char c[] = "c"; 279 280 // New value. 281 EXPECT_EQ(0, setenv("test-variable", a, 0)); 282 EXPECT_STREQ(a, getenv("test-variable")); 283 284 // Existing value, no overwrite. 285 EXPECT_EQ(0, setenv("test-variable", b, 0)); 286 EXPECT_STREQ(a, getenv("test-variable")); 287 288 // Existing value, overwrite. 289 EXPECT_EQ(0, setenv("test-variable", c, 1)); 290 EXPECT_STREQ(c, getenv("test-variable")); 291 // But the arrays backing the values are unchanged. 292 EXPECT_EQ('a', a[0]); 293 EXPECT_EQ('b', b[0]); 294 EXPECT_EQ('c', c[0]); 295 296 ASSERT_EQ(0, unsetenv("test-variable")); 297 } 298 299 TEST(unistd, putenv) { 300 ASSERT_EQ(0, unsetenv("a")); 301 302 char* s1 = strdup("a=b"); 303 ASSERT_EQ(0, putenv(s1)); 304 305 ASSERT_STREQ("b", getenv("a")); 306 s1[2] = 'c'; 307 ASSERT_STREQ("c", getenv("a")); 308 309 char* s2 = strdup("a=b"); 310 ASSERT_EQ(0, putenv(s2)); 311 312 ASSERT_STREQ("b", getenv("a")); 313 ASSERT_EQ('c', s1[2]); 314 315 ASSERT_EQ(0, unsetenv("a")); 316 free(s1); 317 free(s2); 318 } 319 320 TEST(unistd, clearenv) { 321 extern char** environ; 322 323 // Guarantee that environ is not initially empty... 324 ASSERT_EQ(0, setenv("test-variable", "a", 1)); 325 326 // Stash a copy. 327 std::vector<char*> old_environ; 328 for (size_t i = 0; environ[i] != NULL; ++i) { 329 old_environ.push_back(strdup(environ[i])); 330 } 331 332 ASSERT_EQ(0, clearenv()); 333 334 EXPECT_TRUE(environ == NULL || environ[0] == NULL); 335 EXPECT_EQ(NULL, getenv("test-variable")); 336 EXPECT_EQ(0, setenv("test-variable", "post-clear", 1)); 337 EXPECT_STREQ("post-clear", getenv("test-variable")); 338 339 // Put the old environment back. 340 for (size_t i = 0; i < old_environ.size(); ++i) { 341 EXPECT_EQ(0, putenv(old_environ[i])); 342 } 343 344 // Check it wasn't overwritten. 345 EXPECT_STREQ("a", getenv("test-variable")); 346 347 EXPECT_EQ(0, unsetenv("test-variable")); 348 } 349 350 static void TestFsyncFunction(int (*fn)(int)) { 351 int fd; 352 353 // Can't sync an invalid fd. 354 errno = 0; 355 EXPECT_EQ(-1, fn(-1)); 356 EXPECT_EQ(EBADF, errno); 357 358 // It doesn't matter whether you've opened a file for write or not. 359 TemporaryFile tf; 360 ASSERT_NE(-1, tf.fd); 361 362 EXPECT_EQ(0, fn(tf.fd)); 363 364 ASSERT_NE(-1, fd = open(tf.filename, O_RDONLY)); 365 EXPECT_EQ(0, fn(fd)); 366 close(fd); 367 368 ASSERT_NE(-1, fd = open(tf.filename, O_RDWR)); 369 EXPECT_EQ(0, fn(fd)); 370 close(fd); 371 372 // The fd can even be a directory. 373 ASSERT_NE(-1, fd = open("/", O_RDONLY)); 374 EXPECT_EQ(0, fn(fd)); 375 close(fd); 376 377 // But some file systems may choose to be fussy... 378 errno = 0; 379 ASSERT_NE(-1, fd = open("/proc/version", O_RDONLY)); 380 EXPECT_EQ(-1, fn(fd)); 381 EXPECT_EQ(EINVAL, errno); 382 close(fd); 383 } 384 385 TEST(unistd, fdatasync) { 386 TestFsyncFunction(fdatasync); 387 } 388 389 TEST(unistd, fsync) { 390 TestFsyncFunction(fsync); 391 } 392 393 static void AssertGetPidCorrect() { 394 // The loop is just to make manual testing/debugging with strace easier. 395 pid_t getpid_syscall_result = syscall(__NR_getpid); 396 for (size_t i = 0; i < 128; ++i) { 397 ASSERT_EQ(getpid_syscall_result, getpid()); 398 } 399 } 400 401 TEST(unistd, getpid_caching_and_fork) { 402 pid_t parent_pid = getpid(); 403 ASSERT_EQ(syscall(__NR_getpid), parent_pid); 404 405 pid_t fork_result = fork(); 406 ASSERT_NE(fork_result, -1); 407 if (fork_result == 0) { 408 // We're the child. 409 AssertGetPidCorrect(); 410 ASSERT_EQ(parent_pid, getppid()); 411 _exit(123); 412 } else { 413 // We're the parent. 414 ASSERT_EQ(parent_pid, getpid()); 415 416 int status; 417 ASSERT_EQ(fork_result, waitpid(fork_result, &status, 0)); 418 ASSERT_TRUE(WIFEXITED(status)); 419 ASSERT_EQ(123, WEXITSTATUS(status)); 420 } 421 } 422 423 static int GetPidCachingCloneStartRoutine(void*) { 424 AssertGetPidCorrect(); 425 return 123; 426 } 427 428 TEST(unistd, getpid_caching_and_clone) { 429 pid_t parent_pid = getpid(); 430 ASSERT_EQ(syscall(__NR_getpid), parent_pid); 431 432 void* child_stack[1024]; 433 int clone_result = clone(GetPidCachingCloneStartRoutine, &child_stack[1024], CLONE_NEWNS | SIGCHLD, NULL); 434 if (clone_result == -1 && errno == EPERM && getuid() != 0) { 435 GTEST_LOG_(INFO) << "This test only works if you have permission to CLONE_NEWNS; try running as root.\n"; 436 return; 437 } 438 ASSERT_NE(clone_result, -1); 439 440 ASSERT_EQ(parent_pid, getpid()); 441 442 int status; 443 ASSERT_EQ(clone_result, waitpid(clone_result, &status, 0)); 444 ASSERT_TRUE(WIFEXITED(status)); 445 ASSERT_EQ(123, WEXITSTATUS(status)); 446 } 447 448 static void* GetPidCachingPthreadStartRoutine(void*) { 449 AssertGetPidCorrect(); 450 return NULL; 451 } 452 453 TEST(unistd, getpid_caching_and_pthread_create) { 454 pid_t parent_pid = getpid(); 455 456 pthread_t t; 457 ASSERT_EQ(0, pthread_create(&t, NULL, GetPidCachingPthreadStartRoutine, NULL)); 458 459 ASSERT_EQ(parent_pid, getpid()); 460 461 void* result; 462 ASSERT_EQ(0, pthread_join(t, &result)); 463 ASSERT_EQ(NULL, result); 464 } 465