git: d1cd0cc32b53 - main - rtld: add direct-exec option -o

From: Konstantin Belousov <kib_at_FreeBSD.org>
Date: Tue, 30 Apr 2024 00:55:04 UTC
The branch main has been updated by kib:

URL: https://cgit.FreeBSD.org/src/commit/?id=d1cd0cc32b53c09e72e33116b94a5b0b9781a183

commit d1cd0cc32b53c09e72e33116b94a5b0b9781a183
Author:     Konstantin Belousov <kib@FreeBSD.org>
AuthorDate: 2024-04-28 03:19:39 +0000
Commit:     Konstantin Belousov <kib@FreeBSD.org>
CommitDate: 2024-04-30 00:16:05 +0000

    rtld: add direct-exec option -o
    
    allowing to set any known LD_ parameter for the current rtld invocation,
    but without polluting the activated' binary environment.  In other
    words, the set parameter is not exported into the environment.
    
    Reviewed by:    markj
    Sponsored by:   The FreeBSD Foundation
    MFC after:      1 week
    Differential revision:  https://reviews.freebsd.org/D44988
---
 libexec/rtld-elf/rtld.1 | 20 +++++++++++++++++++-
 libexec/rtld-elf/rtld.c | 30 ++++++++++++++++++++++++++++++
 2 files changed, 49 insertions(+), 1 deletion(-)

diff --git a/libexec/rtld-elf/rtld.1 b/libexec/rtld-elf/rtld.1
index a152dd444bd7..0f1e8f68b10a 100644
--- a/libexec/rtld-elf/rtld.1
+++ b/libexec/rtld-elf/rtld.1
@@ -26,7 +26,7 @@
 .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 .\"
-.Dd October 29, 2023
+.Dd April 28, 2024
 .Dt RTLD 1
 .Os
 .Sh NAME
@@ -352,6 +352,7 @@ The syntax of the direct invocation is
 .Op Fl b Ar exe
 .Op Fl d
 .Op Fl f Ar fd
+.Op Fl o Ar OPT=NAME
 .Op Fl p
 .Op Fl u
 .Op Fl v
@@ -387,6 +388,23 @@ If this option is specified,
 is only used to provide the
 .Va argv[0]
 value to the program.
+.It Fl o Ar OPT=VALUE
+Set the
+.Ar OPT
+configuration variable to the value
+.Ar VALUE .
+The possible variable names are listed above as
+.Ev LD_
+prefixed environment variables, but here are referenced without the
+.Ev LD_
+prefix.
+A configuration variable set this way does not leak into
+the activated image's environment.
+.Pp
+The option can be repeated as many times as needed to set
+all configuration parameters.
+The parameters set using this option have priority over
+the same parameters assigned via environment.
 .It Fl p
 If the
 .Pa image_path
diff --git a/libexec/rtld-elf/rtld.c b/libexec/rtld-elf/rtld.c
index a46cbe4e59c8..f5a2eeb37f10 100644
--- a/libexec/rtld-elf/rtld.c
+++ b/libexec/rtld-elf/rtld.c
@@ -6157,6 +6157,35 @@ parse_args(char* argv[], int argc, bool *use_pathp, int *fdp,
 				*fdp = fd;
 				seen_f = true;
 				break;
+			} else if (opt == 'o') {
+				struct ld_env_var_desc *l;
+				char *n, *v;
+				u_int ll;
+
+				if (j != arglen - 1) {
+					_rtld_error("Invalid options: %s", arg);
+					rtld_die();
+				}
+				i++;
+				n = argv[i];
+				v = strchr(n, '=');
+				if (v == NULL) {
+					_rtld_error("No '=' in -o parameter");
+					rtld_die();
+				}
+				for (ll = 0; ll < nitems(ld_env_vars); ll++) {
+					l = &ld_env_vars[ll];
+					if (v - n == (ptrdiff_t)strlen(l->n) &&
+					    strncmp(n, l->n, v - n) == 0) {
+						l->val = v + 1;
+						break;
+					}
+				}
+				if (ll == nitems(ld_env_vars)) {
+					_rtld_error("Unknown LD_ option %s",
+					    n);
+					rtld_die();
+				}
 			} else if (opt == 'p') {
 				*use_pathp = true;
 			} else if (opt == 'u') {
@@ -6240,6 +6269,7 @@ print_usage(const char *argv0)
 	    "  -b <exe>  Execute <exe> instead of <binary>, arg0 is <binary>\n"
 	    "  -d        Ignore lack of exec permissions for the binary\n"
 	    "  -f <FD>   Execute <FD> instead of searching for <binary>\n"
+	    "  -o <OPT>=<VAL> Set LD_<OPT> to <VAL>, without polluting env\n"
 	    "  -p        Search in PATH for named binary\n"
 	    "  -u        Ignore LD_ environment variables\n"
 	    "  -v        Display identification information\n"