diff options
author | David Woodhouse <dwmw2@shinybook.infradead.org> | 2005-05-17 07:08:48 -0400 |
---|---|---|
committer | David Woodhouse <dwmw2@shinybook.infradead.org> | 2005-05-17 07:08:48 -0400 |
commit | 3ec3b2fba526ead2fa3f3d7c91924f39a0733749 (patch) | |
tree | 12b9b3de4e0d5bb3c977ea3ef534ba4f7e556cb9 | |
parent | 69887ac1dcb79dfc773dabac2dd081fa6d6e2573 (diff) |
AUDIT: Capture sys_socketcall arguments and sockaddrs
Signed-off-by: David Woodhouse <dwmw2@infradead.org>
-rw-r--r-- | include/linux/audit.h | 7 | ||||
-rw-r--r-- | kernel/auditsc.c | 73 | ||||
-rw-r--r-- | net/socket.c | 9 |
3 files changed, 84 insertions, 5 deletions
diff --git a/include/linux/audit.h b/include/linux/audit.h index 51e5879af7fc..2f5dc60f8bbd 100644 --- a/include/linux/audit.h +++ b/include/linux/audit.h | |||
@@ -69,8 +69,9 @@ | |||
69 | #define AUDIT_FS_WATCH 1301 /* Filesystem watch event */ | 69 | #define AUDIT_FS_WATCH 1301 /* Filesystem watch event */ |
70 | #define AUDIT_PATH 1302 /* Filname path information */ | 70 | #define AUDIT_PATH 1302 /* Filname path information */ |
71 | #define AUDIT_IPC 1303 /* IPC record */ | 71 | #define AUDIT_IPC 1303 /* IPC record */ |
72 | #define AUDIT_SOCKET 1304 /* Socket record */ | 72 | #define AUDIT_SOCKETCALL 1304 /* sys_socketcall arguments */ |
73 | #define AUDIT_CONFIG_CHANGE 1305 /* Audit system configuration change */ | 73 | #define AUDIT_CONFIG_CHANGE 1305 /* Audit system configuration change */ |
74 | #define AUDIT_SOCKADDR 1306 /* sockaddr copied as syscall arg */ | ||
74 | 75 | ||
75 | #define AUDIT_AVC 1400 /* SE Linux avc denial or grant */ | 76 | #define AUDIT_AVC 1400 /* SE Linux avc denial or grant */ |
76 | #define AUDIT_SELINUX_ERR 1401 /* Internal SE Linux Errors */ | 77 | #define AUDIT_SELINUX_ERR 1401 /* Internal SE Linux Errors */ |
@@ -235,6 +236,8 @@ extern int audit_get_stamp(struct audit_context *ctx, | |||
235 | extern int audit_set_loginuid(struct task_struct *task, uid_t loginuid); | 236 | extern int audit_set_loginuid(struct task_struct *task, uid_t loginuid); |
236 | extern uid_t audit_get_loginuid(struct audit_context *ctx); | 237 | extern uid_t audit_get_loginuid(struct audit_context *ctx); |
237 | extern int audit_ipc_perms(unsigned long qbytes, uid_t uid, gid_t gid, mode_t mode); | 238 | extern int audit_ipc_perms(unsigned long qbytes, uid_t uid, gid_t gid, mode_t mode); |
239 | extern int audit_socketcall(int nargs, unsigned long *args); | ||
240 | extern int audit_sockaddr(int len, void *addr); | ||
238 | extern void audit_signal_info(int sig, struct task_struct *t); | 241 | extern void audit_signal_info(int sig, struct task_struct *t); |
239 | #else | 242 | #else |
240 | #define audit_alloc(t) ({ 0; }) | 243 | #define audit_alloc(t) ({ 0; }) |
@@ -248,6 +251,8 @@ extern void audit_signal_info(int sig, struct task_struct *t); | |||
248 | #define audit_get_stamp(c,t,s) ({ 0; }) | 251 | #define audit_get_stamp(c,t,s) ({ 0; }) |
249 | #define audit_get_loginuid(c) ({ -1; }) | 252 | #define audit_get_loginuid(c) ({ -1; }) |
250 | #define audit_ipc_perms(q,u,g,m) ({ 0; }) | 253 | #define audit_ipc_perms(q,u,g,m) ({ 0; }) |
254 | #define audit_socketcall(n,a) ({ 0; }) | ||
255 | #define audit_sockaddr(len, addr) ({ 0; }) | ||
251 | #define audit_signal_info(s,t) do { ; } while (0) | 256 | #define audit_signal_info(s,t) do { ; } while (0) |
252 | #endif | 257 | #endif |
253 | 258 | ||
diff --git a/kernel/auditsc.c b/kernel/auditsc.c index 773d28a3f701..818778d5b6ad 100644 --- a/kernel/auditsc.c +++ b/kernel/auditsc.c | |||
@@ -34,7 +34,7 @@ | |||
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/socket.h> | |
38 | #include <linux/audit.h> | 38 | #include <linux/audit.h> |
39 | #include <linux/personality.h> | 39 | #include <linux/personality.h> |
40 | #include <linux/time.h> | 40 | #include <linux/time.h> |
@@ -112,6 +112,18 @@ struct audit_aux_data_ipcctl { | |||
112 | mode_t mode; | 112 | mode_t mode; |
113 | }; | 113 | }; |
114 | 114 | ||
115 | struct audit_aux_data_socketcall { | ||
116 | struct audit_aux_data d; | ||
117 | int nargs; | ||
118 | unsigned long args[0]; | ||
119 | }; | ||
120 | |||
121 | struct audit_aux_data_sockaddr { | ||
122 | struct audit_aux_data d; | ||
123 | int len; | ||
124 | char a[0]; | ||
125 | }; | ||
126 | |||
115 | 127 | ||
116 | /* The per-task audit context. */ | 128 | /* The per-task audit context. */ |
117 | struct audit_context { | 129 | struct audit_context { |
@@ -694,7 +706,22 @@ static void audit_log_exit(struct audit_context *context) | |||
694 | audit_log_format(ab, | 706 | audit_log_format(ab, |
695 | " qbytes=%lx iuid=%d igid=%d mode=%x", | 707 | " qbytes=%lx iuid=%d igid=%d mode=%x", |
696 | axi->qbytes, axi->uid, axi->gid, axi->mode); | 708 | axi->qbytes, axi->uid, axi->gid, axi->mode); |
697 | } | 709 | break; } |
710 | |||
711 | case AUDIT_SOCKETCALL: { | ||
712 | int i; | ||
713 | struct audit_aux_data_socketcall *axs = (void *)aux; | ||
714 | audit_log_format(ab, "nargs=%d", axs->nargs); | ||
715 | for (i=0; i<axs->nargs; i++) | ||
716 | audit_log_format(ab, " a%d=%lx", i, axs->args[i]); | ||
717 | break; } | ||
718 | |||
719 | case AUDIT_SOCKADDR: { | ||
720 | struct audit_aux_data_sockaddr *axs = (void *)aux; | ||
721 | |||
722 | audit_log_format(ab, "saddr="); | ||
723 | audit_log_hex(ab, axs->a, axs->len); | ||
724 | break; } | ||
698 | } | 725 | } |
699 | audit_log_end(ab); | 726 | audit_log_end(ab); |
700 | 727 | ||
@@ -1053,6 +1080,48 @@ int audit_ipc_perms(unsigned long qbytes, uid_t uid, gid_t gid, mode_t mode) | |||
1053 | return 0; | 1080 | return 0; |
1054 | } | 1081 | } |
1055 | 1082 | ||
1083 | int audit_socketcall(int nargs, unsigned long *args) | ||
1084 | { | ||
1085 | struct audit_aux_data_socketcall *ax; | ||
1086 | struct audit_context *context = current->audit_context; | ||
1087 | |||
1088 | if (likely(!context)) | ||
1089 | return 0; | ||
1090 | |||
1091 | ax = kmalloc(sizeof(*ax) + nargs * sizeof(unsigned long), GFP_KERNEL); | ||
1092 | if (!ax) | ||
1093 | return -ENOMEM; | ||
1094 | |||
1095 | ax->nargs = nargs; | ||
1096 | memcpy(ax->args, args, nargs * sizeof(unsigned long)); | ||
1097 | |||
1098 | ax->d.type = AUDIT_SOCKETCALL; | ||
1099 | ax->d.next = context->aux; | ||
1100 | context->aux = (void *)ax; | ||
1101 | return 0; | ||
1102 | } | ||
1103 | |||
1104 | int audit_sockaddr(int len, void *a) | ||
1105 | { | ||
1106 | struct audit_aux_data_sockaddr *ax; | ||
1107 | struct audit_context *context = current->audit_context; | ||
1108 | |||
1109 | if (likely(!context)) | ||
1110 | return 0; | ||
1111 | |||
1112 | ax = kmalloc(sizeof(*ax) + len, GFP_KERNEL); | ||
1113 | if (!ax) | ||
1114 | return -ENOMEM; | ||
1115 | |||
1116 | ax->len = len; | ||
1117 | memcpy(ax->a, a, len); | ||
1118 | |||
1119 | ax->d.type = AUDIT_SOCKADDR; | ||
1120 | ax->d.next = context->aux; | ||
1121 | context->aux = (void *)ax; | ||
1122 | return 0; | ||
1123 | } | ||
1124 | |||
1056 | void audit_signal_info(int sig, struct task_struct *t) | 1125 | void audit_signal_info(int sig, struct task_struct *t) |
1057 | { | 1126 | { |
1058 | extern pid_t audit_sig_pid; | 1127 | extern pid_t audit_sig_pid; |
diff --git a/net/socket.c b/net/socket.c index cec0cb38b9ce..6b7c3b51a7c1 100644 --- a/net/socket.c +++ b/net/socket.c | |||
@@ -81,6 +81,7 @@ | |||
81 | #include <linux/syscalls.h> | 81 | #include <linux/syscalls.h> |
82 | #include <linux/compat.h> | 82 | #include <linux/compat.h> |
83 | #include <linux/kmod.h> | 83 | #include <linux/kmod.h> |
84 | #include <linux/audit.h> | ||
84 | 85 | ||
85 | #ifdef CONFIG_NET_RADIO | 86 | #ifdef CONFIG_NET_RADIO |
86 | #include <linux/wireless.h> /* Note : will define WIRELESS_EXT */ | 87 | #include <linux/wireless.h> /* Note : will define WIRELESS_EXT */ |
@@ -226,7 +227,7 @@ int move_addr_to_kernel(void __user *uaddr, int ulen, void *kaddr) | |||
226 | return 0; | 227 | return 0; |
227 | if(copy_from_user(kaddr,uaddr,ulen)) | 228 | if(copy_from_user(kaddr,uaddr,ulen)) |
228 | return -EFAULT; | 229 | return -EFAULT; |
229 | return 0; | 230 | return audit_sockaddr(ulen, kaddr); |
230 | } | 231 | } |
231 | 232 | ||
232 | /** | 233 | /** |
@@ -1906,7 +1907,11 @@ asmlinkage long sys_socketcall(int call, unsigned long __user *args) | |||
1906 | /* copy_from_user should be SMP safe. */ | 1907 | /* copy_from_user should be SMP safe. */ |
1907 | if (copy_from_user(a, args, nargs[call])) | 1908 | if (copy_from_user(a, args, nargs[call])) |
1908 | return -EFAULT; | 1909 | return -EFAULT; |
1909 | 1910 | ||
1911 | err = audit_socketcall(nargs[call]/sizeof(unsigned long), args); | ||
1912 | if (err) | ||
1913 | return err; | ||
1914 | |||
1910 | a0=a[0]; | 1915 | a0=a[0]; |
1911 | a1=a[1]; | 1916 | a1=a[1]; |
1912 | 1917 | ||