diff options
Diffstat (limited to 'kernel/auditsc.c')
| -rw-r--r-- | kernel/auditsc.c | 259 | 
1 files changed, 184 insertions, 75 deletions
diff --git a/kernel/auditsc.c b/kernel/auditsc.c index 37b3ac94bc47..e75f84e1a1a0 100644 --- a/kernel/auditsc.c +++ b/kernel/auditsc.c  | |||
| @@ -34,7 +34,8 @@ | |||
| 34 | #include <asm/types.h> | 34 | #include <asm/types.h> | 
| 35 | #include <linux/mm.h> | 35 | #include <linux/mm.h> | 
| 36 | #include <linux/module.h> | 36 | #include <linux/module.h> | 
| 37 | 37 | #include <linux/mount.h> | |
| 38 | #include <linux/socket.h> | ||
| 38 | #include <linux/audit.h> | 39 | #include <linux/audit.h> | 
| 39 | #include <linux/personality.h> | 40 | #include <linux/personality.h> | 
| 40 | #include <linux/time.h> | 41 | #include <linux/time.h> | 
| @@ -112,6 +113,23 @@ struct audit_aux_data_ipcctl { | |||
| 112 | mode_t mode; | 113 | mode_t mode; | 
| 113 | }; | 114 | }; | 
| 114 | 115 | ||
| 116 | struct audit_aux_data_socketcall { | ||
| 117 | struct audit_aux_data d; | ||
| 118 | int nargs; | ||
| 119 | unsigned long args[0]; | ||
| 120 | }; | ||
| 121 | |||
| 122 | struct audit_aux_data_sockaddr { | ||
| 123 | struct audit_aux_data d; | ||
| 124 | int len; | ||
| 125 | char a[0]; | ||
| 126 | }; | ||
| 127 | |||
| 128 | struct audit_aux_data_path { | ||
| 129 | struct audit_aux_data d; | ||
| 130 | struct dentry *dentry; | ||
| 131 | struct vfsmount *mnt; | ||
| 132 | }; | ||
| 115 | 133 | ||
| 116 | /* The per-task audit context. */ | 134 | /* The per-task audit context. */ | 
| 117 | struct audit_context { | 135 | struct audit_context { | 
| @@ -127,6 +145,8 @@ struct audit_context { | |||
| 127 | int auditable; /* 1 if record should be written */ | 145 | int auditable; /* 1 if record should be written */ | 
| 128 | int name_count; | 146 | int name_count; | 
| 129 | struct audit_names names[AUDIT_NAMES]; | 147 | struct audit_names names[AUDIT_NAMES]; | 
| 148 | struct dentry * pwd; | ||
| 149 | struct vfsmount * pwdmnt; | ||
| 130 | struct audit_context *previous; /* For nested syscalls */ | 150 | struct audit_context *previous; /* For nested syscalls */ | 
| 131 | struct audit_aux_data *aux; | 151 | struct audit_aux_data *aux; | 
| 132 | 152 | ||
| @@ -157,6 +177,8 @@ struct audit_entry { | |||
| 157 | struct audit_rule rule; | 177 | struct audit_rule rule; | 
| 158 | }; | 178 | }; | 
| 159 | 179 | ||
| 180 | extern int audit_pid; | ||
| 181 | |||
| 160 | /* Check to see if two rules are identical. It is called from | 182 | /* Check to see if two rules are identical. It is called from | 
| 161 | * audit_del_rule during AUDIT_DEL. */ | 183 | * audit_del_rule during AUDIT_DEL. */ | 
| 162 | static int audit_compare_rule(struct audit_rule *a, struct audit_rule *b) | 184 | static int audit_compare_rule(struct audit_rule *a, struct audit_rule *b) | 
| @@ -226,7 +248,6 @@ static inline int audit_del_rule(struct audit_rule *rule, | |||
| 226 | return -EFAULT; /* No matching rule */ | 248 | return -EFAULT; /* No matching rule */ | 
| 227 | } | 249 | } | 
| 228 | 250 | ||
| 229 | #ifdef CONFIG_NET | ||
| 230 | /* Copy rule from user-space to kernel-space. Called during | 251 | /* Copy rule from user-space to kernel-space. Called during | 
| 231 | * AUDIT_ADD. */ | 252 | * AUDIT_ADD. */ | 
| 232 | static int audit_copy_rule(struct audit_rule *d, struct audit_rule *s) | 253 | static int audit_copy_rule(struct audit_rule *d, struct audit_rule *s) | 
| @@ -287,7 +308,8 @@ int audit_receive_filter(int type, int pid, int uid, int seq, void *data, | |||
| 287 | err = audit_add_rule(entry, &audit_entlist); | 308 | err = audit_add_rule(entry, &audit_entlist); | 
| 288 | if (!err && (flags & AUDIT_AT_EXIT)) | 309 | if (!err && (flags & AUDIT_AT_EXIT)) | 
| 289 | err = audit_add_rule(entry, &audit_extlist); | 310 | err = audit_add_rule(entry, &audit_extlist); | 
| 290 | audit_log(NULL, "auid %u added an audit rule\n", loginuid); | 311 | audit_log(NULL, AUDIT_CONFIG_CHANGE, | 
| 312 | "auid=%u added an audit rule\n", loginuid); | ||
| 291 | break; | 313 | break; | 
| 292 | case AUDIT_DEL: | 314 | case AUDIT_DEL: | 
| 293 | flags =((struct audit_rule *)data)->flags; | 315 | flags =((struct audit_rule *)data)->flags; | 
| @@ -297,7 +319,8 @@ int audit_receive_filter(int type, int pid, int uid, int seq, void *data, | |||
| 297 | err = audit_del_rule(data, &audit_entlist); | 319 | err = audit_del_rule(data, &audit_entlist); | 
| 298 | if (!err && (flags & AUDIT_AT_EXIT)) | 320 | if (!err && (flags & AUDIT_AT_EXIT)) | 
| 299 | err = audit_del_rule(data, &audit_extlist); | 321 | err = audit_del_rule(data, &audit_extlist); | 
| 300 | audit_log(NULL, "auid %u removed an audit rule\n", loginuid); | 322 | audit_log(NULL, AUDIT_CONFIG_CHANGE, | 
| 323 | "auid=%u removed an audit rule\n", loginuid); | ||
| 301 | break; | 324 | break; | 
| 302 | default: | 325 | default: | 
| 303 | return -EINVAL; | 326 | return -EINVAL; | 
| @@ -305,7 +328,6 @@ int audit_receive_filter(int type, int pid, int uid, int seq, void *data, | |||
| 305 | 328 | ||
| 306 | return err; | 329 | return err; | 
| 307 | } | 330 | } | 
| 308 | #endif | ||
| 309 | 331 | ||
| 310 | /* Compare a task_struct with an audit_rule. Return 1 on match, 0 | 332 | /* Compare a task_struct with an audit_rule. Return 1 on match, 0 | 
| 311 | * otherwise. */ | 333 | * otherwise. */ | 
| @@ -444,7 +466,7 @@ static enum audit_state audit_filter_task(struct task_struct *tsk) | |||
| 444 | 466 | ||
| 445 | /* At syscall entry and exit time, this filter is called if the | 467 | /* At syscall entry and exit time, this filter is called if the | 
| 446 | * audit_state is not low enough that auditing cannot take place, but is | 468 | * audit_state is not low enough that auditing cannot take place, but is | 
| 447 | * also not high enough that we already know we have to write and audit | 469 | * also not high enough that we already know we have to write an audit | 
| 448 | * record (i.e., the state is AUDIT_SETUP_CONTEXT or AUDIT_BUILD_CONTEXT). | 470 | * record (i.e., the state is AUDIT_SETUP_CONTEXT or AUDIT_BUILD_CONTEXT). | 
| 449 | */ | 471 | */ | 
| 450 | static enum audit_state audit_filter_syscall(struct task_struct *tsk, | 472 | static enum audit_state audit_filter_syscall(struct task_struct *tsk, | 
| @@ -532,6 +554,12 @@ static inline void audit_free_names(struct audit_context *context) | |||
| 532 | if (context->names[i].name) | 554 | if (context->names[i].name) | 
| 533 | __putname(context->names[i].name); | 555 | __putname(context->names[i].name); | 
| 534 | context->name_count = 0; | 556 | context->name_count = 0; | 
| 557 | if (context->pwd) | ||
| 558 | dput(context->pwd); | ||
| 559 | if (context->pwdmnt) | ||
| 560 | mntput(context->pwdmnt); | ||
| 561 | context->pwd = NULL; | ||
| 562 | context->pwdmnt = NULL; | ||
| 535 | } | 563 | } | 
| 536 | 564 | ||
| 537 | static inline void audit_free_aux(struct audit_context *context) | 565 | static inline void audit_free_aux(struct audit_context *context) | 
| @@ -539,6 +567,11 @@ static inline void audit_free_aux(struct audit_context *context) | |||
| 539 | struct audit_aux_data *aux; | 567 | struct audit_aux_data *aux; | 
| 540 | 568 | ||
| 541 | while ((aux = context->aux)) { | 569 | while ((aux = context->aux)) { | 
| 570 | if (aux->type == AUDIT_AVC_PATH) { | ||
| 571 | struct audit_aux_data_path *axi = (void *)aux; | ||
| 572 | dput(axi->dentry); | ||
| 573 | mntput(axi->mnt); | ||
| 574 | } | ||
| 542 | context->aux = aux->next; | 575 | context->aux = aux->next; | 
| 543 | kfree(aux); | 576 | kfree(aux); | 
| 544 | } | 577 | } | 
| @@ -625,7 +658,8 @@ static void audit_log_task_info(struct audit_buffer *ab) | |||
| 625 | struct vm_area_struct *vma; | 658 | struct vm_area_struct *vma; | 
| 626 | 659 | ||
| 627 | get_task_comm(name, current); | 660 | get_task_comm(name, current); | 
| 628 | audit_log_format(ab, " comm=%s", name); | 661 | audit_log_format(ab, " comm="); | 
| 662 | audit_log_untrustedstring(ab, name); | ||
| 629 | 663 | ||
| 630 | if (!mm) | 664 | if (!mm) | 
| 631 | return; | 665 | return; | 
| @@ -649,23 +683,24 @@ static void audit_log_exit(struct audit_context *context) | |||
| 649 | { | 683 | { | 
| 650 | int i; | 684 | int i; | 
| 651 | struct audit_buffer *ab; | 685 | struct audit_buffer *ab; | 
| 686 | struct audit_aux_data *aux; | ||
| 652 | 687 | ||
| 653 | ab = audit_log_start(context); | 688 | ab = audit_log_start(context, AUDIT_SYSCALL); | 
| 654 | if (!ab) | 689 | if (!ab) | 
| 655 | return; /* audit_panic has been called */ | 690 | return; /* audit_panic has been called */ | 
| 656 | audit_log_format(ab, "syscall=%d", context->major); | 691 | audit_log_format(ab, "arch=%x syscall=%d", | 
| 692 | context->arch, context->major); | ||
| 657 | if (context->personality != PER_LINUX) | 693 | if (context->personality != PER_LINUX) | 
| 658 | audit_log_format(ab, " per=%lx", context->personality); | 694 | audit_log_format(ab, " per=%lx", context->personality); | 
| 659 | audit_log_format(ab, " arch=%x", context->arch); | ||
| 660 | if (context->return_valid) | 695 | if (context->return_valid) | 
| 661 | audit_log_format(ab, " success=%s exit=%ld", | 696 | audit_log_format(ab, " success=%s exit=%ld", | 
| 662 | (context->return_valid==AUDITSC_SUCCESS)?"yes":"no", | 697 | (context->return_valid==AUDITSC_SUCCESS)?"yes":"no", | 
| 663 | context->return_code); | 698 | context->return_code); | 
| 664 | audit_log_format(ab, | 699 | audit_log_format(ab, | 
| 665 | " a0=%lx a1=%lx a2=%lx a3=%lx items=%d" | 700 | " a0=%lx a1=%lx a2=%lx a3=%lx items=%d" | 
| 666 | " pid=%d loginuid=%d uid=%d gid=%d" | 701 | " pid=%d auid=%u uid=%u gid=%u" | 
| 667 | " euid=%d suid=%d fsuid=%d" | 702 | " euid=%u suid=%u fsuid=%u" | 
| 668 | " egid=%d sgid=%d fsgid=%d", | 703 | " egid=%u sgid=%u fsgid=%u", | 
| 669 | context->argv[0], | 704 | context->argv[0], | 
| 670 | context->argv[1], | 705 | context->argv[1], | 
| 671 | context->argv[2], | 706 | context->argv[2], | 
| @@ -679,33 +714,57 @@ static void audit_log_exit(struct audit_context *context) | |||
| 679 | context->egid, context->sgid, context->fsgid); | 714 | context->egid, context->sgid, context->fsgid); | 
| 680 | audit_log_task_info(ab); | 715 | audit_log_task_info(ab); | 
| 681 | audit_log_end(ab); | 716 | audit_log_end(ab); | 
| 682 | while (context->aux) { | ||
| 683 | struct audit_aux_data *aux; | ||
| 684 | 717 | ||
| 685 | ab = audit_log_start(context); | 718 | for (aux = context->aux; aux; aux = aux->next) { | 
| 719 | |||
| 720 | ab = audit_log_start(context, aux->type); | ||
| 686 | if (!ab) | 721 | if (!ab) | 
| 687 | continue; /* audit_panic has been called */ | 722 | continue; /* audit_panic has been called */ | 
| 688 | 723 | ||
| 689 | aux = context->aux; | ||
| 690 | context->aux = aux->next; | ||
| 691 | |||
| 692 | audit_log_format(ab, "auxitem=%d", aux->type); | ||
| 693 | switch (aux->type) { | 724 | switch (aux->type) { | 
| 694 | case AUDIT_AUX_IPCPERM: { | 725 | case AUDIT_IPC: { | 
| 695 | struct audit_aux_data_ipcctl *axi = (void *)aux; | 726 | struct audit_aux_data_ipcctl *axi = (void *)aux; | 
| 696 | audit_log_format(ab, | 727 | audit_log_format(ab, | 
| 697 | " qbytes=%lx uid=%d gid=%d mode=%x", | 728 | " qbytes=%lx iuid=%u igid=%u mode=%x", | 
| 698 | axi->qbytes, axi->uid, axi->gid, axi->mode); | 729 | axi->qbytes, axi->uid, axi->gid, axi->mode); | 
| 699 | } | 730 | break; } | 
| 731 | |||
| 732 | case AUDIT_SOCKETCALL: { | ||
| 733 | int i; | ||
| 734 | struct audit_aux_data_socketcall *axs = (void *)aux; | ||
| 735 | audit_log_format(ab, "nargs=%d", axs->nargs); | ||
| 736 | for (i=0; i<axs->nargs; i++) | ||
| 737 | audit_log_format(ab, " a%d=%lx", i, axs->args[i]); | ||
| 738 | break; } | ||
| 739 | |||
| 740 | case AUDIT_SOCKADDR: { | ||
| 741 | struct audit_aux_data_sockaddr *axs = (void *)aux; | ||
| 742 | |||
| 743 | audit_log_format(ab, "saddr="); | ||
| 744 | audit_log_hex(ab, axs->a, axs->len); | ||
| 745 | break; } | ||
| 746 | |||
| 747 | case AUDIT_AVC_PATH: { | ||
| 748 | struct audit_aux_data_path *axi = (void *)aux; | ||
| 749 | audit_log_d_path(ab, "path=", axi->dentry, axi->mnt); | ||
| 750 | break; } | ||
| 751 | |||
| 700 | } | 752 | } | 
| 701 | audit_log_end(ab); | 753 | audit_log_end(ab); | 
| 702 | kfree(aux); | ||
| 703 | } | 754 | } | 
| 704 | 755 | ||
| 756 | if (context->pwd && context->pwdmnt) { | ||
| 757 | ab = audit_log_start(context, AUDIT_CWD); | ||
| 758 | if (ab) { | ||
| 759 | audit_log_d_path(ab, "cwd=", context->pwd, context->pwdmnt); | ||
| 760 | audit_log_end(ab); | ||
| 761 | } | ||
| 762 | } | ||
| 705 | for (i = 0; i < context->name_count; i++) { | 763 | for (i = 0; i < context->name_count; i++) { | 
| 706 | ab = audit_log_start(context); | 764 | ab = audit_log_start(context, AUDIT_PATH); | 
| 707 | if (!ab) | 765 | if (!ab) | 
| 708 | continue; /* audit_panic has been called */ | 766 | continue; /* audit_panic has been called */ | 
| 767 | |||
| 709 | audit_log_format(ab, "item=%d", i); | 768 | audit_log_format(ab, "item=%d", i); | 
| 710 | if (context->names[i].name) { | 769 | if (context->names[i].name) { | 
| 711 | audit_log_format(ab, " name="); | 770 | audit_log_format(ab, " name="); | 
| @@ -713,7 +772,7 @@ static void audit_log_exit(struct audit_context *context) | |||
| 713 | } | 772 | } | 
| 714 | if (context->names[i].ino != (unsigned long)-1) | 773 | if (context->names[i].ino != (unsigned long)-1) | 
| 715 | audit_log_format(ab, " inode=%lu dev=%02x:%02x mode=%#o" | 774 | audit_log_format(ab, " inode=%lu dev=%02x:%02x mode=%#o" | 
| 716 | " uid=%d gid=%d rdev=%02x:%02x", | 775 | " ouid=%u ogid=%u rdev=%02x:%02x", | 
| 717 | context->names[i].ino, | 776 | context->names[i].ino, | 
| 718 | MAJOR(context->names[i].dev), | 777 | MAJOR(context->names[i].dev), | 
| 719 | MINOR(context->names[i].dev), | 778 | MINOR(context->names[i].dev), | 
| @@ -741,42 +800,12 @@ void audit_free(struct task_struct *tsk) | |||
| 741 | 800 | ||
| 742 | /* Check for system calls that do not go through the exit | 801 | /* Check for system calls that do not go through the exit | 
| 743 | * function (e.g., exit_group), then free context block. */ | 802 | * function (e.g., exit_group), then free context block. */ | 
| 744 | if (context->in_syscall && context->auditable) | 803 | if (context->in_syscall && context->auditable && context->pid != audit_pid) | 
| 745 | audit_log_exit(context); | 804 | audit_log_exit(context); | 
| 746 | 805 | ||
| 747 | audit_free_context(context); | 806 | audit_free_context(context); | 
| 748 | } | 807 | } | 
| 749 | 808 | ||
| 750 | /* Compute a serial number for the audit record. Audit records are | ||
| 751 | * written to user-space as soon as they are generated, so a complete | ||
| 752 | * audit record may be written in several pieces. The timestamp of the | ||
| 753 | * record and this serial number are used by the user-space daemon to | ||
| 754 | * determine which pieces belong to the same audit record. The | ||
| 755 | * (timestamp,serial) tuple is unique for each syscall and is live from | ||
| 756 | * syscall entry to syscall exit. | ||
| 757 | * | ||
| 758 | * Atomic values are only guaranteed to be 24-bit, so we count down. | ||
| 759 | * | ||
| 760 | * NOTE: Another possibility is to store the formatted records off the | ||
| 761 | * audit context (for those records that have a context), and emit them | ||
| 762 | * all at syscall exit. However, this could delay the reporting of | ||
| 763 | * significant errors until syscall exit (or never, if the system | ||
| 764 | * halts). */ | ||
| 765 | static inline unsigned int audit_serial(void) | ||
| 766 | { | ||
| 767 | static atomic_t serial = ATOMIC_INIT(0xffffff); | ||
| 768 | unsigned int a, b; | ||
| 769 | |||
| 770 | do { | ||
| 771 | a = atomic_read(&serial); | ||
| 772 | if (atomic_dec_and_test(&serial)) | ||
| 773 | atomic_set(&serial, 0xffffff); | ||
| 774 | b = atomic_read(&serial); | ||
| 775 | } while (b != a - 1); | ||
| 776 | |||
| 777 | return 0xffffff - b; | ||
| 778 | } | ||
| 779 | |||
| 780 | /* Fill in audit context at syscall entry. This only happens if the | 809 | /* Fill in audit context at syscall entry. This only happens if the | 
| 781 | * audit context was created when the task was created and the state or | 810 | * audit context was created when the task was created and the state or | 
| 782 | * filters demand the audit context be built. If the state from the | 811 | * filters demand the audit context be built. If the state from the | 
| @@ -876,7 +905,7 @@ void audit_syscall_exit(struct task_struct *tsk, int valid, long return_code) | |||
| 876 | if (likely(!context)) | 905 | if (likely(!context)) | 
| 877 | return; | 906 | return; | 
| 878 | 907 | ||
| 879 | if (context->in_syscall && context->auditable) | 908 | if (context->in_syscall && context->auditable && context->pid != audit_pid) | 
| 880 | audit_log_exit(context); | 909 | audit_log_exit(context); | 
| 881 | 910 | ||
| 882 | context->in_syscall = 0; | 911 | context->in_syscall = 0; | 
| @@ -916,6 +945,13 @@ void audit_getname(const char *name) | |||
| 916 | context->names[context->name_count].name = name; | 945 | context->names[context->name_count].name = name; | 
| 917 | context->names[context->name_count].ino = (unsigned long)-1; | 946 | context->names[context->name_count].ino = (unsigned long)-1; | 
| 918 | ++context->name_count; | 947 | ++context->name_count; | 
| 948 | if (!context->pwd) { | ||
| 949 | read_lock(¤t->fs->lock); | ||
| 950 | context->pwd = dget(current->fs->pwd); | ||
| 951 | context->pwdmnt = mntget(current->fs->pwdmnt); | ||
| 952 | read_unlock(¤t->fs->lock); | ||
| 953 | } | ||
| 954 | |||
| 919 | } | 955 | } | 
| 920 | 956 | ||
| 921 | /* Intercept a putname request. Called from | 957 | /* Intercept a putname request. Called from | 
| @@ -994,34 +1030,26 @@ void audit_inode(const char *name, const struct inode *inode) | |||
| 994 | context->names[idx].rdev = inode->i_rdev; | 1030 | context->names[idx].rdev = inode->i_rdev; | 
| 995 | } | 1031 | } | 
| 996 | 1032 | ||
| 997 | void audit_get_stamp(struct audit_context *ctx, | 1033 | void auditsc_get_stamp(struct audit_context *ctx, | 
| 998 | struct timespec *t, unsigned int *serial) | 1034 | struct timespec *t, unsigned int *serial) | 
| 999 | { | 1035 | { | 
| 1000 | if (ctx) { | 1036 | t->tv_sec = ctx->ctime.tv_sec; | 
| 1001 | t->tv_sec = ctx->ctime.tv_sec; | 1037 | t->tv_nsec = ctx->ctime.tv_nsec; | 
| 1002 | t->tv_nsec = ctx->ctime.tv_nsec; | 1038 | *serial = ctx->serial; | 
| 1003 | *serial = ctx->serial; | 1039 | ctx->auditable = 1; | 
| 1004 | ctx->auditable = 1; | ||
| 1005 | } else { | ||
| 1006 | *t = CURRENT_TIME; | ||
| 1007 | *serial = 0; | ||
| 1008 | } | ||
| 1009 | } | 1040 | } | 
| 1010 | 1041 | ||
| 1011 | extern int audit_set_type(struct audit_buffer *ab, int type); | ||
| 1012 | |||
| 1013 | int audit_set_loginuid(struct task_struct *task, uid_t loginuid) | 1042 | int audit_set_loginuid(struct task_struct *task, uid_t loginuid) | 
| 1014 | { | 1043 | { | 
| 1015 | if (task->audit_context) { | 1044 | if (task->audit_context) { | 
| 1016 | struct audit_buffer *ab; | 1045 | struct audit_buffer *ab; | 
| 1017 | 1046 | ||
| 1018 | ab = audit_log_start(NULL); | 1047 | ab = audit_log_start(NULL, AUDIT_LOGIN); | 
| 1019 | if (ab) { | 1048 | if (ab) { | 
| 1020 | audit_log_format(ab, "login pid=%d uid=%u " | 1049 | audit_log_format(ab, "login pid=%d uid=%u " | 
| 1021 | "old loginuid=%u new loginuid=%u", | 1050 | "old auid=%u new auid=%u", | 
| 1022 | task->pid, task->uid, | 1051 | task->pid, task->uid, | 
| 1023 | task->audit_context->loginuid, loginuid); | 1052 | task->audit_context->loginuid, loginuid); | 
| 1024 | audit_set_type(ab, AUDIT_LOGIN); | ||
| 1025 | audit_log_end(ab); | 1053 | audit_log_end(ab); | 
| 1026 | } | 1054 | } | 
| 1027 | task->audit_context->loginuid = loginuid; | 1055 | task->audit_context->loginuid = loginuid; | 
| @@ -1051,8 +1079,89 @@ int audit_ipc_perms(unsigned long qbytes, uid_t uid, gid_t gid, mode_t mode) | |||
| 1051 | ax->gid = gid; | 1079 | ax->gid = gid; | 
| 1052 | ax->mode = mode; | 1080 | ax->mode = mode; | 
| 1053 | 1081 | ||
| 1054 | ax->d.type = AUDIT_AUX_IPCPERM; | 1082 | ax->d.type = AUDIT_IPC; | 
| 1083 | ax->d.next = context->aux; | ||
| 1084 | context->aux = (void *)ax; | ||
| 1085 | return 0; | ||
| 1086 | } | ||
| 1087 | |||
| 1088 | int audit_socketcall(int nargs, unsigned long *args) | ||
| 1089 | { | ||
| 1090 | struct audit_aux_data_socketcall *ax; | ||
| 1091 | struct audit_context *context = current->audit_context; | ||
| 1092 | |||
| 1093 | if (likely(!context)) | ||
| 1094 | return 0; | ||
| 1095 | |||
| 1096 | ax = kmalloc(sizeof(*ax) + nargs * sizeof(unsigned long), GFP_KERNEL); | ||
| 1097 | if (!ax) | ||
| 1098 | return -ENOMEM; | ||
| 1099 | |||
| 1100 | ax->nargs = nargs; | ||
| 1101 | memcpy(ax->args, args, nargs * sizeof(unsigned long)); | ||
| 1102 | |||
| 1103 | ax->d.type = AUDIT_SOCKETCALL; | ||
| 1104 | ax->d.next = context->aux; | ||
| 1105 | context->aux = (void *)ax; | ||
| 1106 | return 0; | ||
| 1107 | } | ||
| 1108 | |||
| 1109 | int audit_sockaddr(int len, void *a) | ||
| 1110 | { | ||
| 1111 | struct audit_aux_data_sockaddr *ax; | ||
| 1112 | struct audit_context *context = current->audit_context; | ||
| 1113 | |||
| 1114 | if (likely(!context)) | ||
| 1115 | return 0; | ||
| 1116 | |||
| 1117 | ax = kmalloc(sizeof(*ax) + len, GFP_KERNEL); | ||
| 1118 | if (!ax) | ||
| 1119 | return -ENOMEM; | ||
| 1120 | |||
| 1121 | ax->len = len; | ||
| 1122 | memcpy(ax->a, a, len); | ||
| 1123 | |||
| 1124 | ax->d.type = AUDIT_SOCKADDR; | ||
| 1055 | ax->d.next = context->aux; | 1125 | ax->d.next = context->aux; | 
| 1056 | context->aux = (void *)ax; | 1126 | context->aux = (void *)ax; | 
| 1057 | return 0; | 1127 | return 0; | 
| 1058 | } | 1128 | } | 
| 1129 | |||
| 1130 | int audit_avc_path(struct dentry *dentry, struct vfsmount *mnt) | ||
| 1131 | { | ||
| 1132 | struct audit_aux_data_path *ax; | ||
| 1133 | struct audit_context *context = current->audit_context; | ||
| 1134 | |||
| 1135 | if (likely(!context)) | ||
| 1136 | return 0; | ||
| 1137 | |||
| 1138 | ax = kmalloc(sizeof(*ax), GFP_ATOMIC); | ||
| 1139 | if (!ax) | ||
| 1140 | return -ENOMEM; | ||
| 1141 | |||
| 1142 | ax->dentry = dget(dentry); | ||
| 1143 | ax->mnt = mntget(mnt); | ||
| 1144 | |||
| 1145 | ax->d.type = AUDIT_AVC_PATH; | ||
| 1146 | ax->d.next = context->aux; | ||
| 1147 | context->aux = (void *)ax; | ||
| 1148 | return 0; | ||
| 1149 | } | ||
| 1150 | |||
| 1151 | void audit_signal_info(int sig, struct task_struct *t) | ||
| 1152 | { | ||
| 1153 | extern pid_t audit_sig_pid; | ||
| 1154 | extern uid_t audit_sig_uid; | ||
| 1155 | |||
| 1156 | if (unlikely(audit_pid && t->pid == audit_pid)) { | ||
| 1157 | if (sig == SIGTERM || sig == SIGHUP) { | ||
| 1158 | struct audit_context *ctx = current->audit_context; | ||
| 1159 | audit_sig_pid = current->pid; | ||
| 1160 | if (ctx) | ||
| 1161 | audit_sig_uid = ctx->loginuid; | ||
| 1162 | else | ||
| 1163 | audit_sig_uid = current->uid; | ||
| 1164 | } | ||
| 1165 | } | ||
| 1166 | } | ||
| 1167 | |||
