pack-audit.c 2.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. /* GNU Guix --- Functional package management for GNU
  2. Copyright (C) 2020 Ludovic Courtès <ludo@gnu.org>
  3. This file is part of GNU Guix.
  4. GNU Guix is free software; you can redistribute it and/or modify it
  5. under the terms of the GNU General Public License as published by
  6. the Free Software Foundation; either version 3 of the License, or (at
  7. your option) any later version.
  8. GNU Guix is distributed in the hope that it will be useful, but
  9. WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. GNU General Public License for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with GNU Guix. If not, see <http://www.gnu.org/licenses/>. */
  14. /* This file implements part of the GNU ld.so audit interface. It is used by
  15. the "fakechroot" engine of the 'guix pack -RR' wrappers to make sure the
  16. loader looks for shared objects under the "fake" root directory. */
  17. #define _GNU_SOURCE 1
  18. #include <link.h>
  19. #include <error.h>
  20. #include <stdlib.h>
  21. #include <string.h>
  22. #include <assert.h>
  23. /* The pseudo root directory and store that we are relocating to. */
  24. static const char *root_directory;
  25. static char *store;
  26. /* The original store, "/gnu/store" by default. */
  27. static const char original_store[] = "@STORE_DIRECTORY@";
  28. /* Like 'malloc', but abort if 'malloc' returns NULL. */
  29. static void *
  30. xmalloc (size_t size)
  31. {
  32. void *result = malloc (size);
  33. assert (result != NULL);
  34. return result;
  35. }
  36. unsigned int
  37. la_version (unsigned int v)
  38. {
  39. if (v != LAV_CURRENT)
  40. error (1, 0, "cannot handle interface version %u", v);
  41. root_directory = getenv ("FAKECHROOT_BASE");
  42. if (root_directory == NULL)
  43. error (1, 0, "'FAKECHROOT_BASE' is not set");
  44. store = xmalloc (strlen (root_directory) + sizeof original_store);
  45. strcpy (store, root_directory);
  46. strcat (store, original_store);
  47. return v;
  48. }
  49. /* Return NAME, a shared object file name, relocated under STORE. This
  50. function is called by the loader whenever it looks for a shared object. */
  51. char *
  52. la_objsearch (const char *name, uintptr_t *cookie, unsigned int flag)
  53. {
  54. char *result;
  55. if (strncmp (name, original_store,
  56. sizeof original_store - 1) == 0)
  57. {
  58. size_t len = strlen (name) - sizeof original_store
  59. + strlen (store) + 1;
  60. result = xmalloc (len);
  61. strcpy (result, store);
  62. strcat (result, name + sizeof original_store - 1);
  63. }
  64. else
  65. result = strdup (name);
  66. return result;
  67. }