The Pedigree Project 0.1
ipc-common.h
1#ifndef POSIX_IPC_COMMON_H
2#define POSIX_IPC_COMMON_H
3
4#include "pedigree/kernel/process/Process.h"
5#include "pedigree/kernel/process/Thread.h"
6#include "pedigree/kernel/processor/Processor.h"
7#include "pedigree/kernel/processor/ProcessorInformation.h"
8#include "pedigree/kernel/processor/types.h"
9#include "pedigree/kernel/utilities/Vector.h"
10
11#include "ipc-namespace.h"
12
13namespace PosixIpc {
14struct Permission {
15 int32_t key;
16 uint32_t uid, gid, cuid, cgid;
17 uint32_t mode, sequence, padding;
18 uint64_t unused[2];
19};
20static_assert(sizeof(Permission) == 48, "Linux amd64 ipc_perm layout");
21
22inline Process* process() {
23 return Processor::information().getCurrentThread()->getParent();
24}
25
26inline void initialize(Permission& permission, int key, unsigned mode, unsigned sequence) {
27 Process* current = process();
28 permission = {};
29 permission.key = key;
30 permission.uid = permission.cuid = current->getEffectiveUserId();
31 permission.gid = permission.cgid = current->getEffectiveGroupId();
32 permission.mode = mode & 0777;
33 permission.sequence = sequence;
34}
35
36inline bool owner(const Permission& permission) {
37 const int64_t uid = process()->getEffectiveUserId();
38 return uid == permission.uid || uid == permission.cuid ||
39 posix_namespace_capable(posix_ipc_owner(), PosixCapabilities::SysAdmin);
40}
41
42inline bool allowed(const Permission& permission, unsigned requestedMode) {
43 Process* current = process();
44 const int64_t uid = current->getEffectiveUserId();
45 if (!requestedMode || posix_namespace_capable(posix_ipc_owner(), 15)) {
46 return true;
47 }
48 unsigned shift = 0;
49 if (uid == permission.uid || uid == permission.cuid) {
50 shift = 6;
51 } else {
52 const int64_t gid = current->getEffectiveGroupId();
53 bool group = gid == permission.gid || gid == permission.cgid;
54 if (!group) {
55 Vector<int64_t> groups;
56 current->getSupplementalGroupIds(groups);
57 for (size_t i = 0; i < groups.count(); ++i) {
58 if (groups[i] == permission.gid || groups[i] == permission.cgid) {
59 group = true;
60 break;
61 }
62 }
63 }
64 if (group) {
65 shift = 3;
66 }
67 }
68 return (((permission.mode >> shift) & requestedMode) == requestedMode);
69}
70} // namespace PosixIpc
71#endif
Process * getParent()
Definition Process.h:620
static ProcessorInformation & information()
A vector / dynamic array.
Definition Vector.h:33
size_t count() const
Definition Vector.h:270