mirror of
https://github.com/chromium/crashpad.git
synced 2024-12-29 00:32:35 +08:00
50ed179e9a
Use BUILDFLAG(IS_*) instead of defined(OS_*). This was generated mostly mechnically by performing the following steps: - sed -i '' -E -e 's/defined\(OS_/BUILDFLAG(IS_/g' \ -e 's%([ !])OS_([A-Z]+)%\1BUILDFLAG(IS_\2)%g' \ $(git grep -l 'OS_' '**/*.c' '**/*.cc' '**/*.h' '**/*.m' '**/*.mm') - sed -i '' -e 's/#ifdef BUILDFLAG(/#if BUILDFLAG(/' \ $(git grep -l '#ifdef BUILDFLAG(' '**/*.c' '**/*.cc' '**/*.h' '**/*.m' '**/*.mm') - gsed -i -z -E -e \ 's%(.*)#include "%\1#include "build/buildflag.h"\n#include "%' \ $(git grep -l 'BUILDFLAG(IS_' '**/*.c' '**/*.cc' '**/*.h' '**/*.m' '**/*.mm') - Spot checks to move #include "build/buildflag.h" to the correct parts of files. - sed -i '' -E -e \ 's%^(#include "build/buildflag.h")$%#include "build/build_config.h"\n\1%' \ $(grep -L '^#include "build/build_config.h"$' $(git grep -l 'BUILDFLAG(IS_' '**/*.c' '**/*.cc' '**/*.h' '**/*.m' '**/*.mm')) - Add “clang-format off” around tool usage messages. - git cl format - Update mini_chromium to 85ba51f98278 (intermediate step). TESTING ONLY). - for f in $(git grep -l '^#include "build/buildflag.h"$' '**/*.c' '**/*.cc' '**/*.h' '**/*.m' '**/*.mm'); do \ grep -v '^#include "build/buildflag.h"$' "${f}" > /tmp/z; \ cp /tmp/z "${f}"; done - git cl format - Update mini_chromium to 735143774c5f (intermediate step). - Update mini_chromium to f41420eb45fa (as checked in). - Update mini_chromium to 6e2f204b4ae1 (as checked in). For ease of review and inspection, each of these steps is uploaded as a new patch set in a review series. This includes an update of mini_chromium to 6e2f204b4ae1: f41420eb45fa Use BUILDFLAG for OS checking 6e2f204b4ae1 Include what you use: string_util.h uses build_config.h Bug: chromium:1234043 Change-Id: Ieef86186f094c64e59b853729737e36982f8cf69 Reviewed-on: https://chromium-review.googlesource.com/c/crashpad/crashpad/+/3400258 Reviewed-by: Joshua Peraza <jperaza@chromium.org> Commit-Queue: Mark Mentovai <mark@chromium.org>
94 lines
4.0 KiB
C++
94 lines
4.0 KiB
C++
// Copyright 2014 The Crashpad Authors. All rights reserved.
|
||
//
|
||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||
// you may not use this file except in compliance with the License.
|
||
// You may obtain a copy of the License at
|
||
//
|
||
// http://www.apache.org/licenses/LICENSE-2.0
|
||
//
|
||
// Unless required by applicable law or agreed to in writing, software
|
||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||
// See the License for the specific language governing permissions and
|
||
// limitations under the License.
|
||
|
||
#include <unistd.h>
|
||
|
||
#include <ostream>
|
||
|
||
#include "base/check_op.h"
|
||
#include "build/build_config.h"
|
||
|
||
namespace crashpad {
|
||
|
||
void DropPrivileges() {
|
||
gid_t gid = getgid();
|
||
uid_t uid = getuid();
|
||
|
||
#if BUILDFLAG(IS_APPLE)
|
||
// Based on the POSIX.1-2008 2013 edition documentation for setreuid() and
|
||
// setregid(), setreuid() and setregid() alone should be sufficient to drop
|
||
// privileges. The standard specifies that the saved ID should be set to the
|
||
// effective ID whenever the real ID is not -1, or whenever the effective ID
|
||
// is set not equal to the real ID. This code never specifies -1, so the
|
||
// setreuid() and setregid() alone should work according to the standard.
|
||
//
|
||
// In practice, on older versions of macOS, setuid() and setgid() (or
|
||
// seteuid() and setegid()) must be called first. Otherwise, setreuid() and
|
||
// setregid() do not alter the saved IDs, leaving open the possibility for
|
||
// future privilege escalation.
|
||
//
|
||
// The problem exists in 10.9.5 xnu-2422.115.4/bsd/kern/kern_prot.c
|
||
// setreuid(). Based on its comments, it purports to set the svuid to the new
|
||
// euid when the old svuid doesn’t match one of the new ruid and euid. This
|
||
// isn’t how POSIX.1-2008 says it should behave, but it should work for this
|
||
// function’s purposes. In reality, setreuid() doesn’t even do this: it sets
|
||
// the svuid to the old euid, which does not drop privileges when the old euid
|
||
// is different from the desired euid. The workaround of calling setuid() or
|
||
// seteuid() before setreuid() works because it sets the euid so that by the
|
||
// time setreuid() runs, the old euid is actually the value that ought to be
|
||
// set as the svuid. setregid() is similar. This bug was reported as radar
|
||
// 18987552, fixed in 10.10.3 and security updates to 10.9.5 and 10.8.5.
|
||
//
|
||
// setuid() and setgid() alone will only set the saved IDs when running as
|
||
// root. When running a setuid non-root or setgid program, they do not alter
|
||
// the saved ID, and do not effect a permanent privilege drop.
|
||
gid_t egid = getegid();
|
||
PCHECK(setgid(gid) == 0) << "setgid";
|
||
PCHECK(setregid(gid, gid) == 0) << "setregid";
|
||
|
||
uid_t euid = geteuid();
|
||
PCHECK(setuid(uid) == 0) << "setuid";
|
||
PCHECK(setreuid(uid, uid) == 0) << "setreuid";
|
||
|
||
if (uid != 0) {
|
||
// Because the setXid()+setreXid() interface to change IDs is fragile,
|
||
// ensure that privileges cannot be regained. This can only be done if the
|
||
// real user ID (and now the effective user ID as well) is not root, because
|
||
// root always has permission to change identity.
|
||
if (euid != uid) {
|
||
CHECK_EQ(seteuid(euid), -1);
|
||
}
|
||
if (egid != gid) {
|
||
CHECK_EQ(setegid(egid), -1);
|
||
}
|
||
}
|
||
#elif BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_ANDROID)
|
||
PCHECK(setresgid(gid, gid, gid) == 0) << "setresgid";
|
||
PCHECK(setresuid(uid, uid, uid) == 0) << "setresuid";
|
||
|
||
// Don’t check to see if privileges can be regained on Linux, because on
|
||
// Linux, it’s not as simple as ensuring that this can’t be done if non-root.
|
||
// Instead, the ability to change user and group IDs are controlled by the
|
||
// CAP_SETUID and CAP_SETGID capabilities, which may be granted to non-root
|
||
// processes. Since the setresXid() interface is well-defined, it shouldn’t be
|
||
// necessary to perform any additional checking anyway.
|
||
//
|
||
// TODO(mark): Drop CAP_SETUID and CAP_SETGID if present and non-root?
|
||
#else
|
||
#error Port this function to your system.
|
||
#endif
|
||
}
|
||
|
||
} // namespace crashpad
|