2 * Copyright (c) 2008-2011 Apple Inc.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. Neither the name of Apple Inc. ("Apple") nor the names of
14 * its contributors may be used to endorse or promote products derived
15 * from this software without specific prior written permission.
17 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR
21 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
25 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
26 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 * POSSIBILITY OF SUCH DAMAGE.
31 #include <sys/param.h>
33 #include <security/audit/audit.h>
35 #include <bsm/audit_errno.h>
36 #include <bsm/audit_record.h>
38 #include <sys/errno.h>
42 * Different operating systems use different numeric constants for different
43 * error numbers, and sometimes error numbers don't exist in more than one
44 * operating system. These routines convert between BSM and local error
45 * number spaces, subject to the above realities. BSM error numbers are
46 * stored in a single 8-bit character, so don't have a byte order.
48 * Don't include string definitions when this code is compiled into a kernel.
53 #if !defined(KERNEL) && !defined(_KERNEL)
54 const char *be_strerror
;
58 #define ERRNO_NO_LOCAL_MAPPING -600
60 #if !defined(KERNEL) && !defined(_KERNEL)
67 * Mapping table -- please maintain in numeric sorted order with respect to
68 * the BSM constant. Today we do a linear lookup, but could switch to a
69 * binary search if it makes sense. We only ifdef errors that aren't
70 * generally available, but it does make the table a lot more ugly.
72 * XXXRW: It would be nice to have a similar ordered table mapping to BSM
73 * constant from local constant, but the order of local constants varies by
74 * OS. Really we need to build that table at compile-time but don't do that
77 * XXXRW: We currently embed English-language error strings here, but should
78 * support catalogues; these are only used if the OS doesn't have an error
79 * string using strerror(3).
81 static const struct bsm_errno bsm_errnos
[] = {
82 { BSM_ERRNO_ESUCCESS
, 0, ES("Success") },
83 { BSM_ERRNO_EPERM
, EPERM
, ES("Operation not permitted") },
84 { BSM_ERRNO_ENOENT
, ENOENT
, ES("No such file or directory") },
85 { BSM_ERRNO_ESRCH
, ESRCH
, ES("No such process") },
86 { BSM_ERRNO_EINTR
, EINTR
, ES("Interrupted system call") },
87 { BSM_ERRNO_EIO
, EIO
, ES("Input/output error") },
88 { BSM_ERRNO_ENXIO
, ENXIO
, ES("Device not configured") },
89 { BSM_ERRNO_E2BIG
, E2BIG
, ES("Argument list too long") },
90 { BSM_ERRNO_ENOEXEC
, ENOEXEC
, ES("Exec format error") },
91 { BSM_ERRNO_EBADF
, EBADF
, ES("Bad file descriptor") },
92 { BSM_ERRNO_ECHILD
, ECHILD
, ES("No child processes") },
93 { BSM_ERRNO_EAGAIN
, EAGAIN
, ES("Resource temporarily unavailable") },
94 { BSM_ERRNO_ENOMEM
, ENOMEM
, ES("Cannot allocate memory") },
95 { BSM_ERRNO_EACCES
, EACCES
, ES("Permission denied") },
96 { BSM_ERRNO_EFAULT
, EFAULT
, ES("Bad address") },
97 { BSM_ERRNO_ENOTBLK
, ENOTBLK
, ES("Block device required") },
98 { BSM_ERRNO_EBUSY
, EBUSY
, ES("Device busy") },
99 { BSM_ERRNO_EEXIST
, EEXIST
, ES("File exists") },
100 { BSM_ERRNO_EXDEV
, EXDEV
, ES("Cross-device link") },
101 { BSM_ERRNO_ENODEV
, ENODEV
, ES("Operation not supported by device") },
102 { BSM_ERRNO_ENOTDIR
, ENOTDIR
, ES("Not a directory") },
103 { BSM_ERRNO_EISDIR
, EISDIR
, ES("Is a directory") },
104 { BSM_ERRNO_EINVAL
, EINVAL
, ES("Invalid argument") },
105 { BSM_ERRNO_ENFILE
, ENFILE
, ES("Too many open files in system") },
106 { BSM_ERRNO_EMFILE
, EMFILE
, ES("Too many open files") },
107 { BSM_ERRNO_ENOTTY
, ENOTTY
, ES("Inappropriate ioctl for device") },
108 { BSM_ERRNO_ETXTBSY
, ETXTBSY
, ES("Text file busy") },
109 { BSM_ERRNO_EFBIG
, EFBIG
, ES("File too large") },
110 { BSM_ERRNO_ENOSPC
, ENOSPC
, ES("No space left on device") },
111 { BSM_ERRNO_ESPIPE
, ESPIPE
, ES("Illegal seek") },
112 { BSM_ERRNO_EROFS
, EROFS
, ES("Read-only file system") },
113 { BSM_ERRNO_EMLINK
, EMLINK
, ES("Too many links") },
114 { BSM_ERRNO_EPIPE
, EPIPE
, ES("Broken pipe") },
115 { BSM_ERRNO_EDOM
, EDOM
, ES("Numerical argument out of domain") },
116 { BSM_ERRNO_ERANGE
, ERANGE
, ES("Result too large") },
117 { BSM_ERRNO_ENOMSG
, ENOMSG
, ES("No message of desired type") },
118 { BSM_ERRNO_EIDRM
, EIDRM
, ES("Identifier removed") },
123 ERRNO_NO_LOCAL_MAPPING
,
125 ES("Channel number out of range") },
126 { BSM_ERRNO_EL2NSYNC
,
130 ERRNO_NO_LOCAL_MAPPING
,
132 ES("Level 2 not synchronized") },
137 ERRNO_NO_LOCAL_MAPPING
,
139 ES("Level 3 halted") },
144 ERRNO_NO_LOCAL_MAPPING
,
146 ES("Level 3 reset") },
151 ERRNO_NO_LOCAL_MAPPING
,
153 ES("Link number out of range") },
158 ERRNO_NO_LOCAL_MAPPING
,
160 ES("Protocol driver not attached") },
165 ERRNO_NO_LOCAL_MAPPING
,
167 ES("No CSI structure available") },
172 ERRNO_NO_LOCAL_MAPPING
,
174 ES("Level 2 halted") },
175 { BSM_ERRNO_EDEADLK
, EDEADLK
, ES("Resource deadlock avoided") },
176 { BSM_ERRNO_ENOLCK
, ENOLCK
, ES("No locks available") },
177 { BSM_ERRNO_ECANCELED
, ECANCELED
, ES("Operation canceled") },
178 { BSM_ERRNO_ENOTSUP
, ENOTSUP
, ES("Operation not supported") },
179 { BSM_ERRNO_EDQUOT
, EDQUOT
, ES("Disc quota exceeded") },
184 ERRNO_NO_LOCAL_MAPPING
,
186 ES("Invalid exchange") },
191 ERRNO_NO_LOCAL_MAPPING
,
193 ES("Invalid request descriptor") },
198 ERRNO_NO_LOCAL_MAPPING
,
200 ES("Exchange full") },
205 ERRNO_NO_LOCAL_MAPPING
,
212 ERRNO_NO_LOCAL_MAPPING
,
214 ES("Invalid request descriptor") },
219 ERRNO_NO_LOCAL_MAPPING
,
221 ES("Invalid slot") },
222 { BSM_ERRNO_EDEADLOCK
,
226 ERRNO_NO_LOCAL_MAPPING
,
228 ES("Resource deadlock avoided") },
233 ERRNO_NO_LOCAL_MAPPING
,
235 ES("Bad font file format") },
236 { BSM_ERRNO_EOWNERDEAD
,
240 ERRNO_NO_LOCAL_MAPPING
,
242 ES("Process died with the lock") },
243 { BSM_ERRNO_ENOTRECOVERABLE
,
244 #ifdef ENOTRECOVERABLE
247 ERRNO_NO_LOCAL_MAPPING
,
249 ES("Lock is not recoverable") },
254 ERRNO_NO_LOCAL_MAPPING
,
256 ES("Device not a stream") },
261 ERRNO_NO_LOCAL_MAPPING
,
263 ES("Machine is not on the network") },
268 ERRNO_NO_LOCAL_MAPPING
,
270 ES("Package not installed") },
271 { BSM_ERRNO_EREMOTE
, EREMOTE
,
272 ES("Too many levels of remote in path") },
277 ERRNO_NO_LOCAL_MAPPING
,
279 ES("Link has been severed") },
284 ERRNO_NO_LOCAL_MAPPING
,
286 ES("Advertise error") },
291 ERRNO_NO_LOCAL_MAPPING
,
293 ES("srmount error") },
298 ERRNO_NO_LOCAL_MAPPING
,
300 ES("Communication error on send") },
305 ERRNO_NO_LOCAL_MAPPING
,
307 ES("Protocol error") },
308 { BSM_ERRNO_ELOCKUNMAPPED
,
312 ERRNO_NO_LOCAL_MAPPING
,
314 ES("Locked lock was unmapped") },
315 { BSM_ERRNO_ENOTACTIVE
,
319 ERRNO_NO_LOCAL_MAPPING
,
321 ES("Facility is not active") },
322 { BSM_ERRNO_EMULTIHOP
,
326 ERRNO_NO_LOCAL_MAPPING
,
328 ES("Multihop attempted") },
333 ERRNO_NO_LOCAL_MAPPING
,
336 { BSM_ERRNO_ENAMETOOLONG
, ENAMETOOLONG
, ES("File name too long") },
337 { BSM_ERRNO_EOVERFLOW
, EOVERFLOW
,
338 ES("Value too large to be stored in data type") },
339 { BSM_ERRNO_ENOTUNIQ
,
343 ERRNO_NO_LOCAL_MAPPING
,
345 ES("Given log name not unique") },
350 ERRNO_NO_LOCAL_MAPPING
,
352 ES("Given f.d. invalid for this operation") },
357 ERRNO_NO_LOCAL_MAPPING
,
359 ES("Remote address changed") },
364 ERRNO_NO_LOCAL_MAPPING
,
366 ES("Can't access a needed shared lib") },
371 ERRNO_NO_LOCAL_MAPPING
,
373 ES("Accessing a corrupted shared lib") },
378 ERRNO_NO_LOCAL_MAPPING
,
380 ES(".lib section in a.out corrupted") },
385 ERRNO_NO_LOCAL_MAPPING
,
387 ES("Attempting to link in too many libs") },
388 { BSM_ERRNO_ELIBEXEC
,
392 ERRNO_NO_LOCAL_MAPPING
,
394 ES("Attempting to exec a shared library") },
395 { BSM_ERRNO_EILSEQ
, EILSEQ
, ES("Illegal byte sequence") },
396 { BSM_ERRNO_ENOSYS
, ENOSYS
, ES("Function not implemented") },
397 { BSM_ERRNO_ELOOP
, ELOOP
, ES("Too many levels of symbolic links") },
398 { BSM_ERRNO_ERESTART
,
402 ERRNO_NO_LOCAL_MAPPING
,
404 ES("Restart syscall") },
405 { BSM_ERRNO_ESTRPIPE
,
409 ERRNO_NO_LOCAL_MAPPING
,
411 ES("If pipe/FIFO, don't sleep in stream head") },
412 { BSM_ERRNO_ENOTEMPTY
, ENOTEMPTY
, ES("Directory not empty") },
413 { BSM_ERRNO_EUSERS
, EUSERS
, ES("Too many users") },
414 { BSM_ERRNO_ENOTSOCK
, ENOTSOCK
,
415 ES("Socket operation on non-socket") },
416 { BSM_ERRNO_EDESTADDRREQ
, EDESTADDRREQ
,
417 ES("Destination address required") },
418 { BSM_ERRNO_EMSGSIZE
, EMSGSIZE
, ES("Message too long") },
419 { BSM_ERRNO_EPROTOTYPE
, EPROTOTYPE
,
420 ES("Protocol wrong type for socket") },
421 { BSM_ERRNO_ENOPROTOOPT
, ENOPROTOOPT
, ES("Protocol not available") },
422 { BSM_ERRNO_EPROTONOSUPPORT
, EPROTONOSUPPORT
,
423 ES("Protocol not supported") },
424 { BSM_ERRNO_ESOCKTNOSUPPORT
, ESOCKTNOSUPPORT
,
425 ES("Socket type not supported") },
426 { BSM_ERRNO_EOPNOTSUPP
, EOPNOTSUPP
, ES("Operation not supported") },
427 { BSM_ERRNO_EPFNOSUPPORT
, EPFNOSUPPORT
,
428 ES("Protocol family not supported") },
429 { BSM_ERRNO_EAFNOSUPPORT
, EAFNOSUPPORT
,
430 ES("Address family not supported by protocol family") },
431 { BSM_ERRNO_EADDRINUSE
, EADDRINUSE
, ES("Address already in use") },
432 { BSM_ERRNO_EADDRNOTAVAIL
, EADDRNOTAVAIL
,
433 ES("Can't assign requested address") },
434 { BSM_ERRNO_ENETDOWN
, ENETDOWN
, ES("Network is down") },
435 { BSM_ERRNO_ENETRESET
, ENETRESET
,
436 ES("Network dropped connection on reset") },
437 { BSM_ERRNO_ECONNABORTED
, ECONNABORTED
,
438 ES("Software caused connection abort") },
439 { BSM_ERRNO_ECONNRESET
, ECONNRESET
, ES("Connection reset by peer") },
440 { BSM_ERRNO_ENOBUFS
, ENOBUFS
, ES("No buffer space available") },
441 { BSM_ERRNO_EISCONN
, EISCONN
, ES("Socket is already connected") },
442 { BSM_ERRNO_ENOTCONN
, ENOTCONN
, ES("Socket is not connected") },
443 { BSM_ERRNO_ESHUTDOWN
, ESHUTDOWN
,
444 ES("Can't send after socket shutdown") },
445 { BSM_ERRNO_ETOOMANYREFS
, ETOOMANYREFS
,
446 ES("Too many references: can't splice") },
447 { BSM_ERRNO_ETIMEDOUT
, ETIMEDOUT
, ES("Operation timed out") },
448 { BSM_ERRNO_ECONNREFUSED
, ECONNREFUSED
, ES("Connection refused") },
449 { BSM_ERRNO_EHOSTDOWN
, EHOSTDOWN
, ES("Host is down") },
450 { BSM_ERRNO_EHOSTUNREACH
, EHOSTUNREACH
, ES("No route to host") },
451 { BSM_ERRNO_EALREADY
, EALREADY
, ES("Operation already in progress") },
452 { BSM_ERRNO_EINPROGRESS
, EINPROGRESS
,
453 ES("Operation now in progress") },
454 { BSM_ERRNO_ESTALE
, ESTALE
, ES("Stale NFS file handle") },
455 { BSM_ERRNO_EQFULL
, EQFULL
, ES("Interface output queue is full") },
460 ERRNO_NO_LOCAL_MAPPING
,
462 ES("Device power is off") },
467 ERRNO_NO_LOCAL_MAPPING
,
469 ES("Device error") },
470 { BSM_ERRNO_EBADEXEC
,
474 ERRNO_NO_LOCAL_MAPPING
,
476 ES("Bad executable") },
477 { BSM_ERRNO_EBADARCH
,
481 ERRNO_NO_LOCAL_MAPPING
,
483 ES("Bad CPU type in executable") },
484 { BSM_ERRNO_ESHLIBVERS
,
488 ERRNO_NO_LOCAL_MAPPING
,
490 ES("Shared library version mismatch") },
491 { BSM_ERRNO_EBADMACHO
,
495 ERRNO_NO_LOCAL_MAPPING
,
497 ES("Malformed Macho file") },
502 ERRNO_NO_LOCAL_MAPPING
,
504 ES("Operation failed by policy") },
509 ERRNO_NO_LOCAL_MAPPING
,
511 ES("RFS specific error") },
516 ERRNO_NO_LOCAL_MAPPING
,
518 ES("Structure needs cleaning") },
523 ERRNO_NO_LOCAL_MAPPING
,
525 ES("Not a XENIX named type file") },
530 ERRNO_NO_LOCAL_MAPPING
,
532 ES("No XENIX semaphores available") },
537 ERRNO_NO_LOCAL_MAPPING
,
539 ES("Is a named type file") },
540 { BSM_ERRNO_EREMOTEIO
,
544 ERRNO_NO_LOCAL_MAPPING
,
546 ES("Remote I/O error") },
547 { BSM_ERRNO_ENOMEDIUM
,
551 ERRNO_NO_LOCAL_MAPPING
,
553 ES("No medium found") },
554 { BSM_ERRNO_EMEDIUMTYPE
,
558 ERRNO_NO_LOCAL_MAPPING
,
560 ES("Wrong medium type") },
565 ERRNO_NO_LOCAL_MAPPING
,
567 ES("Required key not available") },
568 { BSM_ERRNO_EKEYEXPIRED
,
572 ERRNO_NO_LOCAL_MAPPING
,
574 ES("Key has expired") },
575 { BSM_ERRNO_EKEYREVOKED
,
579 ERRNO_NO_LOCAL_MAPPING
,
581 ES("Key has been revoked") },
582 { BSM_ERRNO_EKEYREJECTED
,
586 ERRNO_NO_LOCAL_MAPPING
,
588 ES("Key was rejected by service") },
590 static const int bsm_errnos_count
= sizeof(bsm_errnos
) / sizeof(bsm_errnos
[0]);
592 static const struct bsm_errno
*
593 bsm_lookup_errno_local(int local_errno
)
597 for (i
= 0; i
< bsm_errnos_count
; i
++) {
598 if (bsm_errnos
[i
].be_local_errno
== local_errno
)
599 return (&bsm_errnos
[i
]);
605 * Conversion to the BSM errno space isn't allowed to fail; we simply map to
606 * BSM_ERRNO_UNKNOWN and let the remote endpoint deal with it.
609 au_errno_to_bsm(int local_errno
)
611 const struct bsm_errno
*bsme
;
613 bsme
= bsm_lookup_errno_local(local_errno
);
615 return (BSM_ERRNO_UNKNOWN
);
616 return (bsme
->be_bsm_errno
);
619 static const struct bsm_errno
*
620 bsm_lookup_errno_bsm(u_char bsm_errno
)
624 for (i
= 0; i
< bsm_errnos_count
; i
++) {
625 if (bsm_errnos
[i
].be_bsm_errno
== bsm_errno
)
626 return (&bsm_errnos
[i
]);
632 * Converstion from a BSM error to a local error number may fail if either
633 * OpenBSM doesn't recognize the error on the wire, or because there is no
634 * appropriate local mapping.
637 au_bsm_to_errno(u_char bsm_errno
, int *errorp
)
639 const struct bsm_errno
*bsme
;
641 bsme
= bsm_lookup_errno_bsm(bsm_errno
);
642 if (bsme
== NULL
|| bsme
->be_local_errno
== ERRNO_NO_LOCAL_MAPPING
)
644 *errorp
= bsme
->be_local_errno
;
648 #if !defined(KERNEL) && !defined(_KERNEL)
650 au_strerror(u_char bsm_errno
)
652 const struct bsm_errno
*bsme
;
654 bsme
= bsm_lookup_errno_bsm(bsm_errno
);
656 return ("Unrecognized BSM error");
657 if (bsme
->be_local_errno
!= ERRNO_NO_LOCAL_MAPPING
)
658 return (strerror(bsme
->be_local_errno
));
659 return (bsme
->be_strerror
);
662 #endif /* CONFIG_AUDIT */