Skip to content

Commit e090ec0

Browse files
committed
Add system privilege PROFILE_ANY_ATTACHMENT and permission check.
Add some static_asserts.
1 parent 82a569f commit e090ec0

File tree

4 files changed

+20
-1
lines changed

4 files changed

+20
-1
lines changed

doc/sql.extensions/README.ddl.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -557,6 +557,7 @@ GRANT_REVOKE_ANY_DDL_RIGHT GRANT and REVOKE any DDL rights
557557
CREATE_PRIVILEGED_ROLES Use SET SYSTEM PRIVILEGES in roles
558558
MODIFY_EXT_CONN_POOL Manage properties of pool of external connections
559559
REPLICATE_INTO_DATABASE Use replication API to load changesets into database
560+
PROFILE_ANY_ATTACHMENT Profile other users' attachments
560561

561562

562563
22) New grantee type in GRANT and REVOKE operators - SYSTEM PRIVILEGE.

doc/sql.extensions/README.profiler.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ Remote profiling just forwards commands to the remote attachment. So it's possib
1414

1515
Remote issued commands needs that the target attachment be in an idle state, i.e., not executing others requests. When they are not idle the call blocks waiting for that state.
1616

17+
If remote attachment is from a different user, the calling user must have system privilege PROFILE_ANY_ATTACHMENT.
18+
1719
After a session is started, PSQL and SQL statements statistics starts to be collected in memory. Note that a profile session collects data only of statements executed in the same attachment associated with the session.
1820

1921
Data is aggregated and stored per requests (i.e. a statement execution). When querying snapshot tables, user may do extra aggregation per statements or use the auxiliary views that do that automatically.

src/jrd/ProfilerManager.cpp

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ namespace
8888
event_t clientEvent;
8989
USHORT bufferSize;
9090
Tag tag;
91+
char userName[USERNAME_LENGTH + 1]; // \0 if has PROFILE_ANY_ATTACHMENT
9192
alignas(FB_ALIGNMENT) UCHAR buffer[4096];
9293
};
9394

@@ -107,12 +108,14 @@ namespace
107108
template <typename Input, typename Output>
108109
void sendAndReceive(thread_db* tdbb, Tag tag, const Input* in, Output* out)
109110
{
111+
static_assert(sizeof(*in) <= sizeof(std::declval<Header>().buffer), "Buffer size too small");
110112
internalSendAndReceive(tdbb, tag, in, sizeof(*in), out, sizeof(*out));
111113
}
112114

113115
template <typename Input>
114116
void send(thread_db* tdbb, Tag tag, const Input* in)
115117
{
118+
static_assert(sizeof(*in) <= sizeof(std::declval<Header>().buffer), "Buffer size too small");
116119
internalSendAndReceive(tdbb, tag, in, sizeof(*in), nullptr, 0);
117120
}
118121

@@ -757,6 +760,8 @@ void ProfilerIpc::mutexBug(int osErrorCode, const char* text)
757760
void ProfilerIpc::internalSendAndReceive(thread_db* tdbb, Tag tag,
758761
const void* in, unsigned inSize, void* out, unsigned outSize)
759762
{
763+
const auto attachment = tdbb->getAttachment();
764+
760765
{ // scope
761766
ThreadStatusGuard tempStatus(tdbb);
762767

@@ -782,9 +787,15 @@ void ProfilerIpc::internalSendAndReceive(thread_db* tdbb, Tag tag,
782787

783788
const auto header = sharedMemory->getHeader();
784789

785-
header->bufferSize = inSize;
786790
header->tag = tag;
787791

792+
if (attachment->locksmith(tdbb, PROFILE_ANY_ATTACHMENT))
793+
header->userName[0] = '\0';
794+
else
795+
strcpy(header->userName, attachment->getUserName().c_str());
796+
797+
header->bufferSize = inSize;
798+
788799
fb_assert(inSize <= sizeof(header->buffer));
789800
memcpy(header->buffer, in, inSize);
790801

@@ -928,6 +939,9 @@ void ProfilerListener::processCommand(thread_db* tdbb)
928939
const auto header = ipc->sharedMemory->getHeader();
929940
const auto profilerManager = attachment->getProfilerManager(tdbb);
930941

942+
if (header->userName[0] && attachment->getUserName() != header->userName)
943+
status_exception::raise(Arg::Gds(isc_miss_prvlg) << "PROFILE_ANY_ATTACHMENT");
944+
931945
using Tag = ProfilerIpc::Tag;
932946

933947
switch (header->tag)
@@ -983,6 +997,7 @@ void ProfilerListener::processCommand(thread_db* tdbb)
983997
in->pluginOptionsNull ? 0 : in->pluginOptions.length);
984998

985999
const auto out = reinterpret_cast<ProfilerPackage::StartSessionOutput::Type*>(header->buffer);
1000+
static_assert(sizeof(*out) <= sizeof(header->buffer), "Buffer size too small");
9861001
header->bufferSize = sizeof(*out);
9871002

9881003
out->sessionIdNull = FB_FALSE;

src/jrd/SystemPrivileges.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ SYSTEM_PRIVILEGE(CREATE_PRIVILEGED_ROLES)
6565
SYSTEM_PRIVILEGE(GET_DBCRYPT_INFO)
6666
SYSTEM_PRIVILEGE(MODIFY_EXT_CONN_POOL)
6767
SYSTEM_PRIVILEGE(REPLICATE_INTO_DATABASE)
68+
SYSTEM_PRIVILEGE(PROFILE_ANY_ATTACHMENT)
6869

6970
#ifdef FB_JRD_SYSTEM_PRIVILEGES_TMP
7071
maxSystemPrivilege

0 commit comments

Comments
 (0)