From c67062fcb41d0a6defee7b1322c425d09211a46e Mon Sep 17 00:00:00 2001 From: Seungbae Shin Date: Mon, 6 Sep 2021 20:15:18 +0900 Subject: [PATCH] Allow permission if the process that setting stream volume is identical to stream creater [Version] 13.0-34 [Issue Type] Bug fix Change-Id: I739c602d6e63a4228cc4eaef9a16a27dd2078171 --- packaging/pulseaudio.spec | 2 +- src/pulsecore/cynara.c | 12 +++++++++--- src/pulsecore/cynara.h | 3 ++- src/pulsecore/protocol-native.c | 33 ++++++++++++++++++++++++--------- 4 files changed, 36 insertions(+), 14 deletions(-) diff --git a/packaging/pulseaudio.spec b/packaging/pulseaudio.spec index 82e5f76..ffff57a 100644 --- a/packaging/pulseaudio.spec +++ b/packaging/pulseaudio.spec @@ -3,7 +3,7 @@ Name: pulseaudio Summary: Improved Linux sound server Version: 13.0 -Release: 33 +Release: 34 Group: Multimedia/Audio License: LGPL-2.1 URL: http://pulseaudio.org diff --git a/src/pulsecore/cynara.c b/src/pulsecore/cynara.c index d1dd3e6..89fcfce 100644 --- a/src/pulsecore/cynara.c +++ b/src/pulsecore/cynara.c @@ -22,17 +22,17 @@ void cynara_log(const char *string, int cynara_status) { pa_log_debug("%s: %s", string, buf); } -bool cynara_check_privilege(int fd, const char *privilege) { +bool cynara_check_privilege(int fd, const char *privilege, pid_t allowed_pid) { cynara *p_cynara = NULL; cynara_configuration *p_conf = NULL; int ret = 0; - int result = false; + bool result = false; char *user = NULL; char *client = NULL; char *session = NULL; - int pid = 0; + pid_t pid = 0; ret = cynara_configuration_create(&p_conf); cynara_log("cynara_configuration_create()", ret); @@ -64,6 +64,12 @@ bool cynara_check_privilege(int fd, const char *privilege) { goto CLEANUP; } + if (pid == allowed_pid) { + pa_log_info("identical to allowed pid"); + result = true; + goto CLEANUP; + } + ret = cynara_creds_socket_get_client(fd, CLIENT_METHOD_DEFAULT, &client); cynara_log("cynara_creds_socket_get_client()", ret); if (ret != CYNARA_API_SUCCESS) { diff --git a/src/pulsecore/cynara.h b/src/pulsecore/cynara.h index 1c75c5a..540f992 100644 --- a/src/pulsecore/cynara.h +++ b/src/pulsecore/cynara.h @@ -1,7 +1,8 @@ #include +#include #define VOLUME_SET_PRIVILEGE "http://tizen.org/privilege/volume.set" #define RECORDER_PRIVILEGE "http://tizen.org/privilege/recorder" void cynara_log(const char *string, int cynara_status); -bool cynara_check_privilege(int fd, const char *privilege); +bool cynara_check_privilege(int fd, const char *privilege, pid_t allowed_pid); diff --git a/src/pulsecore/protocol-native.c b/src/pulsecore/protocol-native.c index c1aa9c1..acc74b4 100644 --- a/src/pulsecore/protocol-native.c +++ b/src/pulsecore/protocol-native.c @@ -2357,7 +2357,7 @@ static void command_check_privilege(pa_pdispatch *pd, uint32_t command, uint32_t return; } - CHECK_VALIDITY(c->pstream, cynara_check_privilege(_get_connection_out_fd(c), privilege), tag, PA_ERR_ACCESS); + CHECK_VALIDITY(c->pstream, cynara_check_privilege(_get_connection_out_fd(c), privilege, -1), tag, PA_ERR_ACCESS); pa_pstream_send_simple_ack(c->pstream, tag); } #endif @@ -2441,7 +2441,7 @@ static void command_create_record_stream(pa_pdispatch *pd, uint32_t command, uin pa_log_info("is virtual stream : %s, is remote stream : %s", pa_yes_no(is_virtual_stream), pa_yes_no(is_remote_stream)); if (!is_virtual_stream && !is_remote_stream) - CHECK_VALIDITY(c->pstream, cynara_check_privilege(_get_connection_out_fd(c), RECORDER_PRIVILEGE), tag, PA_ERR_ACCESS); + CHECK_VALIDITY(c->pstream, cynara_check_privilege(_get_connection_out_fd(c), RECORDER_PRIVILEGE, -1), tag, PA_ERR_ACCESS); #endif p = pa_proplist_new(); @@ -3942,6 +3942,23 @@ static void command_subscribe(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_pstream_send_simple_ack(c->pstream, tag); } +#ifdef TIZEN_SECURITY +static pid_t get_pid_to_skip(pa_sink_input *si, pa_source_output *so) { + int32_t pid = 0; + const char *pid_str = NULL; + + if (si) + pid_str = pa_proplist_gets(si->proplist, PA_PROP_APPLICATION_PROCESS_ID); + else if (so) + pid_str = pa_proplist_gets(so->proplist, PA_PROP_APPLICATION_PROCESS_ID); + + if (!pid_str || pa_atoi(pid_str, &pid) == -1) + return -1; + + return (pid_t)pid; +} +#endif + static void command_set_volume( pa_pdispatch *pd, uint32_t command, @@ -3975,13 +3992,8 @@ static void command_set_volume( CHECK_VALIDITY(c->pstream, !name || pa_namereg_is_valid_name_or_wildcard(name, command == PA_COMMAND_SET_SINK_VOLUME ? PA_NAMEREG_SINK : PA_NAMEREG_SOURCE), tag, PA_ERR_INVALID); CHECK_VALIDITY(c->pstream, (idx != PA_INVALID_INDEX) ^ (name != NULL), tag, PA_ERR_INVALID); CHECK_VALIDITY(c->pstream, pa_cvolume_valid(&volume), tag, PA_ERR_INVALID); -#ifdef TIZEN_SECURITY - CHECK_VALIDITY(c->pstream, cynara_check_privilege(_get_connection_out_fd(c), VOLUME_SET_PRIVILEGE), - tag, PA_ERR_ACCESS); -#endif switch (command) { - case PA_COMMAND_SET_SINK_VOLUME: if (idx != PA_INVALID_INDEX) sink = pa_idxset_get_by_index(c->protocol->core->sinks, idx); @@ -4009,7 +4021,10 @@ static void command_set_volume( } CHECK_VALIDITY(c->pstream, si || so || sink || source, tag, PA_ERR_NOENTITY); - +#ifdef TIZEN_SECURITY + CHECK_VALIDITY(c->pstream, cynara_check_privilege(_get_connection_out_fd(c), VOLUME_SET_PRIVILEGE, get_pid_to_skip(si, so)), + tag, PA_ERR_ACCESS); +#endif client_name = pa_strnull(pa_proplist_gets(c->client->proplist, PA_PROP_APPLICATION_PROCESS_BINARY)); if (sink) { @@ -4075,7 +4090,7 @@ static void command_set_mute( CHECK_VALIDITY(c->pstream, !name || pa_namereg_is_valid_name_or_wildcard(name, command == PA_COMMAND_SET_SINK_MUTE ? PA_NAMEREG_SINK : PA_NAMEREG_SOURCE), tag, PA_ERR_INVALID); CHECK_VALIDITY(c->pstream, (idx != PA_INVALID_INDEX) ^ (name != NULL), tag, PA_ERR_INVALID); #ifdef TIZEN_SECURITY - CHECK_VALIDITY(c->pstream, cynara_check_privilege(_get_connection_out_fd(c), VOLUME_SET_PRIVILEGE), + CHECK_VALIDITY(c->pstream, cynara_check_privilege(_get_connection_out_fd(c), VOLUME_SET_PRIVILEGE, -1), tag, PA_ERR_ACCESS); #endif -- 2.7.4