diff options
| -rw-r--r-- | include/linux/audit.h | 32 | ||||
| -rw-r--r-- | include/uapi/linux/audit.h | 7 | ||||
| -rw-r--r-- | kernel/audit.c | 12 | ||||
| -rw-r--r-- | kernel/audit.h | 3 | ||||
| -rw-r--r-- | kernel/auditsc.c | 40 | ||||
| -rw-r--r-- | kernel/module.c | 5 | ||||
| -rw-r--r-- | net/compat.c | 17 |
7 files changed, 96 insertions, 20 deletions
diff --git a/include/linux/audit.h b/include/linux/audit.h index f51fca8d0b6f..504e784b7ffa 100644 --- a/include/linux/audit.h +++ b/include/linux/audit.h | |||
| @@ -360,6 +360,7 @@ extern int __audit_log_bprm_fcaps(struct linux_binprm *bprm, | |||
| 360 | const struct cred *old); | 360 | const struct cred *old); |
| 361 | extern void __audit_log_capset(const struct cred *new, const struct cred *old); | 361 | extern void __audit_log_capset(const struct cred *new, const struct cred *old); |
| 362 | extern void __audit_mmap_fd(int fd, int flags); | 362 | extern void __audit_mmap_fd(int fd, int flags); |
| 363 | extern void __audit_log_kern_module(char *name); | ||
| 363 | 364 | ||
| 364 | static inline void audit_ipc_obj(struct kern_ipc_perm *ipcp) | 365 | static inline void audit_ipc_obj(struct kern_ipc_perm *ipcp) |
| 365 | { | 366 | { |
| @@ -387,6 +388,20 @@ static inline int audit_socketcall(int nargs, unsigned long *args) | |||
| 387 | return __audit_socketcall(nargs, args); | 388 | return __audit_socketcall(nargs, args); |
| 388 | return 0; | 389 | return 0; |
| 389 | } | 390 | } |
| 391 | |||
| 392 | static inline int audit_socketcall_compat(int nargs, u32 *args) | ||
| 393 | { | ||
| 394 | unsigned long a[AUDITSC_ARGS]; | ||
| 395 | int i; | ||
| 396 | |||
| 397 | if (audit_dummy_context()) | ||
| 398 | return 0; | ||
| 399 | |||
| 400 | for (i = 0; i < nargs; i++) | ||
| 401 | a[i] = (unsigned long)args[i]; | ||
| 402 | return __audit_socketcall(nargs, a); | ||
| 403 | } | ||
| 404 | |||
| 390 | static inline int audit_sockaddr(int len, void *addr) | 405 | static inline int audit_sockaddr(int len, void *addr) |
| 391 | { | 406 | { |
| 392 | if (unlikely(!audit_dummy_context())) | 407 | if (unlikely(!audit_dummy_context())) |
| @@ -436,6 +451,12 @@ static inline void audit_mmap_fd(int fd, int flags) | |||
| 436 | __audit_mmap_fd(fd, flags); | 451 | __audit_mmap_fd(fd, flags); |
| 437 | } | 452 | } |
| 438 | 453 | ||
| 454 | static inline void audit_log_kern_module(char *name) | ||
| 455 | { | ||
| 456 | if (!audit_dummy_context()) | ||
| 457 | __audit_log_kern_module(name); | ||
| 458 | } | ||
| 459 | |||
| 439 | extern int audit_n_rules; | 460 | extern int audit_n_rules; |
| 440 | extern int audit_signals; | 461 | extern int audit_signals; |
| 441 | #else /* CONFIG_AUDITSYSCALL */ | 462 | #else /* CONFIG_AUDITSYSCALL */ |
| @@ -513,6 +534,12 @@ static inline int audit_socketcall(int nargs, unsigned long *args) | |||
| 513 | { | 534 | { |
| 514 | return 0; | 535 | return 0; |
| 515 | } | 536 | } |
| 537 | |||
| 538 | static inline int audit_socketcall_compat(int nargs, u32 *args) | ||
| 539 | { | ||
| 540 | return 0; | ||
| 541 | } | ||
| 542 | |||
| 516 | static inline void audit_fd_pair(int fd1, int fd2) | 543 | static inline void audit_fd_pair(int fd1, int fd2) |
| 517 | { } | 544 | { } |
| 518 | static inline int audit_sockaddr(int len, void *addr) | 545 | static inline int audit_sockaddr(int len, void *addr) |
| @@ -541,6 +568,11 @@ static inline void audit_log_capset(const struct cred *new, | |||
| 541 | { } | 568 | { } |
| 542 | static inline void audit_mmap_fd(int fd, int flags) | 569 | static inline void audit_mmap_fd(int fd, int flags) |
| 543 | { } | 570 | { } |
| 571 | |||
| 572 | static inline void audit_log_kern_module(char *name) | ||
| 573 | { | ||
| 574 | } | ||
| 575 | |||
| 544 | static inline void audit_ptrace(struct task_struct *t) | 576 | static inline void audit_ptrace(struct task_struct *t) |
| 545 | { } | 577 | { } |
| 546 | #define audit_n_rules 0 | 578 | #define audit_n_rules 0 |
diff --git a/include/uapi/linux/audit.h b/include/uapi/linux/audit.h index 1c107cb1c83f..0714a66f0e0c 100644 --- a/include/uapi/linux/audit.h +++ b/include/uapi/linux/audit.h | |||
| @@ -111,6 +111,7 @@ | |||
| 111 | #define AUDIT_PROCTITLE 1327 /* Proctitle emit event */ | 111 | #define AUDIT_PROCTITLE 1327 /* Proctitle emit event */ |
| 112 | #define AUDIT_FEATURE_CHANGE 1328 /* audit log listing feature changes */ | 112 | #define AUDIT_FEATURE_CHANGE 1328 /* audit log listing feature changes */ |
| 113 | #define AUDIT_REPLACE 1329 /* Replace auditd if this packet unanswerd */ | 113 | #define AUDIT_REPLACE 1329 /* Replace auditd if this packet unanswerd */ |
| 114 | #define AUDIT_KERN_MODULE 1330 /* Kernel Module events */ | ||
| 114 | 115 | ||
| 115 | #define AUDIT_AVC 1400 /* SE Linux avc denial or grant */ | 116 | #define AUDIT_AVC 1400 /* SE Linux avc denial or grant */ |
| 116 | #define AUDIT_SELINUX_ERR 1401 /* Internal SE Linux Errors */ | 117 | #define AUDIT_SELINUX_ERR 1401 /* Internal SE Linux Errors */ |
| @@ -326,17 +327,21 @@ enum { | |||
| 326 | #define AUDIT_STATUS_RATE_LIMIT 0x0008 | 327 | #define AUDIT_STATUS_RATE_LIMIT 0x0008 |
| 327 | #define AUDIT_STATUS_BACKLOG_LIMIT 0x0010 | 328 | #define AUDIT_STATUS_BACKLOG_LIMIT 0x0010 |
| 328 | #define AUDIT_STATUS_BACKLOG_WAIT_TIME 0x0020 | 329 | #define AUDIT_STATUS_BACKLOG_WAIT_TIME 0x0020 |
| 330 | #define AUDIT_STATUS_LOST 0x0040 | ||
| 329 | 331 | ||
| 330 | #define AUDIT_FEATURE_BITMAP_BACKLOG_LIMIT 0x00000001 | 332 | #define AUDIT_FEATURE_BITMAP_BACKLOG_LIMIT 0x00000001 |
| 331 | #define AUDIT_FEATURE_BITMAP_BACKLOG_WAIT_TIME 0x00000002 | 333 | #define AUDIT_FEATURE_BITMAP_BACKLOG_WAIT_TIME 0x00000002 |
| 332 | #define AUDIT_FEATURE_BITMAP_EXECUTABLE_PATH 0x00000004 | 334 | #define AUDIT_FEATURE_BITMAP_EXECUTABLE_PATH 0x00000004 |
| 333 | #define AUDIT_FEATURE_BITMAP_EXCLUDE_EXTEND 0x00000008 | 335 | #define AUDIT_FEATURE_BITMAP_EXCLUDE_EXTEND 0x00000008 |
| 334 | #define AUDIT_FEATURE_BITMAP_SESSIONID_FILTER 0x00000010 | 336 | #define AUDIT_FEATURE_BITMAP_SESSIONID_FILTER 0x00000010 |
| 337 | #define AUDIT_FEATURE_BITMAP_LOST_RESET 0x00000020 | ||
| 338 | |||
| 335 | #define AUDIT_FEATURE_BITMAP_ALL (AUDIT_FEATURE_BITMAP_BACKLOG_LIMIT | \ | 339 | #define AUDIT_FEATURE_BITMAP_ALL (AUDIT_FEATURE_BITMAP_BACKLOG_LIMIT | \ |
| 336 | AUDIT_FEATURE_BITMAP_BACKLOG_WAIT_TIME | \ | 340 | AUDIT_FEATURE_BITMAP_BACKLOG_WAIT_TIME | \ |
| 337 | AUDIT_FEATURE_BITMAP_EXECUTABLE_PATH | \ | 341 | AUDIT_FEATURE_BITMAP_EXECUTABLE_PATH | \ |
| 338 | AUDIT_FEATURE_BITMAP_EXCLUDE_EXTEND | \ | 342 | AUDIT_FEATURE_BITMAP_EXCLUDE_EXTEND | \ |
| 339 | AUDIT_FEATURE_BITMAP_SESSIONID_FILTER) | 343 | AUDIT_FEATURE_BITMAP_SESSIONID_FILTER | \ |
| 344 | AUDIT_FEATURE_BITMAP_LOST_RESET) | ||
| 340 | 345 | ||
| 341 | /* deprecated: AUDIT_VERSION_* */ | 346 | /* deprecated: AUDIT_VERSION_* */ |
| 342 | #define AUDIT_VERSION_LATEST AUDIT_FEATURE_BITMAP_ALL | 347 | #define AUDIT_VERSION_LATEST AUDIT_FEATURE_BITMAP_ALL |
diff --git a/kernel/audit.c b/kernel/audit.c index 6e399bb69d7c..e794544f5e63 100644 --- a/kernel/audit.c +++ b/kernel/audit.c | |||
| @@ -121,7 +121,7 @@ u32 audit_sig_sid = 0; | |||
| 121 | 3) suppressed due to audit_rate_limit | 121 | 3) suppressed due to audit_rate_limit |
| 122 | 4) suppressed due to audit_backlog_limit | 122 | 4) suppressed due to audit_backlog_limit |
| 123 | */ | 123 | */ |
| 124 | static atomic_t audit_lost = ATOMIC_INIT(0); | 124 | static atomic_t audit_lost = ATOMIC_INIT(0); |
| 125 | 125 | ||
| 126 | /* The netlink socket. */ | 126 | /* The netlink socket. */ |
| 127 | static struct sock *audit_sock; | 127 | static struct sock *audit_sock; |
| @@ -1058,6 +1058,12 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) | |||
| 1058 | if (err < 0) | 1058 | if (err < 0) |
| 1059 | return err; | 1059 | return err; |
| 1060 | } | 1060 | } |
| 1061 | if (s.mask == AUDIT_STATUS_LOST) { | ||
| 1062 | u32 lost = atomic_xchg(&audit_lost, 0); | ||
| 1063 | |||
| 1064 | audit_log_config_change("lost", 0, lost, 1); | ||
| 1065 | return lost; | ||
| 1066 | } | ||
| 1061 | break; | 1067 | break; |
| 1062 | } | 1068 | } |
| 1063 | case AUDIT_GET_FEATURE: | 1069 | case AUDIT_GET_FEATURE: |
| @@ -1349,7 +1355,9 @@ static int __init audit_init(void) | |||
| 1349 | panic("audit: failed to start the kauditd thread (%d)\n", err); | 1355 | panic("audit: failed to start the kauditd thread (%d)\n", err); |
| 1350 | } | 1356 | } |
| 1351 | 1357 | ||
| 1352 | audit_log(NULL, GFP_KERNEL, AUDIT_KERNEL, "initialized"); | 1358 | audit_log(NULL, GFP_KERNEL, AUDIT_KERNEL, |
| 1359 | "state=initialized audit_enabled=%u res=1", | ||
| 1360 | audit_enabled); | ||
| 1353 | 1361 | ||
| 1354 | return 0; | 1362 | return 0; |
| 1355 | } | 1363 | } |
diff --git a/kernel/audit.h b/kernel/audit.h index 960d49c9db5e..ca579880303a 100644 --- a/kernel/audit.h +++ b/kernel/audit.h | |||
| @@ -199,6 +199,9 @@ struct audit_context { | |||
| 199 | struct { | 199 | struct { |
| 200 | int argc; | 200 | int argc; |
| 201 | } execve; | 201 | } execve; |
| 202 | struct { | ||
| 203 | char *name; | ||
| 204 | } module; | ||
| 202 | }; | 205 | }; |
| 203 | int fds[2]; | 206 | int fds[2]; |
| 204 | struct audit_proctitle proctitle; | 207 | struct audit_proctitle proctitle; |
diff --git a/kernel/auditsc.c b/kernel/auditsc.c index cf1fa43512c1..d6a8de5f8fa3 100644 --- a/kernel/auditsc.c +++ b/kernel/auditsc.c | |||
| @@ -1221,7 +1221,7 @@ static void show_special(struct audit_context *context, int *call_panic) | |||
| 1221 | context->ipc.perm_mode); | 1221 | context->ipc.perm_mode); |
| 1222 | } | 1222 | } |
| 1223 | break; } | 1223 | break; } |
| 1224 | case AUDIT_MQ_OPEN: { | 1224 | case AUDIT_MQ_OPEN: |
| 1225 | audit_log_format(ab, | 1225 | audit_log_format(ab, |
| 1226 | "oflag=0x%x mode=%#ho mq_flags=0x%lx mq_maxmsg=%ld " | 1226 | "oflag=0x%x mode=%#ho mq_flags=0x%lx mq_maxmsg=%ld " |
| 1227 | "mq_msgsize=%ld mq_curmsgs=%ld", | 1227 | "mq_msgsize=%ld mq_curmsgs=%ld", |
| @@ -1230,8 +1230,8 @@ static void show_special(struct audit_context *context, int *call_panic) | |||
| 1230 | context->mq_open.attr.mq_maxmsg, | 1230 | context->mq_open.attr.mq_maxmsg, |
| 1231 | context->mq_open.attr.mq_msgsize, | 1231 | context->mq_open.attr.mq_msgsize, |
| 1232 | context->mq_open.attr.mq_curmsgs); | 1232 | context->mq_open.attr.mq_curmsgs); |
| 1233 | break; } | 1233 | break; |
| 1234 | case AUDIT_MQ_SENDRECV: { | 1234 | case AUDIT_MQ_SENDRECV: |
| 1235 | audit_log_format(ab, | 1235 | audit_log_format(ab, |
| 1236 | "mqdes=%d msg_len=%zd msg_prio=%u " | 1236 | "mqdes=%d msg_len=%zd msg_prio=%u " |
| 1237 | "abs_timeout_sec=%ld abs_timeout_nsec=%ld", | 1237 | "abs_timeout_sec=%ld abs_timeout_nsec=%ld", |
| @@ -1240,12 +1240,12 @@ static void show_special(struct audit_context *context, int *call_panic) | |||
| 1240 | context->mq_sendrecv.msg_prio, | 1240 | context->mq_sendrecv.msg_prio, |
| 1241 | context->mq_sendrecv.abs_timeout.tv_sec, | 1241 | context->mq_sendrecv.abs_timeout.tv_sec, |
| 1242 | context->mq_sendrecv.abs_timeout.tv_nsec); | 1242 | context->mq_sendrecv.abs_timeout.tv_nsec); |
| 1243 | break; } | 1243 | break; |
| 1244 | case AUDIT_MQ_NOTIFY: { | 1244 | case AUDIT_MQ_NOTIFY: |
| 1245 | audit_log_format(ab, "mqdes=%d sigev_signo=%d", | 1245 | audit_log_format(ab, "mqdes=%d sigev_signo=%d", |
| 1246 | context->mq_notify.mqdes, | 1246 | context->mq_notify.mqdes, |
| 1247 | context->mq_notify.sigev_signo); | 1247 | context->mq_notify.sigev_signo); |
| 1248 | break; } | 1248 | break; |
| 1249 | case AUDIT_MQ_GETSETATTR: { | 1249 | case AUDIT_MQ_GETSETATTR: { |
| 1250 | struct mq_attr *attr = &context->mq_getsetattr.mqstat; | 1250 | struct mq_attr *attr = &context->mq_getsetattr.mqstat; |
| 1251 | audit_log_format(ab, | 1251 | audit_log_format(ab, |
| @@ -1255,19 +1255,24 @@ static void show_special(struct audit_context *context, int *call_panic) | |||
| 1255 | attr->mq_flags, attr->mq_maxmsg, | 1255 | attr->mq_flags, attr->mq_maxmsg, |
| 1256 | attr->mq_msgsize, attr->mq_curmsgs); | 1256 | attr->mq_msgsize, attr->mq_curmsgs); |
| 1257 | break; } | 1257 | break; } |
| 1258 | case AUDIT_CAPSET: { | 1258 | case AUDIT_CAPSET: |
| 1259 | audit_log_format(ab, "pid=%d", context->capset.pid); | 1259 | audit_log_format(ab, "pid=%d", context->capset.pid); |
| 1260 | audit_log_cap(ab, "cap_pi", &context->capset.cap.inheritable); | 1260 | audit_log_cap(ab, "cap_pi", &context->capset.cap.inheritable); |
| 1261 | audit_log_cap(ab, "cap_pp", &context->capset.cap.permitted); | 1261 | audit_log_cap(ab, "cap_pp", &context->capset.cap.permitted); |
| 1262 | audit_log_cap(ab, "cap_pe", &context->capset.cap.effective); | 1262 | audit_log_cap(ab, "cap_pe", &context->capset.cap.effective); |
| 1263 | break; } | 1263 | break; |
| 1264 | case AUDIT_MMAP: { | 1264 | case AUDIT_MMAP: |
| 1265 | audit_log_format(ab, "fd=%d flags=0x%x", context->mmap.fd, | 1265 | audit_log_format(ab, "fd=%d flags=0x%x", context->mmap.fd, |
| 1266 | context->mmap.flags); | 1266 | context->mmap.flags); |
| 1267 | break; } | 1267 | break; |
| 1268 | case AUDIT_EXECVE: { | 1268 | case AUDIT_EXECVE: |
| 1269 | audit_log_execve_info(context, &ab); | 1269 | audit_log_execve_info(context, &ab); |
| 1270 | break; } | 1270 | break; |
| 1271 | case AUDIT_KERN_MODULE: | ||
| 1272 | audit_log_format(ab, "name="); | ||
| 1273 | audit_log_untrustedstring(ab, context->module.name); | ||
| 1274 | kfree(context->module.name); | ||
| 1275 | break; | ||
| 1271 | } | 1276 | } |
| 1272 | audit_log_end(ab); | 1277 | audit_log_end(ab); |
| 1273 | } | 1278 | } |
| @@ -2368,6 +2373,15 @@ void __audit_mmap_fd(int fd, int flags) | |||
| 2368 | context->type = AUDIT_MMAP; | 2373 | context->type = AUDIT_MMAP; |
| 2369 | } | 2374 | } |
| 2370 | 2375 | ||
| 2376 | void __audit_log_kern_module(char *name) | ||
| 2377 | { | ||
| 2378 | struct audit_context *context = current->audit_context; | ||
| 2379 | |||
| 2380 | context->module.name = kmalloc(strlen(name) + 1, GFP_KERNEL); | ||
| 2381 | strcpy(context->module.name, name); | ||
| 2382 | context->type = AUDIT_KERN_MODULE; | ||
| 2383 | } | ||
| 2384 | |||
| 2371 | static void audit_log_task(struct audit_buffer *ab) | 2385 | static void audit_log_task(struct audit_buffer *ab) |
| 2372 | { | 2386 | { |
| 2373 | kuid_t auid, uid; | 2387 | kuid_t auid, uid; |
| @@ -2411,7 +2425,7 @@ void audit_core_dumps(long signr) | |||
| 2411 | if (unlikely(!ab)) | 2425 | if (unlikely(!ab)) |
| 2412 | return; | 2426 | return; |
| 2413 | audit_log_task(ab); | 2427 | audit_log_task(ab); |
| 2414 | audit_log_format(ab, " sig=%ld", signr); | 2428 | audit_log_format(ab, " sig=%ld res=1", signr); |
| 2415 | audit_log_end(ab); | 2429 | audit_log_end(ab); |
| 2416 | } | 2430 | } |
| 2417 | 2431 | ||
diff --git a/kernel/module.c b/kernel/module.c index 3d8f126208e3..e2eec4b47143 100644 --- a/kernel/module.c +++ b/kernel/module.c | |||
| @@ -61,6 +61,7 @@ | |||
| 61 | #include <linux/pfn.h> | 61 | #include <linux/pfn.h> |
| 62 | #include <linux/bsearch.h> | 62 | #include <linux/bsearch.h> |
| 63 | #include <linux/dynamic_debug.h> | 63 | #include <linux/dynamic_debug.h> |
| 64 | #include <linux/audit.h> | ||
| 64 | #include <uapi/linux/module.h> | 65 | #include <uapi/linux/module.h> |
| 65 | #include "module-internal.h" | 66 | #include "module-internal.h" |
| 66 | 67 | ||
| @@ -3608,6 +3609,8 @@ static int load_module(struct load_info *info, const char __user *uargs, | |||
| 3608 | goto free_copy; | 3609 | goto free_copy; |
| 3609 | } | 3610 | } |
| 3610 | 3611 | ||
| 3612 | audit_log_kern_module(mod->name); | ||
| 3613 | |||
| 3611 | /* Reserve our place in the list. */ | 3614 | /* Reserve our place in the list. */ |
| 3612 | err = add_unformed_module(mod); | 3615 | err = add_unformed_module(mod); |
| 3613 | if (err) | 3616 | if (err) |
| @@ -3696,7 +3699,7 @@ static int load_module(struct load_info *info, const char __user *uargs, | |||
| 3696 | mod->name, after_dashes); | 3699 | mod->name, after_dashes); |
| 3697 | } | 3700 | } |
| 3698 | 3701 | ||
| 3699 | /* Link in to syfs. */ | 3702 | /* Link in to sysfs. */ |
| 3700 | err = mod_sysfs_setup(mod, info, mod->kp, mod->num_kp); | 3703 | err = mod_sysfs_setup(mod, info, mod->kp, mod->num_kp); |
| 3701 | if (err < 0) | 3704 | if (err < 0) |
| 3702 | goto coming_cleanup; | 3705 | goto coming_cleanup; |
diff --git a/net/compat.c b/net/compat.c index 96c544b05b15..d69f539ca0bc 100644 --- a/net/compat.c +++ b/net/compat.c | |||
| @@ -22,6 +22,7 @@ | |||
| 22 | #include <linux/filter.h> | 22 | #include <linux/filter.h> |
| 23 | #include <linux/compat.h> | 23 | #include <linux/compat.h> |
| 24 | #include <linux/security.h> | 24 | #include <linux/security.h> |
| 25 | #include <linux/audit.h> | ||
| 25 | #include <linux/export.h> | 26 | #include <linux/export.h> |
| 26 | 27 | ||
| 27 | #include <net/scm.h> | 28 | #include <net/scm.h> |
| @@ -781,14 +782,24 @@ COMPAT_SYSCALL_DEFINE5(recvmmsg, int, fd, struct compat_mmsghdr __user *, mmsg, | |||
| 781 | 782 | ||
| 782 | COMPAT_SYSCALL_DEFINE2(socketcall, int, call, u32 __user *, args) | 783 | COMPAT_SYSCALL_DEFINE2(socketcall, int, call, u32 __user *, args) |
| 783 | { | 784 | { |
| 784 | int ret; | 785 | u32 a[AUDITSC_ARGS]; |
| 785 | u32 a[6]; | 786 | unsigned int len; |
| 786 | u32 a0, a1; | 787 | u32 a0, a1; |
| 788 | int ret; | ||
| 787 | 789 | ||
| 788 | if (call < SYS_SOCKET || call > SYS_SENDMMSG) | 790 | if (call < SYS_SOCKET || call > SYS_SENDMMSG) |
| 789 | return -EINVAL; | 791 | return -EINVAL; |
| 790 | if (copy_from_user(a, args, nas[call])) | 792 | len = nas[call]; |
| 793 | if (len > sizeof(a)) | ||
| 794 | return -EINVAL; | ||
| 795 | |||
| 796 | if (copy_from_user(a, args, len)) | ||
| 791 | return -EFAULT; | 797 | return -EFAULT; |
| 798 | |||
| 799 | ret = audit_socketcall_compat(len / sizeof(a[0]), a); | ||
| 800 | if (ret) | ||
| 801 | return ret; | ||
| 802 | |||
| 792 | a0 = a[0]; | 803 | a0 = a[0]; |
| 793 | a1 = a[1]; | 804 | a1 = a[1]; |
| 794 | 805 | ||
