e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * CDDL HEADER START
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * The contents of this file are subject to the terms of the
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * Common Development and Distribution License (the "License").
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * You may not use this file except in compliance with the License.
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * or http://www.opensolaris.org/os/licensing.
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * See the License for the specific language governing permissions
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * and limitations under the License.
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * When distributing Covered Code, include this CDDL HEADER in each
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * If applicable, add the following below this CDDL HEADER, with the
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * fields enclosed by brackets "[]" replaced with your own identifying
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * information: Portions Copyright [yyyy] [name of copyright owner]
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * CDDL HEADER END
406fc5100dac8d225a315a6def6be8d628f34e24Toomas Soome * Copyright 2016 Toomas Soome <tsoome@me.com>
b49b27dcb66b2c7f4a23f7bc158e2dde5cd79030Theo Schlossnagle * Copyright (c) 2013, OmniTI Computer Consulting, Inc. All rights reserved.
80e2ca8596e3435bc3b76f3c597833ea0a87f85e * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
80e2ca8596e3435bc3b76f3c597833ea0a87f85e * See usr/src/lib/brand/shared/brand/common/brand_util.c for general
80e2ca8596e3435bc3b76f3c597833ea0a87f85e * emulation notes.
ad601a0502a167436cd68b185fff0eb78c34777bjv * S10_FEATURE_IS_PRESENT is a macro that helps facilitate conditional
ad601a0502a167436cd68b185fff0eb78c34777bjv * emulation. For each constant N defined in the s10_emulated_features
ad601a0502a167436cd68b185fff0eb78c34777bjv * enumeration in usr/src/uts/common/brand/solaris10/s10_brand.h,
ad601a0502a167436cd68b185fff0eb78c34777bjv * S10_FEATURE_IS_PRESENT(N) is true iff the feature/backport represented by N
ad601a0502a167436cd68b185fff0eb78c34777bjv * is present in the Solaris 10 image hosted within the zone. In other words,
ad601a0502a167436cd68b185fff0eb78c34777bjv * S10_FEATURE_IS_PRESENT(N) is true iff the file /usr/lib/brand/solaris10/M,
ad601a0502a167436cd68b185fff0eb78c34777bjv * where M is the enum value of N, was present in the zone when the zone booted.
ad601a0502a167436cd68b185fff0eb78c34777bjv * *** Sample Usage
ad601a0502a167436cd68b185fff0eb78c34777bjv * Suppose that you need to backport a fix to Solaris 10 and there is
ad601a0502a167436cd68b185fff0eb78c34777bjv * emulation in place for the fix. Suppose further that the emulation won't be
ad601a0502a167436cd68b185fff0eb78c34777bjv * needed if the fix is backported (i.e., if the fix is present in the hosted
ad601a0502a167436cd68b185fff0eb78c34777bjv * Solaris 10 environment, then the brand won't need the emulation). Then if
ad601a0502a167436cd68b185fff0eb78c34777bjv * you add a constant named "S10_FEATURE_X" to the end of the
ad601a0502a167436cd68b185fff0eb78c34777bjv * s10_emulated_features enumeration that represents the backported fix and
ad601a0502a167436cd68b185fff0eb78c34777bjv * S10_FEATURE_X evaluates to four, then you should create a file named
ad601a0502a167436cd68b185fff0eb78c34777bjv * /usr/lib/brand/solaris10/4 as part of your backport. Additionally, you
ad601a0502a167436cd68b185fff0eb78c34777bjv * should retain the aforementioned emulation but modify it so that it's
ad601a0502a167436cd68b185fff0eb78c34777bjv * performed only when S10_FEATURE_IS_PRESENT(S10_FEATURE_X) is false. Thus the
ad601a0502a167436cd68b185fff0eb78c34777bjv * emulation function should look something like the following:
ad601a0502a167436cd68b185fff0eb78c34777bjv * static int
ad601a0502a167436cd68b185fff0eb78c34777bjv * my_emul_function(sysret_t *rv, ...)
ad601a0502a167436cd68b185fff0eb78c34777bjv * if (S10_FEATURE_IS_PRESENT(S10_FEATURE_X)) {
ad601a0502a167436cd68b185fff0eb78c34777bjv * // Don't emulate
ad601a0502a167436cd68b185fff0eb78c34777bjv * return (__systemcall(rv, ...));
ad601a0502a167436cd68b185fff0eb78c34777bjv * } else {
ad601a0502a167436cd68b185fff0eb78c34777bjv * // Emulate whatever needs to be emulated when the
ad601a0502a167436cd68b185fff0eb78c34777bjv * // backport isn't present in the Solaris 10 image.
ad601a0502a167436cd68b185fff0eb78c34777bjv#define S10_FEATURE_IS_PRESENT(s10_emulated_features_constant) \
0fbb751d81ab0a7c7ddfd8d4e447e075a9f7024fJohn Levon * If the ioctl fd's major doesn't match "major", then pass through the
0fbb751d81ab0a7c7ddfd8d4e447e075a9f7024fJohn Levon * ioctl, since it is not the expected device. major should be a
0fbb751d81ab0a7c7ddfd8d4e447e075a9f7024fJohn Levon * pointer to a static dev_t initialized to -1, and devname should be
0fbb751d81ab0a7c7ddfd8d4e447e075a9f7024fJohn Levon * the path of the device.
0fbb751d81ab0a7c7ddfd8d4e447e075a9f7024fJohn Levon * Returns 1 if the ioctl was handled (in which case *err contains the
0fbb751d81ab0a7c7ddfd8d4e447e075a9f7024fJohn Levon * error code), or 0 if it still needs handling.
0fbb751d81ab0a7c7ddfd8d4e447e075a9f7024fJohn Levonpassthru_otherdev_ioctl(dev_t *majordev, const char *devname, int *err,
0fbb751d81ab0a7c7ddfd8d4e447e075a9f7024fJohn Levon if ((*err = __systemcall(rval, SYS_fstatat + 1024,
0fbb751d81ab0a7c7ddfd8d4e447e075a9f7024fJohn Levon if ((*err = __systemcall(rval, SYS_fstatat + 1024, fdes,
0fbb751d81ab0a7c7ddfd8d4e447e075a9f7024fJohn Levon *err = (__systemcall(rval, SYS_ioctl + 1024, fdes, cmd, arg));
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * Figures out the PID of init for the zone. Also returns a boolean
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * indicating whether this process currently has that pid: if so,
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * then at this moment, we are init.
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * Determine the current process PID and the PID of the zone's init.
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * We use care not to call getpid() here, because we're not supposed
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * to call getpid() until after the program is fully linked-- the
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * first call to getpid() is a signal from the linker to debuggers
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * that linking has been completed.
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek B_S10_PIDINFO, &pid, &zone_init_pid)) != 0) {
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * Note that we need to be cautious with the pid we get back--
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * it should not be stashed and used in place of getpid(), since
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * we might fork(2). So we keep zone_init_pid and toss the pid
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * we otherwise got.
c5aee8047f101b999b8f96ced79e802071372a52Robert Harris/* Free the thread-local storage provided by mntfs_get_mntentbuf(). */
c5aee8047f101b999b8f96ced79e802071372a52Robert Harris/* Provide the thread-local storage required by mntfs_ioctl(). */
835ee2195df075073d2670eb95a6eab413d6c789Robert Harrisstatic struct mntentbuf *
835ee2195df075073d2670eb95a6eab413d6c789Robert Harris /* Create the key. */
835ee2195df075073d2670eb95a6eab413d6c789Robert Harris if (thr_keycreate(&key, mntfs_free_mntentbuf)) {
835ee2195df075073d2670eb95a6eab413d6c789Robert Harris * The thread-specific datum for this key is the address of a struct
835ee2195df075073d2670eb95a6eab413d6c789Robert Harris * mntentbuf. If this is the first time here then we allocate the struct
835ee2195df075073d2670eb95a6eab413d6c789Robert Harris * and its contents, and associate its address with the thread; if there
835ee2195df075073d2670eb95a6eab413d6c789Robert Harris * are any problems then we abort.
835ee2195df075073d2670eb95a6eab413d6c789Robert Harris if (!(embufp = calloc(1, sizeof (struct mntentbuf))) ||
835ee2195df075073d2670eb95a6eab413d6c789Robert Harris !(embufp->mbuf_emp = malloc(sizeof (struct extmnttab))) ||
835ee2195df075073d2670eb95a6eab413d6c789Robert Harris /* Return the buffer, resizing it if necessary. */
835ee2195df075073d2670eb95a6eab413d6c789Robert Harris if ((embufp->mbuf_buf = malloc(size)) == NULL) {
c5aee8047f101b999b8f96ced79e802071372a52Robert Harris * The MNTIOC_GETMNTENT command in this release differs from that in early
c5aee8047f101b999b8f96ced79e802071372a52Robert Harris * versions of Solaris 10.
835ee2195df075073d2670eb95a6eab413d6c789Robert Harris * Previously, the command would copy a pointer to a struct extmnttab to an
835ee2195df075073d2670eb95a6eab413d6c789Robert Harris * address provided as an argument. The pointer would be somewhere within a
835ee2195df075073d2670eb95a6eab413d6c789Robert Harris * mapping already present within the user's address space. In addition, the
835ee2195df075073d2670eb95a6eab413d6c789Robert Harris * text to which the struct's members pointed would also be within a
835ee2195df075073d2670eb95a6eab413d6c789Robert Harris * pre-existing mapping. Now, the user is required to allocate memory for both
835ee2195df075073d2670eb95a6eab413d6c789Robert Harris * the struct and the text buffer, and to pass the address of each within a
835ee2195df075073d2670eb95a6eab413d6c789Robert Harris * struct mntentbuf. In order to conceal these details from a Solaris 10 client
835ee2195df075073d2670eb95a6eab413d6c789Robert Harris * we allocate some thread-local storage in which to create the necessary data
835ee2195df075073d2670eb95a6eab413d6c789Robert Harris * structures; this is static, thread-safe memory that will be cleaned up
835ee2195df075073d2670eb95a6eab413d6c789Robert Harris * without the caller's intervention.
835ee2195df075073d2670eb95a6eab413d6c789Robert Harris * MNTIOC_GETEXTMNTENT and MNTIOC_GETMNTANY are new in this release; they should
835ee2195df075073d2670eb95a6eab413d6c789Robert Harris * not work for older clients.
835ee2195df075073d2670eb95a6eab413d6c789Robert Harrismntfs_ioctl(sysret_t *rval, int fdes, int cmd, intptr_t arg)
c5aee8047f101b999b8f96ced79e802071372a52Robert Harris /* Do not emulate mntfs commands from up-to-date clients. */
c5aee8047f101b999b8f96ced79e802071372a52Robert Harris if (S10_FEATURE_IS_PRESENT(S10_FEATURE_ALTERED_MNTFS_IOCTL))
c5aee8047f101b999b8f96ced79e802071372a52Robert Harris return (__systemcall(rval, SYS_ioctl + 1024, fdes, cmd, arg));
c5aee8047f101b999b8f96ced79e802071372a52Robert Harris /* Do not emulate mntfs commands directed at other file systems. */
8fd04b8338ed5093ec2d1e668fa620b7de44c177Roger A. Faulkner if ((err = __systemcall(rval, SYS_fstatat + 1024,
835ee2195df075073d2670eb95a6eab413d6c789Robert Harris if (strcmp(statbuf.st_fstype, MNTTYPE_MNTFS) != 0)
835ee2195df075073d2670eb95a6eab413d6c789Robert Harris return (__systemcall(rval, SYS_ioctl + 1024, fdes, cmd, arg));
835ee2195df075073d2670eb95a6eab413d6c789Robert Harris if (cmd == MNTIOC_GETEXTMNTENT || cmd == MNTIOC_GETMNTANY)
835ee2195df075073d2670eb95a6eab413d6c789Robert Harris if ((embufp = mntfs_get_mntentbuf(bufsize)) == NULL)
835ee2195df075073d2670eb95a6eab413d6c789Robert Harris * MNTIOC_GETEXTMNTENT advances the file pointer once it has
835ee2195df075073d2670eb95a6eab413d6c789Robert Harris * successfully copied out the result to the address provided. We
835ee2195df075073d2670eb95a6eab413d6c789Robert Harris * therefore need to check the user-supplied address now since the
835ee2195df075073d2670eb95a6eab413d6c789Robert Harris * one we'll be providing is guaranteed to work.
80e2ca8596e3435bc3b76f3c597833ea0a87f85e if (brand_uucopy(&embufp->mbuf_emp, (void *)arg, sizeof (void *)) != 0)
835ee2195df075073d2670eb95a6eab413d6c789Robert Harris * Keep retrying for as long as we fail for want of a large enough
835ee2195df075073d2670eb95a6eab413d6c789Robert Harris if ((err = __systemcall(rval, SYS_ioctl + 1024, fdes,
835ee2195df075073d2670eb95a6eab413d6c789Robert Harris /* The buffer wasn't large enough. */
835ee2195df075073d2670eb95a6eab413d6c789Robert Harris (void) atomic_swap_ulong((unsigned long *)&bufsize,
835ee2195df075073d2670eb95a6eab413d6c789Robert Harris if ((embufp = mntfs_get_mntentbuf(bufsize)) == NULL)
80e2ca8596e3435bc3b76f3c597833ea0a87f85e if (brand_uucopy(&embufp->mbuf_emp, (void *)arg, sizeof (void *)) != 0)
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * Assign the structure member value from the s (source) structure to the
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * d (dest) structure.
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek#define struct_assign(d, s, val) (((d).val) = ((s).val))
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * The CRYPTO_GET_FUNCTION_LIST parameter structure crypto_function_list_t
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * changed between S10 and Nevada, so we have to emulate the old S10
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * crypto_function_list_t structure when interposing on the ioctl syscall.
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * The structure returned by the CRYPTO_GET_FUNCTION_LIST ioctl on /dev/crypto
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * increased in size due to:
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * 6482533 Threshold for HW offload via PKCS11 interface
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * between S10 and Nevada. This is a relatively simple process of filling
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * in the S10 structure fields with the Nevada data.
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * We stat the device to make sure that the ioctl is meant for /dev/crypto.
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinekcrypto_ioctl(sysret_t *rval, int fdes, int cmd, intptr_t arg)
0fbb751d81ab0a7c7ddfd8d4e447e075a9f7024fJohn Levon if (passthru_otherdev_ioctl(&crypto_dev, "/dev/crypto", &err,
80e2ca8596e3435bc3b76f3c597833ea0a87f85e if (brand_uucopy((const void *)arg, &s10_param, sizeof (s10_param))
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek struct_assign(native_param, s10_param, fl_provider_id);
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek if ((err = __systemcall(rval, SYS_ioctl + 1024, fdes, cmd,
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek struct_assign(s10_param, native_param, fl_return_value);
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek struct_assign(s10_param, native_param, fl_provider_id);
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek struct_assign(s10_param, native_param, fl_list.fl_digest_init);
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek struct_assign(s10_param, native_param, fl_list.fl_digest);
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek struct_assign(s10_param, native_param, fl_list.fl_digest_update);
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek struct_assign(s10_param, native_param, fl_list.fl_digest_key);
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek struct_assign(s10_param, native_param, fl_list.fl_digest_final);
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek struct_assign(s10_param, native_param, fl_list.fl_encrypt_init);
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek struct_assign(s10_param, native_param, fl_list.fl_encrypt);
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek struct_assign(s10_param, native_param, fl_list.fl_encrypt_update);
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek struct_assign(s10_param, native_param, fl_list.fl_encrypt_final);
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek struct_assign(s10_param, native_param, fl_list.fl_decrypt_init);
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek struct_assign(s10_param, native_param, fl_list.fl_decrypt);
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek struct_assign(s10_param, native_param, fl_list.fl_decrypt_update);
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek struct_assign(s10_param, native_param, fl_list.fl_decrypt_final);
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek struct_assign(s10_param, native_param, fl_list.fl_mac_init);
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek struct_assign(s10_param, native_param, fl_list.fl_mac);
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek struct_assign(s10_param, native_param, fl_list.fl_mac_update);
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek struct_assign(s10_param, native_param, fl_list.fl_mac_final);
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek struct_assign(s10_param, native_param, fl_list.fl_sign_init);
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek struct_assign(s10_param, native_param, fl_list.fl_sign);
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek struct_assign(s10_param, native_param, fl_list.fl_sign_update);
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek struct_assign(s10_param, native_param, fl_list.fl_sign_final);
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek struct_assign(s10_param, native_param, fl_list.fl_sign_recover_init);
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek struct_assign(s10_param, native_param, fl_list.fl_sign_recover);
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek struct_assign(s10_param, native_param, fl_list.fl_verify_init);
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek struct_assign(s10_param, native_param, fl_list.fl_verify);
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek struct_assign(s10_param, native_param, fl_list.fl_verify_update);
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek struct_assign(s10_param, native_param, fl_list.fl_verify_final);
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek struct_assign(s10_param, native_param, fl_list.fl_verify_recover_init);
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek struct_assign(s10_param, native_param, fl_list.fl_verify_recover);
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek struct_assign(s10_param, native_param, fl_list.fl_sign_encrypt_update);
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek struct_assign(s10_param, native_param, fl_list.fl_seed_random);
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek struct_assign(s10_param, native_param, fl_list.fl_generate_random);
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek struct_assign(s10_param, native_param, fl_list.fl_session_open);
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek struct_assign(s10_param, native_param, fl_list.fl_session_close);
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek struct_assign(s10_param, native_param, fl_list.fl_session_login);
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek struct_assign(s10_param, native_param, fl_list.fl_session_logout);
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek struct_assign(s10_param, native_param, fl_list.fl_object_create);
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek struct_assign(s10_param, native_param, fl_list.fl_object_copy);
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek struct_assign(s10_param, native_param, fl_list.fl_object_destroy);
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek struct_assign(s10_param, native_param, fl_list.fl_object_get_size);
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek struct_assign(s10_param, native_param, fl_list.fl_object_find_init);
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek struct_assign(s10_param, native_param, fl_list.fl_object_find);
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek struct_assign(s10_param, native_param, fl_list.fl_object_find_final);
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek struct_assign(s10_param, native_param, fl_list.fl_key_generate);
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek struct_assign(s10_param, native_param, fl_list.fl_key_generate_pair);
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek struct_assign(s10_param, native_param, fl_list.fl_key_wrap);
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek struct_assign(s10_param, native_param, fl_list.fl_key_unwrap);
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek struct_assign(s10_param, native_param, fl_list.fl_key_derive);
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek struct_assign(s10_param, native_param, fl_list.fl_init_token);
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek struct_assign(s10_param, native_param, fl_list.fl_init_pin);
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek struct_assign(s10_param, native_param, fl_list.fl_set_pin);
4df55fde49134f9735f84011f23a767c75e393c7Janie Lu struct_assign(s10_param, native_param, fl_list.prov_is_hash_limited);
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek struct_assign(s10_param, native_param, fl_list.prov_hash_threshold);
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek struct_assign(s10_param, native_param, fl_list.prov_hash_limit);
80e2ca8596e3435bc3b76f3c597833ea0a87f85e return (brand_uucopy(&s10_param, (void *)arg, sizeof (s10_param)));
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * The process contract CT_TGET and CT_TSET parameter structure ct_param_t
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * changed between S10 and Nevada, so we have to emulate the old S10
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * ct_param_t structure when interposing on the ioctl syscall.
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * We have to emulate process contract ioctls for init(1M) because the
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * ioctl parameter structure changed between S10 and Nevada. This is
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * a relatively simple process of filling Nevada structure fields,
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * shuffling values, and initiating a native system call.
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * For now, we'll assume that all consumers of CT_TGET and CT_TSET will
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * need emulation. We'll issue a stat to make sure that the ioctl
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * is meant for the contract file system.
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinekctfs_ioctl(sysret_t *rval, int fdes, int cmd, intptr_t arg)
8fd04b8338ed5093ec2d1e668fa620b7de44c177Roger A. Faulkner if ((err = __systemcall(rval, SYS_fstatat + 1024,
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek if (strcmp(statbuf.st_fstype, MNTTYPE_CTFS) != 0)
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek return (__systemcall(rval, SYS_ioctl + 1024, fdes, cmd, arg));
80e2ca8596e3435bc3b76f3c597833ea0a87f85e if (brand_uucopy((const void *)arg, &s10param, sizeof (s10param)) != 0)
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek if ((err = __systemcall(rval, SYS_ioctl + 1024, fdes, cmd, ¶m))
80e2ca8596e3435bc3b76f3c597833ea0a87f85e sizeof (s10param)));
f3680c6ce4e182fbab2b5d7ea0f9989e952b81d2 * ZFS ioctls have changed in each Solaris 10 (S10) release as well as in
f3680c6ce4e182fbab2b5d7ea0f9989e952b81d2 * Solaris Next. The brand wraps ZFS commands so that the native commands
f3680c6ce4e182fbab2b5d7ea0f9989e952b81d2 * are used, but we want to be sure no command sneaks in that uses ZFS
f3680c6ce4e182fbab2b5d7ea0f9989e952b81d2 * without our knowledge. We'll abort the process if we see a ZFS ioctl.
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinekzfs_ioctl(sysret_t *rval, int fdes, int cmd, intptr_t arg)
0fbb751d81ab0a7c7ddfd8d4e447e075a9f7024fJohn Levon if (passthru_otherdev_ioctl(&zfs_dev, ZFS_DEV, &err,
f3680c6ce4e182fbab2b5d7ea0f9989e952b81d2 /*NOTREACHED*/
f3680c6ce4e182fbab2b5d7ea0f9989e952b81d2 return (0);
0fbb751d81ab0a7c7ddfd8d4e447e075a9f7024fJohn Levonlofi_ioctl(sysret_t *rval, int fdes, int cmd, intptr_t arg)
0fbb751d81ab0a7c7ddfd8d4e447e075a9f7024fJohn Levon if (passthru_otherdev_ioctl(&lofi_dev, "/dev/lofictl", &err,
0fbb751d81ab0a7c7ddfd8d4e447e075a9f7024fJohn Levon sizeof (s10_param)) != 0)
0fbb751d81ab0a7c7ddfd8d4e447e075a9f7024fJohn Levon * Somewhat weirdly, EIO is what the S10 lofi driver would
0fbb751d81ab0a7c7ddfd8d4e447e075a9f7024fJohn Levon * return for unrecognised cmds.
0fbb751d81ab0a7c7ddfd8d4e447e075a9f7024fJohn Levon struct_assign(native_param, s10_param, li_force);
0fbb751d81ab0a7c7ddfd8d4e447e075a9f7024fJohn Levon * Careful here, this has changed from [MAXPATHLEN + 1] to
0fbb751d81ab0a7c7ddfd8d4e447e075a9f7024fJohn Levon * [MAXPATHLEN].
0fbb751d81ab0a7c7ddfd8d4e447e075a9f7024fJohn Levon bcopy(s10_param.li_filename, native_param.li_filename,
0fbb751d81ab0a7c7ddfd8d4e447e075a9f7024fJohn Levon err = __systemcall(rval, SYS_ioctl + 1024, fdes, cmd, &native_param);
0fbb751d81ab0a7c7ddfd8d4e447e075a9f7024fJohn Levon /* li_force is input-only */
0fbb751d81ab0a7c7ddfd8d4e447e075a9f7024fJohn Levon bcopy(native_param.li_filename, s10_param.li_filename,
0fbb751d81ab0a7c7ddfd8d4e447e075a9f7024fJohn Levon (void) brand_uucopy(&s10_param, (void *)arg, sizeof (s10_param));
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelineks10_ioctl(sysret_t *rval, int fdes, int cmd, intptr_t arg)
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek return (__systemcall(rval, SYS_ioctl + 1024, fdes, cmd, arg));
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * Unfortunately, pwrite()'s behavior differs between S10 and Nevada when
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * applied to files opened with O_APPEND. The offset argument is ignored and
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * the buffer is appended to the target file in S10, whereas the current file
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * position is ignored in Nevada (i.e., pwrite() acts as though the target file
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * wasn't opened with O_APPEND). This is a result of the fix for CR 6655660
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * (pwrite() must ignore the O_APPEND/FAPPEND flag).
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * We emulate the old S10 pwrite() behavior by checking whether the target file
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * was opened with O_APPEND. If it was, then invoke the write() system call
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * instead of pwrite(); otherwise, invoke the pwrite() system call as usual.
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelineks10_pwrite(sysret_t *rval, int fd, const void *bufferp, size_t num_bytes,
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek if ((err = __systemcall(rval, SYS_fcntl + 1024, fd, F_GETFL)) != 0)
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek return (__systemcall(rval, SYS_write + 1024, fd, bufferp,
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek return (__systemcall(rval, SYS_pwrite + 1024, fd, bufferp, num_bytes,
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * This is the large file version of the pwrite() system call for 32-bit
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * processes. This exists for the same reason that s10_pwrite() exists; see
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * the comment above s10_pwrite().
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelineks10_pwrite64(sysret_t *rval, int fd, const void *bufferp, size32_t num_bytes,
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek if ((err = __systemcall(rval, SYS_fcntl + 1024, fd, F_GETFL)) != 0)
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek return (__systemcall(rval, SYS_write + 1024, fd, bufferp,
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek return (__systemcall(rval, SYS_pwrite64 + 1024, fd, bufferp,
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek#endif /* !_LP64 */
8b4cf83723ce3e17ebe029b21f549390e849b03fjv * These are convenience macros that s10_getdents_common() uses. Both treat
8b4cf83723ce3e17ebe029b21f549390e849b03fjv * their arguments, which should be character pointers, as dirent pointers or
8b4cf83723ce3e17ebe029b21f549390e849b03fjv * dirent64 pointers and yield their d_name and d_reclen fields. These
8b4cf83723ce3e17ebe029b21f549390e849b03fjv * macros shouldn't be used outside of s10_getdents_common().
8b4cf83723ce3e17ebe029b21f549390e849b03fjv (*(unsigned short *)(uintptr_t)((charptr) + reclen_offset))
8b4cf83723ce3e17ebe029b21f549390e849b03fjv * This function contains code that is common to both s10_getdents() and
8b4cf83723ce3e17ebe029b21f549390e849b03fjv * s10_getdents64(). See the comment above s10_getdents() for details.
8b4cf83723ce3e17ebe029b21f549390e849b03fjv * rval, fd, buf, and nbyte should be passed unmodified from s10_getdents()
8b4cf83723ce3e17ebe029b21f549390e849b03fjv * and s10_getdents64(). getdents_syscall_id should be either SYS_getdents
8b4cf83723ce3e17ebe029b21f549390e849b03fjv * or SYS_getdents64. name_offset should be the the byte offset of
8b4cf83723ce3e17ebe029b21f549390e849b03fjv * the d_name field in the dirent structures passed to the kernel via the
8b4cf83723ce3e17ebe029b21f549390e849b03fjv * syscall represented by getdents_syscall_id. reclen_offset should be
8b4cf83723ce3e17ebe029b21f549390e849b03fjv * the byte offset of the d_reclen field in the aforementioned dirent
8b4cf83723ce3e17ebe029b21f549390e849b03fjv * structures.
8b4cf83723ce3e17ebe029b21f549390e849b03fjvs10_getdents_common(sysret_t *rval, int fd, char *buf, size_t nbyte,
8b4cf83723ce3e17ebe029b21f549390e849b03fjv int getdents_syscall_id, size_t name_offset, size_t reclen_offset)
8b4cf83723ce3e17ebe029b21f549390e849b03fjv * Use a special brand operation, B_S10_ISFDXATTRDIR, to determine
8b4cf83723ce3e17ebe029b21f549390e849b03fjv * whether the specified file descriptor refers to an extended file
8b4cf83723ce3e17ebe029b21f549390e849b03fjv * attribute directory. If it doesn't, then SYS_getdents won't
8b4cf83723ce3e17ebe029b21f549390e849b03fjv * reveal extended file attributes, in which case we can simply
8b4cf83723ce3e17ebe029b21f549390e849b03fjv * hand the syscall to the native kernel.
8b4cf83723ce3e17ebe029b21f549390e849b03fjv if ((err = __systemcall(rval, SYS_brand + 1024, B_S10_ISFDXATTRDIR,
8b4cf83723ce3e17ebe029b21f549390e849b03fjv return (__systemcall(rval, getdents_syscall_id + 1024, fd, buf,
8b4cf83723ce3e17ebe029b21f549390e849b03fjv * The file descriptor refers to an extended file attributes directory.
8b4cf83723ce3e17ebe029b21f549390e849b03fjv * We need to create a dirent buffer that's as large as buf into which
8b4cf83723ce3e17ebe029b21f549390e849b03fjv * the native SYS_getdents will store the special extended file
8b4cf83723ce3e17ebe029b21f549390e849b03fjv * attribute directory's entries. We can't dereference buf because
8b4cf83723ce3e17ebe029b21f549390e849b03fjv * it might be an invalid pointer!
8b4cf83723ce3e17ebe029b21f549390e849b03fjv * getdents(2) doesn't return an error code indicating a memory
8b4cf83723ce3e17ebe029b21f549390e849b03fjv * allocation error and it doesn't make sense to return any of
8b4cf83723ce3e17ebe029b21f549390e849b03fjv * its documented error codes for a malloc(3C) failure. We'll
8b4cf83723ce3e17ebe029b21f549390e849b03fjv * use ENOMEM even though getdents(2) doesn't use it because it
8b4cf83723ce3e17ebe029b21f549390e849b03fjv * best describes the failure.
80e2ca8596e3435bc3b76f3c597833ea0a87f85e (void) B_TRUSS_POINT_3(rval, getdents_syscall_id, ENOMEM, fd,
8b4cf83723ce3e17ebe029b21f549390e849b03fjv * Issue a native SYS_getdents syscall but use our local dirent buffer
8b4cf83723ce3e17ebe029b21f549390e849b03fjv * instead of buf. This will allow us to examine the returned dirent
8b4cf83723ce3e17ebe029b21f549390e849b03fjv * structures immediately and copy them to buf later. That way the
8b4cf83723ce3e17ebe029b21f549390e849b03fjv * calling process won't be able to see the dirent structures until
8b4cf83723ce3e17ebe029b21f549390e849b03fjv * we finish examining them.
8b4cf83723ce3e17ebe029b21f549390e849b03fjv if ((err = __systemcall(rval, getdents_syscall_id + 1024, fd, local_buf,
8b4cf83723ce3e17ebe029b21f549390e849b03fjv if (buf_size == 0) {
8b4cf83723ce3e17ebe029b21f549390e849b03fjv return (0);
8b4cf83723ce3e17ebe029b21f549390e849b03fjv * Look for SUNWattr_ro (VIEW_READONLY) and SUNWattr_rw
8b4cf83723ce3e17ebe029b21f549390e849b03fjv * (VIEW_READWRITE) in the directory entries and remove them
8b4cf83723ce3e17ebe029b21f549390e849b03fjv * from the dirent buffer.
8b4cf83723ce3e17ebe029b21f549390e849b03fjv (size_t)(buf_current - local_buf) < buf_size; /* cstyle */) {
8b4cf83723ce3e17ebe029b21f549390e849b03fjv if (strcmp(dirent_name(buf_current), VIEW_READONLY) != 0 &&
8b4cf83723ce3e17ebe029b21f549390e849b03fjv * The dirent refers to an attribute that should
8b4cf83723ce3e17ebe029b21f549390e849b03fjv * be visible to Solaris 10 processes. Keep it
8b4cf83723ce3e17ebe029b21f549390e849b03fjv * and examine the next entry in the buffer.
8b4cf83723ce3e17ebe029b21f549390e849b03fjv * We found either SUNWattr_ro (VIEW_READONLY)
8b4cf83723ce3e17ebe029b21f549390e849b03fjv * or SUNWattr_rw (VIEW_READWRITE). Remove it
8b4cf83723ce3e17ebe029b21f549390e849b03fjv * from the dirent buffer by decrementing
8b4cf83723ce3e17ebe029b21f549390e849b03fjv * buf_size by the size of the entry and
8b4cf83723ce3e17ebe029b21f549390e849b03fjv * overwriting the entry with the remaining
8b4cf83723ce3e17ebe029b21f549390e849b03fjv * entries.
8b4cf83723ce3e17ebe029b21f549390e849b03fjv * Copy local_buf into buf so that the calling process can see
8b4cf83723ce3e17ebe029b21f549390e849b03fjv * the results.
8b4cf83723ce3e17ebe029b21f549390e849b03fjv return (0);
8b4cf83723ce3e17ebe029b21f549390e849b03fjv * Solaris Next added two special extended file attributes, SUNWattr_ro and
8b4cf83723ce3e17ebe029b21f549390e849b03fjv * SUNWattr_rw, which are called "extended system attributes". They have
8b4cf83723ce3e17ebe029b21f549390e849b03fjv * special semantics (e.g., a process cannot unlink SUNWattr_ro) and should
8b4cf83723ce3e17ebe029b21f549390e849b03fjv * not appear in solaris10-branded zones because no Solaris 10 applications,
8b4cf83723ce3e17ebe029b21f549390e849b03fjv * including system commands such as tar(1), are coded to correctly handle these
8b4cf83723ce3e17ebe029b21f549390e849b03fjv * special attributes.
8b4cf83723ce3e17ebe029b21f549390e849b03fjv * This emulation function solves the aforementioned problem by emulating
8b4cf83723ce3e17ebe029b21f549390e849b03fjv * the getdents(2) syscall and filtering both system attributes out of resulting
8b4cf83723ce3e17ebe029b21f549390e849b03fjv * directory entry lists. The emulation function only filters results when
8b4cf83723ce3e17ebe029b21f549390e849b03fjv * the given file descriptor refers to an extended file attribute directory.
8b4cf83723ce3e17ebe029b21f549390e849b03fjv * Filtering getdents(2) results is expensive because it requires dynamic
8b4cf83723ce3e17ebe029b21f549390e849b03fjv * memory allocation; however, the performance cost is tolerable because
8b4cf83723ce3e17ebe029b21f549390e849b03fjv * we don't expect Solaris 10 processes to frequently examine extended file
8b4cf83723ce3e17ebe029b21f549390e849b03fjv * attribute directories.
8b4cf83723ce3e17ebe029b21f549390e849b03fjv * The brand's emulation library needs two getdents(2) emulation functions
8b4cf83723ce3e17ebe029b21f549390e849b03fjv * because getdents(2) comes in two flavors: non-largefile-aware getdents(2)
8b4cf83723ce3e17ebe029b21f549390e849b03fjv * and largefile-aware getdents64(2). s10_getdents() handles the non-largefile-
8b4cf83723ce3e17ebe029b21f549390e849b03fjv * aware case for 32-bit processes and all getdents(2) syscalls for 64-bit
8b4cf83723ce3e17ebe029b21f549390e849b03fjv * processes (64-bit processes use largefile-aware interfaces by default).
8b4cf83723ce3e17ebe029b21f549390e849b03fjv * See s10_getdents64() below for the largefile-aware getdents64(2) emulation
8b4cf83723ce3e17ebe029b21f549390e849b03fjv * function for 32-bit processes.
8b4cf83723ce3e17ebe029b21f549390e849b03fjvs10_getdents(sysret_t *rval, int fd, struct dirent *buf, size_t nbyte)
8b4cf83723ce3e17ebe029b21f549390e849b03fjv return (s10_getdents_common(rval, fd, (char *)buf, nbyte, SYS_getdents,
8b4cf83723ce3e17ebe029b21f549390e849b03fjv * This is the largefile-aware version of getdents(2) for 32-bit processes.
8b4cf83723ce3e17ebe029b21f549390e849b03fjv * This exists for the same reason that s10_getdents() exists. See the comment
8b4cf83723ce3e17ebe029b21f549390e849b03fjv * above s10_getdents().
8b4cf83723ce3e17ebe029b21f549390e849b03fjvs10_getdents64(sysret_t *rval, int fd, struct dirent64 *buf, size_t nbyte)
8b4cf83723ce3e17ebe029b21f549390e849b03fjv return (s10_getdents_common(rval, fd, (char *)buf, nbyte,
8b4cf83723ce3e17ebe029b21f549390e849b03fjv#endif /* !_LP64 */
f3f1e74c80144abbd168779e485ea0cb810b8256 * Check if the ACL qualifies as a trivial ACL based on the native
f3f1e74c80144abbd168779e485ea0cb810b8256 * interpretation.
f3f1e74c80144abbd168779e485ea0cb810b8256has_trivial_native_acl(int cmd, int cnt, const char *fname, int fd)
f3f1e74c80144abbd168779e485ea0cb810b8256 * If we just got the ACL cnt, we don't need to get it again, its
f3f1e74c80144abbd168779e485ea0cb810b8256 * passed in as the cnt arg.
f3f1e74c80144abbd168779e485ea0cb810b8256 if (__systemcall(&rval, SYS_acl + 1024, fname, ACE_GETACL, cnt,
f3f1e74c80144abbd168779e485ea0cb810b8256 if (__systemcall(&rval, SYS_facl + 1024, fd, ACE_GETACL, cnt,
f3f1e74c80144abbd168779e485ea0cb810b8256 * The following is based on the logic from the native OS
f3f1e74c80144abbd168779e485ea0cb810b8256 * ace_trivial_common() to determine if the native ACL is trivial.
f3f1e74c80144abbd168779e485ea0cb810b8256 for (i = 0; i < cnt; i++) {
f3f1e74c80144abbd168779e485ea0cb810b8256 * Special check for some special bits
f3f1e74c80144abbd168779e485ea0cb810b8256 * Don't allow anybody to deny reading basic
f3f1e74c80144abbd168779e485ea0cb810b8256 * attributes or a files ACL.
f3f1e74c80144abbd168779e485ea0cb810b8256 if (buf[i].a_access_mask & (ACE_READ_ACL|ACE_READ_ATTRIBUTES) &&
f3f1e74c80144abbd168779e485ea0cb810b8256 * Delete permissions are never set by default
f3f1e74c80144abbd168779e485ea0cb810b8256 * only allow owner@ to have
f3f1e74c80144abbd168779e485ea0cb810b8256 * The following logic is based on the S10 adjust_ace_pair_common() code.
f3f1e74c80144abbd168779e485ea0cb810b8256static void
f3f1e74c80144abbd168779e485ea0cb810b8256s10_adjust_ace_mask(void *pair, size_t access_off, size_t pairsize, mode_t mode)
f3f1e74c80144abbd168779e485ea0cb810b8256 uint32_t *amask0 = (uint32_t *)(uintptr_t)(datap + access_off);
f3f1e74c80144abbd168779e485ea0cb810b8256 uint32_t *amask1 = (uint32_t *)(uintptr_t)(datap + pairsize +
f3f1e74c80144abbd168779e485ea0cb810b8256 * Construct a trivial S10 style ACL.
f3f1e74c80144abbd168779e485ea0cb810b8256static int
f3f1e74c80144abbd168779e485ea0cb810b8256 {(uint_t)-1, ACE_WRITE_ACL|ACE_WRITE_OWNER|ACE_WRITE_ATTRIBUTES|
f3f1e74c80144abbd168779e485ea0cb810b8256 {(uint_t)-1, ACE_WRITE_ACL|ACE_WRITE_OWNER|ACE_WRITE_ATTRIBUTES|
f3f1e74c80144abbd168779e485ea0cb810b8256 if ((err = __systemcall(&rval, SYS_fstatat64 + 1024, AT_FDCWD,
f3f1e74c80144abbd168779e485ea0cb810b8256 return (err);
f3f1e74c80144abbd168779e485ea0cb810b8256 return (err);
f3f1e74c80144abbd168779e485ea0cb810b8256 s10_adjust_ace_mask(&trivial_s10_acl[0], offsetof(ace_t, a_access_mask),
f3f1e74c80144abbd168779e485ea0cb810b8256 s10_adjust_ace_mask(&trivial_s10_acl[2], offsetof(ace_t, a_access_mask),
f3f1e74c80144abbd168779e485ea0cb810b8256 s10_adjust_ace_mask(&trivial_s10_acl[4], offsetof(ace_t, a_access_mask),
f3f1e74c80144abbd168779e485ea0cb810b8256 if (brand_uucopy(&trivial_s10_acl, bp, sizeof (trivial_s10_acl)) != 0)
f3f1e74c80144abbd168779e485ea0cb810b8256 return (0);
f3f1e74c80144abbd168779e485ea0cb810b8256 * The definition of a trivial ace-style ACL (used by ZFS and NFSv4) has been
f3f1e74c80144abbd168779e485ea0cb810b8256 * simplified since S10. Instead of 6 entries on a trivial S10 ACE ACL we now
f3f1e74c80144abbd168779e485ea0cb810b8256 * have 3 streamlined entries. The new, simpler trivial style confuses S10
f3f1e74c80144abbd168779e485ea0cb810b8256 * commands such as 'ls -v' or 'cp -p' which don't see the expected S10 trivial
f3f1e74c80144abbd168779e485ea0cb810b8256 * ACL entries and thus assume that there is a complex ACL on the file.
f3f1e74c80144abbd168779e485ea0cb810b8256 * See: PSARC/2010/029 Improved ACL interoperability
f3f1e74c80144abbd168779e485ea0cb810b8256 * Note that the trival ACL detection code is implemented in acl_trival() in
f3f1e74c80144abbd168779e485ea0cb810b8256 * lib/libsec/common/aclutils.c. It always uses the acl() syscall (not the
f3f1e74c80144abbd168779e485ea0cb810b8256 * facl syscall) to determine if an ACL is trivial. However, we emulate both
f3f1e74c80144abbd168779e485ea0cb810b8256 * acl() and facl() so that the two provide consistent results.
f3f1e74c80144abbd168779e485ea0cb810b8256 * We don't currently try to emulate setting of ACLs since the primary
f3f1e74c80144abbd168779e485ea0cb810b8256 * consumer of this feature is SMB or NFSv4 servers, neither of which are
f3f1e74c80144abbd168779e485ea0cb810b8256 * supported in solaris10-branded zones. If ACLs are used they must be set on
f3f1e74c80144abbd168779e485ea0cb810b8256 * files using the native OS interpretation.
f3f1e74c80144abbd168779e485ea0cb810b8256s10_acl(sysret_t *rval, const char *fname, int cmd, int nentries, void *aclbufp)
f3f1e74c80144abbd168779e485ea0cb810b8256 res = __systemcall(rval, SYS_acl + 1024, fname, cmd, nentries, aclbufp);
f3f1e74c80144abbd168779e485ea0cb810b8256 switch (cmd) {
f3f1e74c80144abbd168779e485ea0cb810b8256 if (res == 0 &&
f3f1e74c80144abbd168779e485ea0cb810b8256 return (res);
f3f1e74c80144abbd168779e485ea0cb810b8256s10_facl(sysret_t *rval, int fdes, int cmd, int nentries, void *aclbufp)
f3f1e74c80144abbd168779e485ea0cb810b8256 res = __systemcall(rval, SYS_facl + 1024, fdes, cmd, nentries, aclbufp);
f3f1e74c80144abbd168779e485ea0cb810b8256 switch (cmd) {
f3f1e74c80144abbd168779e485ea0cb810b8256 if (res == 0 &&
f3f1e74c80144abbd168779e485ea0cb810b8256 return (res);
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * The mode shift, mode mask and option mask for acctctl have changed. The
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * mode is currently the top full byte and the option is the lower 3 full bytes.
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelineks10_acctctl(sysret_t *rval, int cmd, void *buf, size_t bufsz)
80e2ca8596e3435bc3b76f3c597833ea0a87f85e return (B_TRUSS_POINT_3(rval, SYS_acctctl, EINVAL, cmd, buf,
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek return (__systemcall(rval, SYS_acctctl + 1024, mode | option, buf,
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * The Audit Policy parameters have changed due to:
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * 6466722 audituser and AUDIT_USER are defined, unused, undocumented and
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * should be removed.
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * In S10 we had the following flag:
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * #define AUDIT_USER 0x0040
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * which doesn't exist in Solaris Next where the subsequent flags are shifted
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * down. For example, in S10 we had:
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * #define AUDIT_GROUP 0x0080
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * but on Solaris Next we have:
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * #define AUDIT_GROUP 0x0040
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * AUDIT_GROUP has the value AUDIT_USER had in S10 and all of the subsequent
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * bits are also shifted one place.
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * When we're getting or setting the Audit Policy parameters we need to
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * shift the outgoing or incoming bits into their proper positions. Since
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * S10_AUDIT_USER was always unused, we always clear that bit on A_GETPOLICY.
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * The command we care about, BSM_AUDITCTL, passes the most parameters (3),
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * so declare this function to take up to 4 args and just pass them on.
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * The number of parameters for s10_auditsys needs to be equal to the BSM_*
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * subcommand that has the most parameters, since we want to pass all
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * parameters through, regardless of which subcommands we interpose on.
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * Note that the auditsys system call uses the SYSENT_AP macro wrapper instead
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * of the more common SYSENT_CI macro. This means the return value is a
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * SE_64RVAL so the syscall table uses RV_64RVAL.
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelineks10_auditsys(sysret_t *rval, int bsmcmd, intptr_t a0, intptr_t a1, intptr_t a2)
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek return (__systemcall(rval, SYS_auditsys + 1024, bsmcmd, a0, a1,
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek if ((err = __systemcall(rval, SYS_auditsys + 1024, bsmcmd, a0,
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek m = ((m & S10_AUDIT_HMASK) << 1) | (m & S10_AUDIT_LMASK);
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek m = ((m >> 1) & S10_AUDIT_HMASK) | (m & S10_AUDIT_LMASK);
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek return (__systemcall(rval, SYS_auditsys + 1024, bsmcmd, a0, &m,
005d3feb53a9a10272d4a24b03991575d6a9bcb3Marek Pospisil if ((err = __systemcall(rval, SYS_auditsys + 1024, bsmcmd, a0,
005d3feb53a9a10272d4a24b03991575d6a9bcb3Marek Pospisil return (__systemcall(rval, SYS_auditsys + 1024, bsmcmd, a0, &m,
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek return (__systemcall(rval, SYS_auditsys + 1024, bsmcmd, a0, a1, a2));
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * Determine whether the executable passed to SYS_exec or SYS_execve is a
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * native executable. The s10_npreload.so invokes the B_S10_NATIVE brand
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * operation which patches up the processes exec info to eliminate any trace
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * of the wrapper. That will make pgrep and other commands that examine
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * process' executable names and command-line parameters work properly.
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelineks10_exec_native(sysret_t *rval, const char *fname, const char **argp,
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek const char **envp)
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek /* Get a copy of the executable we're trying to run */
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek /* Check if we're trying to run a native binary */
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek if (strncmp(path, "/.SUNWnative/usr/lib/brand/solaris10/s10_native",
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek sizeof (path)) != 0)
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek /* Skip the first element in the argv array */
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * The the path of the dynamic linker is the second parameter
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * of s10_native_exec().
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek /* If an exec call succeeds, it never returns */
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek err = __systemcall(rval, SYS_brand + 1024, B_EXEC_NATIVE, filename,
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * Interpose on the SYS_exec syscall to detect native wrappers.
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelineks10_exec(sysret_t *rval, const char *fname, const char **argp)
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek if ((err = s10_exec_native(rval, fname, argp, NULL)) != 0)
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek /* If an exec call succeeds, it never returns */
8fd04b8338ed5093ec2d1e668fa620b7de44c177Roger A. Faulkner err = __systemcall(rval, SYS_execve + 1024, fname, argp, NULL);
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * Interpose on the SYS_execve syscall to detect native wrappers.
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelineks10_execve(sysret_t *rval, const char *fname, const char **argp,
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek const char **envp)
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek if ((err = s10_exec_native(rval, fname, argp, envp)) != 0)
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek /* If an exec call succeeds, it never returns */
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek err = __systemcall(rval, SYS_execve + 1024, fname, argp, envp);
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * S10's issetugid() syscall is now a subcode to privsys().
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek return (__systemcall(rval, SYS_privsys + 1024, PRIVSYS_ISSETUGID,
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek 0, 0, 0, 0, 0));
b49b27dcb66b2c7f4a23f7bc158e2dde5cd79030Theo Schlossnagle * S10's socket() syscall does not split type and flags
b49b27dcb66b2c7f4a23f7bc158e2dde5cd79030Theo Schlossnagles10_so_socket(sysret_t *rval, int domain, int type, int protocol,
b49b27dcb66b2c7f4a23f7bc158e2dde5cd79030Theo Schlossnagle return (__systemcall(rval, SYS_so_socket + 1024, domain, type,
b49b27dcb66b2c7f4a23f7bc158e2dde5cd79030Theo Schlossnagle * S10's pipe() syscall has a different calling convention
b49b27dcb66b2c7f4a23f7bc158e2dde5cd79030Theo Schlossnagle if ((err = __systemcall(rval, SYS_pipe + 1024, fds, 0)) != 0)
b49b27dcb66b2c7f4a23f7bc158e2dde5cd79030Theo Schlossnagle * S10's accept() syscall takes three arguments
b49b27dcb66b2c7f4a23f7bc158e2dde5cd79030Theo Schlossnagles10_accept(sysret_t *rval, int sock, struct sockaddr *addr, uint_t *addrlen,
b49b27dcb66b2c7f4a23f7bc158e2dde5cd79030Theo Schlossnagle return (__systemcall(rval, SYS_accept + 1024, sock, addr, addrlen,
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek struct utsname un, *unp = (struct utsname *)p1;
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek if ((err = __systemcall(rv, SYS_uname + 1024, &un)) != 0)
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek (void) strlcpy(un.release, S10_UTS_RELEASE, _SYS_NMLN);
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek (void) strlcpy(un.version, S10_UTS_VERSION, _SYS_NMLN);
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek /* copy out the modified uname info */
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner * We must interpose on the sysconfig(2) requests
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner * that deal with the realtime signal number range.
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner * All others get passed to the native sysconfig(2).
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner return (__systemcall(rv, SYS_sysconfig + 1024, which));
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelineks10_sysinfo(sysret_t *rv, int command, char *buf, long count)
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * We must interpose on the sysinfo(2) commands SI_RELEASE and
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * SI_VERSION; all others get passed to the native sysinfo(2)
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * The default action is to pass the command to the
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * native sysinfo(2) syscall.
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek return (__systemcall(rv, SYS_systeminfo + 1024,
80e2ca8596e3435bc3b76f3c597833ea0a87f85e * Assure NULL termination of buf as brand_uucopystr() doesn't.
80e2ca8596e3435bc3b76f3c597833ea0a87f85e if (len > count && brand_uucopy("\0", buf + (count - 1), 1)
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * On success, sysinfo(2) returns the size of buffer required to hold
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * the complete value plus its terminating NULL byte.
80e2ca8596e3435bc3b76f3c597833ea0a87f85e (void) B_TRUSS_POINT_3(rv, SYS_systeminfo, 0, command, buf, count);
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * 64-bit x86 LWPs created by SYS_lwp_create start here if they need to set
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * their %fs registers to the legacy Solaris 10 selector value.
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * This function does three things:
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * 1. Trap to the kernel so that it can set %fs to the legacy Solaris 10
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * selector value.
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * 2. Read the LWP's true entry point (the entry point supplied by libc
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * when SYS_lwp_create was invoked) from %r14.
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * 3. Eliminate this function's stack frame and pass control to the LWP's
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * true entry point.
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * See the comment above s10_lwp_create_correct_fs() (see below) for the reason
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * why this function exists.
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelineks10_lwp_create_entry_point(void *ulwp_structp)
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * The new LWP's %fs register is initially zero, but libc won't
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * function correctly when %fs is zero. Change the LWP's %fs register
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * via SYS_brand.
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek (void) __systemcall(&rval, SYS_brand + 1024, B_S10_FSREGCORRECTION);
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * Jump to the true entry point, which is stored in %r14.
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * Remove our stack frame before jumping so that
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * s10_lwp_create_entry_point() won't be seen in stack traces.
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * NOTE: s10_lwp_create_entry_point() pushes %r12 onto its stack frame
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * so that it can use it as a temporary register. We don't restore %r12
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * in this assembly block because we don't care about its value (and
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * neither does _lwp_start()). Besides, the System V ABI AMD64
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * Actirecture Processor Supplement doesn't specify that %r12 should
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * have a special value when LWPs start, so we can ignore its value when
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * we jump to the true entry point. Furthermore, %r12 is a callee-saved
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * register, so the true entry point should push %r12 onto its stack
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * before using the register. We ignore %r14 after we read it for
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * similar reasons.
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * NOTE: The compiler will generate a function epilogue for this
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * function despite the fact that the LWP will never execute it.
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * We could hand-code this entire function in assembly to eliminate
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * the epilogue, but the epilogue is only three or four instructions,
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * so we wouldn't save much space. Besides, why would we want
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * to create yet another ugly, hard-to-maintain assembly function when
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * we could write most of it in C?
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek "movq %0, %%rdi\n\t" /* pass ulwp_structp as arg1 */
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek "movq %%rbp, %%rsp\n\t" /* eliminate the stack frame */
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek "popq %%rbp\n\t"
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek "jmp *%%r14\n\t" /* jump to the true entry point */
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek /*NOTREACHED*/
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * The S10 libc expects that %fs will be nonzero for new 64-bit x86 LWPs but the
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * Nevada kernel clears %fs for such LWPs. Unforunately, new LWPs do not issue
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * SYS_lwp_private (see s10_lwp_private() below) after they are created, so
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * we must ensure that new LWPs invoke a brand operation that sets %fs to a
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * nonzero value immediately after their creation.
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * The easiest way to do this is to make new LWPs start at a special function,
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * s10_lwp_create_entry_point() (see its definition above), that invokes the
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * brand operation that corrects %fs. We'll store the entry points of new LWPs
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * in their %r14 registers so that s10_lwp_create_entry_point() can find and
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * call them after invoking the special brand operation. %r14 is a callee-saved
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * register; therefore, any functions invoked by s10_lwp_create_entry_point()
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * and all functions dealing with signals (e.g., sigacthandler()) will preserve
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * %r14 for s10_lwp_create_entry_point().
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * The Nevada kernel can safely work with nonzero %fs values because the kernel
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * configures per-thread %fs segment descriptors so that the legacy %fs selector
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * value will still work. See the comment in lwp_load() regarding %fs and
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * %fsbase in 64-bit x86 processes.
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * This emulation exists thanks to CRs 6467491 and 6501650.
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelineks10_lwp_create_correct_fs(sysret_t *rval, ucontext_t *ucp, int flags,
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * Copy the supplied ucontext_t structure to the local stack
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * frame and store the new LWP's entry point (the value of %rip
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * stored in the ucontext_t) in the new LWP's %r14 register.
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * Then make s10_lwp_create_entry_point() the new LWP's entry
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek s10_uc.uc_mcontext.gregs[REG_R14] = s10_uc.uc_mcontext.gregs[REG_RIP];
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek s10_uc.uc_mcontext.gregs[REG_RIP] = (greg_t)s10_lwp_create_entry_point;
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner /* fix up the signal mask */
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner (void) s10sigset_to_native(&s10_uc.uc_sigmask,
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * Issue SYS_lwp_create to create the new LWP. We pass the
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * modified ucontext_t to make sure that the new LWP starts at
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * s10_lwp_create_entry_point().
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek return (__systemcall(rval, SYS_lwp_create + 1024, &s10_uc,
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek#endif /* __amd64 */
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * SYS_lwp_private is issued by libc_init() to set %fsbase in 64-bit x86
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * processes. The Nevada kernel sets %fs to zero but the S10 libc expects
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * %fs to be nonzero. We'll pass the issued system call to the kernel untouched
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * and invoke a brand operation to set %fs to the legacy S10 selector value.
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * This emulation exists thanks to CRs 6467491 and 6501650.
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelineks10_lwp_private(sysret_t *rval, int cmd, int which, uintptr_t base)
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * The current LWP's %fs register should be zero. Determine whether the
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * Solaris 10 libc with which we're working functions correctly when %fs
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * is zero by calling thr_main() after issuing the SYS_lwp_private
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * syscall. If thr_main() barfs (returns -1), then change the LWP's %fs
80e2ca8596e3435bc3b76f3c597833ea0a87f85e * register via SYS_brand and patch brand_sysent_table so that issuing
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * SYS_lwp_create executes s10_lwp_create_correct_fs() rather than the
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * default s10_lwp_create(). s10_lwp_create_correct_fs() will
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * guarantee that new LWPs will have correct %fs values.
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek if ((err = __systemcall(rval, SYS_lwp_private + 1024, cmd, which,
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * SYS_lwp_private is only issued by libc_init(), which is
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * executed when libc is first loaded by ld.so.1. Thus we
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * are guaranteed to be single-threaded at this point. Even
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * if we were multithreaded at this point, writing a 64-bit
80e2ca8596e3435bc3b76f3c597833ea0a87f85e * value to the st_callc field of a brand_sysent_table
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * entry is guaranteed to be atomic on 64-bit x86 chips
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * as long as the field is not split across cache lines
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * (It shouldn't be.). See chapter 8, section 1.1 of
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * "The Intel 64 and IA32 Architectures Software Developer's
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * Manual," Volume 3A for more details.
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek#else /* !__amd64 */
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek return (__systemcall(rval, SYS_lwp_private + 1024, cmd, which, base));
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek#endif /* !__amd64 */
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek#endif /* __x86 */
db94676fbd90b0affb8474a2af4e10718ba3136dRoger A. Faulkner * The Opensolaris versions of lwp_mutex_timedlock() and lwp_mutex_trylock()
db94676fbd90b0affb8474a2af4e10718ba3136dRoger A. Faulkner * add an extra argument to the interfaces, a uintptr_t value for the mutex's
db94676fbd90b0affb8474a2af4e10718ba3136dRoger A. Faulkner * mutex_owner field. The Solaris 10 libc assigns the mutex_owner field at
db94676fbd90b0affb8474a2af4e10718ba3136dRoger A. Faulkner * user-level, so we just make the extra argument be zero in both syscalls.
db94676fbd90b0affb8474a2af4e10718ba3136dRoger A. Faulkners10_lwp_mutex_timedlock(sysret_t *rval, lwp_mutex_t *lp, timespec_t *tsp)
db94676fbd90b0affb8474a2af4e10718ba3136dRoger A. Faulkner return (__systemcall(rval, SYS_lwp_mutex_timedlock + 1024, lp, tsp, 0));
db94676fbd90b0affb8474a2af4e10718ba3136dRoger A. Faulkners10_lwp_mutex_trylock(sysret_t *rval, lwp_mutex_t *lp)
db94676fbd90b0affb8474a2af4e10718ba3136dRoger A. Faulkner return (__systemcall(rval, SYS_lwp_mutex_trylock + 1024, lp, 0));
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * If the emul_global_zone flag is set then emulate some aspects of the
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * zone system call. In particular, emulate the global zone ID on the
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * ZONE_LOOKUP subcommand and emulate some of the global zone attributes
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * on the ZONE_GETATTR subcommand. If the flag is not set or we're performing
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * some other operation, simply pass the calls through.
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelineks10_zone(sysret_t *rval, int cmd, void *arg1, void *arg2, void *arg3,
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * We only emulate the zone syscall for a subset of specific commands,
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * otherwise we just pass the call through.
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek return (__systemcall(rval, SYS_zone + 1024, cmd, arg1, arg2,
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * If the request is for the global zone then we're emulating
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * that, otherwise pass this thru.
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * We only emulate a subset of the attrs, use the
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * real zone id to pass thru the rest.
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * Assure NULL termination of "buf" as
80e2ca8596e3435bc3b76f3c597833ea0a87f85e * brand_uucopystr() does NOT.
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek return (__systemcall(rval, SYS_zone + 1024, cmd, arg1, arg2, arg3,
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * Cache the pid of the zone's init process and determine if
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * we're init(1m) for the zone. Remember: we might be init
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * now, but as soon as we fork(2) we won't be.
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek /* get the current zoneid */
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek err = __systemcall(&rval, SYS_zone, ZONE_LOOKUP, NULL);
ad601a0502a167436cd68b185fff0eb78c34777bjv /* Get the zone's emulation bitmap. */
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek if ((err = __systemcall(&rval, SYS_zone, ZONE_GETATTR, zoneid,
ad601a0502a167436cd68b185fff0eb78c34777bjv S10_EMUL_BITMAP, emul_bitmap, sizeof (emul_bitmap))) != 0) {
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek /*NOTREACHED*/
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * In general we want the S10 commands that are zone-aware to continue
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * to behave as they normally do within a zone. Since these commands
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * are zone-aware, they should continue to "do the right thing".
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * However, some zone-aware commands aren't going to work the way
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * we expect them to inside the branded zone. In particular, the pkg
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * and patch commands will not properly manage all pkgs/patches
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * unless the commands think they are running in the global zone. For
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * these commands we want to emulate the global zone.
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * We don't do any emulation for pkgcond since it is typically used
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * in pkg/patch postinstall scripts and we want those scripts to do
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * the right thing inside a zone.
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * One issue is the handling of hollow pkgs. Since the pkgs are
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * hollow, they won't use pkgcond in their postinstall scripts. These
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * pkgs typically are installing drivers so we handle that by
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * replacing add_drv and rem_drv in the s10_boot script.
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek if (strcmp("pkgadd", bname) == 0 || strcmp("pkgrm", bname) == 0 ||
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek strcmp("patchadd", bname) == 0 || strcmp("patchrm", bname) == 0)
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek /*NOTREACHED*/
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * This table must have at least NSYSCALL entries in it.
80e2ca8596e3435bc3b76f3c597833ea0a87f85e * The second parameter of each entry in the brand_sysent_table
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * contains the number of parameters and flags that describe the
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * syscall return value encoding. See the block comments at the
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * top of this file for more information about the syscall return
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * value flags and when they should be used.
8fd04b8338ed5093ec2d1e668fa620b7de44c177Roger A. Faulkner EMULATE(s10_forkall, 0 | RV_32RVAL2), /* 2 */
8fd04b8338ed5093ec2d1e668fa620b7de44c177Roger A. Faulkner EMULATE(s10_open, 3 | RV_DEFAULT), /* 5 */
8fd04b8338ed5093ec2d1e668fa620b7de44c177Roger A. Faulkner EMULATE(s10_wait, 0 | RV_32RVAL2), /* 7 */
8fd04b8338ed5093ec2d1e668fa620b7de44c177Roger A. Faulkner EMULATE(s10_creat, 2 | RV_DEFAULT), /* 8 */
794f0adb050e571bbfde4d2a19b9f88b852079ddRoger A. Faulkner EMULATE(s10_link, 2 | RV_DEFAULT), /* 9 */
8fd04b8338ed5093ec2d1e668fa620b7de44c177Roger A. Faulkner EMULATE(s10_unlink, 1 | RV_DEFAULT), /* 10 */
794f0adb050e571bbfde4d2a19b9f88b852079ddRoger A. Faulkner EMULATE(s10_mknod, 3 | RV_DEFAULT), /* 14 */
794f0adb050e571bbfde4d2a19b9f88b852079ddRoger A. Faulkner EMULATE(s10_chmod, 2 | RV_DEFAULT), /* 15 */
8fd04b8338ed5093ec2d1e668fa620b7de44c177Roger A. Faulkner EMULATE(s10_chown, 3 | RV_DEFAULT), /* 16 */
8fd04b8338ed5093ec2d1e668fa620b7de44c177Roger A. Faulkner EMULATE(s10_stat, 2 | RV_DEFAULT), /* 18 */
8fd04b8338ed5093ec2d1e668fa620b7de44c177Roger A. Faulkner EMULATE(s10_umount, 1 | RV_DEFAULT), /* 22 */
8fd04b8338ed5093ec2d1e668fa620b7de44c177Roger A. Faulkner EMULATE(s10_fstat, 2 | RV_DEFAULT), /* 28 */
8fd04b8338ed5093ec2d1e668fa620b7de44c177Roger A. Faulkner EMULATE(s10_utime, 2 | RV_DEFAULT), /* 30 */
8fd04b8338ed5093ec2d1e668fa620b7de44c177Roger A. Faulkner EMULATE(s10_access, 2 | RV_DEFAULT), /* 33 */
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner EMULATE(s10_kill, 2 | RV_DEFAULT), /* 37 */
8fd04b8338ed5093ec2d1e668fa620b7de44c177Roger A. Faulkner EMULATE(s10_dup, 1 | RV_DEFAULT), /* 41 */
b49b27dcb66b2c7f4a23f7bc158e2dde5cd79030Theo Schlossnagle EMULATE(s10_pipe, 0 | RV_32RVAL2), /* 42 */
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek EMULATE(s10_execve, 3 | RV_DEFAULT), /* 59 */
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek EMULATE(s10_acctctl, 3 | RV_DEFAULT), /* 71 */
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek EMULATE(s10_issetugid, 0 | RV_DEFAULT), /* 75 */
8fd04b8338ed5093ec2d1e668fa620b7de44c177Roger A. Faulkner EMULATE(s10_fsat, 6 | RV_DEFAULT), /* 76 */
8fd04b8338ed5093ec2d1e668fa620b7de44c177Roger A. Faulkner EMULATE(s10_rmdir, 1 | RV_DEFAULT), /* 79 */
794f0adb050e571bbfde4d2a19b9f88b852079ddRoger A. Faulkner EMULATE(s10_mkdir, 2 | RV_DEFAULT), /* 80 */
8fd04b8338ed5093ec2d1e668fa620b7de44c177Roger A. Faulkner EMULATE(s10_poll, 3 | RV_DEFAULT), /* 87 */
8fd04b8338ed5093ec2d1e668fa620b7de44c177Roger A. Faulkner EMULATE(s10_lstat, 2 | RV_DEFAULT), /* 88 */
794f0adb050e571bbfde4d2a19b9f88b852079ddRoger A. Faulkner EMULATE(s10_symlink, 2 | RV_DEFAULT), /* 89 */
794f0adb050e571bbfde4d2a19b9f88b852079ddRoger A. Faulkner EMULATE(s10_readlink, 3 | RV_DEFAULT), /* 90 */
794f0adb050e571bbfde4d2a19b9f88b852079ddRoger A. Faulkner EMULATE(s10_fchmod, 2 | RV_DEFAULT), /* 93 */
8fd04b8338ed5093ec2d1e668fa620b7de44c177Roger A. Faulkner EMULATE(s10_fchown, 3 | RV_DEFAULT), /* 94 */
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner EMULATE(s10_sigprocmask, 3 | RV_DEFAULT), /* 95 */
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner EMULATE(s10_sigsuspend, 1 | RV_DEFAULT), /* 96 */
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner EMULATE(s10_sigaction, 3 | RV_DEFAULT), /* 98 */
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner EMULATE(s10_sigpending, 2 | RV_DEFAULT), /* 99 */
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner EMULATE(s10_waitid, 4 | RV_DEFAULT), /* 107 */
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner EMULATE(s10_sigsendsys, 2 | RV_DEFAULT), /* 108 */
8fd04b8338ed5093ec2d1e668fa620b7de44c177Roger A. Faulkner EMULATE(s10_xstat, 3 | RV_DEFAULT), /* 123 */
8fd04b8338ed5093ec2d1e668fa620b7de44c177Roger A. Faulkner EMULATE(s10_lxstat, 3 | RV_DEFAULT), /* 124 */
8fd04b8338ed5093ec2d1e668fa620b7de44c177Roger A. Faulkner EMULATE(s10_fxstat, 3 | RV_DEFAULT), /* 125 */
8fd04b8338ed5093ec2d1e668fa620b7de44c177Roger A. Faulkner EMULATE(s10_xmknod, 4 | RV_DEFAULT), /* 126 */
8fd04b8338ed5093ec2d1e668fa620b7de44c177Roger A. Faulkner EMULATE(s10_lchown, 3 | RV_DEFAULT), /* 130 */
8fd04b8338ed5093ec2d1e668fa620b7de44c177Roger A. Faulkner EMULATE(s10_rename, 2 | RV_DEFAULT), /* 134 */
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek EMULATE(s10_uname, 1 | RV_DEFAULT), /* 135 */
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner EMULATE(s10_sysconfig, 1 | RV_DEFAULT), /* 137 */
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek EMULATE(s10_sysinfo, 3 | RV_DEFAULT), /* 139 */
8fd04b8338ed5093ec2d1e668fa620b7de44c177Roger A. Faulkner EMULATE(s10_fork1, 0 | RV_32RVAL2), /* 143 */
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner EMULATE(s10_sigtimedwait, 3 | RV_DEFAULT), /* 144 */
8fd04b8338ed5093ec2d1e668fa620b7de44c177Roger A. Faulkner EMULATE(s10_lwp_sema_wait, 1 | RV_DEFAULT), /* 147 */
8fd04b8338ed5093ec2d1e668fa620b7de44c177Roger A. Faulkner EMULATE(s10_utimes, 2 | RV_DEFAULT), /* 154 */
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek EMULATE(s10_lwp_create, 3 | RV_DEFAULT), /* 159 */
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner EMULATE(s10_lwp_kill, 2 | RV_DEFAULT), /* 163 */
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner EMULATE(s10_lwp_sigmask, 3 | RV_32RVAL2), /* 165 */
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek EMULATE(s10_lwp_private, 3 | RV_DEFAULT), /* 166 */
8fd04b8338ed5093ec2d1e668fa620b7de44c177Roger A. Faulkner EMULATE(s10_lwp_mutex_lock, 1 | RV_DEFAULT), /* 169 */
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek EMULATE(s10_pwrite, 4 | RV_DEFAULT), /* 174 */
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek EMULATE(s10_auditsys, 4 | RV_64RVAL), /* 186 */
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek EMULATE(s10_sigqueue, 4 | RV_DEFAULT), /* 190 */
bdf0047c9427cca40961a023475891c898579c37Roger A. Faulkner EMULATE(s10_signotify, 3 | RV_DEFAULT), /* 205 */
8fd04b8338ed5093ec2d1e668fa620b7de44c177Roger A. Faulkner EMULATE(s10_lwp_mutex_timedlock, 2 | RV_DEFAULT), /* 210 */
8fd04b8338ed5093ec2d1e668fa620b7de44c177Roger A. Faulkner EMULATE(s10_stat64, 2 | RV_DEFAULT), /* 215 */
8fd04b8338ed5093ec2d1e668fa620b7de44c177Roger A. Faulkner EMULATE(s10_lstat64, 2 | RV_DEFAULT), /* 216 */
8fd04b8338ed5093ec2d1e668fa620b7de44c177Roger A. Faulkner EMULATE(s10_fstat64, 2 | RV_DEFAULT), /* 217 */
8fd04b8338ed5093ec2d1e668fa620b7de44c177Roger A. Faulkner EMULATE(s10_pwrite64, 5 | RV_DEFAULT), /* 223 */
8fd04b8338ed5093ec2d1e668fa620b7de44c177Roger A. Faulkner EMULATE(s10_creat64, 2 | RV_DEFAULT), /* 224 */
8fd04b8338ed5093ec2d1e668fa620b7de44c177Roger A. Faulkner EMULATE(s10_open64, 3 | RV_DEFAULT), /* 225 */
b49b27dcb66b2c7f4a23f7bc158e2dde5cd79030Theo Schlossnagle EMULATE(s10_so_socket, 5 | RV_DEFAULT), /* 230 */
b49b27dcb66b2c7f4a23f7bc158e2dde5cd79030Theo Schlossnagle EMULATE(s10_accept, 4 | RV_DEFAULT), /* 234 */