1 /* $NetBSD: secmodel_example.c,v 1.1 2006/09/15 15:49:29 elad Exp $ */ 2 3 /* 4 * This file is placed in the public domain. 5 */ 6 7 /* 8 * Skeleton file for building a NetBSD security model from scratch, containing 9 * every kauth(9) scope, action, and request, as well as some coding hints. 10 * 11 * This file will be kept in-sync with the official NetBSD kernel, so *always* 12 * use the latest revision. 13 */ 14 15 #include <sys/cdefs.h> 16 __KERNEL_RCSID(0, "$NetBSD: secmodel_example.c,v 1.1 2006/09/15 15:49:29 elad Exp $"); 17 18 #include <sys/types.h> 19 #include <sys/param.h> 20 #include <sys/kauth.h> 21 22 #include <sys/sysctl.h> 23 24 #include <secmodel/secmodel.h> 25 26 #include <secmodel/example/example.h> 27 28 /* 29 * Initialize the security model. 30 */ 31 void 32 secmodel_example_init(void) 33 { 34 return; 35 } 36 37 /* 38 * If the security model is to be used as an LKM, this routine should be 39 * changed, because otherwise creating permanent sysctl(9) nodes will fail. 40 * 41 * To make it work, the prototype should be changed to something like: 42 * 43 * void secmodel_example_sysctl(void) 44 * 45 * and it should be called from secmodel_start(). 46 * 47 * In addition, the CTLFLAG_PERMANENT flag must be removed from all the 48 * nodes. 49 */ 50 SYSCTL_SETUP(sysctl_security_example_setup, 51 "sysctl security example setup") 52 { 53 const struct sysctlnode *rnode; 54 55 sysctl_createv(clog, 0, NULL, &rnode, 56 CTLFLAG_PERMANENT, 57 CTLTYPE_NODE, "security", NULL, 58 NULL, 0, NULL, 0, 59 CTL_CREATE, CTL_EOL); 60 61 sysctl_createv(clog, 0, &rnode, &rnode, 62 CTLFLAG_PERMANENT, 63 CTLTYPE_NODE, "models", NULL, 64 NULL, 0, NULL, 0, 65 CTL_CREATE, CTL_EOL); 66 67 sysctl_createv(clog, 0, &rnode, &rnode, 68 CTLFLAG_PERMANENT, 69 CTLTYPE_NODE, "example", 70 SYSCTL_DESCR("example security model"), 71 NULL, 0, NULL, 0, 72 CTL_CREATE, CTL_EOL); 73 74 sysctl_createv(clog, 0, &rnode, NULL, 75 CTLFLAG_PERMANENT, 76 CTLTYPE_STRING, "name", NULL, 77 NULL, 0, __UNCONST("Example"), 0 78 CTL_CREATE, CTL_EOL); 79 80 } 81 82 /* 83 * Start the security model. 84 */ 85 void 86 secmodel_start(void) 87 { 88 secmodel_example_init(); 89 90 kauth_listen_scope(KAUTH_SCOPE_GENERIC, 91 secmodel_example_generic_cb, NULL); 92 kauth_listen_scope(KAUTH_SCOPE_SYSTEM, 93 secmodel_example_system_cb, NULL); 94 kauth_listen_scope(KAUTH_SCOPE_PROCESS, 95 secmodel_example_process_cb, NULL); 96 kauth_listen_scope(KAUTH_SCOPE_NETWORK, 97 secmodel_example_network_cb, NULL); 98 kauth_listen_scope(KAUTH_SCOPE_MACHDEP, 99 secmodel_example_machdep_cb, NULL); 100 } 101 102 /* 103 * Security model: example 104 * Scope: Generic 105 */ 106 int 107 secmodel_example_generic_cb(kauth_cred_t, kauth_action_t action, 108 void *cookie, void *arg0, void *arg1, void *arg2, void *arg3) 109 { 110 int result; 111 112 result = KAUTH_RESULT_DENY; 113 114 switch(action) { 115 case KAUTH_GENERIC_ISSUSER: 116 case KAUTH_GENERIC_CANSEE: 117 default: 118 result = KAUTH_RESULT_DEFER; 119 break; 120 } 121 122 return (result); 123 } 124 125 /* 126 * Security model: example 127 * Scope: System 128 */ 129 int 130 secmodel_example_system_cb(kauth_cred_t cred, kauth_action_t action, 131 void *cookie, void *arg0, void *arg1, void *arg2, void *arg3) 132 { 133 int result; 134 enum kauth_system_req req; 135 136 result = KAUTH_RESULT_DENY; 137 138 req = (enum kauth_system_req)arg0; 139 140 switch (action) { 141 case KAUTH_SYSTEM_RAWIO: { 142 u_int rw; 143 144 rw = (u_int)(u_long)arg1; 145 146 switch (req) { 147 case KAUTH_REQ_SYSTEM_RAWIO_MEMORY: { 148 switch (rw) { 149 case KAUTH_REQ_SYSTEM_RAWIO_READ: 150 case KAUTH_REQ_SYSTEM_RAWIO_WRITE: 151 case KAUTH_REQ_SYSTEM_RAWIO_RW: 152 default: 153 result = KAUTH_RESULT_DEFER; 154 break; 155 } 156 157 break; 158 } 159 case KAUTH_REQ_SYSTEM_RAWIO_DISK: { 160 switch (rw) { 161 case KAUTH_REQ_SYSTEM_RAWIO_READ: 162 case KAUTH_REQ_SYSTEM_RAWIO_WRITE: 163 case KAUTH_REQ_SYSTEM_RAWIO_RW: 164 default: 165 result = KAUTH_RESULT_DEFER; 166 break; 167 } 168 169 break; 170 } 171 172 173 default: 174 result = KAUTH_RESULT_DEFER; 175 break; 176 } 177 break; 178 } 179 180 case KAUTH_SYSTEM_TIME: 181 switch (req) { 182 case KAUTH_REQ_SYSTEM_TIME_ADJTIME: 183 case KAUTH_REQ_SYSTEM_TIME_BACKWARDS: 184 case KAUTH_REQ_SYSTEM_TIME_NTPADJTIME: 185 case KAUTH_REQ_SYSTEM_TIME_RTCOFFSET: 186 case KAUTH_REQ_SYSTEM_TIME_SYSTEM: 187 default: 188 result = KAUTH_RESULT_DEFER; 189 break; 190 } 191 break; 192 193 case KAUTH_SYSTEM_SYSCTL: 194 switch (req) { 195 case KAUTH_REQ_SYSTEM_SYSCTL_ADD: 196 case KAUTH_REQ_SYSTEM_SYSCTL_DELETE: 197 case KAUTH_REQ_SYSTEM_SYSCTL_DESC: 198 default: 199 result = KAUTH_RESULT_DEFER; 200 break; 201 } 202 break; 203 204 case KAUTH_SYSTEM_CHROOT: 205 switch (req) { 206 case KAUTH_REQ_SYSTEM_CHROOT_CHROOT: 207 case KAUTH_REQ_SYSTEM_CHROOT_FCHROOT: 208 default: 209 result = KAUTH_RESULT_DEFER; 210 break; 211 } 212 break; 213 214 case KAUTH_SYSTEM_DEBUG: 215 switch (req) { 216 case KAUTH_REQ_SYSTEM_DEBUG_IPKDB: 217 default: 218 result = KAUTH_RESULT_DEFER; 219 break; 220 } 221 break; 222 223 case KAUTH_SYSTEM_LKM: 224 case KAUTH_SYSTEM_FILEHANDLE: 225 case KAUTH_SYSTEM_MKNOD: 226 case KAUTH_SYSTEM_SETIDCORE: 227 case KAUTH_SYSTEM_SWAPCTL: 228 case KAUTH_SYSTEM_ACCOUNTING: 229 case KAUTH_SYSTEM_REBOOT: 230 default: 231 result = KAUTH_RESULT_DEFER; 232 break; 233 } 234 235 return (result); 236 } 237 238 /* 239 * kauth(9) listener 240 * 241 * Security model: example 242 * Scope: Process 243 */ 244 int 245 secmodel_example_process_cb(kauth_cred_t cred, kauth_action_t action, 246 void *cookie, void *arg0, void *arg1, void *arg2, void *arg3) 247 { 248 int result; 249 250 result = KAUTH_RESULT_DENY; 251 252 switch (action) { 253 case KAUTH_PROCESS_RESOURCE: 254 switch((u_long)arg0) { 255 case KAUTH_REQ_PROCESS_RESOURCE_NICE: 256 case KAUTH_REQ_PROCESS_RESOURCE_RLIMIT: 257 default: 258 result = KAUTH_RESULT_DEFER; 259 break; 260 } 261 break; 262 263 case KAUTH_PROCESS_SETID: 264 case KAUTH_PROCESS_CANSEE: 265 case KAUTH_PROCESS_CANSIGNAL: 266 case KAUTH_PROCESS_CORENAME: 267 default: 268 result = KAUTH_RESULT_DEFER; 269 break; 270 } 271 272 return (result); 273 } 274 275 /* 276 * kauth(9) listener 277 * 278 * Security model: example 279 * Scope: Network 280 */ 281 int 282 secmodel_example_network_cb(kauth_cred_t cred, kauth_action_t action, 283 void *cookie, void *arg0, void *arg1, void *arg2, void *arg3) 284 { 285 int result; 286 287 result = KAUTH_RESULT_DENY; 288 289 switch (action) { 290 case KAUTH_NETWORK_ALTQ: 291 switch((u_long)arg0) { 292 case KAUTH_REQ_NETWORK_ALTQ_AFMAP: 293 case KAUTH_REQ_NETWORK_ALTQ_BLUE: 294 case KAUTH_REQ_NETWORK_ALTQ_CBQ: 295 case KAUTH_REQ_NETWORK_ALTQ_CDNR: 296 case KAUTH_REQ_NETWORK_ALTQ_CONF: 297 case KAUTH_REQ_NETWORK_ALTQ_FIFOQ: 298 case KAUTH_REQ_NETWORK_ALTQ_HFSC: 299 case KAUTH_REQ_NETWORK_ALTQ_PRIQ: 300 case KAUTH_REQ_NETWORK_ALTQ_RED: 301 case KAUTH_REQ_NETWORK_ALTQ_RIO: 302 case KAUTH_REQ_NETWORK_ALTQ_WFQ: 303 default: 304 result = KAUTH_RESULT_DEFER; 305 break; 306 } 307 break; 308 309 case KAUTH_NETWORK_BIND: 310 switch((u_long)arg0) { 311 case KAUTH_REQ_NETWORK_BIND_PORT: 312 case KAUTH_REQ_NETWORK_BIND_PRIVPORT: 313 default: 314 result = KAUTH_RESULT_DEFER; 315 break; 316 } 317 break; 318 319 case KAUTH_NETWORK_FIREWALL: 320 switch ((u_long)arg0) { 321 case KAUTH_REQ_NETWORK_FIREWALL_FW: 322 case KAUTH_REQ_NETWORK_FIREWALL_NAT: 323 default: 324 result = KAUTH_RESULT_DEFER; 325 break; 326 } 327 break; 328 329 case KAUTH_NETWORK_SOCKET: 330 switch((u_long)arg0) { 331 case KAUTH_REQ_NETWORK_SOCKET_ATTACH: 332 case KAUTH_REQ_NETWORK_SOCKET_RAWSOCK: 333 default: 334 result = KAUTH_RESULT_DEFER; 335 break; 336 } 337 break; 338 339 case KAUTH_NETWORK_FORWSRCRT: 340 case KAUTH_NETWORK_ROUTE: 341 default: 342 result = KAUTH_RESULT_DEFER; 343 break; 344 } 345 346 return (result); 347 } 348 349 /* 350 * kauth(9) listener 351 * 352 * Security model: example 353 * Scope: Machdep 354 */ 355 int 356 secmodel_example_machdep_cb(kauth_cred_t cred, kauth_action_t action, 357 void *cookie, void *arg0, void *arg1, void *arg2, void *arg3) 358 { 359 int result; 360 361 result = KAUTH_RESULT_DENY; 362 363 switch (action) { 364 case KAUTH_MACHDEP_X86: 365 switch ((u_long)arg0) { 366 case KAUTH_REQ_MACHDEP_X86_IOPL: 367 case KAUTH_REQ_MACHDEP_X86_IOPERM: 368 case KAUTH_REQ_MACHDEP_X86_MTRR_SET: 369 default: 370 result = KAUTH_RESULT_DEFER; 371 break; 372 } 373 374 break; 375 376 case KAUTH_MACHDEP_X86_64: 377 switch ((u_long)arg0) { 378 case KAUTH_REQ_MACHDPE_X86_64_MTRR_GET: 379 default: 380 result = KAUTH_RESULT_DEFER; 381 break; 382 } 383 break; 384 385 default: 386 result = KAUTH_RESULT_DEFER; 387 break; 388 } 389 390 return (result); 391 } 392 393