Make sure logs are always ended with newline

This commit is contained in:
topjohnwu 2022-09-09 04:29:50 -07:00
parent 44029875a6
commit a66a3b7438
19 changed files with 76 additions and 47 deletions

View File

@ -146,6 +146,8 @@ int sigemptyset(sigset_t *set) {
return 0; return 0;
} }
#undef vsnprintf
#undef snprintf
#include "fortify.hpp" #include "fortify.hpp"
#endif #endif

View File

@ -10,7 +10,7 @@
using namespace std; using namespace std;
ssize_t fd_path(int fd, char *path, size_t size) { ssize_t fd_path(int fd, char *path, size_t size) {
snprintf(path, size, "/proc/self/fd/%d", fd); ssprintf(path, size, "/proc/self/fd/%d", fd);
return xreadlink(path, path, size); return xreadlink(path, path, size);
} }

View File

@ -13,7 +13,7 @@ using namespace std;
static int fmt_and_log_with_rs(LogLevel level, const char *fmt, va_list ap) { static int fmt_and_log_with_rs(LogLevel level, const char *fmt, va_list ap) {
char buf[4096]; char buf[4096];
int ret = vsnprintf(buf, sizeof(buf), fmt, ap); int ret = vssprintf(buf, sizeof(buf), fmt, ap);
log_with_rs(level, rust::Str(buf, ret)); log_with_rs(level, rust::Str(buf, ret));
return ret; return ret;
} }
@ -41,10 +41,15 @@ extern "C" int magisk_log_print(int prio, const char *tag, const char *fmt, ...)
} }
char fmt_buf[4096]; char fmt_buf[4096];
auto len = strlcpy(fmt_buf, tag, sizeof(fmt_buf)); auto len = strlcpy(fmt_buf, tag, sizeof(fmt_buf) - 1);
// Prevent format specifications in the tag // Prevent format specifications in the tag
std::replace(fmt_buf, fmt_buf + len, '%', '_'); std::replace(fmt_buf, fmt_buf + len, '%', '_');
snprintf(fmt_buf + len, sizeof(fmt_buf) - len, ": %s", fmt); len = ssprintf(fmt_buf + len, sizeof(fmt_buf) - len - 1, ": %s", fmt) + len;
// Ensure the fmt string always ends with newline
if (fmt_buf[len - 1] != '\n') {
fmt_buf[len] = '\n';
fmt_buf[len + 1] = '\0';
}
va_list argv; va_list argv;
va_start(argv, fmt); va_start(argv, fmt);
int ret = cpp_logger(level, fmt_buf, argv); int ret = cpp_logger(level, fmt_buf, argv);

View File

@ -168,7 +168,7 @@ uint32_t binary_gcd(uint32_t u, uint32_t v) {
int switch_mnt_ns(int pid) { int switch_mnt_ns(int pid) {
char mnt[32]; char mnt[32];
snprintf(mnt, sizeof(mnt), "/proc/%d/ns/mnt", pid); ssprintf(mnt, sizeof(mnt), "/proc/%d/ns/mnt", pid);
if (access(mnt, R_OK) == -1) return 1; // Maybe process died.. if (access(mnt, R_OK) == -1) return 1; // Maybe process died..
int fd, ret; int fd, ret;
@ -211,3 +211,16 @@ vector<string> split(const string &s, const string &delims) {
vector<string_view> split_ro(string_view s, string_view delims) { vector<string_view> split_ro(string_view s, string_view delims) {
return split_impl<string_view>(s, delims); return split_impl<string_view>(s, delims);
} }
#undef vsnprintf
int vssprintf(char *dest, size_t size, const char *fmt, va_list ap) {
return std::min(vsnprintf(dest, size, fmt, ap), (int) size - 1);
}
int ssprintf(char *dest, size_t size, const char *fmt, ...) {
va_list va;
va_start(va, fmt);
int r = vssprintf(dest, size, fmt, va);
va_end(va);
return r;
}

View File

@ -156,6 +156,15 @@ std::string &replace_all(std::string &str, std::string_view from, std::string_vi
std::vector<std::string> split(const std::string &s, const std::string &delims); std::vector<std::string> split(const std::string &s, const std::string &delims);
std::vector<std::string_view> split_ro(std::string_view, std::string_view delims); std::vector<std::string_view> split_ro(std::string_view, std::string_view delims);
// Similar to vsnprintf, but the return value is the written number of bytes
int vssprintf(char *dest, size_t size, const char *fmt, va_list ap);
// Similar to snprintf, but the return value is the written number of bytes
int ssprintf(char *dest, size_t size, const char *fmt, ...);
// Ban usage of unsafe cstring functions
#define vsnprintf __use_vssprintf_instead__
#define snprintf __use_ssprintf_instead__
struct exec_t { struct exec_t {
bool err = false; bool err = false;
int fd = -2; int fd = -2;

View File

@ -26,8 +26,8 @@ bool zygisk_enabled = false;
#define MNT_DIR_IS(dir) (me->mnt_dir == string_view(dir)) #define MNT_DIR_IS(dir) (me->mnt_dir == string_view(dir))
#define MNT_TYPE_IS(type) (me->mnt_type == string_view(type)) #define MNT_TYPE_IS(type) (me->mnt_type == string_view(type))
#define SETMIR(b, part) snprintf(b, sizeof(b), "%s/" MIRRDIR "/" #part, MAGISKTMP.data()) #define SETMIR(b, part) ssprintf(b, sizeof(b), "%s/" MIRRDIR "/" #part, MAGISKTMP.data())
#define SETBLK(b, part) snprintf(b, sizeof(b), "%s/" BLOCKDIR "/" #part, MAGISKTMP.data()) #define SETBLK(b, part) ssprintf(b, sizeof(b), "%s/" BLOCKDIR "/" #part, MAGISKTMP.data())
#define do_mount_mirror(part) { \ #define do_mount_mirror(part) { \
SETMIR(buf1, part); \ SETMIR(buf1, part); \

View File

@ -286,13 +286,13 @@ done:
static void switch_cgroup(const char *cgroup, int pid) { static void switch_cgroup(const char *cgroup, int pid) {
char buf[32]; char buf[32];
snprintf(buf, sizeof(buf), "%s/cgroup.procs", cgroup); ssprintf(buf, sizeof(buf), "%s/cgroup.procs", cgroup);
if (access(buf, F_OK) != 0) if (access(buf, F_OK) != 0)
return; return;
int fd = xopen(buf, O_WRONLY | O_APPEND | O_CLOEXEC); int fd = xopen(buf, O_WRONLY | O_APPEND | O_CLOEXEC);
if (fd == -1) if (fd == -1)
return; return;
snprintf(buf, sizeof(buf), "%d\n", pid); ssprintf(buf, sizeof(buf), "%d\n", pid);
xwrite(fd, buf, strlen(buf)); xwrite(fd, buf, strlen(buf));
close(fd); close(fd);
} }

View File

@ -332,7 +332,7 @@ int get_db_settings(db_settings &cfg, int key) {
}; };
if (key >= 0) { if (key >= 0) {
char query[128]; char query[128];
snprintf(query, sizeof(query), "SELECT * FROM settings WHERE key='%s'", DB_SETTING_KEYS[key]); ssprintf(query, sizeof(query), "SELECT * FROM settings WHERE key='%s'", DB_SETTING_KEYS[key]);
err = db_exec(query, settings_cb); err = db_exec(query, settings_cb);
} else { } else {
err = db_exec("SELECT * FROM settings", settings_cb); err = db_exec("SELECT * FROM settings", settings_cb);
@ -350,7 +350,7 @@ int get_db_strings(db_strings &str, int key) {
}; };
if (key >= 0) { if (key >= 0) {
char query[128]; char query[128];
snprintf(query, sizeof(query), "SELECT * FROM strings WHERE key='%s'", DB_STRING_KEYS[key]); ssprintf(query, sizeof(query), "SELECT * FROM strings WHERE key='%s'", DB_STRING_KEYS[key]);
err = db_exec(query, string_cb); err = db_exec(query, string_cb);
} else { } else {
err = db_exec("SELECT * FROM strings", string_cb); err = db_exec("SELECT * FROM strings", string_cb);
@ -362,7 +362,7 @@ int get_db_strings(db_strings &str, int key) {
void rm_db_strings(int key) { void rm_db_strings(int key) {
char *err; char *err;
char query[128]; char query[128];
snprintf(query, sizeof(query), "DELETE FROM strings WHERE key == '%s'", DB_STRING_KEYS[key]); ssprintf(query, sizeof(query), "DELETE FROM strings WHERE key == '%s'", DB_STRING_KEYS[key]);
err = db_exec(query); err = db_exec(query);
db_err_cmd(err, return); db_err_cmd(err, return);
} }

View File

@ -114,7 +114,7 @@ static void *logfile_writer(void *arg) {
} }
long ms = tv.tv_usec / 1000; long ms = tv.tv_usec / 1000;
size_t off = strftime(aux, sizeof(aux), "%m-%d %T", &tm); size_t off = strftime(aux, sizeof(aux), "%m-%d %T", &tm);
off += snprintf(aux + off, sizeof(aux) - off, off += ssprintf(aux + off, sizeof(aux) - off,
".%03ld %5d %5d %c : ", ms, meta.pid, meta.tid, type); ".%03ld %5d %5d %c : ", ms, meta.pid, meta.tid, type);
iov[0].iov_len = off; iov[0].iov_len = off;

View File

@ -100,7 +100,7 @@ int get_manager(int user_id, string *pkg, bool install) {
auto check_dyn = [&](int u) -> bool { auto check_dyn = [&](int u) -> bool {
#if ENFORCE_SIGNATURE #if ENFORCE_SIGNATURE
snprintf(app_path, sizeof(app_path), ssprintf(app_path, sizeof(app_path),
"%s/%d/%s/dyn/current.apk", APP_DATA_DIR, u, mgr_pkg->data()); "%s/%d/%s/dyn/current.apk", APP_DATA_DIR, u, mgr_pkg->data());
int dyn = open(app_path, O_RDONLY | O_CLOEXEC); int dyn = open(app_path, O_RDONLY | O_CLOEXEC);
if (dyn < 0) { if (dyn < 0) {
@ -124,7 +124,7 @@ int get_manager(int user_id, string *pkg, bool install) {
} }
// Just need to check whether the app is installed in the user // Just need to check whether the app is installed in the user
const char *name = mgr_pkg->empty() ? JAVA_PACKAGE_NAME : mgr_pkg->data(); const char *name = mgr_pkg->empty() ? JAVA_PACKAGE_NAME : mgr_pkg->data();
snprintf(app_path, sizeof(app_path), "%s/%d/%s", APP_DATA_DIR, user_id, name); ssprintf(app_path, sizeof(app_path), "%s/%d/%s", APP_DATA_DIR, user_id, name);
if (access(app_path, F_OK) == 0) { if (access(app_path, F_OK) == 0) {
// Always check dyn signature for repackaged app // Always check dyn signature for repackaged app
if (!mgr_pkg->empty() && !check_dyn(user_id)) if (!mgr_pkg->empty() && !check_dyn(user_id))
@ -165,7 +165,7 @@ int get_manager(int user_id, string *pkg, bool install) {
bool invalid = false; bool invalid = false;
auto check_pkg = [&](int u) -> bool { auto check_pkg = [&](int u) -> bool {
snprintf(app_path, sizeof(app_path), ssprintf(app_path, sizeof(app_path),
"%s/%d/%s", APP_DATA_DIR, u, str[SU_MANAGER].data()); "%s/%d/%s", APP_DATA_DIR, u, str[SU_MANAGER].data());
if (stat(app_path, &st) == 0) { if (stat(app_path, &st) == 0) {
int app_id = to_app_id(st.st_uid); int app_id = to_app_id(st.st_uid);
@ -223,7 +223,7 @@ int get_manager(int user_id, string *pkg, bool install) {
bool invalid = false; bool invalid = false;
auto check_pkg = [&](int u) -> bool { auto check_pkg = [&](int u) -> bool {
snprintf(app_path, sizeof(app_path), "%s/%d/" JAVA_PACKAGE_NAME, APP_DATA_DIR, u); ssprintf(app_path, sizeof(app_path), "%s/%d/" JAVA_PACKAGE_NAME, APP_DATA_DIR, u);
if (stat(app_path, &st) == 0) { if (stat(app_path, &st) == 0) {
#if ENFORCE_SIGNATURE #if ENFORCE_SIGNATURE
string apk = find_apk_path(JAVA_PACKAGE_NAME); string apk = find_apk_path(JAVA_PACKAGE_NAME);

View File

@ -164,7 +164,7 @@ void install_apk(const char *apk) {
.fork = fork_no_orphan .fork = fork_no_orphan
}; };
char cmds[sizeof(install_script) + 4096]; char cmds[sizeof(install_script) + 4096];
snprintf(cmds, sizeof(cmds), install_script, apk, JAVA_PACKAGE_NAME); ssprintf(cmds, sizeof(cmds), install_script, apk, JAVA_PACKAGE_NAME);
exec_command_sync(exec, "/system/bin/sh", "-c", cmds); exec_command_sync(exec, "/system/bin/sh", "-c", cmds);
} }
@ -179,7 +179,7 @@ void uninstall_pkg(const char *pkg) {
.fork = fork_no_orphan .fork = fork_no_orphan
}; };
char cmds[sizeof(uninstall_script) + 256]; char cmds[sizeof(uninstall_script) + 256];
snprintf(cmds, sizeof(cmds), uninstall_script, pkg); ssprintf(cmds, sizeof(cmds), uninstall_script, pkg);
exec_command_sync(exec, "/system/bin/sh", "-c", cmds); exec_command_sync(exec, "/system/bin/sh", "-c", cmds);
} }
@ -195,7 +195,7 @@ void clear_pkg(const char *pkg, int user_id) {
.fork = fork_no_orphan .fork = fork_no_orphan
}; };
char cmds[sizeof(clear_script) + 288]; char cmds[sizeof(clear_script) + 288];
snprintf(cmds, sizeof(cmds), clear_script, pkg, user_id); ssprintf(cmds, sizeof(cmds), clear_script, pkg, user_id);
exec_command_sync(exec, "/system/bin/sh", "-c", cmds); exec_command_sync(exec, "/system/bin/sh", "-c", cmds);
} }

View File

@ -125,7 +125,7 @@ extern "C" void klog_write(const char *msg, int len) {
static int klog_with_rs(LogLevel level, const char *fmt, va_list ap) { static int klog_with_rs(LogLevel level, const char *fmt, va_list ap) {
char buf[4096]; char buf[4096];
strlcpy(buf, "magiskinit: ", sizeof(buf)); strlcpy(buf, "magiskinit: ", sizeof(buf));
int len = vsnprintf(buf + 12, sizeof(buf) - 12, fmt, ap) + 12; int len = vssprintf(buf + 12, sizeof(buf) - 12, fmt, ap) + 12;
log_with_rs(level, rust::Str(buf, len)); log_with_rs(level, rust::Str(buf, len));
return len; return len;
} }
@ -211,7 +211,7 @@ void BootConfig::print() {
} }
#define read_dt(name, key) \ #define read_dt(name, key) \
snprintf(file_name, sizeof(file_name), "%s/" name, config->dt_dir); \ ssprintf(file_name, sizeof(file_name), "%s/" name, config->dt_dir); \
if (access(file_name, R_OK) == 0) { \ if (access(file_name, R_OK) == 0) { \
string data = full_read(file_name); \ string data = full_read(file_name); \
if (!data.empty()) { \ if (!data.empty()) { \

View File

@ -71,7 +71,7 @@ bool MagiskInit::hijack_sepolicy() {
// This only happens on Android 8.0 - 9.0 // This only happens on Android 8.0 - 9.0
char buf[4096]; char buf[4096];
snprintf(buf, sizeof(buf), "%s/fstab/compatible", config->dt_dir); ssprintf(buf, sizeof(buf), "%s/fstab/compatible", config->dt_dir);
dt_compat = full_read(buf); dt_compat = full_read(buf);
if (dt_compat.empty()) { if (dt_compat.empty()) {
// Device does not do early mount and uses monolithic policy // Device does not do early mount and uses monolithic policy
@ -121,7 +121,7 @@ bool MagiskInit::hijack_sepolicy() {
int fd = xopen(MOCK_COMPAT, O_WRONLY); int fd = xopen(MOCK_COMPAT, O_WRONLY);
char buf[4096]; char buf[4096];
snprintf(buf, sizeof(buf), "%s/fstab/compatible", config->dt_dir); ssprintf(buf, sizeof(buf), "%s/fstab/compatible", config->dt_dir);
xumount2(buf, MNT_DETACH); xumount2(buf, MNT_DETACH);
hijack(); hijack();

View File

@ -142,7 +142,7 @@ static void pb_getprop(prop_cb *prop_cb) {
static bool file_getprop(const char *name, char *value) { static bool file_getprop(const char *name, char *value) {
char path[4096]; char path[4096];
snprintf(path, sizeof(path), PERSISTENT_PROPERTY_DIR "/%s", name); ssprintf(path, sizeof(path), PERSISTENT_PROPERTY_DIR "/%s", name);
int fd = open(path, O_RDONLY | O_CLOEXEC); int fd = open(path, O_RDONLY | O_CLOEXEC);
if (fd < 0) if (fd < 0)
return false; return false;
@ -230,7 +230,7 @@ bool persist_deleteprop(const char *name) {
return false; return false;
} else { } else {
char path[4096]; char path[4096];
snprintf(path, sizeof(path), PERSISTENT_PROPERTY_DIR "/%s", name); ssprintf(path, sizeof(path), PERSISTENT_PROPERTY_DIR "/%s", name);
if (unlink(path) == 0) { if (unlink(path) == 0) {
LOGD("resetprop: unlink [%s]\n", path); LOGD("resetprop: unlink [%s]\n", path);
return true; return true;

View File

@ -52,7 +52,7 @@ public:
switch (type) { switch (type) {
case INT: case INT:
vec.push_back("--ei"); vec.push_back("--ei");
snprintf(buf, sizeof(buf), "%d", int_val); ssprintf(buf, sizeof(buf), "%d", int_val);
str = buf; str = buf;
val = str.data(); val = str.data();
break; break;
@ -75,7 +75,7 @@ public:
switch (type) { switch (type) {
case INT: case INT:
str += ":i:"; str += ":i:";
snprintf(buf, sizeof(buf), "%d", int_val); ssprintf(buf, sizeof(buf), "%d", int_val);
str += buf; str += buf;
break; break;
case BOOL: case BOOL:
@ -114,13 +114,13 @@ static void exec_cmd(const char *action, vector<Extra> &data,
char exe[128]; char exe[128];
char target[128]; char target[128];
char user[4]; char user[4];
snprintf(user, sizeof(user), "%d", to_user_id(info->eval_uid)); ssprintf(user, sizeof(user), "%d", to_user_id(info->eval_uid));
if (zygisk_enabled) { if (zygisk_enabled) {
#if defined(__LP64__) #if defined(__LP64__)
snprintf(exe, sizeof(exe), "/proc/self/fd/%d", app_process_64); ssprintf(exe, sizeof(exe), "/proc/self/fd/%d", app_process_64);
#else #else
snprintf(exe, sizeof(exe), "/proc/self/fd/%d", app_process_32); ssprintf(exe, sizeof(exe), "/proc/self/fd/%d", app_process_32);
#endif #endif
} else { } else {
strlcpy(exe, "/system/bin/app_process", sizeof(exe)); strlcpy(exe, "/system/bin/app_process", sizeof(exe));
@ -128,7 +128,7 @@ static void exec_cmd(const char *action, vector<Extra> &data,
// First try content provider call method // First try content provider call method
if (provider) { if (provider) {
snprintf(target, sizeof(target), "content://%s.provider", info->mgr_pkg.data()); ssprintf(target, sizeof(target), "content://%s.provider", info->mgr_pkg.data());
vector<const char *> args{ CALL_PROVIDER }; vector<const char *> args{ CALL_PROVIDER };
for (auto &e : data) { for (auto &e : data) {
e.add_bind(args); e.add_bind(args);
@ -165,7 +165,7 @@ static void exec_cmd(const char *action, vector<Extra> &data,
// Finally, fallback to start activity with component name // Finally, fallback to start activity with component name
args[4] = "-n"; args[4] = "-n";
snprintf(target, sizeof(target), "%s/com.topjohnwu.magisk.ui.surequest.SuRequestActivity", info->mgr_pkg.data()); ssprintf(target, sizeof(target), "%s/com.topjohnwu.magisk.ui.surequest.SuRequestActivity", info->mgr_pkg.data());
exec.fd = -2; exec.fd = -2;
exec.fork = fork_dont_care; exec.fork = fork_dont_care;
exec_command(exec); exec_command(exec);

View File

@ -64,7 +64,7 @@ void su_info::check_db() {
if (eval_uid > 0) { if (eval_uid > 0) {
char query[256], *err; char query[256], *err;
snprintf(query, sizeof(query), ssprintf(query, sizeof(query),
"SELECT policy, logging, notification FROM policies " "SELECT policy, logging, notification FROM policies "
"WHERE uid=%d AND (until=0 OR until>%li)", eval_uid, time(nullptr)); "WHERE uid=%d AND (until=0 OR until>%li)", eval_uid, time(nullptr));
err = db_exec(query, [&](db_row &row) -> bool { err = db_exec(query, [&](db_row &row) -> bool {
@ -125,7 +125,7 @@ bool uid_granted_root(int uid) {
bool granted = false; bool granted = false;
char query[256], *err; char query[256], *err;
snprintf(query, sizeof(query), ssprintf(query, sizeof(query),
"SELECT policy FROM policies WHERE uid=%d AND (until=0 OR until>%li)", "SELECT policy FROM policies WHERE uid=%d AND (until=0 OR until>%li)",
uid, time(nullptr)); uid, time(nullptr));
err = db_exec(query, [&](db_row &row) -> bool { err = db_exec(query, [&](db_row &row) -> bool {
@ -158,7 +158,7 @@ void prune_su_access() {
db_err_cmd(err, return); db_err_cmd(err, return);
for (int uid : rm_uids) { for (int uid : rm_uids) {
snprintf(query, sizeof(query), "DELETE FROM policies WHERE uid == %d", uid); ssprintf(query, sizeof(query), "DELETE FROM policies WHERE uid == %d", uid);
// Don't care about errors // Don't care about errors
db_exec(query); db_exec(query);
} }
@ -410,11 +410,11 @@ void su_daemon_handler(int client, const sock_cred *cred) {
// Setup environment // Setup environment
umask(022); umask(022);
char path[32]; char path[32];
snprintf(path, sizeof(path), "/proc/%d/cwd", ctx.pid); ssprintf(path, sizeof(path), "/proc/%d/cwd", ctx.pid);
char cwd[PATH_MAX]; char cwd[PATH_MAX];
if (realpath(path, cwd)) if (realpath(path, cwd))
chdir(cwd); chdir(cwd);
snprintf(path, sizeof(path), "/proc/%d/environ", ctx.pid); ssprintf(path, sizeof(path), "/proc/%d/environ", ctx.pid);
auto env = full_read(path); auto env = full_read(path);
clearenv(); clearenv();
for (size_t pos = 0; pos < env.size(); ++pos) { for (size_t pos = 0; pos < env.size(); ++pos) {

View File

@ -71,7 +71,7 @@ static void update_pkg_uid(const string &pkg, bool remove) {
char buf[PATH_MAX] = {0}; char buf[PATH_MAX] = {0};
// For each user // For each user
while ((entry = xreaddir(data_dir.get()))) { while ((entry = xreaddir(data_dir.get()))) {
snprintf(buf, sizeof(buf), "%s/%s", entry->d_name, pkg.data()); ssprintf(buf, sizeof(buf), "%s/%s", entry->d_name, pkg.data());
if (fstatat(dirfd(data_dir.get()), buf, &st, 0) == 0) { if (fstatat(dirfd(data_dir.get()), buf, &st, 0) == 0) {
int app_id = to_app_id(st.st_uid); int app_id = to_app_id(st.st_uid);
if (remove) { if (remove) {
@ -242,7 +242,7 @@ static int add_list(const char *pkg, const char *proc) {
// Add to database // Add to database
char sql[4096]; char sql[4096];
snprintf(sql, sizeof(sql), ssprintf(sql, sizeof(sql),
"INSERT INTO denylist (package_name, process) VALUES('%s', '%s')", pkg, proc); "INSERT INTO denylist (package_name, process) VALUES('%s', '%s')", pkg, proc);
char *err = db_exec(sql); char *err = db_exec(sql);
db_err_cmd(err, return DenyResponse::ERROR) db_err_cmd(err, return DenyResponse::ERROR)
@ -286,9 +286,9 @@ static int rm_list(const char *pkg, const char *proc) {
char sql[4096]; char sql[4096];
if (proc[0] == '\0') if (proc[0] == '\0')
snprintf(sql, sizeof(sql), "DELETE FROM denylist WHERE package_name='%s'", pkg); ssprintf(sql, sizeof(sql), "DELETE FROM denylist WHERE package_name='%s'", pkg);
else else
snprintf(sql, sizeof(sql), ssprintf(sql, sizeof(sql),
"DELETE FROM denylist WHERE package_name='%s' AND process='%s'", pkg, proc); "DELETE FROM denylist WHERE package_name='%s' AND process='%s'", pkg, proc);
char *err = db_exec(sql); char *err = db_exec(sql);
db_err_cmd(err, return DenyResponse::ERROR) db_err_cmd(err, return DenyResponse::ERROR)

View File

@ -161,7 +161,7 @@ static vector<int> get_module_fds(bool is_64_bit) {
} }
static bool get_exe(int pid, char *buf, size_t sz) { static bool get_exe(int pid, char *buf, size_t sz) {
snprintf(buf, sz, "/proc/%d/exe", pid); ssprintf(buf, sz, "/proc/%d/exe", pid);
return xreadlink(buf, buf, sz) > 0; return xreadlink(buf, buf, sz) > 0;
} }
@ -191,7 +191,7 @@ static void connect_companion(int client, bool is_64_bit) {
// This fd has to survive exec // This fd has to survive exec
fcntl(fds[1], F_SETFD, 0); fcntl(fds[1], F_SETFD, 0);
char buf[16]; char buf[16];
snprintf(buf, sizeof(buf), "%d", fds[1]); ssprintf(buf, sizeof(buf), "%d", fds[1]);
execl(exe.data(), "", "zygisk", "companion", buf, (char *) nullptr); execl(exe.data(), "", "zygisk", "companion", buf, (char *) nullptr);
exit(-1); exit(-1);
} }
@ -340,7 +340,7 @@ static void get_process_info(int client, const sock_cred *cred) {
if (!as_const(bits)[id]) { if (!as_const(bits)[id]) {
// Either not a zygisk module, or incompatible // Either not a zygisk module, or incompatible
char buf[4096]; char buf[4096];
snprintf(buf, sizeof(buf), MODULEROOT "/%s/zygisk", ssprintf(buf, sizeof(buf), MODULEROOT "/%s/zygisk",
module_list->operator[](id).name.data()); module_list->operator[](id).name.data());
if (int dirfd = open(buf, O_RDONLY | O_CLOEXEC); dirfd >= 0) { if (int dirfd = open(buf, O_RDONLY | O_CLOEXEC); dirfd >= 0) {
close(xopenat(dirfd, "unloaded", O_CREAT | O_RDONLY, 0644)); close(xopenat(dirfd, "unloaded", O_CREAT | O_RDONLY, 0644));
@ -363,7 +363,7 @@ static void send_log_pipe(int fd) {
static void get_moddir(int client) { static void get_moddir(int client) {
int id = read_int(client); int id = read_int(client);
char buf[4096]; char buf[4096];
snprintf(buf, sizeof(buf), MODULEROOT "/%s", module_list->operator[](id).name.data()); ssprintf(buf, sizeof(buf), MODULEROOT "/%s", module_list->operator[](id).name.data());
int dfd = xopen(buf, O_RDONLY | O_CLOEXEC); int dfd = xopen(buf, O_RDONLY | O_CLOEXEC);
send_fd(client, dfd); send_fd(client, dfd);
close(dfd); close(dfd);

View File

@ -44,7 +44,7 @@ int app_process_main(int argc, char *argv[]) {
if (fork_dont_care() == 0) { if (fork_dont_care() == 0) {
// This fd has to survive exec // This fd has to survive exec
fcntl(fds[1], F_SETFD, 0); fcntl(fds[1], F_SETFD, 0);
snprintf(buf, sizeof(buf), "%d", fds[1]); ssprintf(buf, sizeof(buf), "%d", fds[1]);
#if defined(__LP64__) #if defined(__LP64__)
execlp("magisk", "", "zygisk", "passthrough", buf, "1", (char *) nullptr); execlp("magisk", "", "zygisk", "passthrough", buf, "1", (char *) nullptr);
#else #else