Merge pull request #31230 from mrc0mmand/test-seccomp

process-util: use only the least significant byte from personality()
This commit is contained in:
Frantisek Sumsal 2024-02-09 10:39:23 +01:00 committed by GitHub
commit 8632590278
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 20 additions and 17 deletions

View file

@ -1303,7 +1303,7 @@ int opinionated_personality(unsigned long *ret) {
if (current < 0)
return current;
if (((unsigned long) current & 0xffff) == PER_LINUX32)
if (((unsigned long) current & OPINIONATED_PERSONALITY_MASK) == PER_LINUX32)
*ret = PER_LINUX32;
else
*ret = PER_LINUX;

View file

@ -101,12 +101,17 @@ bool is_main_thread(void);
bool oom_score_adjust_is_valid(int oa);
#ifndef PERSONALITY_INVALID
/* personality(7) documents that 0xffffffffUL is used for querying the
/* personality(2) documents that 0xFFFFFFFFUL is used for querying the
* current personality, hence let's use that here as error
* indicator. */
#define PERSONALITY_INVALID 0xffffffffLU
#define PERSONALITY_INVALID 0xFFFFFFFFUL
#endif
/* The personality() syscall returns a 32-bit value where the top three bytes are reserved for flags that
* emulate historical or architectural quirks, and only the least significant byte reflects the actual
* personality we're interested in. */
#define OPINIONATED_PERSONALITY_MASK 0xFFUL
unsigned long personality_from_string(const char *p);
const char *personality_to_string(unsigned long);

View file

@ -937,7 +937,7 @@ TEST(native_syscalls_filtered) {
}
TEST(lock_personality) {
unsigned long current;
unsigned long current_opinionated;
pid_t pid;
if (!is_seccomp_available()) {
@ -949,24 +949,21 @@ TEST(lock_personality) {
return;
}
assert_se(opinionated_personality(&current) >= 0);
/* On ppc64le sanitizers disable ASLR (i.e. by setting ADDR_NO_RANDOMIZE),
* which opinionated_personality() doesn't return. Let's tweak the current
* personality ourselves in such cases.
* See: https://github.com/llvm/llvm-project/commit/78f7a6eaa601bfdd6ae70ffd3da2254c21ff77f9
*/
if (FLAGS_SET(safe_personality(PERSONALITY_INVALID), ADDR_NO_RANDOMIZE))
current |= ADDR_NO_RANDOMIZE;
assert_se(opinionated_personality(&current_opinionated) >= 0);
log_info("current personality=0x%lX", current);
log_info("current personality=0x%lX", (unsigned long) safe_personality(PERSONALITY_INVALID));
log_info("current opinionated personality=0x%lX", current_opinionated);
pid = fork();
assert_se(pid >= 0);
if (pid == 0) {
assert_se(seccomp_lock_personality(current) >= 0);
unsigned long current;
assert_se((unsigned long) safe_personality(current) == current);
assert_se(seccomp_lock_personality(current_opinionated) >= 0);
current = safe_personality(current_opinionated);
assert_se((current & OPINIONATED_PERSONALITY_MASK) == current_opinionated);
/* Note, we also test that safe_personality() works correctly, by checking whether errno is properly
* set, in addition to the return value */
@ -981,14 +978,15 @@ TEST(lock_personality) {
assert_se(safe_personality(PER_LINUX_32BIT) == -EPERM);
assert_se(safe_personality(PER_SVR4) == -EPERM);
assert_se(safe_personality(PER_BSD) == -EPERM);
assert_se(safe_personality(current == PER_LINUX ? PER_LINUX32 : PER_LINUX) == -EPERM);
assert_se(safe_personality(current_opinionated == PER_LINUX ? PER_LINUX32 : PER_LINUX) == -EPERM);
assert_se(safe_personality(PER_LINUX32_3GB) == -EPERM);
assert_se(safe_personality(PER_UW7) == -EPERM);
assert_se(safe_personality(0x42) == -EPERM);
assert_se(safe_personality(PERSONALITY_INVALID) == -EPERM); /* maybe remove this later */
assert_se((unsigned long) personality(current) == current);
current = safe_personality(current_opinionated);
assert_se((current & OPINIONATED_PERSONALITY_MASK) == current_opinionated);
_exit(EXIT_SUCCESS);
}