ia64/linux-2.6.18-xen.hg

annotate kernel/auditsc.c @ 798:b02a90bf5bbc

ACPI: Backport missing part for T-State MSR support

Part of below kernel commit was missed while packporting T-State
support.

commit f79f06ab9f86d7203006d2ec8992ac80df36a34e
Author: Zhao Yakui <yakui.zhao@intel.com>
Date: Thu Nov 15 17:06:36 2007 +0800

ACPI: Enable MSR (FixedHW) support for T-States

Add throttling control via MSR when T-states uses
the FixHW Control Status registers.

Signed-off-by: Zhao Yakui <yakui.zhao@intel.com>
Signed-off-by: Li Shaohua <shaohua.li@intel.com>
Signed-off-by: Len Brown <len.brown@intel.com>

Signed-off-by: Wei Gang <gang.wei@intel.com>
author Keir Fraser <keir.fraser@citrix.com>
date Mon Mar 02 10:53:59 2009 +0000 (2009-03-02)
parents 831230e53067
children
rev   line source
ian@0 1 /* auditsc.c -- System-call auditing support
ian@0 2 * Handles all system-call specific auditing features.
ian@0 3 *
ian@0 4 * Copyright 2003-2004 Red Hat Inc., Durham, North Carolina.
ian@0 5 * Copyright 2005 Hewlett-Packard Development Company, L.P.
ian@0 6 * Copyright (C) 2005, 2006 IBM Corporation
ian@0 7 * All Rights Reserved.
ian@0 8 *
ian@0 9 * This program is free software; you can redistribute it and/or modify
ian@0 10 * it under the terms of the GNU General Public License as published by
ian@0 11 * the Free Software Foundation; either version 2 of the License, or
ian@0 12 * (at your option) any later version.
ian@0 13 *
ian@0 14 * This program is distributed in the hope that it will be useful,
ian@0 15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
ian@0 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
ian@0 17 * GNU General Public License for more details.
ian@0 18 *
ian@0 19 * You should have received a copy of the GNU General Public License
ian@0 20 * along with this program; if not, write to the Free Software
ian@0 21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
ian@0 22 *
ian@0 23 * Written by Rickard E. (Rik) Faith <faith@redhat.com>
ian@0 24 *
ian@0 25 * Many of the ideas implemented here are from Stephen C. Tweedie,
ian@0 26 * especially the idea of avoiding a copy by using getname.
ian@0 27 *
ian@0 28 * The method for actual interception of syscall entry and exit (not in
ian@0 29 * this file -- see entry.S) is based on a GPL'd patch written by
ian@0 30 * okir@suse.de and Copyright 2003 SuSE Linux AG.
ian@0 31 *
ian@0 32 * POSIX message queue support added by George Wilson <ltcgcw@us.ibm.com>,
ian@0 33 * 2006.
ian@0 34 *
ian@0 35 * The support of additional filter rules compares (>, <, >=, <=) was
ian@0 36 * added by Dustin Kirkland <dustin.kirkland@us.ibm.com>, 2005.
ian@0 37 *
ian@0 38 * Modified by Amy Griffis <amy.griffis@hp.com> to collect additional
ian@0 39 * filesystem information.
ian@0 40 *
ian@0 41 * Subject and object context labeling support added by <danjones@us.ibm.com>
ian@0 42 * and <dustin.kirkland@us.ibm.com> for LSPP certification compliance.
ian@0 43 */
ian@0 44
ian@0 45 #include <linux/init.h>
ian@0 46 #include <asm/types.h>
ian@0 47 #include <asm/atomic.h>
ian@0 48 #include <asm/types.h>
ian@0 49 #include <linux/fs.h>
ian@0 50 #include <linux/namei.h>
ian@0 51 #include <linux/mm.h>
ian@0 52 #include <linux/module.h>
ian@0 53 #include <linux/mount.h>
ian@0 54 #include <linux/socket.h>
ian@0 55 #include <linux/mqueue.h>
ian@0 56 #include <linux/audit.h>
ian@0 57 #include <linux/personality.h>
ian@0 58 #include <linux/time.h>
ian@0 59 #include <linux/netlink.h>
ian@0 60 #include <linux/compiler.h>
ian@0 61 #include <asm/unistd.h>
ian@0 62 #include <linux/security.h>
ian@0 63 #include <linux/list.h>
ian@0 64 #include <linux/tty.h>
ian@0 65 #include <linux/selinux.h>
ian@0 66 #include <linux/binfmts.h>
ian@0 67 #include <linux/syscalls.h>
ian@0 68
ian@0 69 #include "audit.h"
ian@0 70
ian@0 71 extern struct list_head audit_filter_list[];
ian@0 72
ian@0 73 /* No syscall auditing will take place unless audit_enabled != 0. */
ian@0 74 extern int audit_enabled;
ian@0 75
ian@0 76 /* AUDIT_NAMES is the number of slots we reserve in the audit_context
ian@0 77 * for saving names from getname(). */
ian@0 78 #define AUDIT_NAMES 20
ian@0 79
ian@0 80 /* AUDIT_NAMES_RESERVED is the number of slots we reserve in the
ian@0 81 * audit_context from being used for nameless inodes from
ian@0 82 * path_lookup. */
ian@0 83 #define AUDIT_NAMES_RESERVED 7
ian@0 84
ian@0 85 /* Indicates that audit should log the full pathname. */
ian@0 86 #define AUDIT_NAME_FULL -1
ian@0 87
ian@0 88 /* number of audit rules */
ian@0 89 int audit_n_rules;
ian@0 90
ian@0 91 /* When fs/namei.c:getname() is called, we store the pointer in name and
ian@0 92 * we don't let putname() free it (instead we free all of the saved
ian@0 93 * pointers at syscall exit time).
ian@0 94 *
ian@0 95 * Further, in fs/namei.c:path_lookup() we store the inode and device. */
ian@0 96 struct audit_names {
ian@0 97 const char *name;
ian@0 98 int name_len; /* number of name's characters to log */
ian@0 99 unsigned name_put; /* call __putname() for this name */
ian@0 100 unsigned long ino;
ian@0 101 dev_t dev;
ian@0 102 umode_t mode;
ian@0 103 uid_t uid;
ian@0 104 gid_t gid;
ian@0 105 dev_t rdev;
ian@0 106 u32 osid;
ian@0 107 };
ian@0 108
ian@0 109 struct audit_aux_data {
ian@0 110 struct audit_aux_data *next;
ian@0 111 int type;
ian@0 112 };
ian@0 113
ian@0 114 #define AUDIT_AUX_IPCPERM 0
ian@0 115
ian@0 116 struct audit_aux_data_mq_open {
ian@0 117 struct audit_aux_data d;
ian@0 118 int oflag;
ian@0 119 mode_t mode;
ian@0 120 struct mq_attr attr;
ian@0 121 };
ian@0 122
ian@0 123 struct audit_aux_data_mq_sendrecv {
ian@0 124 struct audit_aux_data d;
ian@0 125 mqd_t mqdes;
ian@0 126 size_t msg_len;
ian@0 127 unsigned int msg_prio;
ian@0 128 struct timespec abs_timeout;
ian@0 129 };
ian@0 130
ian@0 131 struct audit_aux_data_mq_notify {
ian@0 132 struct audit_aux_data d;
ian@0 133 mqd_t mqdes;
ian@0 134 struct sigevent notification;
ian@0 135 };
ian@0 136
ian@0 137 struct audit_aux_data_mq_getsetattr {
ian@0 138 struct audit_aux_data d;
ian@0 139 mqd_t mqdes;
ian@0 140 struct mq_attr mqstat;
ian@0 141 };
ian@0 142
ian@0 143 struct audit_aux_data_ipcctl {
ian@0 144 struct audit_aux_data d;
ian@0 145 struct ipc_perm p;
ian@0 146 unsigned long qbytes;
ian@0 147 uid_t uid;
ian@0 148 gid_t gid;
ian@0 149 mode_t mode;
ian@0 150 u32 osid;
ian@0 151 };
ian@0 152
ian@0 153 struct audit_aux_data_execve {
ian@0 154 struct audit_aux_data d;
ian@0 155 int argc;
ian@0 156 int envc;
ian@0 157 char mem[0];
ian@0 158 };
ian@0 159
ian@0 160 struct audit_aux_data_socketcall {
ian@0 161 struct audit_aux_data d;
ian@0 162 int nargs;
ian@0 163 unsigned long args[0];
ian@0 164 };
ian@0 165
ian@0 166 struct audit_aux_data_sockaddr {
ian@0 167 struct audit_aux_data d;
ian@0 168 int len;
ian@0 169 char a[0];
ian@0 170 };
ian@0 171
ian@0 172 struct audit_aux_data_path {
ian@0 173 struct audit_aux_data d;
ian@0 174 struct dentry *dentry;
ian@0 175 struct vfsmount *mnt;
ian@0 176 };
ian@0 177
ian@0 178 /* The per-task audit context. */
ian@0 179 struct audit_context {
ian@0 180 int dummy; /* must be the first element */
ian@0 181 int in_syscall; /* 1 if task is in a syscall */
ian@0 182 enum audit_state state;
ian@0 183 unsigned int serial; /* serial number for record */
ian@0 184 struct timespec ctime; /* time of syscall entry */
ian@0 185 uid_t loginuid; /* login uid (identity) */
ian@0 186 int major; /* syscall number */
ian@0 187 unsigned long argv[4]; /* syscall arguments */
ian@0 188 int return_valid; /* return code is valid */
ian@0 189 long return_code;/* syscall return code */
ian@0 190 int auditable; /* 1 if record should be written */
ian@0 191 int name_count;
ian@0 192 struct audit_names names[AUDIT_NAMES];
ian@0 193 char * filterkey; /* key for rule that triggered record */
ian@0 194 struct dentry * pwd;
ian@0 195 struct vfsmount * pwdmnt;
ian@0 196 struct audit_context *previous; /* For nested syscalls */
ian@0 197 struct audit_aux_data *aux;
ian@0 198
ian@0 199 /* Save things to print about task_struct */
ian@0 200 pid_t pid, ppid;
ian@0 201 uid_t uid, euid, suid, fsuid;
ian@0 202 gid_t gid, egid, sgid, fsgid;
ian@0 203 unsigned long personality;
ian@0 204 int arch;
ian@0 205
ian@0 206 #if AUDIT_DEBUG
ian@0 207 int put_count;
ian@0 208 int ino_count;
ian@0 209 #endif
ian@0 210 };
ian@0 211
ian@0 212 #define ACC_MODE(x) ("\004\002\006\006"[(x)&O_ACCMODE])
ian@0 213 static inline int open_arg(int flags, int mask)
ian@0 214 {
ian@0 215 int n = ACC_MODE(flags);
ian@0 216 if (flags & (O_TRUNC | O_CREAT))
ian@0 217 n |= AUDIT_PERM_WRITE;
ian@0 218 return n & mask;
ian@0 219 }
ian@0 220
ian@0 221 static int audit_match_perm(struct audit_context *ctx, int mask)
ian@0 222 {
ian@0 223 unsigned n = ctx->major;
ian@0 224 switch (audit_classify_syscall(ctx->arch, n)) {
ian@0 225 case 0: /* native */
ian@0 226 if ((mask & AUDIT_PERM_WRITE) &&
ian@0 227 audit_match_class(AUDIT_CLASS_WRITE, n))
ian@0 228 return 1;
ian@0 229 if ((mask & AUDIT_PERM_READ) &&
ian@0 230 audit_match_class(AUDIT_CLASS_READ, n))
ian@0 231 return 1;
ian@0 232 if ((mask & AUDIT_PERM_ATTR) &&
ian@0 233 audit_match_class(AUDIT_CLASS_CHATTR, n))
ian@0 234 return 1;
ian@0 235 return 0;
ian@0 236 case 1: /* 32bit on biarch */
ian@0 237 if ((mask & AUDIT_PERM_WRITE) &&
ian@0 238 audit_match_class(AUDIT_CLASS_WRITE_32, n))
ian@0 239 return 1;
ian@0 240 if ((mask & AUDIT_PERM_READ) &&
ian@0 241 audit_match_class(AUDIT_CLASS_READ_32, n))
ian@0 242 return 1;
ian@0 243 if ((mask & AUDIT_PERM_ATTR) &&
ian@0 244 audit_match_class(AUDIT_CLASS_CHATTR_32, n))
ian@0 245 return 1;
ian@0 246 return 0;
ian@0 247 case 2: /* open */
ian@0 248 return mask & ACC_MODE(ctx->argv[1]);
ian@0 249 case 3: /* openat */
ian@0 250 return mask & ACC_MODE(ctx->argv[2]);
ian@0 251 case 4: /* socketcall */
ian@0 252 return ((mask & AUDIT_PERM_WRITE) && ctx->argv[0] == SYS_BIND);
ian@0 253 case 5: /* execve */
ian@0 254 return mask & AUDIT_PERM_EXEC;
ian@0 255 default:
ian@0 256 return 0;
ian@0 257 }
ian@0 258 }
ian@0 259
ian@0 260 /* Determine if any context name data matches a rule's watch data */
ian@0 261 /* Compare a task_struct with an audit_rule. Return 1 on match, 0
ian@0 262 * otherwise. */
ian@0 263 static int audit_filter_rules(struct task_struct *tsk,
ian@0 264 struct audit_krule *rule,
ian@0 265 struct audit_context *ctx,
ian@0 266 struct audit_names *name,
ian@0 267 enum audit_state *state)
ian@0 268 {
ian@0 269 int i, j, need_sid = 1;
ian@0 270 u32 sid;
ian@0 271
ian@0 272 for (i = 0; i < rule->field_count; i++) {
ian@0 273 struct audit_field *f = &rule->fields[i];
ian@0 274 int result = 0;
ian@0 275
ian@0 276 switch (f->type) {
ian@0 277 case AUDIT_PID:
ian@0 278 result = audit_comparator(tsk->pid, f->op, f->val);
ian@0 279 break;
ian@0 280 case AUDIT_PPID:
ian@0 281 if (ctx)
ian@0 282 result = audit_comparator(ctx->ppid, f->op, f->val);
ian@0 283 break;
ian@0 284 case AUDIT_UID:
ian@0 285 result = audit_comparator(tsk->uid, f->op, f->val);
ian@0 286 break;
ian@0 287 case AUDIT_EUID:
ian@0 288 result = audit_comparator(tsk->euid, f->op, f->val);
ian@0 289 break;
ian@0 290 case AUDIT_SUID:
ian@0 291 result = audit_comparator(tsk->suid, f->op, f->val);
ian@0 292 break;
ian@0 293 case AUDIT_FSUID:
ian@0 294 result = audit_comparator(tsk->fsuid, f->op, f->val);
ian@0 295 break;
ian@0 296 case AUDIT_GID:
ian@0 297 result = audit_comparator(tsk->gid, f->op, f->val);
ian@0 298 break;
ian@0 299 case AUDIT_EGID:
ian@0 300 result = audit_comparator(tsk->egid, f->op, f->val);
ian@0 301 break;
ian@0 302 case AUDIT_SGID:
ian@0 303 result = audit_comparator(tsk->sgid, f->op, f->val);
ian@0 304 break;
ian@0 305 case AUDIT_FSGID:
ian@0 306 result = audit_comparator(tsk->fsgid, f->op, f->val);
ian@0 307 break;
ian@0 308 case AUDIT_PERS:
ian@0 309 result = audit_comparator(tsk->personality, f->op, f->val);
ian@0 310 break;
ian@0 311 case AUDIT_ARCH:
ian@0 312 if (ctx)
ian@0 313 result = audit_comparator(ctx->arch, f->op, f->val);
ian@0 314 break;
ian@0 315
ian@0 316 case AUDIT_EXIT:
ian@0 317 if (ctx && ctx->return_valid)
ian@0 318 result = audit_comparator(ctx->return_code, f->op, f->val);
ian@0 319 break;
ian@0 320 case AUDIT_SUCCESS:
ian@0 321 if (ctx && ctx->return_valid) {
ian@0 322 if (f->val)
ian@0 323 result = audit_comparator(ctx->return_valid, f->op, AUDITSC_SUCCESS);
ian@0 324 else
ian@0 325 result = audit_comparator(ctx->return_valid, f->op, AUDITSC_FAILURE);
ian@0 326 }
ian@0 327 break;
ian@0 328 case AUDIT_DEVMAJOR:
ian@0 329 if (name)
ian@0 330 result = audit_comparator(MAJOR(name->dev),
ian@0 331 f->op, f->val);
ian@0 332 else if (ctx) {
ian@0 333 for (j = 0; j < ctx->name_count; j++) {
ian@0 334 if (audit_comparator(MAJOR(ctx->names[j].dev), f->op, f->val)) {
ian@0 335 ++result;
ian@0 336 break;
ian@0 337 }
ian@0 338 }
ian@0 339 }
ian@0 340 break;
ian@0 341 case AUDIT_DEVMINOR:
ian@0 342 if (name)
ian@0 343 result = audit_comparator(MINOR(name->dev),
ian@0 344 f->op, f->val);
ian@0 345 else if (ctx) {
ian@0 346 for (j = 0; j < ctx->name_count; j++) {
ian@0 347 if (audit_comparator(MINOR(ctx->names[j].dev), f->op, f->val)) {
ian@0 348 ++result;
ian@0 349 break;
ian@0 350 }
ian@0 351 }
ian@0 352 }
ian@0 353 break;
ian@0 354 case AUDIT_INODE:
ian@0 355 if (name)
ian@0 356 result = (name->ino == f->val);
ian@0 357 else if (ctx) {
ian@0 358 for (j = 0; j < ctx->name_count; j++) {
ian@0 359 if (audit_comparator(ctx->names[j].ino, f->op, f->val)) {
ian@0 360 ++result;
ian@0 361 break;
ian@0 362 }
ian@0 363 }
ian@0 364 }
ian@0 365 break;
ian@0 366 case AUDIT_WATCH:
ian@0 367 if (name && rule->watch->ino != (unsigned long)-1)
ian@0 368 result = (name->dev == rule->watch->dev &&
ian@0 369 name->ino == rule->watch->ino);
ian@0 370 break;
ian@0 371 case AUDIT_LOGINUID:
ian@0 372 result = 0;
ian@0 373 if (ctx)
ian@0 374 result = audit_comparator(ctx->loginuid, f->op, f->val);
ian@0 375 break;
ian@0 376 case AUDIT_SUBJ_USER:
ian@0 377 case AUDIT_SUBJ_ROLE:
ian@0 378 case AUDIT_SUBJ_TYPE:
ian@0 379 case AUDIT_SUBJ_SEN:
ian@0 380 case AUDIT_SUBJ_CLR:
ian@0 381 /* NOTE: this may return negative values indicating
ian@0 382 a temporary error. We simply treat this as a
ian@0 383 match for now to avoid losing information that
ian@0 384 may be wanted. An error message will also be
ian@0 385 logged upon error */
ian@0 386 if (f->se_rule) {
ian@0 387 if (need_sid) {
ian@0 388 selinux_task_ctxid(tsk, &sid);
ian@0 389 need_sid = 0;
ian@0 390 }
ian@0 391 result = selinux_audit_rule_match(sid, f->type,
ian@0 392 f->op,
ian@0 393 f->se_rule,
ian@0 394 ctx);
ian@0 395 }
ian@0 396 break;
ian@0 397 case AUDIT_OBJ_USER:
ian@0 398 case AUDIT_OBJ_ROLE:
ian@0 399 case AUDIT_OBJ_TYPE:
ian@0 400 case AUDIT_OBJ_LEV_LOW:
ian@0 401 case AUDIT_OBJ_LEV_HIGH:
ian@0 402 /* The above note for AUDIT_SUBJ_USER...AUDIT_SUBJ_CLR
ian@0 403 also applies here */
ian@0 404 if (f->se_rule) {
ian@0 405 /* Find files that match */
ian@0 406 if (name) {
ian@0 407 result = selinux_audit_rule_match(
ian@0 408 name->osid, f->type, f->op,
ian@0 409 f->se_rule, ctx);
ian@0 410 } else if (ctx) {
ian@0 411 for (j = 0; j < ctx->name_count; j++) {
ian@0 412 if (selinux_audit_rule_match(
ian@0 413 ctx->names[j].osid,
ian@0 414 f->type, f->op,
ian@0 415 f->se_rule, ctx)) {
ian@0 416 ++result;
ian@0 417 break;
ian@0 418 }
ian@0 419 }
ian@0 420 }
ian@0 421 /* Find ipc objects that match */
ian@0 422 if (ctx) {
ian@0 423 struct audit_aux_data *aux;
ian@0 424 for (aux = ctx->aux; aux;
ian@0 425 aux = aux->next) {
ian@0 426 if (aux->type == AUDIT_IPC) {
ian@0 427 struct audit_aux_data_ipcctl *axi = (void *)aux;
ian@0 428 if (selinux_audit_rule_match(axi->osid, f->type, f->op, f->se_rule, ctx)) {
ian@0 429 ++result;
ian@0 430 break;
ian@0 431 }
ian@0 432 }
ian@0 433 }
ian@0 434 }
ian@0 435 }
ian@0 436 break;
ian@0 437 case AUDIT_ARG0:
ian@0 438 case AUDIT_ARG1:
ian@0 439 case AUDIT_ARG2:
ian@0 440 case AUDIT_ARG3:
ian@0 441 if (ctx)
ian@0 442 result = audit_comparator(ctx->argv[f->type-AUDIT_ARG0], f->op, f->val);
ian@0 443 break;
ian@0 444 case AUDIT_FILTERKEY:
ian@0 445 /* ignore this field for filtering */
ian@0 446 result = 1;
ian@0 447 break;
ian@0 448 case AUDIT_PERM:
ian@0 449 result = audit_match_perm(ctx, f->val);
ian@0 450 break;
ian@0 451 }
ian@0 452
ian@0 453 if (!result)
ian@0 454 return 0;
ian@0 455 }
ian@0 456 if (rule->filterkey)
ian@0 457 ctx->filterkey = kstrdup(rule->filterkey, GFP_ATOMIC);
ian@0 458 switch (rule->action) {
ian@0 459 case AUDIT_NEVER: *state = AUDIT_DISABLED; break;
ian@0 460 case AUDIT_ALWAYS: *state = AUDIT_RECORD_CONTEXT; break;
ian@0 461 }
ian@0 462 return 1;
ian@0 463 }
ian@0 464
ian@0 465 /* At process creation time, we can determine if system-call auditing is
ian@0 466 * completely disabled for this task. Since we only have the task
ian@0 467 * structure at this point, we can only check uid and gid.
ian@0 468 */
ian@0 469 static enum audit_state audit_filter_task(struct task_struct *tsk)
ian@0 470 {
ian@0 471 struct audit_entry *e;
ian@0 472 enum audit_state state;
ian@0 473
ian@0 474 rcu_read_lock();
ian@0 475 list_for_each_entry_rcu(e, &audit_filter_list[AUDIT_FILTER_TASK], list) {
ian@0 476 if (audit_filter_rules(tsk, &e->rule, NULL, NULL, &state)) {
ian@0 477 rcu_read_unlock();
ian@0 478 return state;
ian@0 479 }
ian@0 480 }
ian@0 481 rcu_read_unlock();
ian@0 482 return AUDIT_BUILD_CONTEXT;
ian@0 483 }
ian@0 484
ian@0 485 /* At syscall entry and exit time, this filter is called if the
ian@0 486 * audit_state is not low enough that auditing cannot take place, but is
ian@0 487 * also not high enough that we already know we have to write an audit
ian@0 488 * record (i.e., the state is AUDIT_SETUP_CONTEXT or AUDIT_BUILD_CONTEXT).
ian@0 489 */
ian@0 490 static enum audit_state audit_filter_syscall(struct task_struct *tsk,
ian@0 491 struct audit_context *ctx,
ian@0 492 struct list_head *list)
ian@0 493 {
ian@0 494 struct audit_entry *e;
ian@0 495 enum audit_state state;
ian@0 496
ian@0 497 if (audit_pid && tsk->tgid == audit_pid)
ian@0 498 return AUDIT_DISABLED;
ian@0 499
ian@0 500 rcu_read_lock();
ian@0 501 if (!list_empty(list)) {
ian@0 502 int word = AUDIT_WORD(ctx->major);
ian@0 503 int bit = AUDIT_BIT(ctx->major);
ian@0 504
ian@0 505 list_for_each_entry_rcu(e, list, list) {
ian@0 506 if ((e->rule.mask[word] & bit) == bit &&
ian@0 507 audit_filter_rules(tsk, &e->rule, ctx, NULL,
ian@0 508 &state)) {
ian@0 509 rcu_read_unlock();
ian@0 510 return state;
ian@0 511 }
ian@0 512 }
ian@0 513 }
ian@0 514 rcu_read_unlock();
ian@0 515 return AUDIT_BUILD_CONTEXT;
ian@0 516 }
ian@0 517
ian@0 518 /* At syscall exit time, this filter is called if any audit_names[] have been
ian@0 519 * collected during syscall processing. We only check rules in sublists at hash
ian@0 520 * buckets applicable to the inode numbers in audit_names[].
ian@0 521 * Regarding audit_state, same rules apply as for audit_filter_syscall().
ian@0 522 */
ian@0 523 enum audit_state audit_filter_inodes(struct task_struct *tsk,
ian@0 524 struct audit_context *ctx)
ian@0 525 {
ian@0 526 int i;
ian@0 527 struct audit_entry *e;
ian@0 528 enum audit_state state;
ian@0 529
ian@0 530 if (audit_pid && tsk->tgid == audit_pid)
ian@0 531 return AUDIT_DISABLED;
ian@0 532
ian@0 533 rcu_read_lock();
ian@0 534 for (i = 0; i < ctx->name_count; i++) {
ian@0 535 int word = AUDIT_WORD(ctx->major);
ian@0 536 int bit = AUDIT_BIT(ctx->major);
ian@0 537 struct audit_names *n = &ctx->names[i];
ian@0 538 int h = audit_hash_ino((u32)n->ino);
ian@0 539 struct list_head *list = &audit_inode_hash[h];
ian@0 540
ian@0 541 if (list_empty(list))
ian@0 542 continue;
ian@0 543
ian@0 544 list_for_each_entry_rcu(e, list, list) {
ian@0 545 if ((e->rule.mask[word] & bit) == bit &&
ian@0 546 audit_filter_rules(tsk, &e->rule, ctx, n, &state)) {
ian@0 547 rcu_read_unlock();
ian@0 548 return state;
ian@0 549 }
ian@0 550 }
ian@0 551 }
ian@0 552 rcu_read_unlock();
ian@0 553 return AUDIT_BUILD_CONTEXT;
ian@0 554 }
ian@0 555
ian@0 556 void audit_set_auditable(struct audit_context *ctx)
ian@0 557 {
ian@0 558 ctx->auditable = 1;
ian@0 559 }
ian@0 560
ian@0 561 static inline struct audit_context *audit_get_context(struct task_struct *tsk,
ian@0 562 int return_valid,
ian@0 563 int return_code)
ian@0 564 {
ian@0 565 struct audit_context *context = tsk->audit_context;
ian@0 566
ian@0 567 if (likely(!context))
ian@0 568 return NULL;
ian@0 569 context->return_valid = return_valid;
ian@0 570 context->return_code = return_code;
ian@0 571
ian@0 572 if (context->in_syscall && !context->dummy && !context->auditable) {
ian@0 573 enum audit_state state;
ian@0 574
ian@0 575 state = audit_filter_syscall(tsk, context, &audit_filter_list[AUDIT_FILTER_EXIT]);
ian@0 576 if (state == AUDIT_RECORD_CONTEXT) {
ian@0 577 context->auditable = 1;
ian@0 578 goto get_context;
ian@0 579 }
ian@0 580
ian@0 581 state = audit_filter_inodes(tsk, context);
ian@0 582 if (state == AUDIT_RECORD_CONTEXT)
ian@0 583 context->auditable = 1;
ian@0 584
ian@0 585 }
ian@0 586
ian@0 587 get_context:
ian@0 588
ian@0 589 tsk->audit_context = NULL;
ian@0 590 return context;
ian@0 591 }
ian@0 592
ian@0 593 static inline void audit_free_names(struct audit_context *context)
ian@0 594 {
ian@0 595 int i;
ian@0 596
ian@0 597 #if AUDIT_DEBUG == 2
ian@0 598 if (context->auditable
ian@0 599 ||context->put_count + context->ino_count != context->name_count) {
ian@0 600 printk(KERN_ERR "%s:%d(:%d): major=%d in_syscall=%d"
ian@0 601 " name_count=%d put_count=%d"
ian@0 602 " ino_count=%d [NOT freeing]\n",
ian@0 603 __FILE__, __LINE__,
ian@0 604 context->serial, context->major, context->in_syscall,
ian@0 605 context->name_count, context->put_count,
ian@0 606 context->ino_count);
ian@0 607 for (i = 0; i < context->name_count; i++) {
ian@0 608 printk(KERN_ERR "names[%d] = %p = %s\n", i,
ian@0 609 context->names[i].name,
ian@0 610 context->names[i].name ?: "(null)");
ian@0 611 }
ian@0 612 dump_stack();
ian@0 613 return;
ian@0 614 }
ian@0 615 #endif
ian@0 616 #if AUDIT_DEBUG
ian@0 617 context->put_count = 0;
ian@0 618 context->ino_count = 0;
ian@0 619 #endif
ian@0 620
ian@0 621 for (i = 0; i < context->name_count; i++) {
ian@0 622 if (context->names[i].name && context->names[i].name_put)
ian@0 623 __putname(context->names[i].name);
ian@0 624 }
ian@0 625 context->name_count = 0;
ian@0 626 if (context->pwd)
ian@0 627 dput(context->pwd);
ian@0 628 if (context->pwdmnt)
ian@0 629 mntput(context->pwdmnt);
ian@0 630 context->pwd = NULL;
ian@0 631 context->pwdmnt = NULL;
ian@0 632 }
ian@0 633
ian@0 634 static inline void audit_free_aux(struct audit_context *context)
ian@0 635 {
ian@0 636 struct audit_aux_data *aux;
ian@0 637
ian@0 638 while ((aux = context->aux)) {
ian@0 639 if (aux->type == AUDIT_AVC_PATH) {
ian@0 640 struct audit_aux_data_path *axi = (void *)aux;
ian@0 641 dput(axi->dentry);
ian@0 642 mntput(axi->mnt);
ian@0 643 }
ian@0 644
ian@0 645 context->aux = aux->next;
ian@0 646 kfree(aux);
ian@0 647 }
ian@0 648 }
ian@0 649
ian@0 650 static inline void audit_zero_context(struct audit_context *context,
ian@0 651 enum audit_state state)
ian@0 652 {
ian@0 653 uid_t loginuid = context->loginuid;
ian@0 654
ian@0 655 memset(context, 0, sizeof(*context));
ian@0 656 context->state = state;
ian@0 657 context->loginuid = loginuid;
ian@0 658 }
ian@0 659
ian@0 660 static inline struct audit_context *audit_alloc_context(enum audit_state state)
ian@0 661 {
ian@0 662 struct audit_context *context;
ian@0 663
ian@0 664 if (!(context = kmalloc(sizeof(*context), GFP_KERNEL)))
ian@0 665 return NULL;
ian@0 666 audit_zero_context(context, state);
ian@0 667 return context;
ian@0 668 }
ian@0 669
ian@0 670 /**
ian@0 671 * audit_alloc - allocate an audit context block for a task
ian@0 672 * @tsk: task
ian@0 673 *
ian@0 674 * Filter on the task information and allocate a per-task audit context
ian@0 675 * if necessary. Doing so turns on system call auditing for the
ian@0 676 * specified task. This is called from copy_process, so no lock is
ian@0 677 * needed.
ian@0 678 */
ian@0 679 int audit_alloc(struct task_struct *tsk)
ian@0 680 {
ian@0 681 struct audit_context *context;
ian@0 682 enum audit_state state;
ian@0 683
ian@0 684 if (likely(!audit_enabled))
ian@0 685 return 0; /* Return if not auditing. */
ian@0 686
ian@0 687 state = audit_filter_task(tsk);
ian@0 688 if (likely(state == AUDIT_DISABLED))
ian@0 689 return 0;
ian@0 690
ian@0 691 if (!(context = audit_alloc_context(state))) {
ian@0 692 audit_log_lost("out of memory in audit_alloc");
ian@0 693 return -ENOMEM;
ian@0 694 }
ian@0 695
ian@0 696 /* Preserve login uid */
ian@0 697 context->loginuid = -1;
ian@0 698 if (current->audit_context)
ian@0 699 context->loginuid = current->audit_context->loginuid;
ian@0 700
ian@0 701 tsk->audit_context = context;
ian@0 702 set_tsk_thread_flag(tsk, TIF_SYSCALL_AUDIT);
ian@0 703 return 0;
ian@0 704 }
ian@0 705
ian@0 706 static inline void audit_free_context(struct audit_context *context)
ian@0 707 {
ian@0 708 struct audit_context *previous;
ian@0 709 int count = 0;
ian@0 710
ian@0 711 do {
ian@0 712 previous = context->previous;
ian@0 713 if (previous || (count && count < 10)) {
ian@0 714 ++count;
ian@0 715 printk(KERN_ERR "audit(:%d): major=%d name_count=%d:"
ian@0 716 " freeing multiple contexts (%d)\n",
ian@0 717 context->serial, context->major,
ian@0 718 context->name_count, count);
ian@0 719 }
ian@0 720 audit_free_names(context);
ian@0 721 audit_free_aux(context);
ian@0 722 kfree(context->filterkey);
ian@0 723 kfree(context);
ian@0 724 context = previous;
ian@0 725 } while (context);
ian@0 726 if (count >= 10)
ian@0 727 printk(KERN_ERR "audit: freed %d contexts\n", count);
ian@0 728 }
ian@0 729
ian@0 730 static void audit_log_task_context(struct audit_buffer *ab)
ian@0 731 {
ian@0 732 char *ctx = NULL;
ian@0 733 ssize_t len = 0;
ian@0 734
ian@0 735 len = security_getprocattr(current, "current", NULL, 0);
ian@0 736 if (len < 0) {
ian@0 737 if (len != -EINVAL)
ian@0 738 goto error_path;
ian@0 739 return;
ian@0 740 }
ian@0 741
ian@0 742 ctx = kmalloc(len, GFP_KERNEL);
ian@0 743 if (!ctx)
ian@0 744 goto error_path;
ian@0 745
ian@0 746 len = security_getprocattr(current, "current", ctx, len);
ian@0 747 if (len < 0 )
ian@0 748 goto error_path;
ian@0 749
ian@0 750 audit_log_format(ab, " subj=%s", ctx);
ian@0 751 return;
ian@0 752
ian@0 753 error_path:
ian@0 754 kfree(ctx);
ian@0 755 audit_panic("error in audit_log_task_context");
ian@0 756 return;
ian@0 757 }
ian@0 758
ian@0 759 static void audit_log_task_info(struct audit_buffer *ab, struct task_struct *tsk)
ian@0 760 {
ian@0 761 char name[sizeof(tsk->comm)];
ian@0 762 struct mm_struct *mm = tsk->mm;
ian@0 763 struct vm_area_struct *vma;
ian@0 764
ian@0 765 /* tsk == current */
ian@0 766
ian@0 767 get_task_comm(name, tsk);
ian@0 768 audit_log_format(ab, " comm=");
ian@0 769 audit_log_untrustedstring(ab, name);
ian@0 770
ian@0 771 if (mm) {
ian@0 772 down_read(&mm->mmap_sem);
ian@0 773 vma = mm->mmap;
ian@0 774 while (vma) {
ian@0 775 if ((vma->vm_flags & VM_EXECUTABLE) &&
ian@0 776 vma->vm_file) {
ian@0 777 audit_log_d_path(ab, "exe=",
ian@0 778 vma->vm_file->f_dentry,
ian@0 779 vma->vm_file->f_vfsmnt);
ian@0 780 break;
ian@0 781 }
ian@0 782 vma = vma->vm_next;
ian@0 783 }
ian@0 784 up_read(&mm->mmap_sem);
ian@0 785 }
ian@0 786 audit_log_task_context(ab);
ian@0 787 }
ian@0 788
ian@0 789 static void audit_log_exit(struct audit_context *context, struct task_struct *tsk)
ian@0 790 {
ian@0 791 int i, call_panic = 0;
ian@0 792 struct audit_buffer *ab;
ian@0 793 struct audit_aux_data *aux;
ian@0 794 const char *tty;
ian@0 795
ian@0 796 /* tsk == current */
ian@0 797 context->pid = tsk->pid;
ian@0 798 context->ppid = sys_getppid(); /* sic. tsk == current in all cases */
ian@0 799 context->uid = tsk->uid;
ian@0 800 context->gid = tsk->gid;
ian@0 801 context->euid = tsk->euid;
ian@0 802 context->suid = tsk->suid;
ian@0 803 context->fsuid = tsk->fsuid;
ian@0 804 context->egid = tsk->egid;
ian@0 805 context->sgid = tsk->sgid;
ian@0 806 context->fsgid = tsk->fsgid;
ian@0 807 context->personality = tsk->personality;
ian@0 808
ian@0 809 ab = audit_log_start(context, GFP_KERNEL, AUDIT_SYSCALL);
ian@0 810 if (!ab)
ian@0 811 return; /* audit_panic has been called */
ian@0 812 audit_log_format(ab, "arch=%x syscall=%d",
ian@0 813 context->arch, context->major);
ian@0 814 if (context->personality != PER_LINUX)
ian@0 815 audit_log_format(ab, " per=%lx", context->personality);
ian@0 816 if (context->return_valid)
ian@0 817 audit_log_format(ab, " success=%s exit=%ld",
ian@0 818 (context->return_valid==AUDITSC_SUCCESS)?"yes":"no",
ian@0 819 context->return_code);
ian@0 820 if (tsk->signal && tsk->signal->tty && tsk->signal->tty->name)
ian@0 821 tty = tsk->signal->tty->name;
ian@0 822 else
ian@0 823 tty = "(none)";
ian@0 824 audit_log_format(ab,
ian@0 825 " a0=%lx a1=%lx a2=%lx a3=%lx items=%d"
ian@0 826 " ppid=%d pid=%d auid=%u uid=%u gid=%u"
ian@0 827 " euid=%u suid=%u fsuid=%u"
ian@0 828 " egid=%u sgid=%u fsgid=%u tty=%s",
ian@0 829 context->argv[0],
ian@0 830 context->argv[1],
ian@0 831 context->argv[2],
ian@0 832 context->argv[3],
ian@0 833 context->name_count,
ian@0 834 context->ppid,
ian@0 835 context->pid,
ian@0 836 context->loginuid,
ian@0 837 context->uid,
ian@0 838 context->gid,
ian@0 839 context->euid, context->suid, context->fsuid,
ian@0 840 context->egid, context->sgid, context->fsgid, tty);
ian@0 841 audit_log_task_info(ab, tsk);
ian@0 842 if (context->filterkey) {
ian@0 843 audit_log_format(ab, " key=");
ian@0 844 audit_log_untrustedstring(ab, context->filterkey);
ian@0 845 } else
ian@0 846 audit_log_format(ab, " key=(null)");
ian@0 847 audit_log_end(ab);
ian@0 848
ian@0 849 for (aux = context->aux; aux; aux = aux->next) {
ian@0 850
ian@0 851 ab = audit_log_start(context, GFP_KERNEL, aux->type);
ian@0 852 if (!ab)
ian@0 853 continue; /* audit_panic has been called */
ian@0 854
ian@0 855 switch (aux->type) {
ian@0 856 case AUDIT_MQ_OPEN: {
ian@0 857 struct audit_aux_data_mq_open *axi = (void *)aux;
ian@0 858 audit_log_format(ab,
ian@0 859 "oflag=0x%x mode=%#o mq_flags=0x%lx mq_maxmsg=%ld "
ian@0 860 "mq_msgsize=%ld mq_curmsgs=%ld",
ian@0 861 axi->oflag, axi->mode, axi->attr.mq_flags,
ian@0 862 axi->attr.mq_maxmsg, axi->attr.mq_msgsize,
ian@0 863 axi->attr.mq_curmsgs);
ian@0 864 break; }
ian@0 865
ian@0 866 case AUDIT_MQ_SENDRECV: {
ian@0 867 struct audit_aux_data_mq_sendrecv *axi = (void *)aux;
ian@0 868 audit_log_format(ab,
ian@0 869 "mqdes=%d msg_len=%zd msg_prio=%u "
ian@0 870 "abs_timeout_sec=%ld abs_timeout_nsec=%ld",
ian@0 871 axi->mqdes, axi->msg_len, axi->msg_prio,
ian@0 872 axi->abs_timeout.tv_sec, axi->abs_timeout.tv_nsec);
ian@0 873 break; }
ian@0 874
ian@0 875 case AUDIT_MQ_NOTIFY: {
ian@0 876 struct audit_aux_data_mq_notify *axi = (void *)aux;
ian@0 877 audit_log_format(ab,
ian@0 878 "mqdes=%d sigev_signo=%d",
ian@0 879 axi->mqdes,
ian@0 880 axi->notification.sigev_signo);
ian@0 881 break; }
ian@0 882
ian@0 883 case AUDIT_MQ_GETSETATTR: {
ian@0 884 struct audit_aux_data_mq_getsetattr *axi = (void *)aux;
ian@0 885 audit_log_format(ab,
ian@0 886 "mqdes=%d mq_flags=0x%lx mq_maxmsg=%ld mq_msgsize=%ld "
ian@0 887 "mq_curmsgs=%ld ",
ian@0 888 axi->mqdes,
ian@0 889 axi->mqstat.mq_flags, axi->mqstat.mq_maxmsg,
ian@0 890 axi->mqstat.mq_msgsize, axi->mqstat.mq_curmsgs);
ian@0 891 break; }
ian@0 892
ian@0 893 case AUDIT_IPC: {
ian@0 894 struct audit_aux_data_ipcctl *axi = (void *)aux;
ian@0 895 audit_log_format(ab,
ian@0 896 "ouid=%u ogid=%u mode=%x",
ian@0 897 axi->uid, axi->gid, axi->mode);
ian@0 898 if (axi->osid != 0) {
ian@0 899 char *ctx = NULL;
ian@0 900 u32 len;
ian@0 901 if (selinux_ctxid_to_string(
ian@0 902 axi->osid, &ctx, &len)) {
ian@0 903 audit_log_format(ab, " osid=%u",
ian@0 904 axi->osid);
ian@0 905 call_panic = 1;
ian@0 906 } else
ian@0 907 audit_log_format(ab, " obj=%s", ctx);
ian@0 908 kfree(ctx);
ian@0 909 }
ian@0 910 break; }
ian@0 911
ian@0 912 case AUDIT_IPC_SET_PERM: {
ian@0 913 struct audit_aux_data_ipcctl *axi = (void *)aux;
ian@0 914 audit_log_format(ab,
ian@0 915 "qbytes=%lx ouid=%u ogid=%u mode=%x",
ian@0 916 axi->qbytes, axi->uid, axi->gid, axi->mode);
ian@0 917 break; }
ian@0 918
ian@0 919 case AUDIT_EXECVE: {
ian@0 920 struct audit_aux_data_execve *axi = (void *)aux;
ian@0 921 int i;
ian@0 922 const char *p;
ian@0 923 for (i = 0, p = axi->mem; i < axi->argc; i++) {
ian@0 924 audit_log_format(ab, "a%d=", i);
ian@0 925 p = audit_log_untrustedstring(ab, p);
ian@0 926 audit_log_format(ab, "\n");
ian@0 927 }
ian@0 928 break; }
ian@0 929
ian@0 930 case AUDIT_SOCKETCALL: {
ian@0 931 int i;
ian@0 932 struct audit_aux_data_socketcall *axs = (void *)aux;
ian@0 933 audit_log_format(ab, "nargs=%d", axs->nargs);
ian@0 934 for (i=0; i<axs->nargs; i++)
ian@0 935 audit_log_format(ab, " a%d=%lx", i, axs->args[i]);
ian@0 936 break; }
ian@0 937
ian@0 938 case AUDIT_SOCKADDR: {
ian@0 939 struct audit_aux_data_sockaddr *axs = (void *)aux;
ian@0 940
ian@0 941 audit_log_format(ab, "saddr=");
ian@0 942 audit_log_hex(ab, axs->a, axs->len);
ian@0 943 break; }
ian@0 944
ian@0 945 case AUDIT_AVC_PATH: {
ian@0 946 struct audit_aux_data_path *axi = (void *)aux;
ian@0 947 audit_log_d_path(ab, "path=", axi->dentry, axi->mnt);
ian@0 948 break; }
ian@0 949
ian@0 950 }
ian@0 951 audit_log_end(ab);
ian@0 952 }
ian@0 953
ian@0 954 if (context->pwd && context->pwdmnt) {
ian@0 955 ab = audit_log_start(context, GFP_KERNEL, AUDIT_CWD);
ian@0 956 if (ab) {
ian@0 957 audit_log_d_path(ab, "cwd=", context->pwd, context->pwdmnt);
ian@0 958 audit_log_end(ab);
ian@0 959 }
ian@0 960 }
ian@0 961 for (i = 0; i < context->name_count; i++) {
ian@0 962 struct audit_names *n = &context->names[i];
ian@0 963
ian@0 964 ab = audit_log_start(context, GFP_KERNEL, AUDIT_PATH);
ian@0 965 if (!ab)
ian@0 966 continue; /* audit_panic has been called */
ian@0 967
ian@0 968 audit_log_format(ab, "item=%d", i);
ian@0 969
ian@0 970 if (n->name) {
ian@0 971 switch(n->name_len) {
ian@0 972 case AUDIT_NAME_FULL:
ian@0 973 /* log the full path */
ian@0 974 audit_log_format(ab, " name=");
ian@0 975 audit_log_untrustedstring(ab, n->name);
ian@0 976 break;
ian@0 977 case 0:
ian@0 978 /* name was specified as a relative path and the
ian@0 979 * directory component is the cwd */
ian@0 980 audit_log_d_path(ab, " name=", context->pwd,
ian@0 981 context->pwdmnt);
ian@0 982 break;
ian@0 983 default:
ian@0 984 /* log the name's directory component */
ian@0 985 audit_log_format(ab, " name=");
ian@0 986 audit_log_n_untrustedstring(ab, n->name_len,
ian@0 987 n->name);
ian@0 988 }
ian@0 989 } else
ian@0 990 audit_log_format(ab, " name=(null)");
ian@0 991
ian@0 992 if (n->ino != (unsigned long)-1) {
ian@0 993 audit_log_format(ab, " inode=%lu"
ian@0 994 " dev=%02x:%02x mode=%#o"
ian@0 995 " ouid=%u ogid=%u rdev=%02x:%02x",
ian@0 996 n->ino,
ian@0 997 MAJOR(n->dev),
ian@0 998 MINOR(n->dev),
ian@0 999 n->mode,
ian@0 1000 n->uid,
ian@0 1001 n->gid,
ian@0 1002 MAJOR(n->rdev),
ian@0 1003 MINOR(n->rdev));
ian@0 1004 }
ian@0 1005 if (n->osid != 0) {
ian@0 1006 char *ctx = NULL;
ian@0 1007 u32 len;
ian@0 1008 if (selinux_ctxid_to_string(
ian@0 1009 n->osid, &ctx, &len)) {
ian@0 1010 audit_log_format(ab, " osid=%u", n->osid);
ian@0 1011 call_panic = 2;
ian@0 1012 } else
ian@0 1013 audit_log_format(ab, " obj=%s", ctx);
ian@0 1014 kfree(ctx);
ian@0 1015 }
ian@0 1016
ian@0 1017 audit_log_end(ab);
ian@0 1018 }
ian@0 1019 if (call_panic)
ian@0 1020 audit_panic("error converting sid to string");
ian@0 1021 }
ian@0 1022
ian@0 1023 /**
ian@0 1024 * audit_free - free a per-task audit context
ian@0 1025 * @tsk: task whose audit context block to free
ian@0 1026 *
ian@0 1027 * Called from copy_process and do_exit
ian@0 1028 */
ian@0 1029 void audit_free(struct task_struct *tsk)
ian@0 1030 {
ian@0 1031 struct audit_context *context;
ian@0 1032
ian@0 1033 context = audit_get_context(tsk, 0, 0);
ian@0 1034 if (likely(!context))
ian@0 1035 return;
ian@0 1036
ian@0 1037 /* Check for system calls that do not go through the exit
ian@0 1038 * function (e.g., exit_group), then free context block.
ian@0 1039 * We use GFP_ATOMIC here because we might be doing this
ian@0 1040 * in the context of the idle thread */
ian@0 1041 /* that can happen only if we are called from do_exit() */
ian@0 1042 if (context->in_syscall && context->auditable)
ian@0 1043 audit_log_exit(context, tsk);
ian@0 1044
ian@0 1045 audit_free_context(context);
ian@0 1046 }
ian@0 1047
ian@0 1048 /**
ian@0 1049 * audit_syscall_entry - fill in an audit record at syscall entry
ian@0 1050 * @tsk: task being audited
ian@0 1051 * @arch: architecture type
ian@0 1052 * @major: major syscall type (function)
ian@0 1053 * @a1: additional syscall register 1
ian@0 1054 * @a2: additional syscall register 2
ian@0 1055 * @a3: additional syscall register 3
ian@0 1056 * @a4: additional syscall register 4
ian@0 1057 *
ian@0 1058 * Fill in audit context at syscall entry. This only happens if the
ian@0 1059 * audit context was created when the task was created and the state or
ian@0 1060 * filters demand the audit context be built. If the state from the
ian@0 1061 * per-task filter or from the per-syscall filter is AUDIT_RECORD_CONTEXT,
ian@0 1062 * then the record will be written at syscall exit time (otherwise, it
ian@0 1063 * will only be written if another part of the kernel requests that it
ian@0 1064 * be written).
ian@0 1065 */
ian@0 1066 void audit_syscall_entry(int arch, int major,
ian@0 1067 unsigned long a1, unsigned long a2,
ian@0 1068 unsigned long a3, unsigned long a4)
ian@0 1069 {
ian@0 1070 struct task_struct *tsk = current;
ian@0 1071 struct audit_context *context = tsk->audit_context;
ian@0 1072 enum audit_state state;
ian@0 1073
ian@0 1074 BUG_ON(!context);
ian@0 1075
ian@0 1076 /*
ian@0 1077 * This happens only on certain architectures that make system
ian@0 1078 * calls in kernel_thread via the entry.S interface, instead of
ian@0 1079 * with direct calls. (If you are porting to a new
ian@0 1080 * architecture, hitting this condition can indicate that you
ian@0 1081 * got the _exit/_leave calls backward in entry.S.)
ian@0 1082 *
ian@0 1083 * i386 no
ian@0 1084 * x86_64 no
ian@0 1085 * ppc64 yes (see arch/powerpc/platforms/iseries/misc.S)
ian@0 1086 *
ian@0 1087 * This also happens with vm86 emulation in a non-nested manner
ian@0 1088 * (entries without exits), so this case must be caught.
ian@0 1089 */
ian@0 1090 if (context->in_syscall) {
ian@0 1091 struct audit_context *newctx;
ian@0 1092
ian@0 1093 #if AUDIT_DEBUG
ian@0 1094 printk(KERN_ERR
ian@0 1095 "audit(:%d) pid=%d in syscall=%d;"
ian@0 1096 " entering syscall=%d\n",
ian@0 1097 context->serial, tsk->pid, context->major, major);
ian@0 1098 #endif
ian@0 1099 newctx = audit_alloc_context(context->state);
ian@0 1100 if (newctx) {
ian@0 1101 newctx->previous = context;
ian@0 1102 context = newctx;
ian@0 1103 tsk->audit_context = newctx;
ian@0 1104 } else {
ian@0 1105 /* If we can't alloc a new context, the best we
ian@0 1106 * can do is to leak memory (any pending putname
ian@0 1107 * will be lost). The only other alternative is
ian@0 1108 * to abandon auditing. */
ian@0 1109 audit_zero_context(context, context->state);
ian@0 1110 }
ian@0 1111 }
ian@0 1112 BUG_ON(context->in_syscall || context->name_count);
ian@0 1113
ian@0 1114 if (!audit_enabled)
ian@0 1115 return;
ian@0 1116
ian@0 1117 context->arch = arch;
ian@0 1118 context->major = major;
ian@0 1119 context->argv[0] = a1;
ian@0 1120 context->argv[1] = a2;
ian@0 1121 context->argv[2] = a3;
ian@0 1122 context->argv[3] = a4;
ian@0 1123
ian@0 1124 state = context->state;
ian@0 1125 context->dummy = !audit_n_rules;
ian@0 1126 if (!context->dummy && (state == AUDIT_SETUP_CONTEXT || state == AUDIT_BUILD_CONTEXT))
ian@0 1127 state = audit_filter_syscall(tsk, context, &audit_filter_list[AUDIT_FILTER_ENTRY]);
ian@0 1128 if (likely(state == AUDIT_DISABLED))
ian@0 1129 return;
ian@0 1130
ian@0 1131 context->serial = 0;
ian@0 1132 context->ctime = CURRENT_TIME;
ian@0 1133 context->in_syscall = 1;
ian@0 1134 context->auditable = !!(state == AUDIT_RECORD_CONTEXT);
ian@0 1135 }
ian@0 1136
ian@0 1137 /**
ian@0 1138 * audit_syscall_exit - deallocate audit context after a system call
ian@0 1139 * @tsk: task being audited
ian@0 1140 * @valid: success/failure flag
ian@0 1141 * @return_code: syscall return value
ian@0 1142 *
ian@0 1143 * Tear down after system call. If the audit context has been marked as
ian@0 1144 * auditable (either because of the AUDIT_RECORD_CONTEXT state from
ian@0 1145 * filtering, or because some other part of the kernel write an audit
ian@0 1146 * message), then write out the syscall information. In call cases,
ian@0 1147 * free the names stored from getname().
ian@0 1148 */
ian@0 1149 void audit_syscall_exit(int valid, long return_code)
ian@0 1150 {
ian@0 1151 struct task_struct *tsk = current;
ian@0 1152 struct audit_context *context;
ian@0 1153
ian@0 1154 context = audit_get_context(tsk, valid, return_code);
ian@0 1155
ian@0 1156 if (likely(!context))
ian@0 1157 return;
ian@0 1158
ian@0 1159 if (context->in_syscall && context->auditable)
ian@0 1160 audit_log_exit(context, tsk);
ian@0 1161
ian@0 1162 context->in_syscall = 0;
ian@0 1163 context->auditable = 0;
ian@0 1164
ian@0 1165 if (context->previous) {
ian@0 1166 struct audit_context *new_context = context->previous;
ian@0 1167 context->previous = NULL;
ian@0 1168 audit_free_context(context);
ian@0 1169 tsk->audit_context = new_context;
ian@0 1170 } else {
ian@0 1171 audit_free_names(context);
ian@0 1172 audit_free_aux(context);
ian@0 1173 kfree(context->filterkey);
ian@0 1174 context->filterkey = NULL;
ian@0 1175 tsk->audit_context = context;
ian@0 1176 }
ian@0 1177 }
ian@0 1178
ian@0 1179 /**
ian@0 1180 * audit_getname - add a name to the list
ian@0 1181 * @name: name to add
ian@0 1182 *
ian@0 1183 * Add a name to the list of audit names for this context.
ian@0 1184 * Called from fs/namei.c:getname().
ian@0 1185 */
ian@0 1186 void __audit_getname(const char *name)
ian@0 1187 {
ian@0 1188 struct audit_context *context = current->audit_context;
ian@0 1189
ian@0 1190 if (IS_ERR(name) || !name)
ian@0 1191 return;
ian@0 1192
ian@0 1193 if (!context->in_syscall) {
ian@0 1194 #if AUDIT_DEBUG == 2
ian@0 1195 printk(KERN_ERR "%s:%d(:%d): ignoring getname(%p)\n",
ian@0 1196 __FILE__, __LINE__, context->serial, name);
ian@0 1197 dump_stack();
ian@0 1198 #endif
ian@0 1199 return;
ian@0 1200 }
ian@0 1201 BUG_ON(context->name_count >= AUDIT_NAMES);
ian@0 1202 context->names[context->name_count].name = name;
ian@0 1203 context->names[context->name_count].name_len = AUDIT_NAME_FULL;
ian@0 1204 context->names[context->name_count].name_put = 1;
ian@0 1205 context->names[context->name_count].ino = (unsigned long)-1;
ian@0 1206 ++context->name_count;
ian@0 1207 if (!context->pwd) {
ian@0 1208 read_lock(&current->fs->lock);
ian@0 1209 context->pwd = dget(current->fs->pwd);
ian@0 1210 context->pwdmnt = mntget(current->fs->pwdmnt);
ian@0 1211 read_unlock(&current->fs->lock);
ian@0 1212 }
ian@0 1213
ian@0 1214 }
ian@0 1215
ian@0 1216 /* audit_putname - intercept a putname request
ian@0 1217 * @name: name to intercept and delay for putname
ian@0 1218 *
ian@0 1219 * If we have stored the name from getname in the audit context,
ian@0 1220 * then we delay the putname until syscall exit.
ian@0 1221 * Called from include/linux/fs.h:putname().
ian@0 1222 */
ian@0 1223 void audit_putname(const char *name)
ian@0 1224 {
ian@0 1225 struct audit_context *context = current->audit_context;
ian@0 1226
ian@0 1227 BUG_ON(!context);
ian@0 1228 if (!context->in_syscall) {
ian@0 1229 #if AUDIT_DEBUG == 2
ian@0 1230 printk(KERN_ERR "%s:%d(:%d): __putname(%p)\n",
ian@0 1231 __FILE__, __LINE__, context->serial, name);
ian@0 1232 if (context->name_count) {
ian@0 1233 int i;
ian@0 1234 for (i = 0; i < context->name_count; i++)
ian@0 1235 printk(KERN_ERR "name[%d] = %p = %s\n", i,
ian@0 1236 context->names[i].name,
ian@0 1237 context->names[i].name ?: "(null)");
ian@0 1238 }
ian@0 1239 #endif
ian@0 1240 __putname(name);
ian@0 1241 }
ian@0 1242 #if AUDIT_DEBUG
ian@0 1243 else {
ian@0 1244 ++context->put_count;
ian@0 1245 if (context->put_count > context->name_count) {
ian@0 1246 printk(KERN_ERR "%s:%d(:%d): major=%d"
ian@0 1247 " in_syscall=%d putname(%p) name_count=%d"
ian@0 1248 " put_count=%d\n",
ian@0 1249 __FILE__, __LINE__,
ian@0 1250 context->serial, context->major,
ian@0 1251 context->in_syscall, name, context->name_count,
ian@0 1252 context->put_count);
ian@0 1253 dump_stack();
ian@0 1254 }
ian@0 1255 }
ian@0 1256 #endif
ian@0 1257 }
ian@0 1258
ian@0 1259 /* Copy inode data into an audit_names. */
ian@0 1260 static void audit_copy_inode(struct audit_names *name, const struct inode *inode)
ian@0 1261 {
ian@0 1262 name->ino = inode->i_ino;
ian@0 1263 name->dev = inode->i_sb->s_dev;
ian@0 1264 name->mode = inode->i_mode;
ian@0 1265 name->uid = inode->i_uid;
ian@0 1266 name->gid = inode->i_gid;
ian@0 1267 name->rdev = inode->i_rdev;
ian@0 1268 selinux_get_inode_sid(inode, &name->osid);
ian@0 1269 }
ian@0 1270
ian@0 1271 /**
ian@0 1272 * audit_inode - store the inode and device from a lookup
ian@0 1273 * @name: name being audited
ian@0 1274 * @inode: inode being audited
ian@0 1275 *
ian@0 1276 * Called from fs/namei.c:path_lookup().
ian@0 1277 */
ian@0 1278 void __audit_inode(const char *name, const struct inode *inode)
ian@0 1279 {
ian@0 1280 int idx;
ian@0 1281 struct audit_context *context = current->audit_context;
ian@0 1282
ian@0 1283 if (!context->in_syscall)
ian@0 1284 return;
ian@0 1285 if (context->name_count
ian@0 1286 && context->names[context->name_count-1].name
ian@0 1287 && context->names[context->name_count-1].name == name)
ian@0 1288 idx = context->name_count - 1;
ian@0 1289 else if (context->name_count > 1
ian@0 1290 && context->names[context->name_count-2].name
ian@0 1291 && context->names[context->name_count-2].name == name)
ian@0 1292 idx = context->name_count - 2;
ian@0 1293 else {
ian@0 1294 /* FIXME: how much do we care about inodes that have no
ian@0 1295 * associated name? */
ian@0 1296 if (context->name_count >= AUDIT_NAMES - AUDIT_NAMES_RESERVED)
ian@0 1297 return;
ian@0 1298 idx = context->name_count++;
ian@0 1299 context->names[idx].name = NULL;
ian@0 1300 #if AUDIT_DEBUG
ian@0 1301 ++context->ino_count;
ian@0 1302 #endif
ian@0 1303 }
ian@0 1304 audit_copy_inode(&context->names[idx], inode);
ian@0 1305 }
ian@0 1306
ian@0 1307 /**
ian@0 1308 * audit_inode_child - collect inode info for created/removed objects
ian@0 1309 * @dname: inode's dentry name
ian@0 1310 * @inode: inode being audited
ian@0 1311 * @parent: inode of dentry parent
ian@0 1312 *
ian@0 1313 * For syscalls that create or remove filesystem objects, audit_inode
ian@0 1314 * can only collect information for the filesystem object's parent.
ian@0 1315 * This call updates the audit context with the child's information.
ian@0 1316 * Syscalls that create a new filesystem object must be hooked after
ian@0 1317 * the object is created. Syscalls that remove a filesystem object
ian@0 1318 * must be hooked prior, in order to capture the target inode during
ian@0 1319 * unsuccessful attempts.
ian@0 1320 */
ian@0 1321 void __audit_inode_child(const char *dname, const struct inode *inode,
ian@0 1322 const struct inode *parent)
ian@0 1323 {
ian@0 1324 int idx;
ian@0 1325 struct audit_context *context = current->audit_context;
ian@0 1326 const char *found_name = NULL;
ian@0 1327 int dirlen = 0;
ian@0 1328
ian@0 1329 if (!context->in_syscall)
ian@0 1330 return;
ian@0 1331
ian@0 1332 /* determine matching parent */
ian@0 1333 if (!dname)
ian@0 1334 goto update_context;
ian@0 1335 for (idx = 0; idx < context->name_count; idx++)
ian@0 1336 if (context->names[idx].ino == parent->i_ino) {
ian@0 1337 const char *name = context->names[idx].name;
ian@0 1338
ian@0 1339 if (!name)
ian@0 1340 continue;
ian@0 1341
ian@0 1342 if (audit_compare_dname_path(dname, name, &dirlen) == 0) {
ian@0 1343 context->names[idx].name_len = dirlen;
ian@0 1344 found_name = name;
ian@0 1345 break;
ian@0 1346 }
ian@0 1347 }
ian@0 1348
ian@0 1349 update_context:
ian@0 1350 idx = context->name_count++;
ian@0 1351 #if AUDIT_DEBUG
ian@0 1352 context->ino_count++;
ian@0 1353 #endif
ian@0 1354 /* Re-use the name belonging to the slot for a matching parent directory.
ian@0 1355 * All names for this context are relinquished in audit_free_names() */
ian@0 1356 context->names[idx].name = found_name;
ian@0 1357 context->names[idx].name_len = AUDIT_NAME_FULL;
ian@0 1358 context->names[idx].name_put = 0; /* don't call __putname() */
ian@0 1359
ian@0 1360 if (!inode)
ian@0 1361 context->names[idx].ino = (unsigned long)-1;
ian@0 1362 else
ian@0 1363 audit_copy_inode(&context->names[idx], inode);
ian@0 1364
ian@0 1365 /* A parent was not found in audit_names, so copy the inode data for the
ian@0 1366 * provided parent. */
ian@0 1367 if (!found_name) {
ian@0 1368 idx = context->name_count++;
ian@0 1369 #if AUDIT_DEBUG
ian@0 1370 context->ino_count++;
ian@0 1371 #endif
ian@0 1372 audit_copy_inode(&context->names[idx], parent);
ian@0 1373 }
ian@0 1374 }
ian@0 1375
ian@0 1376 /**
ian@0 1377 * audit_inode_update - update inode info for last collected name
ian@0 1378 * @inode: inode being audited
ian@0 1379 *
ian@0 1380 * When open() is called on an existing object with the O_CREAT flag, the inode
ian@0 1381 * data audit initially collects is incorrect. This additional hook ensures
ian@0 1382 * audit has the inode data for the actual object to be opened.
ian@0 1383 */
ian@0 1384 void __audit_inode_update(const struct inode *inode)
ian@0 1385 {
ian@0 1386 struct audit_context *context = current->audit_context;
ian@0 1387 int idx;
ian@0 1388
ian@0 1389 if (!context->in_syscall || !inode)
ian@0 1390 return;
ian@0 1391
ian@0 1392 if (context->name_count == 0) {
ian@0 1393 context->name_count++;
ian@0 1394 #if AUDIT_DEBUG
ian@0 1395 context->ino_count++;
ian@0 1396 #endif
ian@0 1397 }
ian@0 1398 idx = context->name_count - 1;
ian@0 1399
ian@0 1400 audit_copy_inode(&context->names[idx], inode);
ian@0 1401 }
ian@0 1402
ian@0 1403 /**
ian@0 1404 * auditsc_get_stamp - get local copies of audit_context values
ian@0 1405 * @ctx: audit_context for the task
ian@0 1406 * @t: timespec to store time recorded in the audit_context
ian@0 1407 * @serial: serial value that is recorded in the audit_context
ian@0 1408 *
ian@0 1409 * Also sets the context as auditable.
ian@0 1410 */
ian@0 1411 void auditsc_get_stamp(struct audit_context *ctx,
ian@0 1412 struct timespec *t, unsigned int *serial)
ian@0 1413 {
ian@0 1414 if (!ctx->serial)
ian@0 1415 ctx->serial = audit_serial();
ian@0 1416 t->tv_sec = ctx->ctime.tv_sec;
ian@0 1417 t->tv_nsec = ctx->ctime.tv_nsec;
ian@0 1418 *serial = ctx->serial;
ian@0 1419 ctx->auditable = 1;
ian@0 1420 }
ian@0 1421
ian@0 1422 /**
ian@0 1423 * audit_set_loginuid - set a task's audit_context loginuid
ian@0 1424 * @task: task whose audit context is being modified
ian@0 1425 * @loginuid: loginuid value
ian@0 1426 *
ian@0 1427 * Returns 0.
ian@0 1428 *
ian@0 1429 * Called (set) from fs/proc/base.c::proc_loginuid_write().
ian@0 1430 */
ian@0 1431 int audit_set_loginuid(struct task_struct *task, uid_t loginuid)
ian@0 1432 {
ian@0 1433 struct audit_context *context = task->audit_context;
ian@0 1434
ian@0 1435 if (context) {
ian@0 1436 /* Only log if audit is enabled */
ian@0 1437 if (context->in_syscall) {
ian@0 1438 struct audit_buffer *ab;
ian@0 1439
ian@0 1440 ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_LOGIN);
ian@0 1441 if (ab) {
ian@0 1442 audit_log_format(ab, "login pid=%d uid=%u "
ian@0 1443 "old auid=%u new auid=%u",
ian@0 1444 task->pid, task->uid,
ian@0 1445 context->loginuid, loginuid);
ian@0 1446 audit_log_end(ab);
ian@0 1447 }
ian@0 1448 }
ian@0 1449 context->loginuid = loginuid;
ian@0 1450 }
ian@0 1451 return 0;
ian@0 1452 }
ian@0 1453
ian@0 1454 /**
ian@0 1455 * audit_get_loginuid - get the loginuid for an audit_context
ian@0 1456 * @ctx: the audit_context
ian@0 1457 *
ian@0 1458 * Returns the context's loginuid or -1 if @ctx is NULL.
ian@0 1459 */
ian@0 1460 uid_t audit_get_loginuid(struct audit_context *ctx)
ian@0 1461 {
ian@0 1462 return ctx ? ctx->loginuid : -1;
ian@0 1463 }
ian@0 1464
ian@0 1465 /**
ian@0 1466 * __audit_mq_open - record audit data for a POSIX MQ open
ian@0 1467 * @oflag: open flag
ian@0 1468 * @mode: mode bits
ian@0 1469 * @u_attr: queue attributes
ian@0 1470 *
ian@0 1471 * Returns 0 for success or NULL context or < 0 on error.
ian@0 1472 */
ian@0 1473 int __audit_mq_open(int oflag, mode_t mode, struct mq_attr __user *u_attr)
ian@0 1474 {
ian@0 1475 struct audit_aux_data_mq_open *ax;
ian@0 1476 struct audit_context *context = current->audit_context;
ian@0 1477
ian@0 1478 if (!audit_enabled)
ian@0 1479 return 0;
ian@0 1480
ian@0 1481 if (likely(!context))
ian@0 1482 return 0;
ian@0 1483
ian@0 1484 ax = kmalloc(sizeof(*ax), GFP_ATOMIC);
ian@0 1485 if (!ax)
ian@0 1486 return -ENOMEM;
ian@0 1487
ian@0 1488 if (u_attr != NULL) {
ian@0 1489 if (copy_from_user(&ax->attr, u_attr, sizeof(ax->attr))) {
ian@0 1490 kfree(ax);
ian@0 1491 return -EFAULT;
ian@0 1492 }
ian@0 1493 } else
ian@0 1494 memset(&ax->attr, 0, sizeof(ax->attr));
ian@0 1495
ian@0 1496 ax->oflag = oflag;
ian@0 1497 ax->mode = mode;
ian@0 1498
ian@0 1499 ax->d.type = AUDIT_MQ_OPEN;
ian@0 1500 ax->d.next = context->aux;
ian@0 1501 context->aux = (void *)ax;
ian@0 1502 return 0;
ian@0 1503 }
ian@0 1504
ian@0 1505 /**
ian@0 1506 * __audit_mq_timedsend - record audit data for a POSIX MQ timed send
ian@0 1507 * @mqdes: MQ descriptor
ian@0 1508 * @msg_len: Message length
ian@0 1509 * @msg_prio: Message priority
ian@0 1510 * @u_abs_timeout: Message timeout in absolute time
ian@0 1511 *
ian@0 1512 * Returns 0 for success or NULL context or < 0 on error.
ian@0 1513 */
ian@0 1514 int __audit_mq_timedsend(mqd_t mqdes, size_t msg_len, unsigned int msg_prio,
ian@0 1515 const struct timespec __user *u_abs_timeout)
ian@0 1516 {
ian@0 1517 struct audit_aux_data_mq_sendrecv *ax;
ian@0 1518 struct audit_context *context = current->audit_context;
ian@0 1519
ian@0 1520 if (!audit_enabled)
ian@0 1521 return 0;
ian@0 1522
ian@0 1523 if (likely(!context))
ian@0 1524 return 0;
ian@0 1525
ian@0 1526 ax = kmalloc(sizeof(*ax), GFP_ATOMIC);
ian@0 1527 if (!ax)
ian@0 1528 return -ENOMEM;
ian@0 1529
ian@0 1530 if (u_abs_timeout != NULL) {
ian@0 1531 if (copy_from_user(&ax->abs_timeout, u_abs_timeout, sizeof(ax->abs_timeout))) {
ian@0 1532 kfree(ax);
ian@0 1533 return -EFAULT;
ian@0 1534 }
ian@0 1535 } else
ian@0 1536 memset(&ax->abs_timeout, 0, sizeof(ax->abs_timeout));
ian@0 1537
ian@0 1538 ax->mqdes = mqdes;
ian@0 1539 ax->msg_len = msg_len;
ian@0 1540 ax->msg_prio = msg_prio;
ian@0 1541
ian@0 1542 ax->d.type = AUDIT_MQ_SENDRECV;
ian@0 1543 ax->d.next = context->aux;
ian@0 1544 context->aux = (void *)ax;
ian@0 1545 return 0;
ian@0 1546 }
ian@0 1547
ian@0 1548 /**
ian@0 1549 * __audit_mq_timedreceive - record audit data for a POSIX MQ timed receive
ian@0 1550 * @mqdes: MQ descriptor
ian@0 1551 * @msg_len: Message length
ian@0 1552 * @u_msg_prio: Message priority
ian@0 1553 * @u_abs_timeout: Message timeout in absolute time
ian@0 1554 *
ian@0 1555 * Returns 0 for success or NULL context or < 0 on error.
ian@0 1556 */
ian@0 1557 int __audit_mq_timedreceive(mqd_t mqdes, size_t msg_len,
ian@0 1558 unsigned int __user *u_msg_prio,
ian@0 1559 const struct timespec __user *u_abs_timeout)
ian@0 1560 {
ian@0 1561 struct audit_aux_data_mq_sendrecv *ax;
ian@0 1562 struct audit_context *context = current->audit_context;
ian@0 1563
ian@0 1564 if (!audit_enabled)
ian@0 1565 return 0;
ian@0 1566
ian@0 1567 if (likely(!context))
ian@0 1568 return 0;
ian@0 1569
ian@0 1570 ax = kmalloc(sizeof(*ax), GFP_ATOMIC);
ian@0 1571 if (!ax)
ian@0 1572 return -ENOMEM;
ian@0 1573
ian@0 1574 if (u_msg_prio != NULL) {
ian@0 1575 if (get_user(ax->msg_prio, u_msg_prio)) {
ian@0 1576 kfree(ax);
ian@0 1577 return -EFAULT;
ian@0 1578 }
ian@0 1579 } else
ian@0 1580 ax->msg_prio = 0;
ian@0 1581
ian@0 1582 if (u_abs_timeout != NULL) {
ian@0 1583 if (copy_from_user(&ax->abs_timeout, u_abs_timeout, sizeof(ax->abs_timeout))) {
ian@0 1584 kfree(ax);
ian@0 1585 return -EFAULT;
ian@0 1586 }
ian@0 1587 } else
ian@0 1588 memset(&ax->abs_timeout, 0, sizeof(ax->abs_timeout));
ian@0 1589
ian@0 1590 ax->mqdes = mqdes;
ian@0 1591 ax->msg_len = msg_len;
ian@0 1592
ian@0 1593 ax->d.type = AUDIT_MQ_SENDRECV;
ian@0 1594 ax->d.next = context->aux;
ian@0 1595 context->aux = (void *)ax;
ian@0 1596 return 0;
ian@0 1597 }
ian@0 1598
ian@0 1599 /**
ian@0 1600 * __audit_mq_notify - record audit data for a POSIX MQ notify
ian@0 1601 * @mqdes: MQ descriptor
ian@0 1602 * @u_notification: Notification event
ian@0 1603 *
ian@0 1604 * Returns 0 for success or NULL context or < 0 on error.
ian@0 1605 */
ian@0 1606
ian@0 1607 int __audit_mq_notify(mqd_t mqdes, const struct sigevent __user *u_notification)
ian@0 1608 {
ian@0 1609 struct audit_aux_data_mq_notify *ax;
ian@0 1610 struct audit_context *context = current->audit_context;
ian@0 1611
ian@0 1612 if (!audit_enabled)
ian@0 1613 return 0;
ian@0 1614
ian@0 1615 if (likely(!context))
ian@0 1616 return 0;
ian@0 1617
ian@0 1618 ax = kmalloc(sizeof(*ax), GFP_ATOMIC);
ian@0 1619 if (!ax)
ian@0 1620 return -ENOMEM;
ian@0 1621
ian@0 1622 if (u_notification != NULL) {
ian@0 1623 if (copy_from_user(&ax->notification, u_notification, sizeof(ax->notification))) {
ian@0 1624 kfree(ax);
ian@0 1625 return -EFAULT;
ian@0 1626 }
ian@0 1627 } else
ian@0 1628 memset(&ax->notification, 0, sizeof(ax->notification));
ian@0 1629
ian@0 1630 ax->mqdes = mqdes;
ian@0 1631
ian@0 1632 ax->d.type = AUDIT_MQ_NOTIFY;
ian@0 1633 ax->d.next = context->aux;
ian@0 1634 context->aux = (void *)ax;
ian@0 1635 return 0;
ian@0 1636 }
ian@0 1637
ian@0 1638 /**
ian@0 1639 * __audit_mq_getsetattr - record audit data for a POSIX MQ get/set attribute
ian@0 1640 * @mqdes: MQ descriptor
ian@0 1641 * @mqstat: MQ flags
ian@0 1642 *
ian@0 1643 * Returns 0 for success or NULL context or < 0 on error.
ian@0 1644 */
ian@0 1645 int __audit_mq_getsetattr(mqd_t mqdes, struct mq_attr *mqstat)
ian@0 1646 {
ian@0 1647 struct audit_aux_data_mq_getsetattr *ax;
ian@0 1648 struct audit_context *context = current->audit_context;
ian@0 1649
ian@0 1650 if (!audit_enabled)
ian@0 1651 return 0;
ian@0 1652
ian@0 1653 if (likely(!context))
ian@0 1654 return 0;
ian@0 1655
ian@0 1656 ax = kmalloc(sizeof(*ax), GFP_ATOMIC);
ian@0 1657 if (!ax)
ian@0 1658 return -ENOMEM;
ian@0 1659
ian@0 1660 ax->mqdes = mqdes;
ian@0 1661 ax->mqstat = *mqstat;
ian@0 1662
ian@0 1663 ax->d.type = AUDIT_MQ_GETSETATTR;
ian@0 1664 ax->d.next = context->aux;
ian@0 1665 context->aux = (void *)ax;
ian@0 1666 return 0;
ian@0 1667 }
ian@0 1668
ian@0 1669 /**
ian@0 1670 * audit_ipc_obj - record audit data for ipc object
ian@0 1671 * @ipcp: ipc permissions
ian@0 1672 *
ian@0 1673 * Returns 0 for success or NULL context or < 0 on error.
ian@0 1674 */
ian@0 1675 int __audit_ipc_obj(struct kern_ipc_perm *ipcp)
ian@0 1676 {
ian@0 1677 struct audit_aux_data_ipcctl *ax;
ian@0 1678 struct audit_context *context = current->audit_context;
ian@0 1679
ian@0 1680 ax = kmalloc(sizeof(*ax), GFP_ATOMIC);
ian@0 1681 if (!ax)
ian@0 1682 return -ENOMEM;
ian@0 1683
ian@0 1684 ax->uid = ipcp->uid;
ian@0 1685 ax->gid = ipcp->gid;
ian@0 1686 ax->mode = ipcp->mode;
ian@0 1687 selinux_get_ipc_sid(ipcp, &ax->osid);
ian@0 1688
ian@0 1689 ax->d.type = AUDIT_IPC;
ian@0 1690 ax->d.next = context->aux;
ian@0 1691 context->aux = (void *)ax;
ian@0 1692 return 0;
ian@0 1693 }
ian@0 1694
ian@0 1695 /**
ian@0 1696 * audit_ipc_set_perm - record audit data for new ipc permissions
ian@0 1697 * @qbytes: msgq bytes
ian@0 1698 * @uid: msgq user id
ian@0 1699 * @gid: msgq group id
ian@0 1700 * @mode: msgq mode (permissions)
ian@0 1701 *
ian@0 1702 * Returns 0 for success or NULL context or < 0 on error.
ian@0 1703 */
ian@0 1704 int __audit_ipc_set_perm(unsigned long qbytes, uid_t uid, gid_t gid, mode_t mode)
ian@0 1705 {
ian@0 1706 struct audit_aux_data_ipcctl *ax;
ian@0 1707 struct audit_context *context = current->audit_context;
ian@0 1708
ian@0 1709 ax = kmalloc(sizeof(*ax), GFP_ATOMIC);
ian@0 1710 if (!ax)
ian@0 1711 return -ENOMEM;
ian@0 1712
ian@0 1713 ax->qbytes = qbytes;
ian@0 1714 ax->uid = uid;
ian@0 1715 ax->gid = gid;
ian@0 1716 ax->mode = mode;
ian@0 1717
ian@0 1718 ax->d.type = AUDIT_IPC_SET_PERM;
ian@0 1719 ax->d.next = context->aux;
ian@0 1720 context->aux = (void *)ax;
ian@0 1721 return 0;
ian@0 1722 }
ian@0 1723
ian@0 1724 int audit_bprm(struct linux_binprm *bprm)
ian@0 1725 {
ian@0 1726 struct audit_aux_data_execve *ax;
ian@0 1727 struct audit_context *context = current->audit_context;
ian@0 1728 unsigned long p, next;
ian@0 1729 void *to;
ian@0 1730
ian@0 1731 if (likely(!audit_enabled || !context || context->dummy))
ian@0 1732 return 0;
ian@0 1733
ian@0 1734 ax = kmalloc(sizeof(*ax) + PAGE_SIZE * MAX_ARG_PAGES - bprm->p,
ian@0 1735 GFP_KERNEL);
ian@0 1736 if (!ax)
ian@0 1737 return -ENOMEM;
ian@0 1738
ian@0 1739 ax->argc = bprm->argc;
ian@0 1740 ax->envc = bprm->envc;
ian@0 1741 for (p = bprm->p, to = ax->mem; p < MAX_ARG_PAGES*PAGE_SIZE; p = next) {
ian@0 1742 struct page *page = bprm->page[p / PAGE_SIZE];
ian@0 1743 void *kaddr = kmap(page);
ian@0 1744 next = (p + PAGE_SIZE) & ~(PAGE_SIZE - 1);
ian@0 1745 memcpy(to, kaddr + (p & (PAGE_SIZE - 1)), next - p);
ian@0 1746 to += next - p;
ian@0 1747 kunmap(page);
ian@0 1748 }
ian@0 1749
ian@0 1750 ax->d.type = AUDIT_EXECVE;
ian@0 1751 ax->d.next = context->aux;
ian@0 1752 context->aux = (void *)ax;
ian@0 1753 return 0;
ian@0 1754 }
ian@0 1755
ian@0 1756
ian@0 1757 /**
ian@0 1758 * audit_socketcall - record audit data for sys_socketcall
ian@0 1759 * @nargs: number of args
ian@0 1760 * @args: args array
ian@0 1761 *
ian@0 1762 * Returns 0 for success or NULL context or < 0 on error.
ian@0 1763 */
ian@0 1764 int audit_socketcall(int nargs, unsigned long *args)
ian@0 1765 {
ian@0 1766 struct audit_aux_data_socketcall *ax;
ian@0 1767 struct audit_context *context = current->audit_context;
ian@0 1768
ian@0 1769 if (likely(!context || context->dummy))
ian@0 1770 return 0;
ian@0 1771
ian@0 1772 ax = kmalloc(sizeof(*ax) + nargs * sizeof(unsigned long), GFP_KERNEL);
ian@0 1773 if (!ax)
ian@0 1774 return -ENOMEM;
ian@0 1775
ian@0 1776 ax->nargs = nargs;
ian@0 1777 memcpy(ax->args, args, nargs * sizeof(unsigned long));
ian@0 1778
ian@0 1779 ax->d.type = AUDIT_SOCKETCALL;
ian@0 1780 ax->d.next = context->aux;
ian@0 1781 context->aux = (void *)ax;
ian@0 1782 return 0;
ian@0 1783 }
ian@0 1784
ian@0 1785 /**
ian@0 1786 * audit_sockaddr - record audit data for sys_bind, sys_connect, sys_sendto
ian@0 1787 * @len: data length in user space
ian@0 1788 * @a: data address in kernel space
ian@0 1789 *
ian@0 1790 * Returns 0 for success or NULL context or < 0 on error.
ian@0 1791 */
ian@0 1792 int audit_sockaddr(int len, void *a)
ian@0 1793 {
ian@0 1794 struct audit_aux_data_sockaddr *ax;
ian@0 1795 struct audit_context *context = current->audit_context;
ian@0 1796
ian@0 1797 if (likely(!context || context->dummy))
ian@0 1798 return 0;
ian@0 1799
ian@0 1800 ax = kmalloc(sizeof(*ax) + len, GFP_KERNEL);
ian@0 1801 if (!ax)
ian@0 1802 return -ENOMEM;
ian@0 1803
ian@0 1804 ax->len = len;
ian@0 1805 memcpy(ax->a, a, len);
ian@0 1806
ian@0 1807 ax->d.type = AUDIT_SOCKADDR;
ian@0 1808 ax->d.next = context->aux;
ian@0 1809 context->aux = (void *)ax;
ian@0 1810 return 0;
ian@0 1811 }
ian@0 1812
ian@0 1813 /**
ian@0 1814 * audit_avc_path - record the granting or denial of permissions
ian@0 1815 * @dentry: dentry to record
ian@0 1816 * @mnt: mnt to record
ian@0 1817 *
ian@0 1818 * Returns 0 for success or NULL context or < 0 on error.
ian@0 1819 *
ian@0 1820 * Called from security/selinux/avc.c::avc_audit()
ian@0 1821 */
ian@0 1822 int audit_avc_path(struct dentry *dentry, struct vfsmount *mnt)
ian@0 1823 {
ian@0 1824 struct audit_aux_data_path *ax;
ian@0 1825 struct audit_context *context = current->audit_context;
ian@0 1826
ian@0 1827 if (likely(!context))
ian@0 1828 return 0;
ian@0 1829
ian@0 1830 ax = kmalloc(sizeof(*ax), GFP_ATOMIC);
ian@0 1831 if (!ax)
ian@0 1832 return -ENOMEM;
ian@0 1833
ian@0 1834 ax->dentry = dget(dentry);
ian@0 1835 ax->mnt = mntget(mnt);
ian@0 1836
ian@0 1837 ax->d.type = AUDIT_AVC_PATH;
ian@0 1838 ax->d.next = context->aux;
ian@0 1839 context->aux = (void *)ax;
ian@0 1840 return 0;
ian@0 1841 }
ian@0 1842
ian@0 1843 /**
ian@0 1844 * audit_signal_info - record signal info for shutting down audit subsystem
ian@0 1845 * @sig: signal value
ian@0 1846 * @t: task being signaled
ian@0 1847 *
ian@0 1848 * If the audit subsystem is being terminated, record the task (pid)
ian@0 1849 * and uid that is doing that.
ian@0 1850 */
ian@0 1851 void __audit_signal_info(int sig, struct task_struct *t)
ian@0 1852 {
ian@0 1853 extern pid_t audit_sig_pid;
ian@0 1854 extern uid_t audit_sig_uid;
ian@0 1855 extern u32 audit_sig_sid;
ian@0 1856
ian@0 1857 if (sig == SIGTERM || sig == SIGHUP || sig == SIGUSR1) {
ian@0 1858 struct task_struct *tsk = current;
ian@0 1859 struct audit_context *ctx = tsk->audit_context;
ian@0 1860 audit_sig_pid = tsk->pid;
ian@0 1861 if (ctx)
ian@0 1862 audit_sig_uid = ctx->loginuid;
ian@0 1863 else
ian@0 1864 audit_sig_uid = tsk->uid;
ian@0 1865 selinux_get_task_sid(tsk, &audit_sig_sid);
ian@0 1866 }
ian@0 1867 }