* Check for IPC permission. * * Note: The MAC Framework does not require any modifications to the * ipcperm() function, as access control checks are performed throughout the * implementation of each primitive. Those entry point calls complement the * ipcperm() discertionary checks. Unlike file system discretionary access * control, the original create of an object is given the same rights
| 87 | * current owner. |
| 88 | */ |
| 89 | int |
| 90 | ipcperm(struct thread *td, struct ipc_perm *perm, int acc_mode) |
| 91 | { |
| 92 | struct ucred *cred = td->td_ucred; |
| 93 | int error, obj_mode, dac_granted, priv_granted; |
| 94 | |
| 95 | dac_granted = 0; |
| 96 | if (cred->cr_uid == perm->cuid || cred->cr_uid == perm->uid) { |
| 97 | obj_mode = perm->mode; |
| 98 | dac_granted |= IPC_M; |
| 99 | } else if (groupmember(perm->gid, cred) || |
| 100 | groupmember(perm->cgid, cred)) { |
| 101 | obj_mode = perm->mode; |
| 102 | obj_mode <<= 3; |
| 103 | } else { |
| 104 | obj_mode = perm->mode; |
| 105 | obj_mode <<= 6; |
| 106 | } |
| 107 | |
| 108 | /* |
| 109 | * While the System V IPC permission model allows IPC_M to be |
| 110 | * granted, as part of the mode, our implementation requires |
| 111 | * privilege to adminster the object if not the owner or creator. |
| 112 | */ |
| 113 | #if 0 |
| 114 | if (obj_mode & IPC_M) |
| 115 | dac_granted |= IPC_M; |
| 116 | #endif |
| 117 | if (obj_mode & IPC_R) |
| 118 | dac_granted |= IPC_R; |
| 119 | if (obj_mode & IPC_W) |
| 120 | dac_granted |= IPC_W; |
| 121 | |
| 122 | /* |
| 123 | * Simple case: all required rights are granted by DAC. |
| 124 | */ |
| 125 | if ((dac_granted & acc_mode) == acc_mode) |
| 126 | return (0); |
| 127 | |
| 128 | /* |
| 129 | * Privilege is required to satisfy the request. |
| 130 | */ |
| 131 | priv_granted = 0; |
| 132 | if ((acc_mode & IPC_M) && !(dac_granted & IPC_M)) { |
| 133 | error = priv_check(td, PRIV_IPC_ADMIN); |
| 134 | if (error == 0) |
| 135 | priv_granted |= IPC_M; |
| 136 | } |
| 137 | |
| 138 | if ((acc_mode & IPC_R) && !(dac_granted & IPC_R)) { |
| 139 | error = priv_check(td, PRIV_IPC_READ); |
| 140 | if (error == 0) |
| 141 | priv_granted |= IPC_R; |
| 142 | } |
| 143 | |
| 144 | if ((acc_mode & IPC_W) && !(dac_granted & IPC_W)) { |
| 145 | error = priv_check(td, PRIV_IPC_WRITE); |
| 146 | if (error == 0) |
no test coverage detected