Repository: borgbackup/borg

Issue:
LD_LIBRARY_PATH leaking to executed commands
## Have you checked borgbackup docs, FAQ, and open GitHub issues?

Yes

## Is this a BUG / ISSUE report or a QUESTION?

BUG

## System information. For client/server mode post info for both machines.

#### Your borg version (borg -V).

tested on borg 1.2.4 and 1.2.6 (both linuxold64 pyinstaller-made fat binaries)

#### Operating system (distribution) and version.
CentOS Linux release 7.9.2009 (Core)

## Describe the problem you're observing.
When running `borg create --content-from-command mysql_dump`, `LD_LIBRARY_PATH` is defined to a tmp directory, containing libstdc++.so.6, causing a glibc version error:
```
mysqldump: /lib64/libc.so.6: version `GLIBC_2.18' not found (required by /tmp/_MEIHMhgGt/libstdc++.so.6)
```

#### Can you reproduce the problem? If so, describe how. If not, describe troubleshooting steps you took before opening the issue.
With any appropriate `BORG_REPO` defined:
```
$ borg-linuxold64 create --show-rc --content-from-command '::test-{utcnow}' -- mysqldump --all
Using a pure-python msgpack! This will result in lower performance.
Remote: Using a pure-python msgpack! This will result in lower performance.
mysqldump: /lib64/libc.so.6: version `GLIBC_2.18' not found (required by /tmp/_MEIfnBRKH/libstdc++.so.6)
Command 'mysqldump' exited with status 1
```
 
or to check that `LD_LIBRARY_PATH` is leaking:
```
$ borg create --content-from-command '::test-{utcnow}' -- bash -c 'echo ld:$LD_LIBRARY_PATH >&2'
Using a pure-python msgpack! This will result in lower performance.
Remote: Using a pure-python msgpack! This will result in lower performance.
ld:/tmp/_MEIimhCtC
```



Discussion:

Resolving patch:
diff --git a/src/borg/archiver/create_cmd.py b/src/borg/archiver/create_cmd.py
--- a/src/borg/archiver/create_cmd.py
+++ b/src/borg/archiver/create_cmd.py
@@ -25,6 +25,7 @@
 from ..helpers import log_multi
 from ..helpers import basic_json_data, json_print
 from ..helpers import flags_dir, flags_special_follow, flags_special
+from ..helpers import prepare_subprocess_env
 from ..helpers import sig_int, ignore_sigint
 from ..helpers import iter_separated
 from ..helpers import MakePathSafeAction
@@ -70,8 +71,12 @@ def create_inner(archive, cache, fso):
                 if not dry_run:
                     try:
                         try:
+                            env = prepare_subprocess_env(system=True)
                             proc = subprocess.Popen(
-                                args.paths, stdout=subprocess.PIPE, preexec_fn=None if is_win32 else ignore_sigint
+                                args.paths,
+                                stdout=subprocess.PIPE,
+                                env=env,
+                                preexec_fn=None if is_win32 else ignore_sigint,
                             )
                         except (FileNotFoundError, PermissionError) as e:
                             self.print_error("Failed to execute command: %s", e)
@@ -93,8 +98,9 @@ def create_inner(archive, cache, fso):
                 paths_sep = eval_escapes(args.paths_delimiter) if args.paths_delimiter is not None else "\n"
                 if args.paths_from_command:
                     try:
+                        env = prepare_subprocess_env(system=True)
                         proc = subprocess.Popen(
-                            args.paths, stdout=subprocess.PIPE, preexec_fn=None if is_win32 else ignore_sigint
+                            args.paths, stdout=subprocess.PIPE, env=env, preexec_fn=None if is_win32 else ignore_sigint
                         )
                     except (FileNotFoundError, PermissionError) as e:
                         self.print_error("Failed to execute command: %s", e)


Test patch: