{
	"id": "1a3ef188-fac1-456d-a1fc-64e06a82dd34",
	"created_at": "2026-04-06T00:22:17.260245Z",
	"updated_at": "2026-04-10T03:20:38.422653Z",
	"deleted_at": null,
	"sha1_hash": "349457fa89b7d0c54ab8a5dbf228f458bc358ec7",
	"title": "What Is the LD_PRELOAD Trick? | Baeldung on Linux",
	"llm_title": "",
	"authors": "",
	"file_creation_date": "0001-01-01T00:00:00Z",
	"file_modification_date": "0001-01-01T00:00:00Z",
	"file_size": 90860,
	"plain_text": "What Is the LD_PRELOAD Trick? | Baeldung on Linux\r\nBy baeldung\r\nPublished: 2020-08-09 · Archived: 2026-04-05 22:21:58 UTC\r\n1. Overview\r\nThe LD_PRELOAD trick is a useful technique to influence the linkage of shared libraries and the resolution\r\nof symbols (functions) at runtime. To explain LD_PRELOAD, let’s first discuss a bit about libraries in the Linux\r\nsystem.\r\nIn brief, a library is a collection of compiled functions. We can make use of these functions in our programs\r\nwithout rewriting the same functionality. This can be achieved by either including the library code in our program\r\n(static library) or by linking dynamically at runtime (shared library).\r\nUsing static libraries, we can build standalone programs. On the other hand, programs built with a shared library\r\nrequire runtime linker/loader support. For this reason, before executing a program, all required symbols are\r\nloaded and the program is prepared for execution.\r\nhttps://www.baeldung.com/linux/ld_preload-trick-what-is\r\nPage 1 of 9\n\n2. Runtime Execution Environment\r\nThe LD_PRELOAD trick comes handy in the program execution preparation phase. Linux system programs\r\nld.so and ld-linux.so (dynamic linker/loader) use LD_PRELOAD to load specified shared libraries. In particular,\r\nbefore any other library, the dynamic loader will first load shared libraries that are in LD_PRELOAD.\r\nIt’s important to note that in secure-execution mode, entries in LD_PRELOAD can be ignored. This happens\r\nwhen a slash appears in the path — meaning the file is not in the default search path. In this case, the dynamic\r\nloader will only load a system library if the library has the setuid bit set.\r\nhttps://www.baeldung.com/linux/ld_preload-trick-what-is\r\nPage 2 of 9\n\n3. Use Cases of LD_PRELOAD\r\nIn this section, we’ll try some use cases of the LD_PRELOAD trick. Firstly, we will see how libraries can be\r\noverridden. Later on, we’ll use LD_PRELOAD to interpose (wrap around).\r\nSince LD_PRELOAD is an environment variable, it affects only the current process. Therefore, we will only\r\nuse absolute paths.\r\nBefore getting into the use of LD_PRELOAD, let’s first use the ldd command. The ldd command is useful for\r\nlisting runtime dependencies of a binary program or shared library:\r\n$ ldd /usr/bin/pigz\r\nlinux-vdso.so.1 (0x00007ffd559d7000)\r\nlibm.so.6 =\u003e /lib/x86_64-linux-gnu/libm.so.6 (0x00007fa48bcc1000)\r\nlibpthread.so.0 =\u003e /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007fa48bc9e000)\r\nlibz.so.1 =\u003e /lib/x86_64-linux-gnu/libz.so.1 (0x00007fa48bc82000)\r\nlibc.so.6 =\u003e /lib/x86_64-linux-gnu/libc.so.6 (0x00007fa48ba90000)\r\n/lib64/ld-linux-x86-64.so.2 (0x00007fa48c065000)\r\nUsing ldd, we can see that the pigz program depends on several shared libraries.\r\nWe also have other options for seeing used shared libraries.\r\nhttps://www.baeldung.com/linux/ld_preload-trick-what-is\r\nPage 3 of 9\n\n3.1. Replacing Libraries Using LD_PRELOAD\r\nLet’s now get back to the terminal and see the LD_PRELOAD trick in action:\r\n$ LD_PRELOAD=/data/preload/lib/libz.so.1.2.7 ldd /usr/bin/pigz\r\nlinux-vdso.so.1 (0x00007ffc1d9c4000)\r\n/data/preload/lib/libz.so.1.2.7 (0x00007f33877d9000)\r\nlibm.so.6 =\u003e /lib/x86_64-linux-gnu/libm.so.6 (0x00007f3387674000)\r\nlibpthread.so.0 =\u003e /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f3387651000)\r\nlibc.so.6 =\u003e /lib/x86_64-linux-gnu/libc.so.6 (0x00007f338745f000)\r\n/lib64/ld-linux-x86-64.so.2 (0x00007f3387a32000)\r\nNow, we can see that the zlib (libz) dependency of the pigz program is changed, from the system default\r\nlocation to the location that we have set in LD_PRELOAD.\r\nIf we want to run multiple programs with LD_PRELOAD, it will be better to use export and unset to set and clear\r\nthe environment variable, respectively. Let’s do this now and confirm the change by invoking the pigz program\r\nitself:\r\n$ pigz -vV\r\npigz 2.4\r\nhttps://www.baeldung.com/linux/ld_preload-trick-what-is\r\nPage 4 of 9\n\nzlib 1.2.11\r\n \r\n$ export LD_PRELOAD=/data/preload/lib/libz.so.1.2.7\r\n$ pigz -vV\r\npigz 2.4\r\nzlib 1.2.7\r\n \r\n$ unset LD_PRELOAD\r\n$ pigz -vV\r\npigz 2.4\r\nzlib 1.2.11\r\nHere, we invoked pigz with the -vV options so that it reports both the pigz and zlib versions.\r\n3.2. Interposing Using LD_PRELOAD\r\nLet’s use an interposer library to change the behavior of a system function. For this example, we’ll use an\r\nimaginary library that adds some accounting functionality to malloc.\r\nUsing the LD_PRELOAD trick, we can change the behavior of any program that is dependent on an\r\nexternal shared library. For example, the ls program depends on libc, which provides many system functions,\r\nincluding memory allocation using malloc:\r\nhttps://www.baeldung.com/linux/ld_preload-trick-what-is\r\nPage 5 of 9\n\n$ ls -lh\r\ntotal 2,8G\r\n-rw-rw-r-- 1 baeldung_user baeldung_user 3,6K Jul 4 20:16 BVF_Density.ipynb\r\n-rwxrwxr-x 1 baeldung_user baeldung_user 2,8G Jul 5 15:59 cuda_11.0.1_450.36.06_linux.run\r\ndrwxrwxr-x 2 baeldung_user baeldung_user 25 Jul 8 16:12 h5store\r\ndrwxrwxr-x 2 baeldung_user baeldung_user 30 Jul 5 18:47 pandas_processing\r\ndrwxrwxr-x 4 baeldung_user baeldung_user 142 Jul 19 15:59 preload\r\n$ LD_PRELOAD=/data/preload/lib/malloc_interpose.so ls -lh\r\nmalloc(20000) call number: 223\r\nmalloc(32816) call number: 226\r\ntotal 2,8G\r\n-rw-rw-r-- 1 baeldung_user baeldung_user 3,6K Jul 4 20:16 BVF_Density.ipynb\r\n-rwxrwxr-x 1 baeldung_user baeldung_user 2,8G Jul 5 15:59 cuda_11.0.1_450.36.06_linux.run\r\ndrwxrwxr-x 2 baeldung_user baeldung_user 25 Jul 8 16:12 h5store\r\ndrwxrwxr-x 2 baeldung_user baeldung_user 30 Jul 5 18:47 pandas_processing\r\ndrwxrwxr-x 4 baeldung_user baeldung_user 142 Jul 19 15:59 preload\r\nWith our interposer library preloaded, the output of the ls command is different.\r\nThis is because now the malloc function in our custom-built library takes precedence over the standard malloc\r\nfunction. In this interposer example, the malloc function printed the size and call-count at certain memory\r\nallocation calls.\r\nIt’s possible to specify multiple libraries in the LD_PRELOAD variable. For this, we can provide a list of\r\nlibraries, separated using a colon or space:\r\n$ LD_PRELOAD=\"/data/preload/lib/malloc_interpose.so:/data/preload/lib/free_interpose.so\" ls -lh\r\nmalloc(20000) call number: 223\r\nmalloc(32816) call number: 226\r\ntotal 2,8G\r\nfree((nil)) call number: 174\r\nfree((nil)) call number: 175\r\nfree((nil)) call number: 178\r\n-rw-rw-r-- 1 baeldung_user baeldung_user 3,6K Jul 4 20:16 BVF_Density.ipynb\r\n-rwxrwxr-x 1 baeldung_user baeldung_user 2,8G Jul 5 15:59 cuda_11.0.1_450.36.06_linux.run\r\ndrwxrwxr-x 2 baeldung_user baeldung_user 25 Jul 8 16:12 h5store\r\ndrwxrwxr-x 2 baeldung_user baeldung_user 30 Jul 5 18:47 pandas_processing\r\ndrwxrwxr-x 4 baeldung_user baeldung_user 142 Jul 19 15:59 preload\r\nfree((nil)) call number: 180\r\nNow, we’ve added another imaginary interposer library to the LD_PRELOAD variable that reports on certain calls\r\nto the system function free, where a NULL pointer is passed.\r\nhttps://www.baeldung.com/linux/ld_preload-trick-what-is\r\nPage 6 of 9\n\n4. When Is This Helpful?\r\nThe LD_PRELOAD trick can be helpful in some situations.\r\nFor example, consider the case when two libraries export the same symbol and our program links with the\r\nwrong one. In this case, the library with the correct symbol can be preloaded by using LD_PRELOAD. Doing this\r\nwill result in the resolution of the correct symbol.\r\nAnother use case is when an optimized or custom implementation of a library function should be preferred.\r\nWe can preload this optimized or custom implementation without changing the original library. Moreover, we can\r\nalso replace the whole library by providing a different version.\r\nAdditionally, various profiling and monitoring tools widely use LD_PRELOAD for instrumenting code. For\r\ninstance, a performance profiling application will interpose key system functions. This enables the profiler to\r\ncollect relevant data from the user application.\r\nhttps://www.baeldung.com/linux/ld_preload-trick-what-is\r\nPage 7 of 9\n\n5. Alternative to LD_PRELOAD\r\nBesides the LD_PRELOAD trick, there is an alternative using the /etc/ld.so.preload file. However, this is a\r\nsystem-wide setting. In most systems, this file doesn’t even exist by default, and a system administrator has to\r\ncreate it.\r\nLet’s now create this file and select an older version of zlib for preloading, and then we’ll test the pigz program\r\nagain:\r\n$ pigz -vV\r\npigz 2.4\r\nzlib 1.2.11\r\n \r\n$ sudo -i\r\n# echo \"/data/preload/lib/libz.so.1.2.8\" \u003e /etc/ld.so.preload\r\n# exit\r\nlogout\r\n \r\n$ pigz -vV\r\npigz 2.4\r\nzlib 1.2.8\r\nhttps://www.baeldung.com/linux/ld_preload-trick-what-is\r\nPage 8 of 9\n\n6. Conclusion\r\nIn this article, we discussed various ways to use the LD_PRELOAD trick.\r\nIt’s an advanced technique that can be helpful in certain scenarios. For example, developers can quickly debug and\r\ntest libraries or some functions within the library.\r\nIt’s also a well-known way of code instrumentation in profiling and monitoring tools using interposing techniques.\r\nMoreover, system administrators can also use this to control the execution environment for specific users, or for\r\nall users.\r\nSource: https://www.baeldung.com/linux/ld_preload-trick-what-is\r\nhttps://www.baeldung.com/linux/ld_preload-trick-what-is\r\nPage 9 of 9",
	"extraction_quality": 1,
	"language": "EN",
	"sources": [
		"MITRE"
	],
	"references": [
		"https://www.baeldung.com/linux/ld_preload-trick-what-is"
	],
	"report_names": [
		"ld_preload-trick-what-is"
	],
	"threat_actors": [],
	"ts_created_at": 1775434937,
	"ts_updated_at": 1775791238,
	"ts_creation_date": 0,
	"ts_modification_date": 0,
	"files": {
		"pdf": "https://archive.orkl.eu/349457fa89b7d0c54ab8a5dbf228f458bc358ec7.pdf",
		"text": "https://archive.orkl.eu/349457fa89b7d0c54ab8a5dbf228f458bc358ec7.txt",
		"img": "https://archive.orkl.eu/349457fa89b7d0c54ab8a5dbf228f458bc358ec7.jpg"
	}
}