Files
glibc/elf/tst-origin-secure.h
T
Adhemerval Zanella ed0c137b97 elf: Open the normalized $ORIGIN rpath in AT_SECURE programs (BZ 34360)
For AT_SECURE programs the loader honors $ORIGIN in DT_RPATH only when the
expansion is rooted in a trusted directory, but it validated the lexically
normalized path while opening the raw expansion.  As "a/b/../c" only names
"a/c" when "b" is not a symlink, an attacker who controls a component of
$ORIGIN -- e.g. by hard-linking the setuid binary into an attacker-owned
directory -- can make the opened path escape the trusted directory even
though the check passed, loading an attacker-controlled object.

Normalize the expansion in place and open that, so the path that is opened
is exactly the path that was validated.  _dl_normalize_path rewrites the
string in place without ever advancing its write cursor past its read
cursor or appending, so it stays within the original storage.

Add elf/tst-origin-secure as a regression test.

Reviewed-by: Florian Weimer <fweimer@redhat.com>
2026-09-01 15:40:28 -03:00

42 lines
1.4 KiB
C

/* Definitions shared by the tst-origin-secure test, its victim and modules.
Copyright (C) 2026 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<https://www.gnu.org/licenses/>. */
#ifndef _TST_ORIGIN_SECURE_H
#define _TST_ORIGIN_SECURE_H 1
enum
{
ORIGIN_SECURE_ID_TRUSTED = 1, /* The copy installed in the trusted
SLIBDIR. */
ORIGIN_SECURE_ID_ATTACKER = 2, /* The copy reachable only by resolving the
"sub" symlink. */
};
extern int origin_secure_id (void);
enum
{
ORIGIN_SECURE_STATUS_NONE = 0,
ORIGIN_SECURE_STATUS_ATTACKER = 1 << 0, /* The victim loaded attacker
rather than the trusted. */
ORIGIN_SECURE_STATUS_SECURE = 1 << 1, /* The loader ran the victim in
secure mode. */
};
#endif