Changeset 988 for vendor/current/lib/uid_wrapper
- Timestamp:
- Nov 24, 2016, 1:14:11 PM (9 years ago)
- Location:
- vendor/current/lib/uid_wrapper
- Files:
-
- 3 deleted
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
vendor/current/lib/uid_wrapper/uid_wrapper.c
r740 r988 1 1 /* 2 Copyright (C) Andrew Tridgell 2009 3 4 This program is free software; you can redistribute it and/or modify 5 it under the terms of the GNU General Public License as published by 6 the Free Software Foundation; either version 3 of the License, or 7 (at your option) any later version. 8 9 This program is distributed in the hope that it will be useful, 10 but WITHOUT ANY WARRANTY; without even the implied warranty of 11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 GNU General Public License for more details. 13 14 You should have received a copy of the GNU General Public License 15 along with this program. If not, see <http://www.gnu.org/licenses/>. 2 * Copyright (c) 2009 Andrew Tridgell 3 * Copyright (c) 2011-2013 Andreas Schneider <asn@samba.org> 4 * 5 * This program is free software: you can redistribute it and/or modify 6 * it under the terms of the GNU General Public License as published by 7 * the Free Software Foundation, either version 3 of the License, or 8 * (at your option) any later version. 9 * 10 * This program is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU General Public License for more details. 14 * 15 * You should have received a copy of the GNU General Public License 16 * along with this program. If not, see <http://www.gnu.org/licenses/>. 16 17 */ 17 18 18 #ifdef _SAMBA_BUILD_ 19 20 #define UID_WRAPPER_NOT_REPLACE 21 #include "../replace/replace.h" 22 #include <talloc.h> 23 #include "system/passwd.h" 24 25 #else /* _SAMBA_BUILD_ */ 26 27 #error uid_wrapper_only_supported_in_samba_yet 28 29 #endif 30 31 #ifndef _PUBLIC_ 32 #define _PUBLIC_ 33 #endif 19 #include "config.h" 20 21 #include <errno.h> 22 #include <stdarg.h> 23 #include <stdbool.h> 24 #include <stdlib.h> 25 #include <stdio.h> 26 #include <string.h> 27 #include <sys/types.h> 28 #include <unistd.h> 29 #include <grp.h> 30 #ifdef HAVE_SYS_SYSCALL_H 31 #include <sys/syscall.h> 32 #endif 33 #ifdef HAVE_SYSCALL_H 34 #include <syscall.h> 35 #endif 36 #include <dlfcn.h> 37 38 #include <pthread.h> 39 40 #ifdef HAVE_GCC_THREAD_LOCAL_STORAGE 41 # define UWRAP_THREAD __thread 42 #else 43 # define UWRAP_THREAD 44 #endif 45 46 # define UWRAP_LOCK(m) do { \ 47 pthread_mutex_lock(&( m ## _mutex)); \ 48 } while(0) 49 50 # define UWRAP_UNLOCK(m) do { \ 51 pthread_mutex_unlock(&( m ## _mutex)); \ 52 } while(0) 53 54 /* Add new global locks here please */ 55 # define UWRAP_LOCK_ALL \ 56 UWRAP_LOCK(uwrap_id); \ 57 UWRAP_LOCK(libc_symbol_binding); \ 58 UWRAP_LOCK(libpthread_symbol_binding) 59 60 # define UWRAP_UNLOCK_ALL \ 61 UWRAP_UNLOCK(libpthread_symbol_binding); \ 62 UWRAP_UNLOCK(libc_symbol_binding); \ 63 UWRAP_UNLOCK(uwrap_id) 64 65 #ifdef HAVE_CONSTRUCTOR_ATTRIBUTE 66 #define CONSTRUCTOR_ATTRIBUTE __attribute__ ((constructor)) 67 #else 68 #define CONSTRUCTOR_ATTRIBUTE 69 #endif /* HAVE_CONSTRUCTOR_ATTRIBUTE */ 70 71 #ifdef HAVE_DESTRUCTOR_ATTRIBUTE 72 #define DESTRUCTOR_ATTRIBUTE __attribute__ ((destructor)) 73 #else 74 #define DESTRUCTOR_ATTRIBUTE 75 #endif /* HAVE_DESTRUCTOR_ATTRIBUTE */ 76 77 #ifdef HAVE_ADDRESS_SANITIZER_ATTRIBUTE 78 #define DO_NOT_SANITIZE_ADDRESS_ATTRIBUTE __attribute__((no_sanitize_address)) 79 #else /* DO_NOT_SANITIZE_ADDRESS_ATTRIBUTE */ 80 #define DO_NOT_SANITIZE_ADDRESS_ATTRIBUTE 81 #endif /* DO_NOT_SANITIZE_ADDRESS_ATTRIBUTE */ 82 83 /* GCC have printf type attribute check. */ 84 #ifdef HAVE_FUNCTION_ATTRIBUTE_FORMAT 85 #define PRINTF_ATTRIBUTE(a,b) __attribute__ ((__format__ (__printf__, a, b))) 86 #else 87 #define PRINTF_ATTRIBUTE(a,b) 88 #endif /* HAVE_FUNCTION_ATTRIBUTE_FORMAT */ 89 90 #define UWRAP_DLIST_ADD(list,item) do { \ 91 if (!(list)) { \ 92 (item)->prev = NULL; \ 93 (item)->next = NULL; \ 94 (list) = (item); \ 95 } else { \ 96 (item)->prev = NULL; \ 97 (item)->next = (list); \ 98 (list)->prev = (item); \ 99 (list) = (item); \ 100 } \ 101 } while (0) 102 103 #define UWRAP_DLIST_REMOVE(list,item) do { \ 104 if ((list) == (item)) { \ 105 (list) = (item)->next; \ 106 if (list) { \ 107 (list)->prev = NULL; \ 108 } \ 109 } else { \ 110 if ((item)->prev) { \ 111 (item)->prev->next = (item)->next; \ 112 } \ 113 if ((item)->next) { \ 114 (item)->next->prev = (item)->prev; \ 115 } \ 116 } \ 117 (item)->prev = NULL; \ 118 (item)->next = NULL; \ 119 } while (0) 120 121 #ifndef SAFE_FREE 122 #define SAFE_FREE(x) do { if ((x) != NULL) {free(x); (x)=NULL;} } while(0) 123 #endif 124 125 /***************** 126 * LOGGING 127 *****************/ 128 129 enum uwrap_dbglvl_e { 130 UWRAP_LOG_ERROR = 0, 131 UWRAP_LOG_WARN, 132 UWRAP_LOG_DEBUG, 133 UWRAP_LOG_TRACE 134 }; 135 136 #ifdef NDEBUG 137 # define UWRAP_LOG(...) 138 #else /* NDEBUG */ 139 static void uwrap_log(enum uwrap_dbglvl_e dbglvl, const char *function, const char *format, ...) PRINTF_ATTRIBUTE(3, 4); 140 # define UWRAP_LOG(dbglvl, ...) uwrap_log((dbglvl), __func__, __VA_ARGS__) 141 142 static void uwrap_log(enum uwrap_dbglvl_e dbglvl, const char *function, const char *format, ...) 143 { 144 char buffer[1024]; 145 va_list va; 146 const char *d; 147 unsigned int lvl = 0; 148 149 d = getenv("UID_WRAPPER_DEBUGLEVEL"); 150 if (d != NULL) { 151 lvl = atoi(d); 152 } 153 154 va_start(va, format); 155 vsnprintf(buffer, sizeof(buffer), format, va); 156 va_end(va); 157 158 if (lvl >= dbglvl) { 159 const char *prefix; 160 switch (dbglvl) { 161 case UWRAP_LOG_ERROR: 162 prefix = "UWRAP_ERROR"; 163 break; 164 case UWRAP_LOG_WARN: 165 prefix = "UWRAP_WARN"; 166 break; 167 case UWRAP_LOG_DEBUG: 168 prefix = "UWRAP_DEBUG"; 169 break; 170 case UWRAP_LOG_TRACE: 171 prefix = "UWRAP_TRACE"; 172 break; 173 } 174 175 fprintf(stderr, 176 "%s(%d) - %s: %s\n", 177 prefix, 178 (int)getpid(), 179 function, 180 buffer); 181 } 182 } 183 #endif /* NDEBUG */ 184 185 /***************** 186 * LIBC 187 *****************/ 188 189 #define LIBC_NAME "libc.so" 190 191 typedef int (*__libc_setuid)(uid_t uid); 192 193 typedef uid_t (*__libc_getuid)(void); 194 195 #ifdef HAVE_SETEUID 196 typedef int (*__libc_seteuid)(uid_t euid); 197 #endif 198 199 #ifdef HAVE_SETREUID 200 typedef int (*__libc_setreuid)(uid_t ruid, uid_t euid); 201 #endif 202 203 #ifdef HAVE_SETRESUID 204 typedef int (*__libc_setresuid)(uid_t ruid, uid_t euid, uid_t suid); 205 #endif 206 207 #ifdef HAVE_GETRESUID 208 typedef int (*__libc_getresuid)(uid_t *ruid, uid_t *euid, uid_t *suid); 209 #endif 210 211 typedef uid_t (*__libc_geteuid)(void); 212 213 typedef int (*__libc_setgid)(gid_t gid); 214 215 typedef gid_t (*__libc_getgid)(void); 216 217 #ifdef HAVE_SETEGID 218 typedef int (*__libc_setegid)(uid_t egid); 219 #endif 220 221 #ifdef HAVE_SETREGID 222 typedef int (*__libc_setregid)(uid_t rgid, uid_t egid); 223 #endif 224 225 #ifdef HAVE_SETRESGID 226 typedef int (*__libc_setresgid)(uid_t rgid, uid_t egid, uid_t sgid); 227 #endif 228 229 #ifdef HAVE_GETRESGID 230 typedef int (*__libc_getresgid)(gid_t *rgid, gid_t *egid, gid_t *sgid); 231 #endif 232 233 typedef gid_t (*__libc_getegid)(void); 234 235 typedef int (*__libc_getgroups)(int size, gid_t list[]); 236 237 typedef int (*__libc_setgroups)(size_t size, const gid_t *list); 238 239 #ifdef HAVE_SYSCALL 240 typedef long int (*__libc_syscall)(long int sysno, ...); 241 #endif 242 243 #define UWRAP_SYMBOL_ENTRY(i) \ 244 union { \ 245 __libc_##i f; \ 246 void *obj; \ 247 } _libc_##i 248 249 struct uwrap_libc_symbols { 250 UWRAP_SYMBOL_ENTRY(setuid); 251 UWRAP_SYMBOL_ENTRY(getuid); 252 #ifdef HAVE_SETEUID 253 UWRAP_SYMBOL_ENTRY(seteuid); 254 #endif 255 #ifdef HAVE_SETREUID 256 UWRAP_SYMBOL_ENTRY(setreuid); 257 #endif 258 #ifdef HAVE_SETRESUID 259 UWRAP_SYMBOL_ENTRY(setresuid); 260 #endif 261 #ifdef HAVE_GETRESUID 262 UWRAP_SYMBOL_ENTRY(getresuid); 263 #endif 264 UWRAP_SYMBOL_ENTRY(geteuid); 265 UWRAP_SYMBOL_ENTRY(setgid); 266 UWRAP_SYMBOL_ENTRY(getgid); 267 #ifdef HAVE_SETEGID 268 UWRAP_SYMBOL_ENTRY(setegid); 269 #endif 270 #ifdef HAVE_SETREGID 271 UWRAP_SYMBOL_ENTRY(setregid); 272 #endif 273 #ifdef HAVE_SETRESGID 274 UWRAP_SYMBOL_ENTRY(setresgid); 275 #endif 276 #ifdef HAVE_GETRESGID 277 UWRAP_SYMBOL_ENTRY(getresgid); 278 #endif 279 UWRAP_SYMBOL_ENTRY(getegid); 280 UWRAP_SYMBOL_ENTRY(getgroups); 281 UWRAP_SYMBOL_ENTRY(setgroups); 282 #ifdef HAVE_SYSCALL 283 UWRAP_SYMBOL_ENTRY(syscall); 284 #endif 285 }; 286 #undef UWRAP_SYMBOL_ENTRY 287 288 /***************** 289 * LIBPTHREAD 290 *****************/ 291 /* Yeah... I'm pig. I overloading macro here... So what? */ 292 #define UWRAP_SYMBOL_ENTRY(i) \ 293 union { \ 294 __libpthread_##i f; \ 295 void *obj; \ 296 } _libpthread_##i 297 298 typedef int (*__libpthread_pthread_create)(pthread_t *thread, 299 const pthread_attr_t *attr, 300 void *(*start_routine) (void *), 301 void *arg); 302 typedef void (*__libpthread_pthread_exit)(void *retval); 303 304 struct uwrap_libpthread_symbols { 305 UWRAP_SYMBOL_ENTRY(pthread_create); 306 UWRAP_SYMBOL_ENTRY(pthread_exit); 307 }; 308 #undef UWRAP_SYMBOL_ENTRY 34 309 35 310 /* 36 we keep the virtualised euid/egid/groups information here311 * We keep the virtualised euid/egid/groups information here 37 312 */ 38 static struct { 313 struct uwrap_thread { 314 bool enabled; 315 316 uid_t ruid; 317 uid_t euid; 318 uid_t suid; 319 320 gid_t rgid; 321 gid_t egid; 322 gid_t sgid; 323 324 int ngroups; 325 gid_t *groups; 326 327 struct uwrap_thread *next; 328 struct uwrap_thread *prev; 329 }; 330 331 struct uwrap { 332 struct { 333 void *handle; 334 struct uwrap_libc_symbols symbols; 335 } libc; 336 337 struct { 338 void *handle; 339 struct uwrap_libpthread_symbols symbols; 340 } libpthread; 341 39 342 bool initialised; 343 344 /* Real uid and gid of user who run uid wrapper */ 345 uid_t myuid; 346 gid_t mygid; 347 348 struct uwrap_thread *ids; 349 }; 350 351 static struct uwrap uwrap; 352 353 /* Shortcut to the list item */ 354 static UWRAP_THREAD struct uwrap_thread *uwrap_tls_id; 355 356 /* The mutex or accessing the id */ 357 static pthread_mutex_t uwrap_id_mutex = PTHREAD_MUTEX_INITIALIZER; 358 359 /* The mutex for accessing the global libc.symbols */ 360 static pthread_mutex_t libc_symbol_binding_mutex = PTHREAD_MUTEX_INITIALIZER; 361 362 /* The mutex for accessing the global libpthread.symbols */ 363 static pthread_mutex_t libpthread_symbol_binding_mutex = PTHREAD_MUTEX_INITIALIZER; 364 365 /********************************************************* 366 * UWRAP PROTOTYPES 367 *********************************************************/ 368 369 bool uid_wrapper_enabled(void); 370 void uwrap_constructor(void) CONSTRUCTOR_ATTRIBUTE; 371 void uwrap_destructor(void) DESTRUCTOR_ATTRIBUTE; 372 373 /********************************************************* 374 * UWRAP LIBC LOADER FUNCTIONS 375 *********************************************************/ 376 377 enum uwrap_lib { 378 UWRAP_LIBC, 379 UWRAP_LIBNSL, 380 UWRAP_LIBSOCKET, 381 UWRAP_LIBPTHREAD, 382 }; 383 384 static void *uwrap_load_lib_handle(enum uwrap_lib lib) 385 { 386 int flags = RTLD_LAZY; 387 void *handle = NULL; 388 int i; 389 390 #ifdef RTLD_DEEPBIND 391 flags |= RTLD_DEEPBIND; 392 #endif 393 394 switch (lib) { 395 case UWRAP_LIBNSL: 396 /* FALL TROUGH */ 397 case UWRAP_LIBSOCKET: 398 /* FALL TROUGH */ 399 case UWRAP_LIBC: 400 handle = uwrap.libc.handle; 401 if (handle == NULL) { 402 for (i = 10; i >= 0; i--) { 403 char soname[256] = {0}; 404 405 snprintf(soname, sizeof(soname), "libc.so.%d", i); 406 handle = dlopen(soname, flags); 407 if (handle != NULL) { 408 break; 409 } 410 } 411 412 uwrap.libc.handle = handle; 413 } 414 break; 415 case UWRAP_LIBPTHREAD: 416 handle = uwrap.libpthread.handle; 417 if (handle == NULL) { 418 handle = dlopen("libpthread.so.0", flags); 419 if (handle != NULL) { 420 break; 421 } 422 } 423 break; 424 } 425 426 if (handle == NULL) { 427 #ifdef RTLD_NEXT 428 handle = uwrap.libc.handle = RTLD_NEXT; 429 #else 430 fprintf(stderr, 431 "Failed to dlopen library: %s\n", 432 dlerror()); 433 exit(-1); 434 #endif 435 } 436 437 return handle; 438 } 439 440 static void *_uwrap_bind_symbol(enum uwrap_lib lib, const char *fn_name) 441 { 442 void *handle; 443 void *func; 444 445 handle = uwrap_load_lib_handle(lib); 446 447 func = dlsym(handle, fn_name); 448 if (func == NULL) { 449 fprintf(stderr, 450 "Failed to find %s: %s\n", 451 fn_name, dlerror()); 452 exit(-1); 453 } 454 455 return func; 456 } 457 458 #define uwrap_bind_symbol_libc(sym_name) \ 459 UWRAP_LOCK(libc_symbol_binding); \ 460 if (uwrap.libc.symbols._libc_##sym_name.obj == NULL) { \ 461 uwrap.libc.symbols._libc_##sym_name.obj = \ 462 _uwrap_bind_symbol(UWRAP_LIBC, #sym_name); \ 463 } \ 464 UWRAP_UNLOCK(libc_symbol_binding) 465 466 #define uwrap_bind_symbol_libpthread(sym_name) \ 467 UWRAP_LOCK(libpthread_symbol_binding); \ 468 if (uwrap.libpthread.symbols._libpthread_##sym_name.obj == NULL) { \ 469 uwrap.libpthread.symbols._libpthread_##sym_name.obj = \ 470 _uwrap_bind_symbol(UWRAP_LIBPTHREAD, #sym_name); \ 471 } \ 472 UWRAP_UNLOCK(libpthread_symbol_binding) 473 474 /* 475 * IMPORTANT 476 * 477 * Functions expeciall from libc need to be loaded individually, you can't load 478 * all at once or gdb will segfault at startup. The same applies to valgrind and 479 * has probably something todo with with the linker. 480 * So we need load each function at the point it is called the first time. 481 */ 482 static int libc_setuid(uid_t uid) 483 { 484 uwrap_bind_symbol_libc(setuid); 485 486 return uwrap.libc.symbols._libc_setuid.f(uid); 487 } 488 489 static uid_t libc_getuid(void) 490 { 491 uwrap_bind_symbol_libc(getuid); 492 493 return uwrap.libc.symbols._libc_getuid.f(); 494 } 495 496 #ifdef HAVE_SETEUID 497 static int libc_seteuid(uid_t euid) 498 { 499 uwrap_bind_symbol_libc(seteuid); 500 501 return uwrap.libc.symbols._libc_seteuid.f(euid); 502 } 503 #endif 504 505 #ifdef HAVE_SETREUID 506 static int libc_setreuid(uid_t ruid, uid_t euid) 507 { 508 uwrap_bind_symbol_libc(setreuid); 509 510 return uwrap.libc.symbols._libc_setreuid.f(ruid, euid); 511 } 512 #endif 513 514 #ifdef HAVE_SETRESUID 515 static int libc_setresuid(uid_t ruid, uid_t euid, uid_t suid) 516 { 517 uwrap_bind_symbol_libc(setresuid); 518 519 return uwrap.libc.symbols._libc_setresuid.f(ruid, euid, suid); 520 } 521 #endif 522 523 #ifdef HAVE_GETRESUID 524 static int libc_getresuid(uid_t *ruid, uid_t *euid, uid_t *suid) 525 { 526 uwrap_bind_symbol_libc(getresuid); 527 528 return uwrap.libc.symbols._libc_getresuid.f(ruid, euid, suid); 529 } 530 #endif 531 532 static uid_t libc_geteuid(void) 533 { 534 uwrap_bind_symbol_libc(geteuid); 535 536 return uwrap.libc.symbols._libc_geteuid.f(); 537 } 538 539 static int libc_setgid(gid_t gid) 540 { 541 uwrap_bind_symbol_libc(setgid); 542 543 return uwrap.libc.symbols._libc_setgid.f(gid); 544 } 545 546 static gid_t libc_getgid(void) 547 { 548 uwrap_bind_symbol_libc(getgid); 549 550 return uwrap.libc.symbols._libc_getgid.f(); 551 } 552 553 #ifdef HAVE_SETEGID 554 static int libc_setegid(gid_t egid) 555 { 556 uwrap_bind_symbol_libc(setegid); 557 558 return uwrap.libc.symbols._libc_setegid.f(egid); 559 } 560 #endif 561 562 #ifdef HAVE_SETREGID 563 static int libc_setregid(gid_t rgid, gid_t egid) 564 { 565 uwrap_bind_symbol_libc(setregid); 566 567 return uwrap.libc.symbols._libc_setregid.f(rgid, egid); 568 } 569 #endif 570 571 #ifdef HAVE_SETRESGID 572 static int libc_setresgid(gid_t rgid, gid_t egid, gid_t sgid) 573 { 574 uwrap_bind_symbol_libc(setresgid); 575 576 return uwrap.libc.symbols._libc_setresgid.f(rgid, egid, sgid); 577 } 578 #endif 579 580 #ifdef HAVE_GETRESGID 581 static int libc_getresgid(gid_t *rgid, gid_t *egid, gid_t *sgid) 582 { 583 uwrap_bind_symbol_libc(setresgid); 584 585 return uwrap.libc.symbols._libc_getresgid.f(rgid, egid, sgid); 586 } 587 #endif 588 589 static gid_t libc_getegid(void) 590 { 591 uwrap_bind_symbol_libc(getegid); 592 593 return uwrap.libc.symbols._libc_getegid.f(); 594 } 595 596 static int libc_getgroups(int size, gid_t list[]) 597 { 598 uwrap_bind_symbol_libc(getgroups); 599 600 return uwrap.libc.symbols._libc_getgroups.f(size, list); 601 } 602 603 static int libc_setgroups(size_t size, const gid_t *list) 604 { 605 uwrap_bind_symbol_libc(setgroups); 606 607 return uwrap.libc.symbols._libc_setgroups.f(size, list); 608 } 609 610 #ifdef HAVE_SYSCALL 611 DO_NOT_SANITIZE_ADDRESS_ATTRIBUTE 612 static long int libc_vsyscall(long int sysno, va_list va) 613 { 614 long int args[8]; 615 long int rc; 616 int i; 617 618 uwrap_bind_symbol_libc(syscall); 619 620 for (i = 0; i < 8; i++) { 621 args[i] = va_arg(va, long int); 622 } 623 624 rc = uwrap.libc.symbols._libc_syscall.f(sysno, 625 args[0], 626 args[1], 627 args[2], 628 args[3], 629 args[4], 630 args[5], 631 args[6], 632 args[7]); 633 634 return rc; 635 } 636 #endif 637 638 /* 639 * This part is "optimistic". 640 * Thread can ends without pthread_exit call. 641 */ 642 static void libpthread_pthread_exit(void *retval) 643 { 644 uwrap_bind_symbol_libpthread(pthread_exit); 645 646 uwrap.libpthread.symbols._libpthread_pthread_exit.f(retval); 647 } 648 649 static void uwrap_pthread_exit(void *retval) 650 { 651 struct uwrap_thread *id = uwrap_tls_id; 652 653 UWRAP_LOG(UWRAP_LOG_DEBUG, "Cleanup thread"); 654 655 UWRAP_LOCK(uwrap_id); 656 if (id == NULL) { 657 UWRAP_UNLOCK(uwrap_id); 658 libpthread_pthread_exit(retval); 659 return; 660 } 661 662 UWRAP_DLIST_REMOVE(uwrap.ids, id); 663 SAFE_FREE(id->groups); 664 SAFE_FREE(id); 665 uwrap_tls_id = NULL; 666 667 UWRAP_UNLOCK(uwrap_id); 668 669 libpthread_pthread_exit(retval); 670 } 671 672 void pthread_exit(void *retval) 673 { 674 if (!uid_wrapper_enabled()) { 675 libpthread_pthread_exit(retval); 676 }; 677 678 uwrap_pthread_exit(retval); 679 680 /* Calm down gcc warning. */ 681 exit(666); 682 } 683 684 static int libpthread_pthread_create(pthread_t *thread, 685 const pthread_attr_t *attr, 686 void *(*start_routine) (void *), 687 void *arg) 688 { 689 uwrap_bind_symbol_libpthread(pthread_create); 690 return uwrap.libpthread.symbols._libpthread_pthread_create.f(thread, 691 attr, 692 start_routine, 693 arg); 694 } 695 696 struct uwrap_pthread_create_args { 697 struct uwrap_thread *id; 698 void *(*start_routine) (void *); 699 void *arg; 700 }; 701 702 static void *uwrap_pthread_create_start(void *_a) 703 { 704 struct uwrap_pthread_create_args *a = 705 (struct uwrap_pthread_create_args *)_a; 706 void *(*start_routine) (void *) = a->start_routine; 707 void *arg = a->arg; 708 struct uwrap_thread *id = a->id; 709 710 SAFE_FREE(a); 711 712 uwrap_tls_id = id; 713 714 return start_routine(arg); 715 } 716 717 static int uwrap_pthread_create(pthread_t *thread, 718 const pthread_attr_t *attr, 719 void *(*start_routine) (void *), 720 void *arg) 721 { 722 struct uwrap_pthread_create_args *args; 723 struct uwrap_thread *src_id = uwrap_tls_id; 724 int ret; 725 726 args = malloc(sizeof(struct uwrap_pthread_create_args)); 727 if (args == NULL) { 728 UWRAP_LOG(UWRAP_LOG_ERROR, 729 "uwrap_pthread_create: Unable to allocate memory"); 730 errno = ENOMEM; 731 return -1; 732 } 733 args->start_routine = start_routine; 734 args->arg = arg; 735 736 args->id = calloc(1, sizeof(struct uwrap_thread)); 737 if (args->id == NULL) { 738 SAFE_FREE(args); 739 UWRAP_LOG(UWRAP_LOG_ERROR, 740 "uwrap_pthread_create: Unable to allocate memory"); 741 errno = ENOMEM; 742 return -1; 743 } 744 745 UWRAP_LOCK(uwrap_id); 746 747 args->id->groups = malloc(sizeof(gid_t) * src_id->ngroups); 748 if (args->id->groups == NULL) { 749 UWRAP_UNLOCK(uwrap_id); 750 SAFE_FREE(args->id); 751 SAFE_FREE(args); 752 UWRAP_LOG(UWRAP_LOG_ERROR, 753 "uwrap_pthread_create: Unable to allocate memory again"); 754 errno = ENOMEM; 755 return -1; 756 } 757 758 args->id->ruid = src_id->ruid; 759 args->id->euid = src_id->euid; 760 args->id->suid = src_id->suid; 761 762 args->id->rgid = src_id->rgid; 763 args->id->egid = src_id->egid; 764 args->id->sgid = src_id->sgid; 765 766 args->id->enabled = src_id->enabled; 767 768 args->id->ngroups = src_id->ngroups; 769 if (src_id->groups != NULL) { 770 memcpy(args->id->groups, src_id->groups, 771 sizeof(gid_t) * src_id->ngroups); 772 } else { 773 SAFE_FREE(args->id->groups); 774 } 775 776 UWRAP_DLIST_ADD(uwrap.ids, args->id); 777 UWRAP_UNLOCK(uwrap_id); 778 779 ret = libpthread_pthread_create(thread, attr, 780 uwrap_pthread_create_start, 781 args); 782 if (ret != 0) { 783 return ret; 784 } 785 786 return ret; 787 } 788 789 int pthread_create(pthread_t *thread, 790 const pthread_attr_t *attr, 791 void *(*start_routine) (void *), 792 void *arg) 793 { 794 if (!uid_wrapper_enabled()) { 795 return libpthread_pthread_create(thread, 796 attr, 797 start_routine, 798 arg); 799 }; 800 801 return uwrap_pthread_create(thread, 802 attr, 803 start_routine, 804 arg); 805 } 806 807 /********************************************************* 808 * UWRAP ID HANDLING 809 *********************************************************/ 810 811 static void uwrap_thread_prepare(void) 812 { 813 struct uwrap_thread *id = uwrap_tls_id; 814 815 /* uid_wrapper is loaded but not enabled */ 816 if (id == NULL) { 817 return; 818 } 819 820 UWRAP_LOCK_ALL; 821 822 /* 823 * What happens if another atfork prepare functions calls a uwrap 824 * function? So disable it in case another atfork prepare function 825 * calls a (s)uid function. We disable uid_wrapper only for thread 826 * (process) which called fork. 827 */ 828 id->enabled = false; 829 } 830 831 static void uwrap_thread_parent(void) 832 { 833 struct uwrap_thread *id = uwrap_tls_id; 834 835 /* uid_wrapper is loaded but not enabled */ 836 if (id == NULL) { 837 return; 838 } 839 840 id->enabled = true; 841 842 UWRAP_UNLOCK_ALL; 843 } 844 845 static void uwrap_thread_child(void) 846 { 847 struct uwrap_thread *id = uwrap_tls_id; 848 struct uwrap_thread *u = uwrap.ids; 849 850 /* uid_wrapper is loaded but not enabled */ 851 if (id == NULL) { 852 return; 853 } 854 855 /* 856 * "Garbage collector" - Inspired by DESTRUCTOR. 857 * All threads (except one which called fork()) are dead now.. Dave 858 * That's what posix said... 859 */ 860 while (u != NULL) { 861 if (u == id) { 862 /* Skip this item. */ 863 u = uwrap.ids->next; 864 continue; 865 } 866 867 UWRAP_DLIST_REMOVE(uwrap.ids, u); 868 869 SAFE_FREE(u->groups); 870 SAFE_FREE(u); 871 872 u = uwrap.ids; 873 } 874 875 id->enabled = true; 876 877 UWRAP_UNLOCK_ALL; 878 } 879 880 static void uwrap_init(void) 881 { 882 const char *env; 883 884 UWRAP_LOCK(uwrap_id); 885 886 if (uwrap.initialised) { 887 struct uwrap_thread *id = uwrap_tls_id; 888 889 if (uwrap.ids == NULL) { 890 UWRAP_UNLOCK(uwrap_id); 891 return; 892 } 893 894 if (id == NULL) { 895 UWRAP_LOG(UWRAP_LOG_ERROR, 896 "Invalid id for thread"); 897 exit(-1); 898 } 899 900 UWRAP_UNLOCK(uwrap_id); 901 return; 902 } 903 904 UWRAP_LOG(UWRAP_LOG_DEBUG, "Initialize uid_wrapper"); 905 906 uwrap.initialised = true; 907 908 env = getenv("UID_WRAPPER"); 909 if (env != NULL && env[0] == '1') { 910 const char *root = getenv("UID_WRAPPER_ROOT"); 911 struct uwrap_thread *id; 912 913 id = calloc(1, sizeof(struct uwrap_thread)); 914 if (id == NULL) { 915 UWRAP_LOG(UWRAP_LOG_ERROR, 916 "Unable to allocate memory for main id"); 917 exit(-1); 918 } 919 920 UWRAP_DLIST_ADD(uwrap.ids, id); 921 uwrap_tls_id = id; 922 923 uwrap.myuid = libc_geteuid(); 924 uwrap.mygid = libc_getegid(); 925 926 /* put us in one group */ 927 if (root != NULL && root[0] == '1') { 928 id->ruid = id->euid = id->suid = 0; 929 id->rgid = id->egid = id->sgid = 0; 930 931 id->groups = malloc(sizeof(gid_t) * 1); 932 if (id->groups == NULL) { 933 UWRAP_LOG(UWRAP_LOG_ERROR, 934 "Unable to allocate memory"); 935 exit(-1); 936 } 937 938 id->ngroups = 1; 939 id->groups[0] = 0; 940 941 } else { 942 id->ruid = id->euid = id->suid = uwrap.myuid; 943 id->rgid = id->egid = id->sgid = uwrap.mygid; 944 945 id->ngroups = libc_getgroups(0, NULL); 946 if (id->ngroups == -1) { 947 UWRAP_LOG(UWRAP_LOG_ERROR, 948 "Unable to call libc_getgroups in uwrap_init."); 949 exit(-1); 950 } 951 id->groups = malloc(sizeof(gid_t) * id->ngroups); 952 if (id->groups == NULL) { 953 UWRAP_LOG(UWRAP_LOG_ERROR, "Unable to allocate memory"); 954 exit(-1); 955 } 956 if (libc_getgroups(id->ngroups, id->groups) == -1) { 957 UWRAP_LOG(UWRAP_LOG_ERROR, 958 "Unable to call libc_getgroups again in uwrap_init."); 959 id->groups = 0; 960 /* 961 * Deallocation of uwrap.groups is handled by 962 * library destructor. 963 */ 964 exit(-1); 965 } 966 } 967 968 id->enabled = true; 969 970 UWRAP_LOG(UWRAP_LOG_DEBUG, 971 "Enabled uid_wrapper as %s (real uid=%u)", 972 id->ruid == 0 ? "root" : "user", 973 (unsigned int)uwrap.myuid); 974 } 975 976 UWRAP_UNLOCK(uwrap_id); 977 978 UWRAP_LOG(UWRAP_LOG_DEBUG, "Succeccfully initialized uid_wrapper"); 979 } 980 981 bool uid_wrapper_enabled(void) 982 { 983 struct uwrap_thread *id = uwrap_tls_id; 40 984 bool enabled; 41 uid_t euid; 42 gid_t egid; 43 unsigned ngroups; 44 gid_t *groups; 45 } uwrap; 46 47 static void uwrap_init(void) 48 { 49 if (uwrap.initialised) return; 50 uwrap.initialised = true; 51 if (getenv("UID_WRAPPER")) { 52 uwrap.enabled = true; 53 /* put us in one group */ 54 uwrap.ngroups = 1; 55 uwrap.groups = talloc_array(NULL, gid_t, 1); 56 uwrap.groups[0] = 0; 57 } 58 } 59 60 #undef uwrap_enabled 61 _PUBLIC_ int uwrap_enabled(void) 62 { 63 uwrap_init(); 64 return uwrap.enabled?1:0; 65 } 66 67 _PUBLIC_ int uwrap_seteuid(uid_t euid) 68 { 69 uwrap_init(); 70 if (!uwrap.enabled) { 71 return seteuid(euid); 72 } 73 /* assume for now that the ruid stays as root */ 74 uwrap.euid = euid; 985 986 if (id == NULL) { 987 return false; 988 } 989 990 UWRAP_LOCK(uwrap_id); 991 enabled = id->enabled; 992 UWRAP_UNLOCK(uwrap_id); 993 994 return enabled; 995 } 996 997 /* 998 * UWRAP_SETxUID FUNCTIONS 999 */ 1000 1001 static int uwrap_setresuid_args(uid_t ruid, uid_t euid, uid_t suid) 1002 { 1003 struct uwrap_thread *id = uwrap_tls_id; 1004 1005 UWRAP_LOG(UWRAP_LOG_TRACE, 1006 "ruid %d -> %d, euid %d -> %d, suid %d -> %d", 1007 id->ruid, ruid, id->euid, euid, id->suid, suid); 1008 1009 if (id->euid != 0) { 1010 if (ruid != (uid_t)-1 && 1011 ruid != id->ruid && 1012 ruid != id->euid && 1013 ruid != id->suid) { 1014 errno = EPERM; 1015 return -1; 1016 } 1017 if (euid != (uid_t)-1 && 1018 euid != id->ruid && 1019 euid != id->euid && 1020 euid != id->suid) { 1021 errno = EPERM; 1022 return -1; 1023 } 1024 if (suid != (uid_t)-1 && 1025 suid != id->ruid && 1026 suid != id->euid && 1027 suid != id->suid) { 1028 errno = EPERM; 1029 return -1; 1030 } 1031 } 1032 75 1033 return 0; 76 1034 } 77 1035 78 _PUBLIC_ uid_t uwrap_geteuid(void) 79 { 80 uwrap_init(); 81 if (!uwrap.enabled) { 82 return geteuid(); 83 } 84 return uwrap.euid; 85 } 86 87 _PUBLIC_ int uwrap_setegid(gid_t egid) 88 { 89 uwrap_init(); 90 if (!uwrap.enabled) { 91 return setegid(egid); 92 } 93 /* assume for now that the ruid stays as root */ 94 uwrap.egid = egid; 1036 static int uwrap_setresuid_thread(uid_t ruid, uid_t euid, uid_t suid) 1037 { 1038 struct uwrap_thread *id = uwrap_tls_id; 1039 int rc; 1040 1041 UWRAP_LOG(UWRAP_LOG_TRACE, 1042 "ruid %d -> %d, euid %d -> %d, suid %d -> %d", 1043 id->ruid, ruid, id->euid, euid, id->suid, suid); 1044 1045 rc = uwrap_setresuid_args(ruid, euid, suid); 1046 if (rc != 0) { 1047 return rc; 1048 } 1049 1050 UWRAP_LOCK(uwrap_id); 1051 1052 if (ruid != (uid_t)-1) { 1053 id->ruid = ruid; 1054 } 1055 1056 if (euid != (uid_t)-1) { 1057 id->euid = euid; 1058 } 1059 1060 if (suid != (uid_t)-1) { 1061 id->suid = suid; 1062 } 1063 1064 UWRAP_UNLOCK(uwrap_id); 1065 95 1066 return 0; 96 1067 } 97 1068 98 _PUBLIC_ uid_t uwrap_getegid(void) 99 { 100 uwrap_init(); 101 if (!uwrap.enabled) { 102 return getegid(); 103 } 104 return uwrap.egid; 105 } 106 107 _PUBLIC_ int uwrap_setgroups(size_t size, const gid_t *list) 108 { 109 uwrap_init(); 110 if (!uwrap.enabled) { 111 return setgroups(size, list); 112 } 113 114 talloc_free(uwrap.groups); 115 uwrap.ngroups = 0; 116 uwrap.groups = NULL; 117 118 if (size != 0) { 119 uwrap.groups = talloc_array(NULL, gid_t, size); 120 if (uwrap.groups == NULL) { 121 errno = ENOMEM; 1069 static int uwrap_setresuid(uid_t ruid, uid_t euid, uid_t suid) 1070 { 1071 struct uwrap_thread *id = uwrap_tls_id; 1072 int rc; 1073 1074 UWRAP_LOG(UWRAP_LOG_TRACE, 1075 "ruid %d -> %d, euid %d -> %d, suid %d -> %d", 1076 id->ruid, ruid, id->euid, euid, id->suid, suid); 1077 1078 rc = uwrap_setresuid_args(ruid, euid, suid); 1079 if (rc != 0) { 1080 return rc; 1081 } 1082 1083 UWRAP_LOCK(uwrap_id); 1084 1085 for (id = uwrap.ids; id; id = id->next) { 1086 if (ruid != (uid_t)-1) { 1087 id->ruid = ruid; 1088 } 1089 1090 if (euid != (uid_t)-1) { 1091 id->euid = euid; 1092 } 1093 1094 if (suid != (uid_t)-1) { 1095 id->suid = suid; 1096 } 1097 } 1098 1099 UWRAP_UNLOCK(uwrap_id); 1100 1101 return 0; 1102 } 1103 1104 static int uwrap_setreuid_args(uid_t ruid, uid_t euid, 1105 uid_t *_new_ruid, 1106 uid_t *_new_euid, 1107 uid_t *_new_suid) 1108 { 1109 struct uwrap_thread *id = uwrap_tls_id; 1110 uid_t new_ruid = -1, new_euid = -1, new_suid = -1; 1111 1112 UWRAP_LOG(UWRAP_LOG_TRACE, 1113 "ruid %d -> %d, euid %d -> %d", 1114 id->ruid, ruid, id->euid, euid); 1115 1116 if (ruid != (uid_t)-1) { 1117 new_ruid = ruid; 1118 if (ruid != id->ruid && 1119 ruid != id->euid && 1120 id->euid != 0) { 1121 errno = EPERM; 122 1122 return -1; 123 1123 } 124 memcpy(uwrap.groups, list, size*sizeof(gid_t)); 125 uwrap.ngroups = size; 126 } 1124 } 1125 1126 if (euid != (uid_t)-1) { 1127 new_euid = euid; 1128 if (euid != id->ruid && 1129 euid != id->euid && 1130 euid != id->suid && 1131 id->euid != 0) { 1132 errno = EPERM; 1133 return -1; 1134 } 1135 } 1136 1137 if (ruid != (uid_t) -1 || 1138 (euid != (uid_t)-1 && id->ruid != euid)) { 1139 new_suid = new_euid; 1140 } 1141 1142 *_new_ruid = new_ruid; 1143 *_new_euid = new_euid; 1144 *_new_suid = new_suid; 1145 127 1146 return 0; 128 1147 } 129 1148 130 _PUBLIC_ int uwrap_getgroups(int size, gid_t *list) 131 { 132 uwrap_init(); 133 if (!uwrap.enabled) { 134 return getgroups(size, list); 135 } 136 137 if (size > uwrap.ngroups) { 138 size = uwrap.ngroups; 139 } 140 if (size == 0) { 141 return uwrap.ngroups; 142 } 143 if (size < uwrap.ngroups) { 1149 static int uwrap_setreuid_thread(uid_t ruid, uid_t euid) 1150 { 1151 #ifndef NDEBUG 1152 struct uwrap_thread *id = uwrap_tls_id; 1153 #endif 1154 uid_t new_ruid = -1, new_euid = -1, new_suid = -1; 1155 int rc; 1156 1157 UWRAP_LOG(UWRAP_LOG_TRACE, 1158 "ruid %d -> %d, euid %d -> %d", 1159 id->ruid, ruid, id->euid, euid); 1160 1161 rc = uwrap_setreuid_args(ruid, euid, &new_ruid, &new_euid, &new_suid); 1162 if (rc != 0) { 1163 return rc; 1164 } 1165 1166 return uwrap_setresuid_thread(new_ruid, new_euid, new_suid); 1167 } 1168 1169 #ifdef HAVE_SETREUID 1170 static int uwrap_setreuid(uid_t ruid, uid_t euid) 1171 { 1172 #ifndef NDEBUG 1173 struct uwrap_thread *id = uwrap_tls_id; 1174 #endif 1175 uid_t new_ruid = -1, new_euid = -1, new_suid = -1; 1176 int rc; 1177 1178 UWRAP_LOG(UWRAP_LOG_TRACE, 1179 "ruid %d -> %d, euid %d -> %d", 1180 id->ruid, ruid, id->euid, euid); 1181 1182 rc = uwrap_setreuid_args(ruid, euid, &new_ruid, &new_euid, &new_suid); 1183 if (rc != 0) { 1184 return rc; 1185 } 1186 1187 return uwrap_setresuid(new_ruid, new_euid, new_suid); 1188 } 1189 #endif 1190 1191 static int uwrap_setuid_args(uid_t uid, 1192 uid_t *new_ruid, 1193 uid_t *new_euid, 1194 uid_t *new_suid) 1195 { 1196 struct uwrap_thread *id = uwrap_tls_id; 1197 1198 UWRAP_LOG(UWRAP_LOG_TRACE, 1199 "uid %d -> %d", 1200 id->ruid, uid); 1201 1202 if (uid == (uid_t)-1) { 144 1203 errno = EINVAL; 145 1204 return -1; 146 1205 } 147 memcpy(list, uwrap.groups, size*sizeof(gid_t)); 148 return uwrap.ngroups; 149 } 150 151 _PUBLIC_ uid_t uwrap_getuid(void) 152 { 1206 1207 if (id->euid == 0) { 1208 *new_suid = *new_ruid = uid; 1209 } else if (uid != id->ruid && 1210 uid != id->suid) { 1211 errno = EPERM; 1212 return -1; 1213 } 1214 1215 *new_euid = uid; 1216 1217 return 0; 1218 } 1219 1220 static int uwrap_setuid_thread(uid_t uid) 1221 { 1222 uid_t new_ruid = -1, new_euid = -1, new_suid = -1; 1223 int rc; 1224 1225 rc = uwrap_setuid_args(uid, &new_ruid, &new_euid, &new_suid); 1226 if (rc != 0) { 1227 return rc; 1228 } 1229 1230 return uwrap_setresuid_thread(new_ruid, new_euid, new_suid); 1231 } 1232 1233 static int uwrap_setuid(uid_t uid) 1234 { 1235 uid_t new_ruid = -1, new_euid = -1, new_suid = -1; 1236 int rc; 1237 1238 rc = uwrap_setuid_args(uid, &new_ruid, &new_euid, &new_suid); 1239 if (rc != 0) { 1240 return rc; 1241 } 1242 1243 return uwrap_setresuid(new_ruid, new_euid, new_suid); 1244 } 1245 1246 /* 1247 * UWRAP_GETxUID FUNCTIONS 1248 */ 1249 1250 #ifdef HAVE_GETRESUID 1251 static int uwrap_getresuid(uid_t *ruid, uid_t *euid, uid_t *suid) 1252 { 1253 struct uwrap_thread *id = uwrap_tls_id; 1254 1255 UWRAP_LOCK(uwrap_id); 1256 1257 *ruid = id->ruid; 1258 *euid = id->euid; 1259 *suid = id->suid; 1260 1261 UWRAP_UNLOCK(uwrap_id); 1262 1263 return 0; 1264 } 1265 #endif 1266 1267 #ifdef HAVE_GETRESGID 1268 static int uwrap_getresgid(gid_t *rgid, gid_t *egid, gid_t *sgid) 1269 { 1270 struct uwrap_thread *id = uwrap_tls_id; 1271 1272 UWRAP_LOCK(uwrap_id); 1273 1274 *rgid = id->rgid; 1275 *egid = id->egid; 1276 *sgid = id->sgid; 1277 1278 UWRAP_UNLOCK(uwrap_id); 1279 1280 return 0; 1281 } 1282 #endif 1283 1284 /* 1285 * UWRAP_SETxGID FUNCTIONS 1286 */ 1287 1288 static int uwrap_setresgid_args(gid_t rgid, gid_t egid, gid_t sgid) 1289 { 1290 struct uwrap_thread *id = uwrap_tls_id; 1291 1292 UWRAP_LOG(UWRAP_LOG_TRACE, 1293 "rgid %d -> %d, egid %d -> %d, sgid %d -> %d", 1294 id->rgid, rgid, id->egid, egid, id->sgid, sgid); 1295 1296 if (id->euid != 0) { 1297 if (rgid != (gid_t)-1 && 1298 rgid != id->rgid && 1299 rgid != id->egid && 1300 rgid != id->sgid) { 1301 errno = EPERM; 1302 return -1; 1303 } 1304 if (egid != (gid_t)-1 && 1305 egid != id->rgid && 1306 egid != id->egid && 1307 egid != id->sgid) { 1308 errno = EPERM; 1309 return -1; 1310 } 1311 if (sgid != (gid_t)-1 && 1312 sgid != id->rgid && 1313 sgid != id->egid && 1314 sgid != id->sgid) { 1315 errno = EPERM; 1316 return -1; 1317 } 1318 } 1319 1320 return 0; 1321 } 1322 1323 static int uwrap_setresgid_thread(gid_t rgid, gid_t egid, gid_t sgid) 1324 { 1325 struct uwrap_thread *id = uwrap_tls_id; 1326 int rc; 1327 1328 UWRAP_LOG(UWRAP_LOG_TRACE, 1329 "rgid %d -> %d, egid %d -> %d, sgid %d -> %d", 1330 id->rgid, rgid, id->egid, egid, id->sgid, sgid); 1331 1332 rc = uwrap_setresgid_args(rgid, egid, sgid); 1333 if (rc != 0) { 1334 return rc; 1335 } 1336 1337 UWRAP_LOCK(uwrap_id); 1338 1339 if (rgid != (gid_t)-1) { 1340 id->rgid = rgid; 1341 } 1342 1343 if (egid != (gid_t)-1) { 1344 id->egid = egid; 1345 } 1346 1347 if (sgid != (gid_t)-1) { 1348 id->sgid = sgid; 1349 } 1350 1351 UWRAP_UNLOCK(uwrap_id); 1352 1353 return 0; 1354 } 1355 1356 static int uwrap_setresgid(gid_t rgid, gid_t egid, gid_t sgid) 1357 { 1358 struct uwrap_thread *id = uwrap_tls_id; 1359 int rc; 1360 1361 UWRAP_LOG(UWRAP_LOG_TRACE, 1362 "rgid %d -> %d, egid %d -> %d, sgid %d -> %d", 1363 id->rgid, rgid, id->egid, egid, id->sgid, sgid); 1364 1365 rc = uwrap_setresgid_args(rgid, egid, sgid); 1366 if (rc != 0) { 1367 return rc; 1368 } 1369 1370 UWRAP_LOCK(uwrap_id); 1371 1372 for (id = uwrap.ids; id; id = id->next) { 1373 if (rgid != (gid_t)-1) { 1374 id->rgid = rgid; 1375 } 1376 1377 if (egid != (gid_t)-1) { 1378 id->egid = egid; 1379 } 1380 1381 if (sgid != (gid_t)-1) { 1382 id->sgid = sgid; 1383 } 1384 } 1385 1386 UWRAP_UNLOCK(uwrap_id); 1387 1388 return 0; 1389 } 1390 1391 static int uwrap_setregid_args(gid_t rgid, gid_t egid, 1392 gid_t *_new_rgid, 1393 gid_t *_new_egid, 1394 gid_t *_new_sgid) 1395 { 1396 struct uwrap_thread *id = uwrap_tls_id; 1397 gid_t new_rgid = -1, new_egid = -1, new_sgid = -1; 1398 1399 UWRAP_LOG(UWRAP_LOG_TRACE, 1400 "rgid %d -> %d, egid %d -> %d", 1401 id->rgid, rgid, id->egid, egid); 1402 1403 if (rgid != (gid_t)-1) { 1404 new_rgid = rgid; 1405 if (rgid != id->rgid && 1406 rgid != id->egid && 1407 id->euid != 0) { 1408 errno = EPERM; 1409 return -1; 1410 } 1411 } 1412 1413 if (egid != (gid_t)-1) { 1414 new_egid = egid; 1415 if (egid != id->rgid && 1416 egid != id->egid && 1417 egid != id->sgid && 1418 id->euid != 0) { 1419 errno = EPERM; 1420 return -1; 1421 } 1422 } 1423 1424 if (rgid != (gid_t) -1 || 1425 (egid != (gid_t)-1 && id->rgid != egid)) { 1426 new_sgid = new_egid; 1427 } 1428 1429 *_new_rgid = new_rgid; 1430 *_new_egid = new_egid; 1431 *_new_sgid = new_sgid; 1432 1433 return 0; 1434 } 1435 1436 static int uwrap_setregid_thread(gid_t rgid, gid_t egid) 1437 { 1438 #ifndef NDEBUG 1439 struct uwrap_thread *id = uwrap_tls_id; 1440 #endif 1441 gid_t new_rgid = -1, new_egid = -1, new_sgid = -1; 1442 int rc; 1443 1444 UWRAP_LOG(UWRAP_LOG_TRACE, 1445 "rgid %d -> %d, egid %d -> %d", 1446 id->rgid, rgid, id->egid, egid); 1447 1448 rc = uwrap_setregid_args(rgid, egid, &new_rgid, &new_egid, &new_sgid); 1449 if (rc != 0) { 1450 return rc; 1451 } 1452 1453 return uwrap_setresgid_thread(new_rgid, new_egid, new_sgid); 1454 } 1455 1456 #ifdef HAVE_SETREGID 1457 static int uwrap_setregid(gid_t rgid, gid_t egid) 1458 { 1459 #ifndef NDEBUG 1460 struct uwrap_thread *id = uwrap_tls_id; 1461 #endif 1462 gid_t new_rgid = -1, new_egid = -1, new_sgid = -1; 1463 int rc; 1464 1465 UWRAP_LOG(UWRAP_LOG_TRACE, 1466 "rgid %d -> %d, egid %d -> %d", 1467 id->rgid, rgid, id->egid, egid); 1468 1469 rc = uwrap_setregid_args(rgid, egid, &new_rgid, &new_egid, &new_sgid); 1470 if (rc != 0) { 1471 return rc; 1472 } 1473 1474 return uwrap_setresgid(new_rgid, new_egid, new_sgid); 1475 } 1476 #endif 1477 1478 static int uwrap_setgid_args(gid_t gid, 1479 gid_t *new_rgid, 1480 gid_t *new_egid, 1481 gid_t *new_sgid) 1482 { 1483 struct uwrap_thread *id = uwrap_tls_id; 1484 1485 UWRAP_LOG(UWRAP_LOG_TRACE, 1486 "gid %d -> %d", 1487 id->rgid, gid); 1488 1489 if (gid == (gid_t)-1) { 1490 errno = EINVAL; 1491 return -1; 1492 } 1493 1494 if (id->euid == 0) { 1495 *new_sgid = *new_rgid = gid; 1496 } else if (gid != id->rgid && 1497 gid != id->sgid) { 1498 errno = EPERM; 1499 return -1; 1500 } 1501 1502 *new_egid = gid; 1503 1504 return 0; 1505 } 1506 1507 static int uwrap_setgid_thread(gid_t gid) 1508 { 1509 gid_t new_rgid = -1, new_egid = -1, new_sgid = -1; 1510 int rc; 1511 1512 rc = uwrap_setgid_args(gid, &new_rgid, &new_egid, &new_sgid); 1513 if (rc != 0) { 1514 return rc; 1515 } 1516 1517 return uwrap_setresgid_thread(new_rgid, new_egid, new_sgid); 1518 } 1519 1520 static int uwrap_setgid(gid_t gid) 1521 { 1522 gid_t new_rgid = -1, new_egid = -1, new_sgid = -1; 1523 int rc; 1524 1525 rc = uwrap_setgid_args(gid, &new_rgid, &new_egid, &new_sgid); 1526 if (rc != 0) { 1527 return rc; 1528 } 1529 1530 return uwrap_setresgid(new_rgid, new_egid, new_sgid); 1531 } 1532 1533 /* 1534 * SETUID 1535 */ 1536 int setuid(uid_t uid) 1537 { 1538 if (!uid_wrapper_enabled()) { 1539 return libc_setuid(uid); 1540 } 1541 153 1542 uwrap_init(); 154 if (!uwrap.enabled) { 155 return getuid(); 156 } 157 /* we don't simulate ruid changing */ 158 return 0; 159 } 160 161 _PUBLIC_ gid_t uwrap_getgid(void) 162 { 1543 return uwrap_setuid(uid); 1544 } 1545 1546 #ifdef HAVE_SETEUID 1547 int seteuid(uid_t euid) 1548 { 1549 if (!uid_wrapper_enabled()) { 1550 return libc_seteuid(euid); 1551 } 1552 1553 /* On FreeBSD the uid_t -1 is set and doesn't produce and error */ 1554 if (euid == (uid_t)-1) { 1555 errno = EINVAL; 1556 return -1; 1557 } 1558 163 1559 uwrap_init(); 164 if (!uwrap.enabled) { 165 return getgid(); 166 } 167 /* we don't simulate rgid changing */ 168 return 0; 169 } 1560 return uwrap_setresuid(-1, euid, -1); 1561 } 1562 #endif 1563 1564 #ifdef HAVE_SETREUID 1565 int setreuid(uid_t ruid, uid_t euid) 1566 { 1567 if (!uid_wrapper_enabled()) { 1568 return libc_setreuid(ruid, euid); 1569 } 1570 1571 uwrap_init(); 1572 return uwrap_setreuid(ruid, euid); 1573 } 1574 #endif 1575 1576 #ifdef HAVE_SETRESUID 1577 int setresuid(uid_t ruid, uid_t euid, uid_t suid) 1578 { 1579 if (!uid_wrapper_enabled()) { 1580 return libc_setresuid(ruid, euid, suid); 1581 } 1582 1583 uwrap_init(); 1584 return uwrap_setresuid(ruid, euid, suid); 1585 } 1586 #endif 1587 1588 #ifdef HAVE_GETRESUID 1589 int getresuid(uid_t *ruid, uid_t *euid, uid_t *suid) 1590 { 1591 if (!uid_wrapper_enabled()) { 1592 return libc_getresuid(ruid, euid, suid); 1593 } 1594 1595 uwrap_init(); 1596 return uwrap_getresuid(ruid, euid, suid); 1597 } 1598 #endif 1599 1600 /* 1601 * GETUID 1602 */ 1603 static uid_t uwrap_getuid(void) 1604 { 1605 struct uwrap_thread *id = uwrap_tls_id; 1606 uid_t uid; 1607 1608 UWRAP_LOCK(uwrap_id); 1609 uid = id->ruid; 1610 UWRAP_UNLOCK(uwrap_id); 1611 1612 return uid; 1613 } 1614 1615 uid_t getuid(void) 1616 { 1617 if (!uid_wrapper_enabled()) { 1618 return libc_getuid(); 1619 } 1620 1621 uwrap_init(); 1622 return uwrap_getuid(); 1623 } 1624 1625 /* 1626 * GETEUID 1627 */ 1628 static uid_t uwrap_geteuid(void) 1629 { 1630 const char *env = getenv("UID_WRAPPER_MYUID"); 1631 struct uwrap_thread *id = uwrap_tls_id; 1632 uid_t uid; 1633 1634 UWRAP_LOCK(uwrap_id); 1635 uid = id->euid; 1636 UWRAP_UNLOCK(uwrap_id); 1637 1638 /* Disable root and return myuid */ 1639 if (env != NULL && env[0] == '1') { 1640 uid = uwrap.myuid; 1641 } 1642 1643 return uid; 1644 } 1645 1646 uid_t geteuid(void) 1647 { 1648 if (!uid_wrapper_enabled()) { 1649 return libc_geteuid(); 1650 } 1651 1652 uwrap_init(); 1653 return uwrap_geteuid(); 1654 } 1655 1656 /* 1657 * SETGID 1658 */ 1659 int setgid(gid_t gid) 1660 { 1661 if (!uid_wrapper_enabled()) { 1662 return libc_setgid(gid); 1663 } 1664 1665 uwrap_init(); 1666 return uwrap_setgid(gid); 1667 } 1668 1669 #ifdef HAVE_SETEGID 1670 int setegid(gid_t egid) 1671 { 1672 if (!uid_wrapper_enabled()) { 1673 return libc_setegid(egid); 1674 } 1675 1676 /* On FreeBSD the uid_t -1 is set and doesn't produce and error */ 1677 if (egid == (gid_t)-1) { 1678 errno = EINVAL; 1679 return -1; 1680 } 1681 1682 uwrap_init(); 1683 return uwrap_setresgid(-1, egid, -1); 1684 } 1685 #endif 1686 1687 #ifdef HAVE_SETREGID 1688 int setregid(gid_t rgid, gid_t egid) 1689 { 1690 if (!uid_wrapper_enabled()) { 1691 return libc_setregid(rgid, egid); 1692 } 1693 1694 uwrap_init(); 1695 return uwrap_setregid(rgid, egid); 1696 } 1697 #endif 1698 1699 #ifdef HAVE_SETRESGID 1700 int setresgid(gid_t rgid, gid_t egid, gid_t sgid) 1701 { 1702 if (!uid_wrapper_enabled()) { 1703 return libc_setresgid(rgid, egid, sgid); 1704 } 1705 1706 uwrap_init(); 1707 return uwrap_setresgid(rgid, egid, sgid); 1708 } 1709 #endif 1710 1711 #ifdef HAVE_GETRESGID 1712 int getresgid(gid_t *rgid, gid_t *egid, gid_t *sgid) 1713 { 1714 if (!uid_wrapper_enabled()) { 1715 return libc_getresgid(rgid, egid, sgid); 1716 } 1717 1718 uwrap_init(); 1719 return uwrap_getresgid(rgid, egid, sgid); 1720 } 1721 #endif 1722 1723 /* 1724 * GETGID 1725 */ 1726 static gid_t uwrap_getgid(void) 1727 { 1728 struct uwrap_thread *id = uwrap_tls_id; 1729 gid_t gid; 1730 1731 UWRAP_LOCK(uwrap_id); 1732 gid = id->rgid; 1733 UWRAP_UNLOCK(uwrap_id); 1734 1735 return gid; 1736 } 1737 1738 gid_t getgid(void) 1739 { 1740 if (!uid_wrapper_enabled()) { 1741 return libc_getgid(); 1742 } 1743 1744 uwrap_init(); 1745 return uwrap_getgid(); 1746 } 1747 1748 /* 1749 * GETEGID 1750 */ 1751 static uid_t uwrap_getegid(void) 1752 { 1753 struct uwrap_thread *id = uwrap_tls_id; 1754 gid_t gid; 1755 1756 UWRAP_LOCK(uwrap_id); 1757 gid = id->egid; 1758 UWRAP_UNLOCK(uwrap_id); 1759 1760 return gid; 1761 } 1762 1763 uid_t getegid(void) 1764 { 1765 if (!uid_wrapper_enabled()) { 1766 return libc_getegid(); 1767 } 1768 1769 uwrap_init(); 1770 return uwrap_getegid(); 1771 } 1772 1773 static int uwrap_setgroups_thread(size_t size, const gid_t *list) 1774 { 1775 struct uwrap_thread *id = uwrap_tls_id; 1776 int rc = -1; 1777 1778 UWRAP_LOCK(uwrap_id); 1779 1780 if (size == 0) { 1781 SAFE_FREE(id->groups); 1782 id->ngroups = 0; 1783 } else if (size > 0) { 1784 gid_t *tmp; 1785 1786 tmp = realloc(id->groups, sizeof(gid_t) * size); 1787 if (tmp == NULL) { 1788 errno = ENOMEM; 1789 goto out; 1790 } 1791 id->groups = tmp; 1792 id->ngroups = size; 1793 memcpy(id->groups, list, size * sizeof(gid_t)); 1794 } 1795 1796 rc = 0; 1797 out: 1798 UWRAP_UNLOCK(uwrap_id); 1799 1800 return rc; 1801 } 1802 1803 static int uwrap_setgroups(size_t size, const gid_t *list) 1804 { 1805 struct uwrap_thread *id; 1806 int rc = -1; 1807 1808 UWRAP_LOCK(uwrap_id); 1809 1810 if (size == 0) { 1811 for (id = uwrap.ids; id; id = id->next) { 1812 SAFE_FREE(id->groups); 1813 id->ngroups = 0; 1814 1815 } 1816 } else if (size > 0) { 1817 gid_t *tmp; 1818 1819 for (id = uwrap.ids; id; id = id->next) { 1820 tmp = realloc(id->groups, sizeof(gid_t) * size); 1821 if (tmp == NULL) { 1822 errno = ENOMEM; 1823 goto out; 1824 } 1825 id->groups = tmp; 1826 1827 id->ngroups = size; 1828 memcpy(id->groups, list, size * sizeof(gid_t)); 1829 } 1830 } 1831 1832 rc = 0; 1833 out: 1834 UWRAP_UNLOCK(uwrap_id); 1835 1836 return rc; 1837 } 1838 1839 #ifdef HAVE_SETGROUPS_INT 1840 int setgroups(int size, const gid_t *list) 1841 #else 1842 int setgroups(size_t size, const gid_t *list) 1843 #endif 1844 { 1845 if (!uid_wrapper_enabled()) { 1846 return libc_setgroups(size, list); 1847 } 1848 1849 uwrap_init(); 1850 return uwrap_setgroups(size, list); 1851 } 1852 1853 static int uwrap_getgroups(int size, gid_t *list) 1854 { 1855 struct uwrap_thread *id = uwrap_tls_id; 1856 int ngroups; 1857 1858 UWRAP_LOCK(uwrap_id); 1859 ngroups = id->ngroups; 1860 1861 if (size > ngroups) { 1862 size = ngroups; 1863 } 1864 if (size == 0) { 1865 goto out; 1866 } 1867 if (size < ngroups) { 1868 errno = EINVAL; 1869 ngroups = -1; 1870 } 1871 memcpy(list, id->groups, size * sizeof(gid_t)); 1872 1873 out: 1874 UWRAP_UNLOCK(uwrap_id); 1875 1876 return ngroups; 1877 } 1878 1879 int getgroups(int size, gid_t *list) 1880 { 1881 if (!uid_wrapper_enabled()) { 1882 return libc_getgroups(size, list); 1883 } 1884 1885 uwrap_init(); 1886 return uwrap_getgroups(size, list); 1887 } 1888 1889 #if (defined(HAVE_SYS_SYSCALL_H) || defined(HAVE_SYSCALL_H)) \ 1890 && (defined(SYS_setreuid) || defined(SYS_setreuid32)) 1891 static long int uwrap_syscall (long int sysno, va_list vp) 1892 { 1893 long int rc; 1894 1895 switch (sysno) { 1896 /* gid */ 1897 case SYS_getgid: 1898 #ifdef HAVE_LINUX_32BIT_SYSCALLS 1899 case SYS_getgid32: 1900 #endif 1901 { 1902 rc = uwrap_getgid(); 1903 } 1904 break; 1905 #ifdef SYS_getegid 1906 case SYS_getegid: 1907 #ifdef HAVE_LINUX_32BIT_SYSCALLS 1908 case SYS_getegid32: 1909 #endif 1910 { 1911 rc = uwrap_getegid(); 1912 } 1913 break; 1914 #endif /* SYS_getegid */ 1915 case SYS_setgid: 1916 #ifdef HAVE_LINUX_32BIT_SYSCALLS 1917 case SYS_setgid32: 1918 #endif 1919 { 1920 gid_t gid = (gid_t) va_arg(vp, gid_t); 1921 1922 rc = uwrap_setgid_thread(gid); 1923 } 1924 break; 1925 case SYS_setregid: 1926 #ifdef HAVE_LINUX_32BIT_SYSCALLS 1927 case SYS_setregid32: 1928 #endif 1929 { 1930 gid_t rgid = (gid_t) va_arg(vp, gid_t); 1931 gid_t egid = (gid_t) va_arg(vp, gid_t); 1932 1933 rc = uwrap_setregid_thread(rgid, egid); 1934 } 1935 break; 1936 #ifdef SYS_setresgid 1937 case SYS_setresgid: 1938 #ifdef HAVE_LINUX_32BIT_SYSCALLS 1939 case SYS_setresgid32: 1940 #endif 1941 { 1942 gid_t rgid = (gid_t) va_arg(vp, gid_t); 1943 gid_t egid = (gid_t) va_arg(vp, gid_t); 1944 gid_t sgid = (gid_t) va_arg(vp, gid_t); 1945 1946 rc = uwrap_setresgid_thread(rgid, egid, sgid); 1947 } 1948 break; 1949 #endif /* SYS_setresgid */ 1950 #if defined(SYS_getresgid) && defined(HAVE_GETRESGID) 1951 case SYS_getresgid: 1952 #ifdef HAVE_LINUX_32BIT_SYSCALLS 1953 case SYS_getresgid32: 1954 #endif 1955 { 1956 gid_t *rgid = (gid_t *) va_arg(vp, gid_t *); 1957 gid_t *egid = (gid_t *) va_arg(vp, gid_t *); 1958 gid_t *sgid = (gid_t *) va_arg(vp, gid_t *); 1959 1960 rc = uwrap_getresgid(rgid, egid, sgid); 1961 } 1962 break; 1963 #endif /* SYS_getresgid && HAVE_GETRESGID */ 1964 1965 /* uid */ 1966 case SYS_getuid: 1967 #ifdef HAVE_LINUX_32BIT_SYSCALLS 1968 case SYS_getuid32: 1969 #endif 1970 { 1971 rc = uwrap_getuid(); 1972 } 1973 break; 1974 #ifdef SYS_geteuid 1975 case SYS_geteuid: 1976 #ifdef HAVE_LINUX_32BIT_SYSCALLS 1977 case SYS_geteuid32: 1978 #endif 1979 { 1980 rc = uwrap_geteuid(); 1981 } 1982 break; 1983 #endif /* SYS_geteuid */ 1984 case SYS_setuid: 1985 #ifdef HAVE_LINUX_32BIT_SYSCALLS 1986 case SYS_setuid32: 1987 #endif 1988 { 1989 uid_t uid = (uid_t) va_arg(vp, uid_t); 1990 1991 rc = uwrap_setuid_thread(uid); 1992 } 1993 break; 1994 case SYS_setreuid: 1995 #ifdef HAVE_LINUX_32BIT_SYSCALLS 1996 case SYS_setreuid32: 1997 #endif 1998 { 1999 uid_t ruid = (uid_t) va_arg(vp, uid_t); 2000 uid_t euid = (uid_t) va_arg(vp, uid_t); 2001 2002 rc = uwrap_setreuid_thread(ruid, euid); 2003 } 2004 break; 2005 #ifdef SYS_setresuid 2006 case SYS_setresuid: 2007 #ifdef HAVE_LINUX_32BIT_SYSCALLS 2008 case SYS_setresuid32: 2009 #endif 2010 { 2011 uid_t ruid = (uid_t) va_arg(vp, uid_t); 2012 uid_t euid = (uid_t) va_arg(vp, uid_t); 2013 uid_t suid = (uid_t) va_arg(vp, uid_t); 2014 2015 rc = uwrap_setresuid_thread(ruid, euid, suid); 2016 } 2017 break; 2018 #endif /* SYS_setresuid */ 2019 #if defined(SYS_getresuid) && defined(HAVE_GETRESUID) 2020 case SYS_getresuid: 2021 #ifdef HAVE_LINUX_32BIT_SYSCALLS 2022 case SYS_getresuid32: 2023 #endif 2024 { 2025 uid_t *ruid = (uid_t *) va_arg(vp, uid_t *); 2026 uid_t *euid = (uid_t *) va_arg(vp, uid_t *); 2027 uid_t *suid = (uid_t *) va_arg(vp, uid_t *); 2028 2029 rc = uwrap_getresuid(ruid, euid, suid); 2030 } 2031 break; 2032 #endif /* SYS_getresuid && HAVE_GETRESUID*/ 2033 /* groups */ 2034 case SYS_setgroups: 2035 #ifdef HAVE_LINUX_32BIT_SYSCALLS 2036 case SYS_setgroups32: 2037 #endif 2038 { 2039 size_t size = (size_t) va_arg(vp, size_t); 2040 gid_t *list = (gid_t *) va_arg(vp, int *); 2041 2042 rc = uwrap_setgroups_thread(size, list); 2043 } 2044 break; 2045 default: 2046 UWRAP_LOG(UWRAP_LOG_DEBUG, 2047 "UID_WRAPPER calling non-wrapped syscall %lu", 2048 sysno); 2049 2050 rc = libc_vsyscall(sysno, vp); 2051 break; 2052 } 2053 2054 return rc; 2055 } 2056 2057 #ifdef HAVE_SYSCALL 2058 #ifdef HAVE_SYSCALL_INT 2059 int syscall (int sysno, ...) 2060 #else 2061 long int syscall (long int sysno, ...) 2062 #endif 2063 { 2064 #ifdef HAVE_SYSCALL_INT 2065 int rc; 2066 #else 2067 long int rc; 2068 #endif 2069 va_list va; 2070 2071 va_start(va, sysno); 2072 2073 if (!uid_wrapper_enabled()) { 2074 rc = libc_vsyscall(sysno, va); 2075 va_end(va); 2076 return rc; 2077 } 2078 2079 uwrap_init(); 2080 rc = uwrap_syscall(sysno, va); 2081 va_end(va); 2082 2083 return rc; 2084 } 2085 #endif /* HAVE_SYSCALL */ 2086 #endif /* HAVE_SYS_SYSCALL_H || HAVE_SYSCALL_H */ 2087 2088 /**************************** 2089 * CONSTRUCTOR 2090 ***************************/ 2091 void uwrap_constructor(void) 2092 { 2093 /* 2094 * If we hold a lock and the application forks, then the child 2095 * is not able to unlock the mutex and we are in a deadlock. 2096 * This should prevent such deadlocks. 2097 */ 2098 pthread_atfork(&uwrap_thread_prepare, 2099 &uwrap_thread_parent, 2100 &uwrap_thread_child); 2101 2102 /* Here is safe place to call uwrap_init() and initialize data 2103 * for main process. 2104 */ 2105 uwrap_init(); 2106 } 2107 2108 /**************************** 2109 * DESTRUCTOR 2110 ***************************/ 2111 2112 /* 2113 * This function is called when the library is unloaded and makes sure that 2114 * resources are freed. 2115 */ 2116 void uwrap_destructor(void) 2117 { 2118 struct uwrap_thread *u = uwrap.ids; 2119 2120 UWRAP_LOCK_ALL; 2121 2122 while (u != NULL) { 2123 UWRAP_DLIST_REMOVE(uwrap.ids, u); 2124 2125 SAFE_FREE(u->groups); 2126 SAFE_FREE(u); 2127 2128 u = uwrap.ids; 2129 } 2130 2131 2132 if (uwrap.libc.handle != NULL) { 2133 dlclose(uwrap.libc.handle); 2134 } 2135 2136 if (uwrap.libpthread.handle != NULL) { 2137 dlclose(uwrap.libpthread.handle); 2138 } 2139 2140 UWRAP_UNLOCK_ALL; 2141 } -
vendor/current/lib/uid_wrapper/wscript
r740 r988 2 2 3 3 import Options 4 import os, sys 4 5 5 def set_options(opt): 6 gr = opt.option_group('developer options') 7 gr.add_option('--enable-uid-wrapper', 8 help=("Turn on uid wrapper library (default=no)"), 9 action="store_true", dest='enable_uid_wrapper', default=False) 6 VERSION="1.2.0" 10 7 11 8 def configure(conf): 12 if (Options.options.enable_uid_wrapper or 13 Options.options.developer or 14 Options.options.enable_selftest): 15 conf.DEFINE('UID_WRAPPER', 1) 16 conf.ADD_GLOBAL_DEPENDENCY('uid_wrapper') 9 if conf.CHECK_BUNDLED_SYSTEM('uid_wrapper', minversion=VERSION, set_target=False): 10 conf.DEFINE('USING_SYSTEM_UID_WRAPPER', 1) 11 libuid_wrapper_so_path = 'libuid_wrapper.so' 12 else: 13 # check HAVE_GCC_ATOMIC_BUILTINS 14 conf.CHECK_CODE(''' 15 #include <stdbool.h> 16 int main(void) { 17 bool x; 18 bool *p_x = &x; 19 __atomic_load(p_x, &x, __ATOMIC_RELAXED); 20 return 0; 21 ''', 22 'HAVE_GCC_ATOMIC_BUILTINS', 23 addmain=False, 24 msg='Checking for atomic builtins') 17 25 26 # check HAVE_GCC_THREAD_LOCAL_STORAGE 27 conf.CHECK_CODE(''' 28 __thread int tls; 29 30 int main(void) { 31 return 0; 32 } 33 ''', 34 'HAVE_GCC_THREAD_LOCAL_STORAGE', 35 addmain=False, 36 msg='Checking for thread local storage') 37 38 if Options.options.address_sanitizer: 39 # check HAVE_ADDRESS_SANITIZER_ATTRIBUTE 40 conf.CHECK_CODE(''' 41 void test_address_sanitizer_attribute(void) __attribute__((no_sanitize_address)); 42 43 void test_address_sanitizer_attribute(void) 44 { 45 return; 46 } 47 48 int main(void) { 49 return 0; 50 } 51 ''', 52 'HAVE_ADDRESS_SANITIZER_ATTRIBUTE', 53 addmain=False, 54 cflags='-Wall -Wextra -Werror', 55 msg='Checking for address sanitizer attribute') 56 57 # check HAVE_FUNCTION_ATTRIBUTE_FORMAT 58 conf.CHECK_CODE(''' 59 void log_fn(const char *format, ...) __attribute__ ((format (printf, 1, 2))); 60 61 int main(void) { 62 return 0; 63 } 64 ''', 65 'HAVE_FUNCTION_ATTRIBUTE_FORMAT', 66 addmain=False, 67 msg='Checking for printf format validation support') 68 # Prototype checks 69 conf.CHECK_C_PROTOTYPE('setgroups', 70 'int setgroups(int ngroups, const gid_t *grouplist)', 71 define='HAVE_SETGROUPS_INT', headers='unistd.h sys/types.h') 72 conf.CHECK_C_PROTOTYPE('syscall', 73 'int syscall(int number, ...)', 74 define='HAVE_SYSCALL_INT', headers='unistd.h sys/syscall.h') 75 76 if (sys.platform.rfind('linux') > -1): 77 conf.CHECK_CODE(''' 78 #if defined(HAVE_UNISTD_H) 79 #include <unistd.h> 80 #endif 81 #include <stdlib.h> 82 #include <stdio.h> 83 #include <sys/types.h> 84 #include <errno.h> 85 86 #ifdef HAVE_SYS_PRIV_H 87 #include <sys/priv.h> 88 #endif 89 #ifdef HAVE_SYS_ID_H 90 #include <sys/id.h> 91 #endif 92 93 #if defined(HAVE_SYSCALL_H) 94 #include <syscall.h> 95 #endif 96 97 #if defined(HAVE_SYS_SYSCALL_H) 98 #include <sys/syscall.h> 99 #endif 100 101 syscall(SYS_setresuid32, -1, -1, -1); 102 syscall(SYS_setresgid32, -1, -1, -1); 103 syscall(SYS_setreuid32, -1, -1); 104 syscall(SYS_setregid32, -1, -1); 105 syscall(SYS_setuid32, -1); 106 syscall(SYS_setgid32, -1); 107 syscall(SYS_setgroups32, 0, NULL); 108 ''', 109 'HAVE_LINUX_32BIT_SYSCALLS', 110 msg="Checking whether Linux has 32-bit credential calls"); 111 112 conf.CHECK_FUNCS('getresuid getresgid') 113 114 # Create full path to uid_wrapper 115 srcdir = os.path.realpath(conf.srcdir) 116 libuid_wrapper_so_path = srcdir + '/bin/default/lib/uid_wrapper/libuid-wrapper.so' 117 118 conf.DEFINE('LIBUID_WRAPPER_SO_PATH', libuid_wrapper_so_path) 119 conf.DEFINE('UID_WRAPPER', 1) 120 121 def build(bld): 122 if not bld.CONFIG_SET("USING_SYSTEM_UID_WRAPPER"): 123 # We need to do it this way or the library wont work. 124 # Using private_library=True will add symbol version which 125 # breaks preloading! 126 bld.SAMBA_LIBRARY('uid_wrapper', 127 source='uid_wrapper.c', 128 deps='dl', 129 install=False, 130 realname='libuid-wrapper.so') 131
Note:
See TracChangeset
for help on using the changeset viewer.