From 09fc6bcce8d5cf3a2ef4f9a7e79de8dcc07d3144 Mon Sep 17 00:00:00 2001 From: Mark Salyzyn Date: Mon, 16 May 2016 08:33:59 -0700 Subject: dumpstate: sscanf requires an asciiz string (cherry pick from commit 290f4b97bb736b0652eac9667965444393e683ec) Bug: 28770668 Change-Id: Ice56b129a243296b2691d55e8f8c35b478b1f481 --- cmds/dumpstate/utils.cpp | 93 ++++++++++++++++++++++++------------------------ 1 file changed, 46 insertions(+), 47 deletions(-) (limited to 'cmds/dumpstate/utils.cpp') diff --git a/cmds/dumpstate/utils.cpp b/cmds/dumpstate/utils.cpp index 09c2e7f74a..3c39129b14 100644 --- a/cmds/dumpstate/utils.cpp +++ b/cmds/dumpstate/utils.cpp @@ -38,6 +38,8 @@ #include #define LOG_TAG "dumpstate" + +#include #include #include #include @@ -1246,52 +1248,38 @@ time_t get_mtime(int fd, time_t default_mtime) { } void dump_emmc_ecsd(const char *ext_csd_path) { - static const size_t EXT_CSD_REV = 192; - static const size_t EXT_PRE_EOL_INFO = 267; - static const size_t EXT_DEVICE_LIFE_TIME_EST_TYP_A = 268; - static const size_t EXT_DEVICE_LIFE_TIME_EST_TYP_B = 269; + // List of interesting offsets struct hex { char str[2]; - } buffer[512]; - int fd, ext_csd_rev, ext_pre_eol_info; - ssize_t bytes_read; - static const char *ver_str[] = { - "4.0", "4.1", "4.2", "4.3", "Obsolete", "4.41", "4.5", "5.0" - }; - static const char *eol_str[] = { - "Undefined", - "Normal", - "Warning (consumed 80% of reserve)", - "Urgent (consumed 90% of reserve)" }; + static const size_t EXT_CSD_REV = 192 * sizeof(hex); + static const size_t EXT_PRE_EOL_INFO = 267 * sizeof(hex); + static const size_t EXT_DEVICE_LIFE_TIME_EST_TYP_A = 268 * sizeof(hex); + static const size_t EXT_DEVICE_LIFE_TIME_EST_TYP_B = 269 * sizeof(hex); - printf("------ %s Extended CSD ------\n", ext_csd_path); - - fd = TEMP_FAILURE_RETRY(open(ext_csd_path, - O_RDONLY | O_NONBLOCK | O_CLOEXEC)); - if (fd < 0) { - printf("*** %s: %s\n\n", ext_csd_path, strerror(errno)); + std::string buffer; + if (!android::base::ReadFileToString(ext_csd_path, &buffer)) { return; } - bytes_read = TEMP_FAILURE_RETRY(read(fd, buffer, sizeof(buffer))); - close(fd); - if (bytes_read < 0) { - printf("*** %s: %s\n\n", ext_csd_path, strerror(errno)); - return; - } - if (bytes_read < (ssize_t)(EXT_CSD_REV * sizeof(struct hex))) { - printf("*** %s: truncated content %zd\n\n", ext_csd_path, bytes_read); + printf("------ %s Extended CSD ------\n", ext_csd_path); + + if (buffer.length() < (EXT_CSD_REV + sizeof(hex))) { + printf("*** %s: truncated content %zu\n\n", ext_csd_path, buffer.length()); return; } - ext_csd_rev = 0; - if (sscanf(buffer[EXT_CSD_REV].str, "%02x", &ext_csd_rev) != 1) { - printf("*** %s: EXT_CSD_REV parse error \"%.2s\"\n\n", - ext_csd_path, buffer[EXT_CSD_REV].str); + int ext_csd_rev = 0; + std::string sub = buffer.substr(EXT_CSD_REV, sizeof(hex)); + if (sscanf(sub.c_str(), "%2x", &ext_csd_rev) != 1) { + printf("*** %s: EXT_CSD_REV parse error \"%s\"\n\n", + ext_csd_path, sub.c_str()); return; } + static const char *ver_str[] = { + "4.0", "4.1", "4.2", "4.3", "Obsolete", "4.41", "4.5", "5.0" + }; printf("rev 1.%d (MMC %s)\n", ext_csd_rev, (ext_csd_rev < (int)(sizeof(ver_str) / sizeof(ver_str[0]))) ? @@ -1302,17 +1290,25 @@ void dump_emmc_ecsd(const char *ext_csd_path) { return; } - if (bytes_read < (ssize_t)(EXT_PRE_EOL_INFO * sizeof(struct hex))) { - printf("*** %s: truncated content %zd\n\n", ext_csd_path, bytes_read); + if (buffer.length() < (EXT_PRE_EOL_INFO + sizeof(hex))) { + printf("*** %s: truncated content %zu\n\n", ext_csd_path, buffer.length()); return; } - ext_pre_eol_info = 0; - if (sscanf(buffer[EXT_PRE_EOL_INFO].str, "%02x", &ext_pre_eol_info) != 1) { - printf("*** %s: PRE_EOL_INFO parse error \"%.2s\"\n\n", - ext_csd_path, buffer[EXT_PRE_EOL_INFO].str); + int ext_pre_eol_info = 0; + sub = buffer.substr(EXT_PRE_EOL_INFO, sizeof(hex)); + if (sscanf(sub.c_str(), "%2x", &ext_pre_eol_info) != 1) { + printf("*** %s: PRE_EOL_INFO parse error \"%s\"\n\n", + ext_csd_path, sub.c_str()); return; } + + static const char *eol_str[] = { + "Undefined", + "Normal", + "Warning (consumed 80% of reserve)", + "Urgent (consumed 90% of reserve)" + }; printf("PRE_EOL_INFO %d (MMC %s)\n", ext_pre_eol_info, eol_str[(ext_pre_eol_info < (int) @@ -1321,7 +1317,7 @@ void dump_emmc_ecsd(const char *ext_csd_path) { for (size_t lifetime = EXT_DEVICE_LIFE_TIME_EST_TYP_A; lifetime <= EXT_DEVICE_LIFE_TIME_EST_TYP_B; - ++lifetime) { + lifetime += sizeof(hex)) { int ext_device_life_time_est; static const char *est_str[] = { "Undefined", @@ -1338,21 +1334,24 @@ void dump_emmc_ecsd(const char *ext_csd_path) { "Exceeded the maximum estimated device lifetime", }; - if (bytes_read < (ssize_t)(lifetime * sizeof(struct hex))) { - printf("*** %s: truncated content %zd\n", ext_csd_path, bytes_read); + if (buffer.length() < (lifetime + sizeof(hex))) { + printf("*** %s: truncated content %zu\n", ext_csd_path, buffer.length()); break; } ext_device_life_time_est = 0; - if (sscanf(buffer[lifetime].str, "%02x", &ext_device_life_time_est) != 1) { - printf("*** %s: DEVICE_LIFE_TIME_EST_TYP_%c parse error \"%.2s\"\n", + sub = buffer.substr(lifetime, sizeof(hex)); + if (sscanf(sub.c_str(), "%2x", &ext_device_life_time_est) != 1) { + printf("*** %s: DEVICE_LIFE_TIME_EST_TYP_%c parse error \"%s\"\n", ext_csd_path, - (unsigned)(lifetime - EXT_DEVICE_LIFE_TIME_EST_TYP_A) + 'A', - buffer[lifetime].str); + (unsigned)((lifetime - EXT_DEVICE_LIFE_TIME_EST_TYP_A) / + sizeof(hex)) + 'A', + sub.c_str()); continue; } printf("DEVICE_LIFE_TIME_EST_TYP_%c %d (MMC %s)\n", - (unsigned)(lifetime - EXT_DEVICE_LIFE_TIME_EST_TYP_A) + 'A', + (unsigned)((lifetime - EXT_DEVICE_LIFE_TIME_EST_TYP_A) / + sizeof(hex)) + 'A', ext_device_life_time_est, est_str[(ext_device_life_time_est < (int) (sizeof(est_str) / sizeof(est_str[0]))) ? -- cgit v1.2.3-59-g8ed1b From 02b7e00c1e1b0bf22997ab7ed913a9451e5b6b8a Mon Sep 17 00:00:00 2001 From: Felipe Leme Date: Fri, 22 Jul 2016 12:03:20 -0700 Subject: Added a -p option to bugreportz to show progress. BUG: 28609499 Change-Id: I1e60078dfda7e5679fbd19f4981a5dc7a69c4fc7 --- cmds/bugreportz/bugreportz.cpp | 43 +++++++++++++++++++++++++------------ cmds/bugreportz/bugreportz.h | 2 +- cmds/bugreportz/bugreportz_test.cpp | 34 ++++++++++++++++++++++++----- cmds/bugreportz/main.cpp | 16 +++++++------- cmds/bugreportz/readme.md | 5 +++++ cmds/dumpstate/dumpstate.cpp | 11 +++++----- cmds/dumpstate/dumpstate.h | 2 +- cmds/dumpstate/utils.cpp | 5 +++++ 8 files changed, 84 insertions(+), 34 deletions(-) (limited to 'cmds/dumpstate/utils.cpp') diff --git a/cmds/bugreportz/bugreportz.cpp b/cmds/bugreportz/bugreportz.cpp index 4b81c910dc..7bed2840f9 100644 --- a/cmds/bugreportz/bugreportz.cpp +++ b/cmds/bugreportz/bugreportz.cpp @@ -20,9 +20,27 @@ #include #include +#include + +#include +#include + #include "bugreportz.h" -int bugreportz(int s) { +static constexpr char PROGRESS_PREFIX[] = "PROGRESS:"; + +static void write_line(const std::string& line, bool show_progress) { + if (line.empty()) return; + + // When not invoked with the -p option, it must skip PROGRESS lines otherwise it + // will break adb (which is expecting either OK or FAIL). + if (!show_progress && android::base::StartsWith(line, PROGRESS_PREFIX)) return; + + android::base::WriteStringToFd(line, STDOUT_FILENO); +} + +int bugreportz(int s, bool show_progress) { + std::string line; while (1) { char buffer[65536]; ssize_t bytes_read = TEMP_FAILURE_RETRY(read(s, buffer, sizeof(buffer))); @@ -37,21 +55,18 @@ int bugreportz(int s) { break; } - ssize_t bytes_to_send = bytes_read; - ssize_t bytes_written; - do { - bytes_written = TEMP_FAILURE_RETRY( - write(STDOUT_FILENO, buffer + bytes_read - bytes_to_send, bytes_to_send)); - if (bytes_written == -1) { - fprintf(stderr, - "Failed to write data to stdout: read %zd, trying to send %zd " - "(%s)\n", - bytes_read, bytes_to_send, strerror(errno)); - break; + // Writes line by line. + for (int i = 0; i < bytes_read; i++) { + char c = buffer[i]; + line.append(1, c); + if (c == '\n') { + write_line(line, show_progress); + line.clear(); } - bytes_to_send -= bytes_written; - } while (bytes_written != 0 && bytes_to_send > 0); + } } + // Process final line, in case it didn't finish with newline + write_line(line, show_progress); if (close(s) == -1) { fprintf(stderr, "WARNING: error closing socket: %s\n", strerror(errno)); diff --git a/cmds/bugreportz/bugreportz.h b/cmds/bugreportz/bugreportz.h index d2b79b92f4..304e4b3dc3 100644 --- a/cmds/bugreportz/bugreportz.h +++ b/cmds/bugreportz/bugreportz.h @@ -16,6 +16,6 @@ #define BUGREPORTZ_H // Calls dumpstate using the given socket and output its result to stdout. -int bugreportz(int s); +int bugreportz(int s, bool show_progress); #endif // BUGREPORTZ_H diff --git a/cmds/bugreportz/bugreportz_test.cpp b/cmds/bugreportz/bugreportz_test.cpp index fb6cdc76e5..dfef17f590 100644 --- a/cmds/bugreportz/bugreportz_test.cpp +++ b/cmds/bugreportz/bugreportz_test.cpp @@ -70,12 +70,12 @@ class BugreportzTest : public ::testing::Test { // Tests must call WriteToSocket() to set what's written prior to calling it, since the writing // end of the pipe will be closed before calling bugreportz() (otherwise that function would // hang). - void Bugreportz() { + void Bugreportz(bool show_progress) { close(write_fd_); write_fd_ = -1; CaptureStdout(); - int status = bugreportz(read_fd_); + int status = bugreportz(read_fd_, show_progress); close(read_fd_); read_fd_ = -1; @@ -90,12 +90,36 @@ class BugreportzTest : public ::testing::Test { std::string stdout_; }; -// Tests 'bugreportz', without any argument - it will just echo dumpstate's output to stdout. +// Tests 'bugreportz', without any argument - it will ignore progress lines. TEST_F(BugreportzTest, NoArgument) { WriteToSocket("What happens on 'dumpstate',"); WriteToSocket("stays on 'bugreportz'.\n"); + WriteToSocket("PROGRESS:Y U NO OMITTED?\n"); // Should be ommited. + WriteToSocket("But "); + WriteToSocket("PROGRESS IN THE MIDDLE"); // Ok - not starting a line. + WriteToSocket(" is accepted\n"); - Bugreportz(); + Bugreportz(false); - AssertStdoutEquals("What happens on 'dumpstate',stays on 'bugreportz'.\n"); + AssertStdoutEquals( + "What happens on 'dumpstate',stays on 'bugreportz'.\n" + "But PROGRESS IN THE MIDDLE is accepted\n"); +} + +// Tests 'bugreportz -p' - it will just echo dumpstate's output to stdout +TEST_F(BugreportzTest, WithProgress) { + WriteToSocket("What happens on 'dumpstate',"); + WriteToSocket("stays on 'bugreportz'.\n"); + WriteToSocket("PROGRESS:IS INEVITABLE\n"); + WriteToSocket("PROG"); + WriteToSocket("RESS:IS NOT AUTOMATIC\n"); + WriteToSocket("Newline is optional"); + + Bugreportz(true); + + AssertStdoutEquals( + "What happens on 'dumpstate',stays on 'bugreportz'.\n" + "PROGRESS:IS INEVITABLE\n" + "PROGRESS:IS NOT AUTOMATIC\n" + "Newline is optional"); } diff --git a/cmds/bugreportz/main.cpp b/cmds/bugreportz/main.cpp index 6fa33cc5ab..a3ae1ffa4d 100644 --- a/cmds/bugreportz/main.cpp +++ b/cmds/bugreportz/main.cpp @@ -26,12 +26,13 @@ #include "bugreportz.h" -static constexpr char VERSION[] = "1.0"; +static constexpr char VERSION[] = "1.1"; static void show_usage() { fprintf(stderr, "usage: bugreportz [-h | -v]\n" " -h: to display this help message\n" + " -p: display progress\n" " -v: to display the version\n" " or no arguments to generate a zipped bugreport\n"); } @@ -41,14 +42,18 @@ static void show_version() { } int main(int argc, char* argv[]) { + bool show_progress = false; if (argc > 1) { /* parse arguments */ int c; - while ((c = getopt(argc, argv, "vh")) != -1) { + while ((c = getopt(argc, argv, "hpv")) != -1) { switch (c) { case 'h': show_usage(); return EXIT_SUCCESS; + case 'p': + show_progress = true; + break; case 'v': show_version(); return EXIT_SUCCESS; @@ -57,11 +62,6 @@ int main(int argc, char* argv[]) { return EXIT_FAILURE; } } - // passed an argument not starting with - - if (optind > 1 || argv[optind] != nullptr) { - show_usage(); - return EXIT_FAILURE; - } } // TODO: code below was copy-and-pasted from bugreport.cpp (except by the @@ -95,5 +95,5 @@ int main(int argc, char* argv[]) { fprintf(stderr, "WARNING: Cannot set socket timeout: %s\n", strerror(errno)); } - bugreportz(s); + bugreportz(s, show_progress); } diff --git a/cmds/bugreportz/readme.md b/cmds/bugreportz/readme.md index 85aafcefe4..2bc277e708 100644 --- a/cmds/bugreportz/readme.md +++ b/cmds/bugreportz/readme.md @@ -3,6 +3,11 @@ `bugreportz` is used to generate a zippped bugreport whose path is passed back to `adb`, using the simple protocol defined below. +# Version 1.1 +On version 1.1, in addition to the `OK` and `FAILURE` lines, `bugreportz -p` generates progress +lines in the following format: + +- `PROGRESS:/`, where `` is the current progress units out of a max of ``. ## Version 1.0 On version 1.0, `bugreportz` does not generate any output on `stdout` until the bugreport is diff --git a/cmds/dumpstate/dumpstate.cpp b/cmds/dumpstate/dumpstate.cpp index 279c01030c..f74fe399d9 100644 --- a/cmds/dumpstate/dumpstate.cpp +++ b/cmds/dumpstate/dumpstate.cpp @@ -61,7 +61,7 @@ static time_t now; static std::unique_ptr zip_writer; static std::set mount_points; void add_mountinfo(); -static int control_socket_fd; +int control_socket_fd = -1; /* suffix of the bugreport files - it's typically the date (when invoked with -d), * although it could be changed by the user using a system property */ static std::string suffix; @@ -1196,6 +1196,7 @@ int main(int argc, char *argv[]) { if (use_control_socket) { MYLOGD("Opening control socket\n"); control_socket_fd = open_socket("dumpstate"); + do_update_progress = 1; } /* full path of the temporary file containing the bugreport */ @@ -1268,7 +1269,7 @@ int main(int argc, char *argv[]) { add_text_zip_entry("version.txt", version); } - if (do_update_progress) { + if (do_update_progress && do_broadcast) { std::vector am_args = { "--receiver-permission", "android.permission.DUMP", "--receiver-foreground", "--es", "android.intent.extra.NAME", suffix, @@ -1492,9 +1493,9 @@ int main(int argc, char *argv[]) { fclose(stderr); } - if (use_control_socket && control_socket_fd >= 0) { - MYLOGD("Closing control socket\n"); - close(control_socket_fd); + if (use_control_socket && control_socket_fd != -1) { + MYLOGD("Closing control socket\n"); + close(control_socket_fd); } return 0; diff --git a/cmds/dumpstate/dumpstate.h b/cmds/dumpstate/dumpstate.h index 4769974e0d..5e083cc002 100644 --- a/cmds/dumpstate/dumpstate.h +++ b/cmds/dumpstate/dumpstate.h @@ -79,7 +79,7 @@ static const int WEIGHT_FILE = 5; * It would be better to take advantage of the C++ migration and encapsulate the state in an object, * but that will be better handled in a major C++ refactoring, which would also get rid of other C * idioms (like using std::string instead of char*, removing varargs, etc...) */ -extern int do_update_progress, progress, weight_total; +extern int do_update_progress, progress, weight_total, control_socket_fd; /* full path of the directory where the bugreport files will be written */ extern std::string bugreport_dir; diff --git a/cmds/dumpstate/utils.cpp b/cmds/dumpstate/utils.cpp index 3c39129b14..fd6413d562 100644 --- a/cmds/dumpstate/utils.cpp +++ b/cmds/dumpstate/utils.cpp @@ -1214,6 +1214,11 @@ void update_progress(int delta) { fprintf(stderr, "Setting progress (%s): %s/%d\n", key, value, weight_total); } + if (control_socket_fd >= 0) { + dprintf(control_socket_fd, "PROGRESS:%d/%d\n", progress, weight_total); + fsync(control_socket_fd); + } + int status = property_set(key, value); if (status) { MYLOGE("Could not update progress by setting system property %s to %s: %d\n", -- cgit v1.2.3-59-g8ed1b From f87959e00732d7d737527f1248a71adea99ae29d Mon Sep 17 00:00:00 2001 From: Wei Liu Date: Fri, 26 Aug 2016 14:51:42 -0700 Subject: Dumpstate should hold a wakelock to save bug report time. b/30832947 Change-Id: I0a4b1fcce91caa96ccbc4e890d9968e3033487de --- cmds/dumpstate/Android.mk | 2 +- cmds/dumpstate/dumpstate.cpp | 41 +++++++++++++++++++++++++++++++++-------- cmds/dumpstate/utils.cpp | 8 +++++--- 3 files changed, 39 insertions(+), 12 deletions(-) (limited to 'cmds/dumpstate/utils.cpp') diff --git a/cmds/dumpstate/Android.mk b/cmds/dumpstate/Android.mk index 791a7c4a61..7a9f9adcb3 100644 --- a/cmds/dumpstate/Android.mk +++ b/cmds/dumpstate/Android.mk @@ -14,7 +14,7 @@ LOCAL_SRC_FILES := dumpstate.cpp utils.cpp LOCAL_MODULE := dumpstate -LOCAL_SHARED_LIBRARIES := libcutils liblog libselinux libbase +LOCAL_SHARED_LIBRARIES := libcutils liblog libselinux libbase libhardware_legacy # ZipArchive support, the order matters here to get all symbols. LOCAL_STATIC_LIBRARIES := libziparchive libz libmincrypt LOCAL_HAL_STATIC_LIBRARIES := libdumpstate diff --git a/cmds/dumpstate/dumpstate.cpp b/cmds/dumpstate/dumpstate.cpp index 17d44d2743..97dfd92e78 100644 --- a/cmds/dumpstate/dumpstate.cpp +++ b/cmds/dumpstate/dumpstate.cpp @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include @@ -37,6 +38,7 @@ #include #include #include +#include #include "private/android_filesystem_config.h" @@ -82,6 +84,7 @@ static std::string suffix; #define TOMBSTONE_MAX_LEN (sizeof(TOMBSTONE_FILE_PREFIX) + 4) #define NUM_TOMBSTONES 10 #define WLUTIL "/vendor/xbin/wlutil" +#define WAKE_LOCK_NAME "dumpstate_wakelock" typedef struct { char name[TOMBSTONE_MAX_LEN]; @@ -1147,11 +1150,31 @@ static void usage() { VERSION_DEFAULT.c_str()); } -static void sigpipe_handler(int n) { - // don't complain to stderr or stdout +static void wake_lock_releaser() { + if (release_wake_lock(WAKE_LOCK_NAME) < 0) { + MYLOGE("Failed to release wake lock: %s \n", strerror(errno)); + } else { + MYLOGD("Wake lock released.\n"); + } +} + +static void sig_handler(int signo) { + wake_lock_releaser(); _exit(EXIT_FAILURE); } +static void register_sig_handler() { + struct sigaction sa; + sigemptyset(&sa.sa_mask); + sa.sa_flags = 0; + sa.sa_handler = sig_handler; + sigaction(SIGPIPE, &sa, NULL); // broken pipe + sigaction(SIGSEGV, &sa, NULL); // segment fault + sigaction(SIGINT, &sa, NULL); // ctrl-c + sigaction(SIGTERM, &sa, NULL); // killed + sigaction(SIGQUIT, &sa, NULL); // quit +} + /* adds the temporary report to the existing .zip file, closes the .zip file, and removes the temporary file. */ @@ -1219,7 +1242,6 @@ static std::string SHA256_file_hash(std::string filepath) { } int main(int argc, char *argv[]) { - struct sigaction sigact; int do_add_date = 0; int do_zip_file = 0; int do_vibrate = 1; @@ -1236,6 +1258,14 @@ int main(int argc, char *argv[]) { MYLOGI("begin\n"); + if (acquire_wake_lock(PARTIAL_WAKE_LOCK, WAKE_LOCK_NAME) < 0) { + MYLOGE("Failed to acquire wake lock: %s \n", strerror(errno)); + } else { + MYLOGD("Wake lock acquired.\n"); + atexit(wake_lock_releaser); + register_sig_handler(); + } + /* gets the sequential id */ char last_id[PROPERTY_VALUE_MAX]; property_get("dumpstate.last_id", last_id, "0"); @@ -1244,11 +1274,6 @@ int main(int argc, char *argv[]) { property_set("dumpstate.last_id", last_id); MYLOGI("dumpstate id: %lu\n", id); - /* clear SIGPIPE handler */ - memset(&sigact, 0, sizeof(sigact)); - sigact.sa_handler = sigpipe_handler; - sigaction(SIGPIPE, &sigact, NULL); - /* set as high priority, and protect from OOM killer */ setpriority(PRIO_PROCESS, 0, -20); diff --git a/cmds/dumpstate/utils.cpp b/cmds/dumpstate/utils.cpp index fd6413d562..1035cde9d4 100644 --- a/cmds/dumpstate/utils.cpp +++ b/cmds/dumpstate/utils.cpp @@ -828,7 +828,7 @@ bool drop_root_user() { } gid_t groups[] = { AID_LOG, AID_SDCARD_R, AID_SDCARD_RW, - AID_MOUNT, AID_INET, AID_NET_BW_STATS, AID_READPROC }; + AID_MOUNT, AID_INET, AID_NET_BW_STATS, AID_READPROC, AID_WAKELOCK }; if (setgroups(sizeof(groups)/sizeof(groups[0]), groups) != 0) { MYLOGE("Unable to setgroups, aborting: %s\n", strerror(errno)); return false; @@ -849,8 +849,10 @@ bool drop_root_user() { capheader.version = _LINUX_CAPABILITY_VERSION_3; capheader.pid = 0; - capdata[CAP_TO_INDEX(CAP_SYSLOG)].permitted = CAP_TO_MASK(CAP_SYSLOG); - capdata[CAP_TO_INDEX(CAP_SYSLOG)].effective = CAP_TO_MASK(CAP_SYSLOG); + capdata[CAP_TO_INDEX(CAP_SYSLOG)].permitted = + (CAP_TO_MASK(CAP_SYSLOG) | CAP_TO_MASK(CAP_BLOCK_SUSPEND)); + capdata[CAP_TO_INDEX(CAP_SYSLOG)].effective = + (CAP_TO_MASK(CAP_SYSLOG) | CAP_TO_MASK(CAP_BLOCK_SUSPEND)); capdata[0].inheritable = 0; capdata[1].inheritable = 0; -- cgit v1.2.3-59-g8ed1b