diff --git a/etc/skel/dot.version b/etc/skel/dot.version index f4a564975..47315502f 100644 --- a/etc/skel/dot.version +++ b/etc/skel/dot.version @@ -1 +1 @@ -# SecBSD 1.5-55906ba: Sat Apr 20 00:00:00 UTC 2024 (Yatagarasu) +# SecBSD 1.5-22ee75e: Fri May 3 00:00:00 UTC 2024 (Yatagarasu) diff --git a/lib/libc/sys/msgctl.2 b/lib/libc/sys/msgctl.2 index f14360ea5..f041c78de 100644 --- a/lib/libc/sys/msgctl.2 +++ b/lib/libc/sys/msgctl.2 @@ -1,4 +1,4 @@ -.\" $OpenBSD: msgctl.2,v 1.18 2019/07/18 13:32:40 schwarze Exp $ +.\" $OpenBSD: msgctl.2,v 1.19 2024/04/30 17:03:14 op Exp $ .\" $NetBSD: msgctl.2,v 1.2 1997/03/27 08:20:35 mikel Exp $ .\" .\" Copyright (c) 1995 Frank van der Linden @@ -30,7 +30,7 @@ .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\"/ -.Dd $Mdocdate: July 18 2019 $ +.Dd $Mdocdate: April 30 2024 $ .Dt MSGCTL 2 .Os .Sh NAME @@ -58,9 +58,9 @@ and contains (amongst others) the following members: .Bd -literal struct msqid_ds { struct ipc_perm msg_perm; /* msg queue permission bits */ - u_long msg_cbytes; /* # of bytes in use on the queue */ - u_long msg_qnum; /* # of msgs in the queue */ - u_long msg_qbytes; /* max # of bytes on the queue */ + msglen_t msg_cbytes; /* # of bytes in use on the queue */ + msgqnum_t msg_qnum; /* # of msgs in the queue */ + msglen_t msg_qbytes; /* max # of bytes on the queue */ pid_t msg_lspid; /* pid of last msgsnd() */ pid_t msg_lrpid; /* pid of last msgrcv() */ time_t msg_stime; /* time of last msgsnd() */ diff --git a/lib/libcrypto/asn1/t_crl.c b/lib/libcrypto/asn1/t_crl.c index 1ff6ea02a..6449e7f19 100644 --- a/lib/libcrypto/asn1/t_crl.c +++ b/lib/libcrypto/asn1/t_crl.c @@ -1,4 +1,4 @@ -/* $OpenBSD: t_crl.c,v 1.24 2024/04/09 13:55:02 beck Exp $ */ +/* $OpenBSD: t_crl.c,v 1.26 2024/05/03 02:52:00 tb Exp $ */ /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL * project 1999. */ @@ -96,10 +96,15 @@ X509_CRL_print(BIO *out, X509_CRL *x) BIO_printf(out, "Certificate Revocation List (CRL):\n"); l = X509_CRL_get_version(x); - if (l < 0 || l == LONG_MAX) - goto err; - BIO_printf(out, "%8sVersion %lu (0x%lx)\n", "", l + 1, l); - i = OBJ_obj2nid(x->sig_alg->algorithm); + if (l >= 0 && l <= 1) { + if (BIO_printf(out, "%8sVersion: %lu (0x%lx)\n", + "", l + 1, l) <= 0) + goto err; + } else { + if (BIO_printf(out, "%8sVersion: unknown (%ld)\n", + "", l) <= 0) + goto err; + } if (X509_signature_print(out, x->sig_alg, NULL) == 0) goto err; p = X509_NAME_oneline(X509_CRL_get_issuer(x), NULL, 0); diff --git a/lib/libcrypto/asn1/t_req.c b/lib/libcrypto/asn1/t_req.c index ac011705e..1d4be9865 100644 --- a/lib/libcrypto/asn1/t_req.c +++ b/lib/libcrypto/asn1/t_req.c @@ -1,4 +1,4 @@ -/* $OpenBSD: t_req.c,v 1.27 2024/04/09 13:55:02 beck Exp $ */ +/* $OpenBSD: t_req.c,v 1.28 2024/05/03 02:52:00 tb Exp $ */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * @@ -99,7 +99,6 @@ X509_REQ_print_ex(BIO *bp, X509_REQ *x, unsigned long nmflags, { unsigned long l; int i; - const char *neg; X509_REQ_INFO *ri; EVP_PKEY *pkey; STACK_OF(X509_ATTRIBUTE) *sk; @@ -124,15 +123,14 @@ X509_REQ_print_ex(BIO *bp, X509_REQ *x, unsigned long nmflags, goto err; } if (!(cflag & X509_FLAG_NO_VERSION)) { - neg = (ri->version->type == V_ASN1_NEG_INTEGER) ? "-" : ""; - l = 0; - for (i = 0; i < ri->version->length; i++) { - l <<= 8; - l += ri->version->data[i]; + if ((l = X509_REQ_get_version(x)) == 0) { + if (BIO_printf(bp, "%8sVersion: 1 (0x0)\n", "") <= 0) + goto err; + } else { + if (BIO_printf(bp, "%8sVersion: unknown (%ld)\n", + "", l) <= 0) + goto err; } - if (BIO_printf(bp, "%8sVersion: %s%lu (%s0x%lx)\n", "", neg, - l, neg, l) <= 0) - goto err; } if (!(cflag & X509_FLAG_NO_SUBJECT)) { if (BIO_printf(bp, " Subject:%c", mlch) <= 0) diff --git a/lib/libm/src/s_sincosl.c b/lib/libm/src/s_sincosl.c index e89d30c4b..3afb1a950 100644 --- a/lib/libm/src/s_sincosl.c +++ b/lib/libm/src/s_sincosl.c @@ -72,12 +72,14 @@ sincosl(long double x, long double *sn, long double *cs) *cs = 1; } else __kernel_sincosl(x, 0, 0, sn, cs); + return; } /* If x = NaN or Inf, then sin(x) and cos(x) are NaN. */ if (z.bits.ext_exp == 32767) { *sn = x - x; *cs = x - x; + return; } /* Split z.e into a 24-bit representation. */ diff --git a/share/man/man4/efi.4 b/share/man/man4/efi.4 index 02fd5abde..50887fa41 100644 --- a/share/man/man4/efi.4 +++ b/share/man/man4/efi.4 @@ -1,4 +1,4 @@ -.\" $OpenBSD: efi.4,v 1.1 2024/04/29 20:18:12 kn Exp $ +.\" $OpenBSD: efi.4,v 1.2 2024/04/30 05:05:23 jmc Exp $ .\" .\" Copyright (c) 2018 Mark Kettenis .\" Copyright (c) 2024 Klemens Nanni @@ -15,7 +15,7 @@ .\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. .\" -.Dd $Mdocdate: April 29 2024 $ +.Dd $Mdocdate: April 30 2024 $ .Dt EFI 4 .Os .Sh NAME @@ -47,7 +47,7 @@ The .Nm device driver first appeared for arm64 in .Ox 6.3 . -Support for amd64, the ESRT and EFI variables appeard in +Support for amd64, the ESRT and EFI variables appeared in .Ox 7.3 . .Sh AUTHORS .An -nosplit diff --git a/sys/arch/amd64/amd64/pmap.c b/sys/arch/amd64/amd64/pmap.c index 4d86cb3f2..c66389d0f 100644 --- a/sys/arch/amd64/amd64/pmap.c +++ b/sys/arch/amd64/amd64/pmap.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pmap.c,v 1.166 2024/04/03 18:43:32 miod Exp $ */ +/* $OpenBSD: pmap.c,v 1.167 2024/05/03 13:48:29 dv Exp $ */ /* $NetBSD: pmap.c,v 1.3 2003/05/08 18:13:13 thorpej Exp $ */ /* @@ -3119,6 +3119,7 @@ pmap_convert(struct pmap *pmap, int mode) { pt_entry_t *pte; + mtx_enter(&pmap->pm_mtx); pmap->pm_type = mode; if (mode == PMAP_TYPE_EPT) { @@ -3132,6 +3133,7 @@ pmap_convert(struct pmap *pmap, int mode) pmap->pm_pdir_intel = NULL; } } + mtx_leave(&pmap->pm_mtx); } #ifdef MULTIPROCESSOR diff --git a/sys/arch/amd64/amd64/vmm_machdep.c b/sys/arch/amd64/amd64/vmm_machdep.c index 9338b96b0..b2b7c3401 100644 --- a/sys/arch/amd64/amd64/vmm_machdep.c +++ b/sys/arch/amd64/amd64/vmm_machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: vmm_machdep.c,v 1.25 2024/04/29 14:47:05 dv Exp $ */ +/* $OpenBSD: vmm_machdep.c,v 1.26 2024/05/03 13:48:29 dv Exp $ */ /* * Copyright (c) 2014 Mike Larkin * @@ -91,10 +91,6 @@ int vcpu_run_svm(struct vcpu *, struct vm_run_params *); void vcpu_deinit(struct vcpu *); void vcpu_deinit_svm(struct vcpu *); void vcpu_deinit_vmx(struct vcpu *); -int vm_impl_init(struct vm *, struct proc *); -int vm_impl_init_vmx(struct vm *, struct proc *); -int vm_impl_init_svm(struct vm *, struct proc *); -void vm_impl_deinit(struct vm *); int vcpu_vmx_check_cap(struct vcpu *, uint32_t, uint32_t, int); int vcpu_vmx_compute_ctrl(uint64_t, uint16_t, uint32_t, uint32_t, uint32_t *); int vmx_get_exit_info(uint64_t *, uint64_t *); @@ -1204,147 +1200,72 @@ vmx_remote_vmclear(struct cpu_info *ci, struct vcpu *vcpu) } #endif /* MULTIPROCESSOR */ -/* - * vm_impl_init_vmx - * - * Intel VMX specific VM initialization routine - * - * Parameters: - * vm: the VM being initialized - * p: vmd process owning the VM - * - * Return values: - * 0: the initialization was successful - * ENOMEM: the initialization failed (lack of resources) - */ -int -vm_impl_init_vmx(struct vm *vm, struct proc *p) -{ - int i, ret; - vaddr_t mingpa, maxgpa; - struct vm_mem_range *vmr; - - /* If not EPT, nothing to do here */ - if (vmm_softc->mode != VMM_MODE_EPT) - return (0); - - vmr = &vm->vm_memranges[0]; - mingpa = vmr->vmr_gpa; - vmr = &vm->vm_memranges[vm->vm_nmemranges - 1]; - maxgpa = vmr->vmr_gpa + vmr->vmr_size; - - /* - * uvmspace_alloc (currently) always returns a valid vmspace - */ - vm->vm_vmspace = uvmspace_alloc(mingpa, maxgpa, TRUE, FALSE); - vm->vm_map = &vm->vm_vmspace->vm_map; - - /* Map the new map with an anon */ - DPRINTF("%s: created vm_map @ %p\n", __func__, vm->vm_map); - for (i = 0; i < vm->vm_nmemranges; i++) { - vmr = &vm->vm_memranges[i]; - ret = uvm_share(vm->vm_map, vmr->vmr_gpa, - PROT_READ | PROT_WRITE | PROT_EXEC, - &p->p_vmspace->vm_map, vmr->vmr_va, vmr->vmr_size); - if (ret) { - printf("%s: uvm_share failed (%d)\n", __func__, ret); - /* uvmspace_free calls pmap_destroy for us */ - uvmspace_free(vm->vm_vmspace); - vm->vm_vmspace = NULL; - return (ENOMEM); - } - } - - pmap_convert(vm->vm_map->pmap, PMAP_TYPE_EPT); - - return (0); -} - -/* - * vm_impl_init_svm - * - * AMD SVM specific VM initialization routine - * - * Parameters: - * vm: the VM being initialized - * p: vmd process owning the VM - * - * Return values: - * 0: the initialization was successful - * ENOMEM: the initialization failed (lack of resources) - */ -int -vm_impl_init_svm(struct vm *vm, struct proc *p) -{ - int i, ret; - vaddr_t mingpa, maxgpa; - struct vm_mem_range *vmr; - - /* If not RVI, nothing to do here */ - if (vmm_softc->mode != VMM_MODE_RVI) - return (0); - - vmr = &vm->vm_memranges[0]; - mingpa = vmr->vmr_gpa; - vmr = &vm->vm_memranges[vm->vm_nmemranges - 1]; - maxgpa = vmr->vmr_gpa + vmr->vmr_size; - - /* - * uvmspace_alloc (currently) always returns a valid vmspace - */ - vm->vm_vmspace = uvmspace_alloc(mingpa, maxgpa, TRUE, FALSE); - vm->vm_map = &vm->vm_vmspace->vm_map; - - /* Map the new map with an anon */ - DPRINTF("%s: created vm_map @ %p\n", __func__, vm->vm_map); - for (i = 0; i < vm->vm_nmemranges; i++) { - vmr = &vm->vm_memranges[i]; - ret = uvm_share(vm->vm_map, vmr->vmr_gpa, - PROT_READ | PROT_WRITE | PROT_EXEC, - &p->p_vmspace->vm_map, vmr->vmr_va, vmr->vmr_size); - if (ret) { - printf("%s: uvm_share failed (%d)\n", __func__, ret); - /* uvmspace_free calls pmap_destroy for us */ - uvmspace_free(vm->vm_vmspace); - vm->vm_vmspace = NULL; - return (ENOMEM); - } - } - - /* Convert pmap to RVI */ - pmap_convert(vm->vm_map->pmap, PMAP_TYPE_RVI); - - return (0); -} - /* * vm_impl_init * - * Calls the architecture-specific VM init routine + * VM address space initialization routine * * Parameters: * vm: the VM being initialized * p: vmd process owning the VM * - * Return values (from architecture-specific init routines): + * Return values: * 0: the initialization was successful + * EINVAL: unsupported vmm mode * ENOMEM: the initialization failed (lack of resources) */ int vm_impl_init(struct vm *vm, struct proc *p) { - int ret; + int i, mode, ret; + vaddr_t mingpa, maxgpa; + struct vm_mem_range *vmr; - KERNEL_LOCK(); - if (vmm_softc->mode == VMM_MODE_EPT) - ret = vm_impl_init_vmx(vm, p); - else if (vmm_softc->mode == VMM_MODE_RVI) - ret = vm_impl_init_svm(vm, p); - else - panic("%s: unknown vmm mode: %d", __func__, vmm_softc->mode); - KERNEL_UNLOCK(); + /* If not EPT or RVI, nothing to do here */ + switch (vmm_softc->mode) { + case VMM_MODE_EPT: + mode = PMAP_TYPE_EPT; + break; + case VMM_MODE_RVI: + mode = PMAP_TYPE_RVI; + break; + default: + printf("%s: invalid vmm mode %d\n", __func__, vmm_softc->mode); + return (EINVAL); + } - return (ret); + vmr = &vm->vm_memranges[0]; + mingpa = vmr->vmr_gpa; + vmr = &vm->vm_memranges[vm->vm_nmemranges - 1]; + maxgpa = vmr->vmr_gpa + vmr->vmr_size; + + /* + * uvmspace_alloc (currently) always returns a valid vmspace + */ + vm->vm_vmspace = uvmspace_alloc(mingpa, maxgpa, TRUE, FALSE); + vm->vm_map = &vm->vm_vmspace->vm_map; + + /* Map the new map with an anon */ + DPRINTF("%s: created vm_map @ %p\n", __func__, vm->vm_map); + for (i = 0; i < vm->vm_nmemranges; i++) { + vmr = &vm->vm_memranges[i]; + ret = uvm_share(vm->vm_map, vmr->vmr_gpa, + PROT_READ | PROT_WRITE | PROT_EXEC, + &p->p_vmspace->vm_map, vmr->vmr_va, vmr->vmr_size); + if (ret) { + printf("%s: uvm_share failed (%d)\n", __func__, ret); + /* uvmspace_free calls pmap_destroy for us */ + KERNEL_LOCK(); + uvmspace_free(vm->vm_vmspace); + vm->vm_vmspace = NULL; + KERNEL_UNLOCK(); + return (ENOMEM); + } + } + + pmap_convert(vm->vm_map->pmap, mode); + + return (0); } void diff --git a/sys/arch/amd64/include/cpu.h b/sys/arch/amd64/include/cpu.h index 998fc8edd..318e87b59 100644 --- a/sys/arch/amd64/include/cpu.h +++ b/sys/arch/amd64/include/cpu.h @@ -1,4 +1,4 @@ -/* $OpenBSD: cpu.h,v 1.167 2024/04/19 10:22:50 mpi Exp $ */ +/* $OpenBSD: cpu.h,v 1.168 2024/05/01 12:54:27 mpi Exp $ */ /* $NetBSD: cpu.h,v 1.1 2003/04/26 18:39:39 fvdl Exp $ */ /*- @@ -53,6 +53,7 @@ #include #include #include +#include #ifdef _KERNEL @@ -210,6 +211,8 @@ struct cpu_info { #ifdef MULTIPROCESSOR struct srp_hazard ci_srp_hazards[SRP_HAZARD_NUM]; +#define __HAVE_UVM_PERCPU + struct uvm_pmr_cache ci_uvm; /* [o] page cache */ #endif struct ksensordev ci_sensordev; diff --git a/sys/arch/arm64/include/cpu.h b/sys/arch/arm64/include/cpu.h index 4cc24ee72..c4073465a 100644 --- a/sys/arch/arm64/include/cpu.h +++ b/sys/arch/arm64/include/cpu.h @@ -1,4 +1,4 @@ -/* $OpenBSD: cpu.h,v 1.46 2024/04/29 13:01:54 jsg Exp $ */ +/* $OpenBSD: cpu.h,v 1.47 2024/05/01 12:54:27 mpi Exp $ */ /* * Copyright (c) 2016 Dale Rahn * @@ -104,6 +104,7 @@ extern uint64_t cpu_id_aa64pfr1; #include #include #include +#include struct cpu_info { struct device *ci_dev; /* Device corresponding to this CPU */ @@ -157,6 +158,8 @@ struct cpu_info { #ifdef MULTIPROCESSOR struct srp_hazard ci_srp_hazards[SRP_HAZARD_NUM]; +#define __HAVE_UVM_PERCPU + struct uvm_pmr_cache ci_uvm; volatile int ci_flags; volatile int ci_ddb_paused; diff --git a/sys/arch/i386/include/cpu.h b/sys/arch/i386/include/cpu.h index bb2b7e3f3..82b7e1798 100644 --- a/sys/arch/i386/include/cpu.h +++ b/sys/arch/i386/include/cpu.h @@ -1,4 +1,4 @@ -/* $OpenBSD: cpu.h,v 1.187 2024/04/19 10:22:50 mpi Exp $ */ +/* $OpenBSD: cpu.h,v 1.188 2024/05/01 12:54:27 mpi Exp $ */ /* $NetBSD: cpu.h,v 1.35 1996/05/05 19:29:26 christos Exp $ */ /*- @@ -69,6 +69,7 @@ #include #include #include +#include struct intrsource; @@ -99,6 +100,8 @@ struct cpu_info { #if defined(MULTIPROCESSOR) struct srp_hazard ci_srp_hazards[SRP_HAZARD_NUM]; +#define __HAVE_UVM_PERCPU + struct uvm_pmr_cache ci_uvm; #endif /* diff --git a/sys/dev/ic/dwqe.c b/sys/dev/ic/dwqe.c index 24987008d..5b60afaba 100644 --- a/sys/dev/ic/dwqe.c +++ b/sys/dev/ic/dwqe.c @@ -1,4 +1,4 @@ -/* $OpenBSD: dwqe.c,v 1.19 2024/04/25 08:51:37 jmatthew Exp $ */ +/* $OpenBSD: dwqe.c,v 1.20 2024/05/03 13:02:18 stsp Exp $ */ /* * Copyright (c) 2008, 2019 Mark Kettenis * Copyright (c) 2017, 2022 Patrick Wildt @@ -643,6 +643,66 @@ dwqe_tx_proc(struct dwqe_softc *sc) } } +int +dwqe_have_rx_csum_offload(struct dwqe_softc *sc) +{ + return (sc->sc_hw_feature[0] & GMAC_MAC_HW_FEATURE0_RXCOESEL); +} + +void +dwqe_rx_csum(struct dwqe_softc *sc, struct mbuf *m, struct dwqe_desc *rxd) +{ + uint16_t csum_flags = 0; + + /* + * Checksum offload must be supported, the Last-Descriptor bit + * must be set, RDES1 must be valid, and checksumming must not + * have been bypassed (happens for unknown packet types), and + * an IP header must have been detected. + */ + if (!dwqe_have_rx_csum_offload(sc) || + (rxd->sd_tdes3 & RDES3_LD) == 0 || + (rxd->sd_tdes3 & RDES3_RDES1_VALID) == 0 || + (rxd->sd_tdes1 & RDES1_IP_CSUM_BYPASS) || + (rxd->sd_tdes1 & (RDES1_IPV4_HDR | RDES1_IPV6_HDR)) == 0) + return; + + /* If the IP header checksum is invalid then the payload is ignored. */ + if (rxd->sd_tdes1 & RDES1_IP_HDR_ERROR) { + if (rxd->sd_tdes1 & RDES1_IPV4_HDR) + csum_flags |= M_IPV4_CSUM_IN_BAD; + } else { + if (rxd->sd_tdes1 & RDES1_IPV4_HDR) + csum_flags |= M_IPV4_CSUM_IN_OK; + + /* Detect payload type and corresponding checksum errors. */ + switch (rxd->sd_tdes1 & RDES1_IP_PAYLOAD_TYPE) { + case RDES1_IP_PAYLOAD_UDP: + if (rxd->sd_tdes1 & RDES1_IP_PAYLOAD_ERROR) + csum_flags |= M_UDP_CSUM_IN_BAD; + else + csum_flags |= M_UDP_CSUM_IN_OK; + break; + case RDES1_IP_PAYLOAD_TCP: + if (rxd->sd_tdes1 & RDES1_IP_PAYLOAD_ERROR) + csum_flags |= M_TCP_CSUM_IN_BAD; + else + csum_flags |= M_TCP_CSUM_IN_OK; + break; + case RDES1_IP_PAYLOAD_ICMP: + if (rxd->sd_tdes1 & RDES1_IP_PAYLOAD_ERROR) + csum_flags |= M_ICMP_CSUM_IN_BAD; + else + csum_flags |= M_ICMP_CSUM_IN_OK; + break; + default: + break; + } + } + + m->m_pkthdr.csum_flags |= csum_flags; +} + void dwqe_rx_proc(struct dwqe_softc *sc) { @@ -691,6 +751,7 @@ dwqe_rx_proc(struct dwqe_softc *sc) m->m_pkthdr.len = m->m_len = len; + dwqe_rx_csum(sc, m, rxd); ml_enqueue(&ml, m); } @@ -866,6 +927,12 @@ dwqe_up(struct dwqe_softc *sc) if (!sc->sc_fixed_link) timeout_add_sec(&sc->sc_phy_tick, 1); + + if (dwqe_have_rx_csum_offload(sc)) { + reg = dwqe_read(sc, GMAC_MAC_CONF); + reg |= GMAC_MAC_CONF_IPC; + dwqe_write(sc, GMAC_MAC_CONF, reg); + } } void diff --git a/sys/dev/ic/dwqereg.h b/sys/dev/ic/dwqereg.h index 6f1753b34..7db8b2a40 100644 --- a/sys/dev/ic/dwqereg.h +++ b/sys/dev/ic/dwqereg.h @@ -1,4 +1,4 @@ -/* $OpenBSD: dwqereg.h,v 1.7 2024/04/25 11:37:39 stsp Exp $ */ +/* $OpenBSD: dwqereg.h,v 1.8 2024/05/03 13:02:18 stsp Exp $ */ /* * Copyright (c) 2008, 2019 Mark Kettenis * Copyright (c) 2017, 2022 Patrick Wildt @@ -17,6 +17,7 @@ */ #define GMAC_MAC_CONF 0x0000 +#define GMAC_MAC_CONF_IPC (1 << 27) #define GMAC_MAC_CONF_CST (1 << 21) #define GMAC_MAC_CONF_ACS (1 << 20) #define GMAC_MAC_CONF_BE (1 << 18) @@ -61,6 +62,8 @@ #define GMAC_VERSION 0x0110 #define GMAC_VERSION_SNPS_MASK 0xff #define GMAC_MAC_HW_FEATURE(x) (0x011c + (x) * 0x4) +#define GMAC_MAC_HW_FEATURE0_TXCOESEL (1 << 14) +#define GMAC_MAC_HW_FEATURE0_RXCOESEL (1 << 16) #define GMAC_MAC_HW_FEATURE1_TXFIFOSIZE(x) (((x) >> 6) & 0x1f) #define GMAC_MAC_HW_FEATURE1_RXFIFOSIZE(x) (((x) >> 0) & 0x1f) #define GMAC_MAC_MDIO_ADDR 0x0200 diff --git a/sys/dev/ic/qwx.c b/sys/dev/ic/qwx.c index 3f38f408b..97c935c7d 100644 --- a/sys/dev/ic/qwx.c +++ b/sys/dev/ic/qwx.c @@ -1,4 +1,4 @@ -/* $OpenBSD: qwx.c,v 1.58 2024/03/09 23:29:53 stsp Exp $ */ +/* $OpenBSD: qwx.c,v 1.59 2024/05/03 14:32:11 stsp Exp $ */ /* * Copyright 2023 Stefan Sperling @@ -206,10 +206,6 @@ qwx_init(struct ifnet *ifp) if (error) return error; - /* Configure channel information obtained from firmware. */ - ieee80211_channel_init(ifp); - ieee80211_media_init(ifp, qwx_media_change, ieee80211_media_status); - if (sc->attached) { /* Update MAC in case the upper layers changed it. */ IEEE80211_ADDR_COPY(ic->ic_myaddr, @@ -217,12 +213,18 @@ qwx_init(struct ifnet *ifp) } else { sc->attached = 1; + /* Configure channel information obtained from firmware. */ + ieee80211_channel_init(ifp); + /* Configure initial MAC address. */ error = if_setlladdr(ifp, ic->ic_myaddr); if (error) printf("%s: could not set MAC address %s: %d\n", sc->sc_dev.dv_xname, ether_sprintf(ic->ic_myaddr), error); + + ieee80211_media_init(ifp, qwx_media_change, + ieee80211_media_status); } if (ifp->if_flags & IFF_UP) { @@ -24336,6 +24338,13 @@ qwx_scan(struct qwx_softc *sc) #ifdef notyet spin_unlock_bh(&ar->data_lock); #endif + } else { + /* + * The current mode might have been fixed during association. + * Ensure all channels get scanned. + */ + if (IFM_SUBTYPE(ic->ic_media.ifm_cur->ifm_media) == IFM_AUTO) + ieee80211_setmode(ic, IEEE80211_MODE_AUTO); } #if 0 timeout_add_msec(&sc->scan.timeout, scan_timeout); diff --git a/sys/dev/pci/if_ix.c b/sys/dev/pci/if_ix.c index a705d9f1e..4f79dc58a 100644 --- a/sys/dev/pci/if_ix.c +++ b/sys/dev/pci/if_ix.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_ix.c,v 1.211 2024/03/07 17:09:02 jan Exp $ */ +/* $OpenBSD: if_ix.c,v 1.212 2024/05/01 10:43:42 jan Exp $ */ /****************************************************************************** @@ -154,7 +154,7 @@ void ixgbe_enable_intr(struct ix_softc *); void ixgbe_disable_intr(struct ix_softc *); int ixgbe_txeof(struct tx_ring *); int ixgbe_rxeof(struct rx_ring *); -void ixgbe_rx_checksum(uint32_t, struct mbuf *); +void ixgbe_rx_offload(uint32_t, uint16_t, struct mbuf *); void ixgbe_iff(struct ix_softc *); void ixgbe_map_queue_statistics(struct ix_softc *); void ixgbe_update_link_status(struct ix_softc *); @@ -3245,67 +3245,13 @@ ixgbe_rxeof(struct rx_ring *rxr) sendmp = NULL; mp->m_next = nxbuf->buf; } else { /* Sending this frame? */ - uint16_t pkts; + ixgbe_rx_offload(staterr, vtag, sendmp); - ixgbe_rx_checksum(staterr, sendmp); -#if NVLAN > 0 - if (staterr & IXGBE_RXD_STAT_VP) { - sendmp->m_pkthdr.ether_vtag = vtag; - SET(sendmp->m_flags, M_VLANTAG); - } -#endif if (hashtype != IXGBE_RXDADV_RSSTYPE_NONE) { sendmp->m_pkthdr.ph_flowid = hash; SET(sendmp->m_pkthdr.csum_flags, M_FLOWID); } - pkts = sendmp->m_pkthdr.ph_mss; - sendmp->m_pkthdr.ph_mss = 0; - - if (pkts > 1) { - struct ether_extracted ext; - uint32_t paylen; - - /* - * Calculate the payload size: - * - * The packet length returned by the NIC - * (sendmp->m_pkthdr.len) can contain - * padding, which we don't want to count - * in to the payload size. Therefore, we - * calculate the real payload size based - * on the total ip length field (ext.iplen). - */ - ether_extract_headers(sendmp, &ext); - paylen = ext.iplen; - if (ext.ip4 || ext.ip6) - paylen -= ext.iphlen; - if (ext.tcp) { - paylen -= ext.tcphlen; - tcpstat_inc(tcps_inhwlro); - tcpstat_add(tcps_inpktlro, pkts); - } else { - tcpstat_inc(tcps_inbadlro); - } - - /* - * If we gonna forward this packet, we have to - * mark it as TSO, set a correct mss, - * and recalculate the TCP checksum. - */ - if (ext.tcp && paylen >= pkts) { - SET(sendmp->m_pkthdr.csum_flags, - M_TCP_TSO); - sendmp->m_pkthdr.ph_mss = paylen / pkts; - } - if (ext.tcp && - ISSET(sendmp->m_pkthdr.csum_flags, - M_TCP_CSUM_IN_OK)) { - SET(sendmp->m_pkthdr.csum_flags, - M_TCP_CSUM_OUT); - } - } - ml_enqueue(&ml, sendmp); } next_desc: @@ -3330,29 +3276,103 @@ next_desc: } /********************************************************************* + * + * Check VLAN indication from hardware and inform the stack about the + * annotated TAG. * * Verify that the hardware indicated that the checksum is valid. * Inform the stack about the status of checksum so that stack * doesn't spend time verifying the checksum. * + * Propagate TCP LRO packet from hardware to the stack with MSS annotation. + * *********************************************************************/ void -ixgbe_rx_checksum(uint32_t staterr, struct mbuf * mp) +ixgbe_rx_offload(uint32_t staterr, uint16_t vtag, struct mbuf *m) { uint16_t status = (uint16_t) staterr; uint8_t errors = (uint8_t) (staterr >> 24); + int16_t pkts; - if (status & IXGBE_RXD_STAT_IPCS) { - if (!(errors & IXGBE_RXD_ERR_IPE)) { - /* IP Checksum Good */ - mp->m_pkthdr.csum_flags = M_IPV4_CSUM_IN_OK; - } else - mp->m_pkthdr.csum_flags = 0; + /* + * VLAN Offload + */ + +#if NVLAN > 0 + if (ISSET(staterr, IXGBE_RXD_STAT_VP)) { + m->m_pkthdr.ether_vtag = vtag; + SET(m->m_flags, M_VLANTAG); } - if (status & IXGBE_RXD_STAT_L4CS) { - if (!(errors & IXGBE_RXD_ERR_TCPE)) - mp->m_pkthdr.csum_flags |= - M_TCP_CSUM_IN_OK | M_UDP_CSUM_IN_OK; +#endif + + /* + * Checksum Offload + */ + + if (ISSET(status, IXGBE_RXD_STAT_IPCS)) { + if (ISSET(errors, IXGBE_RXD_ERR_IPE)) + SET(m->m_pkthdr.csum_flags, M_IPV4_CSUM_IN_BAD); + else + SET(m->m_pkthdr.csum_flags, M_IPV4_CSUM_IN_OK); + } + if (ISSET(status, IXGBE_RXD_STAT_L4CS) && + !ISSET(status, IXGBE_RXD_STAT_UDPCS)) { + if (ISSET(errors, IXGBE_RXD_ERR_TCPE)) { + /* on some hardware IPv6 + TCP + Bad is broken */ + if (ISSET(status, IXGBE_RXD_STAT_IPCS)) + SET(m->m_pkthdr.csum_flags, M_TCP_CSUM_IN_BAD); + } else + SET(m->m_pkthdr.csum_flags, M_TCP_CSUM_IN_OK); + } + if (ISSET(status, IXGBE_RXD_STAT_L4CS) && + ISSET(status, IXGBE_RXD_STAT_UDPCS)) { + if (ISSET(errors, IXGBE_RXD_ERR_TCPE)) + SET(m->m_pkthdr.csum_flags, M_UDP_CSUM_IN_BAD); + else + SET(m->m_pkthdr.csum_flags, M_UDP_CSUM_IN_OK); + } + + /* + * TCP Large Receive Offload + */ + + pkts = m->m_pkthdr.ph_mss; + m->m_pkthdr.ph_mss = 0; + + if (pkts > 1) { + struct ether_extracted ext; + uint32_t paylen; + + /* + * Calculate the payload size: + * + * The packet length returned by the NIC (m->m_pkthdr.len) + * can contain padding, which we don't want to count in to the + * payload size. Therefore, we calculate the real payload size + * based on the total ip length field (ext.iplen). + */ + ether_extract_headers(m, &ext); + paylen = ext.iplen; + if (ext.ip4 || ext.ip6) + paylen -= ext.iphlen; + if (ext.tcp) { + paylen -= ext.tcphlen; + tcpstat_inc(tcps_inhwlro); + tcpstat_add(tcps_inpktlro, pkts); + } else { + tcpstat_inc(tcps_inbadlro); + } + + /* + * If we gonna forward this packet, we have to mark it as TSO, + * set a correct mss, and recalculate the TCP checksum. + */ + if (ext.tcp && paylen >= pkts) { + SET(m->m_pkthdr.csum_flags, M_TCP_TSO); + m->m_pkthdr.ph_mss = paylen / pkts; + } + if (ext.tcp && ISSET(m->m_pkthdr.csum_flags, M_TCP_CSUM_IN_OK)) + SET(m->m_pkthdr.csum_flags, M_TCP_CSUM_OUT); } } diff --git a/sys/kern/subr_hibernate.c b/sys/kern/subr_hibernate.c index ec42fe290..2fe5eb2cb 100644 --- a/sys/kern/subr_hibernate.c +++ b/sys/kern/subr_hibernate.c @@ -1,4 +1,4 @@ -/* $OpenBSD: subr_hibernate.c,v 1.138 2022/09/03 18:17:15 mlarkin Exp $ */ +/* $OpenBSD: subr_hibernate.c,v 1.139 2024/04/30 17:12:19 krw Exp $ */ /* * Copyright (c) 2011 Ariane van der Steldt @@ -1134,7 +1134,7 @@ hibernate_resume(void) if (hibernate_block_io(&hib, hib.sig_offset, DEV_BSIZE, (vaddr_t)&disk_hib, 0)) { - DPRINTF("error in hibernate read"); + DPRINTF("error in hibernate read\n"); splx(s); return; } diff --git a/sys/kern/subr_witness.c b/sys/kern/subr_witness.c index 418821866..b8d208313 100644 --- a/sys/kern/subr_witness.c +++ b/sys/kern/subr_witness.c @@ -1,4 +1,4 @@ -/* $OpenBSD: subr_witness.c,v 1.50 2023/05/30 08:30:01 jsg Exp $ */ +/* $OpenBSD: subr_witness.c,v 1.52 2024/05/03 13:47:31 visa Exp $ */ /*- * Copyright (c) 2008 Isilon Systems, Inc. @@ -369,6 +369,13 @@ static struct witness_lock_order_data *witness_lock_order_get( struct witness *child); static void witness_list_lock(struct lock_instance *instance, int (*prnt)(const char *fmt, ...)); +static void witness_print_cycle(int (*prnt)(const char *fmt, ...), + struct witness *parent, struct witness *child); +static void witness_print_cycle_edge(int (*prnt)(const char *fmt, ...), + struct witness *parent, struct witness *child, + int step, int last); +static int witness_search(struct witness *w, struct witness *target, + struct witness **path, int depth, int *remaining); static void witness_setflag(struct lock_object *lock, int flag, int set); /* @@ -652,8 +659,9 @@ witness_ddb_display_descendants(int(*prnt)(const char *fmt, ...), for (i = 0; i < indent; i++) prnt(" "); - prnt("%s (type: %s, depth: %d)", - w->w_type->lt_name, w->w_class->lc_name, w->w_ddb_level); + prnt("%s (%s) (type: %s, depth: %d)", + w->w_subtype, w->w_type->lt_name, + w->w_class->lc_name, w->w_ddb_level); if (w->w_displayed) { prnt(" -- (already displayed)\n"); return; @@ -719,7 +727,8 @@ witness_ddb_display(int(*prnt)(const char *fmt, ...)) SLIST_FOREACH(w, &w_all, w_list) { if (w->w_acquired) continue; - prnt("%s (type: %s, depth: %d)\n", w->w_type->lt_name, + prnt("%s (%s) (type: %s, depth: %d)\n", + w->w_subtype, w->w_type->lt_name, w->w_class->lc_name, w->w_ddb_level); } } @@ -1066,47 +1075,8 @@ witness_checkorder(struct lock_object *lock, int flags, printf(" 3rd %p %s (%s)\n", lock, lock->lo_name, w->w_type->lt_name); } - if (witness_watch > 1) { - struct witness_lock_order_data *wlod1, *wlod2; - - mtx_enter(&w_mtx); - wlod1 = witness_lock_order_get(w, w1); - wlod2 = witness_lock_order_get(w1, w); - mtx_leave(&w_mtx); - - /* - * It is safe to access saved stack traces, - * w_type, and w_class without the lock. - * Once written, they never change. - */ - - if (wlod1 != NULL) { - printf("lock order \"%s\"(%s) -> " - "\"%s\"(%s) first seen at:\n", - w->w_type->lt_name, - w->w_class->lc_name, - w1->w_type->lt_name, - w1->w_class->lc_name); - stacktrace_print( - &wlod1->wlod_stack, printf); - } else { - printf("lock order data " - "w2 -> w1 missing\n"); - } - if (wlod2 != NULL) { - printf("lock order \"%s\"(%s) -> " - "\"%s\"(%s) first seen at:\n", - w1->w_type->lt_name, - w1->w_class->lc_name, - w->w_type->lt_name, - w->w_class->lc_name); - stacktrace_print( - &wlod2->wlod_stack, printf); - } else { - printf("lock order data " - "w1 -> w2 missing\n"); - } - } + if (witness_watch > 1) + witness_print_cycle(printf, w1, w); witness_debugger(0); goto out_splx; } @@ -1875,6 +1845,92 @@ witness_list_lock(struct lock_instance *instance, stacktrace_print(&instance->li_stack->ls_stack, prnt); } +static int +witness_search(struct witness *w, struct witness *target, + struct witness **path, int depth, int *remaining) +{ + int i, any_remaining; + + if (depth == 0) { + *remaining = 1; + return (w == target); + } + + any_remaining = 0; + for (i = 1; i <= w_max_used_index; i++) { + if (w_rmatrix[w->w_index][i] & WITNESS_PARENT) { + if (witness_search(&w_data[i], target, path, depth - 1, + remaining)) { + path[depth - 1] = &w_data[i]; + *remaining = 1; + return 1; + } + if (remaining) + any_remaining = 1; + } + } + *remaining = any_remaining; + return 0; +} + +static void +witness_print_cycle_edge(int(*prnt)(const char *fmt, ...), + struct witness *parent, struct witness *child, int step, int last) +{ + struct witness_lock_order_data *wlod; + int next; + + if (last) + next = 1; + else + next = step + 1; + prnt("lock order [%d] %s (%s) -> [%d] %s (%s)\n", + step, parent->w_subtype, parent->w_type->lt_name, + next, child->w_subtype, child->w_type->lt_name); + if (witness_watch > 1) { + mtx_enter(&w_mtx); + wlod = witness_lock_order_get(parent, child); + mtx_leave(&w_mtx); + + if (wlod != NULL) + stacktrace_print(&wlod->wlod_stack, printf); + else + prnt("lock order data %p -> %p is missing\n", + parent->w_type->lt_name, child->w_type->lt_name); + } +} + +static void +witness_print_cycle(int(*prnt)(const char *fmt, ...), + struct witness *parent, struct witness *child) +{ + struct witness *path[4]; + struct witness *w; + int depth, remaining; + int step = 0; + + /* + * Use depth-limited search to find the shortest path + * from child to parent. + */ + for (depth = 1; depth < nitems(path); depth++) { + if (witness_search(child, parent, path, depth, &remaining)) + goto found; + if (!remaining) + break; + } + prnt("witness: incomplete path, depth %d\n", depth); + return; + +found: + witness_print_cycle_edge(prnt, parent, child, ++step, 0); + for (w = child; depth > 0; depth--) { + witness_print_cycle_edge(prnt, w, path[depth - 1], ++step, + depth == 1); + w = path[depth - 1]; + } +} + #ifdef DDB static int witness_thread_has_locks(struct proc *p) @@ -2123,9 +2179,6 @@ db_witness_list_all(db_expr_t addr, int have_addr, db_expr_t count, char *modif) void witness_print_badstacks(void) { - static struct witness tmp_w1, tmp_w2; - static struct witness_lock_order_data tmp_data1, tmp_data2; - struct witness_lock_order_data *data1, *data2; struct witness *w1, *w2; int error, generation, i, j; @@ -2139,11 +2192,6 @@ witness_print_badstacks(void) } error = 0; - memset(&tmp_w1, 0, sizeof(tmp_w1)); - memset(&tmp_w2, 0, sizeof(tmp_w2)); - memset(&tmp_data1, 0, sizeof(tmp_data1)); - memset(&tmp_data2, 0, sizeof(tmp_data2)); - restart: mtx_enter(&w_mtx); generation = w_generation; @@ -2165,12 +2213,9 @@ restart: mtx_leave(&w_mtx); continue; } - - /* Copy w1 locally so we can release the spin lock. */ - tmp_w1 = *w1; mtx_leave(&w_mtx); - if (tmp_w1.w_reversed == 0) + if (w1->w_reversed == 0) continue; for (j = 1; j < w_max_used_index; j++) { if ((w_rmatrix[i][j] & WITNESS_REVERSAL) == 0 || i > j) @@ -2187,47 +2232,13 @@ restart: } w2 = &w_data[j]; - data1 = witness_lock_order_get(w1, w2); - data2 = witness_lock_order_get(w2, w1); - - /* - * Copy information locally so we can release the - * spin lock. - */ - tmp_w2 = *w2; - - if (data1) - tmp_data1.wlod_stack = data1->wlod_stack; - if (data2 && data2 != data1) - tmp_data2.wlod_stack = data2->wlod_stack; mtx_leave(&w_mtx); db_printf("\nLock order reversal between \"%s\"(%s) " "and \"%s\"(%s)!\n", - tmp_w1.w_type->lt_name, tmp_w1.w_class->lc_name, - tmp_w2.w_type->lt_name, tmp_w2.w_class->lc_name); - if (data1) { - db_printf("Lock order \"%s\"(%s) -> \"%s\"(%s) " - "first seen at:\n", - tmp_w1.w_type->lt_name, - tmp_w1.w_class->lc_name, - tmp_w2.w_type->lt_name, - tmp_w2.w_class->lc_name); - stacktrace_print(&tmp_data1.wlod_stack, - db_printf); - db_printf("\n"); - } - if (data2 && data2 != data1) { - db_printf("Lock order \"%s\"(%s) -> \"%s\"(%s) " - "first seen at:\n", - tmp_w2.w_type->lt_name, - tmp_w2.w_class->lc_name, - tmp_w1.w_type->lt_name, - tmp_w1.w_class->lc_name); - stacktrace_print(&tmp_data2.wlod_stack, - db_printf); - db_printf("\n"); - } + w1->w_type->lt_name, w1->w_class->lc_name, + w2->w_type->lt_name, w2->w_class->lc_name); + witness_print_cycle(db_printf, w1, w2); } } mtx_enter(&w_mtx); diff --git a/sys/kern/sys_socket.c b/sys/kern/sys_socket.c index 748be5a65..e0a34c6fe 100644 --- a/sys/kern/sys_socket.c +++ b/sys/kern/sys_socket.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sys_socket.c,v 1.64 2024/04/11 08:33:37 mvs Exp $ */ +/* $OpenBSD: sys_socket.c,v 1.65 2024/04/30 17:59:15 mvs Exp $ */ /* $NetBSD: sys_socket.c,v 1.13 1995/08/12 23:59:09 mycroft Exp $ */ /* @@ -92,6 +92,7 @@ soo_ioctl(struct file *fp, u_long cmd, caddr_t data, struct proc *p) case FIOASYNC: solock(so); mtx_enter(&so->so_rcv.sb_mtx); + mtx_enter(&so->so_snd.sb_mtx); if (*(int *)data) { so->so_rcv.sb_flags |= SB_ASYNC; so->so_snd.sb_flags |= SB_ASYNC; @@ -99,6 +100,7 @@ soo_ioctl(struct file *fp, u_long cmd, caddr_t data, struct proc *p) so->so_rcv.sb_flags &= ~SB_ASYNC; so->so_snd.sb_flags &= ~SB_ASYNC; } + mtx_leave(&so->so_snd.sb_mtx); mtx_leave(&so->so_rcv.sb_mtx); sounlock(so); break; diff --git a/sys/kern/uipc_socket.c b/sys/kern/uipc_socket.c index 6b539e480..65ae64517 100644 --- a/sys/kern/uipc_socket.c +++ b/sys/kern/uipc_socket.c @@ -1,4 +1,4 @@ -/* $OpenBSD: uipc_socket.c,v 1.330 2024/04/15 21:31:29 mvs Exp $ */ +/* $OpenBSD: uipc_socket.c,v 1.332 2024/05/02 11:55:31 mvs Exp $ */ /* $NetBSD: uipc_socket.c,v 1.21 1996/02/04 02:17:52 christos Exp $ */ /* @@ -146,8 +146,8 @@ soalloc(const struct protosw *prp, int wait) refcnt_init(&so->so_refcnt); rw_init(&so->so_rcv.sb_lock, "sbufrcv"); rw_init(&so->so_snd.sb_lock, "sbufsnd"); - mtx_init(&so->so_rcv.sb_mtx, IPL_MPFLOOR); - mtx_init(&so->so_snd.sb_mtx, IPL_MPFLOOR); + mtx_init_flags(&so->so_rcv.sb_mtx, IPL_MPFLOOR, "sbrcv", 0); + mtx_init_flags(&so->so_snd.sb_mtx, IPL_MPFLOOR, "sbsnd", 0); klist_init_mutex(&so->so_rcv.sb_klist, &so->so_rcv.sb_mtx); klist_init_mutex(&so->so_snd.sb_klist, &so->so_snd.sb_mtx); sigio_init(&so->so_sigio); @@ -158,8 +158,10 @@ soalloc(const struct protosw *prp, int wait) case AF_INET: case AF_INET6: switch (prp->pr_type) { - case SOCK_DGRAM: case SOCK_RAW: + so->so_snd.sb_flags |= SB_MTXLOCK | SB_OWNLOCK; + /* FALLTHROUGH */ + case SOCK_DGRAM: so->so_rcv.sb_flags |= SB_MTXLOCK | SB_OWNLOCK; break; } @@ -346,7 +348,10 @@ sofree(struct socket *so, int keep_lock) sounsplice(so, so->so_sp->ssp_socket, freeing); } #endif /* SOCKET_SPLICE */ + + mtx_enter(&so->so_snd.sb_mtx); sbrelease(so, &so->so_snd); + mtx_leave(&so->so_snd.sb_mtx); /* * Regardless on '_locked' postfix, must release solock() before @@ -569,6 +574,7 @@ sosend(struct socket *so, struct mbuf *addr, struct uio *uio, struct mbuf *top, size_t resid; int error; int atomic = sosendallatonce(so) || top; + int dosolock = ((so->so_snd.sb_flags & SB_OWNLOCK) == 0); if (uio) resid = uio->uio_resid; @@ -601,16 +607,17 @@ sosend(struct socket *so, struct mbuf *addr, struct uio *uio, struct mbuf *top, #define snderr(errno) { error = errno; goto release; } - solock_shared(so); + if (dosolock) + solock_shared(so); restart: if ((error = sblock(so, &so->so_snd, SBLOCKWAIT(flags))) != 0) goto out; + sb_mtx_lock(&so->so_snd); so->so_snd.sb_state |= SS_ISSENDING; do { if (so->so_snd.sb_state & SS_CANTSENDMORE) snderr(EPIPE); - if (so->so_error) { - error = so->so_error; + if ((error = READ_ONCE(so->so_error))) { so->so_error = 0; snderr(error); } @@ -638,8 +645,14 @@ restart: if (flags & MSG_DONTWAIT) snderr(EWOULDBLOCK); sbunlock(so, &so->so_snd); - error = sbwait(so, &so->so_snd); + + if (so->so_snd.sb_flags & SB_MTXLOCK) + error = sbwait_locked(so, &so->so_snd); + else + error = sbwait(so, &so->so_snd); + so->so_snd.sb_state &= ~SS_ISSENDING; + sb_mtx_unlock(&so->so_snd); if (error) goto out; goto restart; @@ -654,9 +667,13 @@ restart: if (flags & MSG_EOR) top->m_flags |= M_EOR; } else { - sounlock_shared(so); + sb_mtx_unlock(&so->so_snd); + if (dosolock) + sounlock_shared(so); error = m_getuio(&top, atomic, space, uio); - solock_shared(so); + if (dosolock) + solock_shared(so); + sb_mtx_lock(&so->so_snd); if (error) goto release; space -= top->m_pkthdr.len; @@ -668,10 +685,16 @@ restart: so->so_snd.sb_state &= ~SS_ISSENDING; if (top && so->so_options & SO_ZEROIZE) top->m_flags |= M_ZEROIZE; + sb_mtx_unlock(&so->so_snd); + if (!dosolock) + solock_shared(so); if (flags & MSG_OOB) error = pru_sendoob(so, top, addr, control); else error = pru_send(so, top, addr, control); + if (!dosolock) + sounlock_shared(so); + sb_mtx_lock(&so->so_snd); clen = 0; control = NULL; top = NULL; @@ -682,9 +705,11 @@ restart: release: so->so_snd.sb_state &= ~SS_ISSENDING; + sb_mtx_unlock(&so->so_snd); sbunlock(so, &so->so_snd); out: - sounlock_shared(so); + if (dosolock) + sounlock_shared(so); m_freem(top); m_freem(control); return (error); @@ -1401,7 +1426,7 @@ sosplice(struct socket *so, int fd, off_t max, struct timeval *tv) if (sosp->so_sp == NULL) sosp->so_sp = pool_get(&sosplice_pool, PR_WAITOK | PR_ZERO); - if ((error = sblock(so, &sosp->so_snd, SBL_WAIT)) != 0) { + if ((error = sblock(sosp, &sosp->so_snd, SBL_WAIT)) != 0) { goto out; } diff --git a/sys/kern/uipc_socket2.c b/sys/kern/uipc_socket2.c index 7fe3df6b1..f454f21bf 100644 --- a/sys/kern/uipc_socket2.c +++ b/sys/kern/uipc_socket2.c @@ -1,4 +1,4 @@ -/* $OpenBSD: uipc_socket2.c,v 1.150 2024/04/25 17:32:53 bluhm Exp $ */ +/* $OpenBSD: uipc_socket2.c,v 1.152 2024/05/02 21:26:52 mvs Exp $ */ /* $NetBSD: uipc_socket2.c,v 1.11 1996/02/04 02:17:55 christos Exp $ */ /* @@ -142,10 +142,15 @@ soisdisconnecting(struct socket *so) soassertlocked(so); so->so_state &= ~SS_ISCONNECTING; so->so_state |= SS_ISDISCONNECTING; + mtx_enter(&so->so_rcv.sb_mtx); so->so_rcv.sb_state |= SS_CANTRCVMORE; mtx_leave(&so->so_rcv.sb_mtx); + + mtx_enter(&so->so_snd.sb_mtx); so->so_snd.sb_state |= SS_CANTSENDMORE; + mtx_leave(&so->so_snd.sb_mtx); + wakeup(&so->so_timeo); sowwakeup(so); sorwakeup(so); @@ -157,10 +162,15 @@ soisdisconnected(struct socket *so) soassertlocked(so); so->so_state &= ~(SS_ISCONNECTING|SS_ISCONNECTED|SS_ISDISCONNECTING); so->so_state |= SS_ISDISCONNECTED; + mtx_enter(&so->so_rcv.sb_mtx); so->so_rcv.sb_state |= SS_CANTRCVMORE; mtx_leave(&so->so_rcv.sb_mtx); + + mtx_enter(&so->so_snd.sb_mtx); so->so_snd.sb_state |= SS_CANTSENDMORE; + mtx_leave(&so->so_snd.sb_mtx); + wakeup(&so->so_timeo); sowwakeup(so); sorwakeup(so); @@ -315,14 +325,16 @@ void socantsendmore(struct socket *so) { soassertlocked(so); + mtx_enter(&so->so_snd.sb_mtx); so->so_snd.sb_state |= SS_CANTSENDMORE; + mtx_leave(&so->so_snd.sb_mtx); sowwakeup(so); } void socantrcvmore(struct socket *so) { - if ((so->so_rcv.sb_flags & SB_OWNLOCK) == 0) + if ((so->so_rcv.sb_flags & SB_MTXLOCK) == 0) soassertlocked(so); mtx_enter(&so->so_rcv.sb_mtx); @@ -666,6 +678,8 @@ soreserve(struct socket *so, u_long sndcc, u_long rcvcc) { soassertlocked(so); + mtx_enter(&so->so_rcv.sb_mtx); + mtx_enter(&so->so_snd.sb_mtx); if (sbreserve(so, &so->so_snd, sndcc)) goto bad; so->so_snd.sb_wat = sndcc; @@ -673,21 +687,20 @@ soreserve(struct socket *so, u_long sndcc, u_long rcvcc) so->so_snd.sb_lowat = MCLBYTES; if (so->so_snd.sb_lowat > so->so_snd.sb_hiwat) so->so_snd.sb_lowat = so->so_snd.sb_hiwat; - - mtx_enter(&so->so_rcv.sb_mtx); - if (sbreserve(so, &so->so_rcv, rcvcc)) { - mtx_leave(&so->so_rcv.sb_mtx); + if (sbreserve(so, &so->so_rcv, rcvcc)) goto bad2; - } so->so_rcv.sb_wat = rcvcc; if (so->so_rcv.sb_lowat == 0) so->so_rcv.sb_lowat = 1; + mtx_leave(&so->so_snd.sb_mtx); mtx_leave(&so->so_rcv.sb_mtx); return (0); bad2: sbrelease(so, &so->so_snd); bad: + mtx_leave(&so->so_snd.sb_mtx); + mtx_leave(&so->so_rcv.sb_mtx); return (ENOBUFS); } diff --git a/sys/kern/uipc_usrreq.c b/sys/kern/uipc_usrreq.c index c55ff320d..12fc60c5e 100644 --- a/sys/kern/uipc_usrreq.c +++ b/sys/kern/uipc_usrreq.c @@ -1,4 +1,4 @@ -/* $OpenBSD: uipc_usrreq.c,v 1.204 2024/04/10 12:04:41 mvs Exp $ */ +/* $OpenBSD: uipc_usrreq.c,v 1.205 2024/05/02 17:10:55 mvs Exp $ */ /* $NetBSD: uipc_usrreq.c,v 1.18 1996/02/09 19:00:50 christos Exp $ */ /* @@ -459,9 +459,9 @@ uipc_shutdown(struct socket *so) socantsendmore(so); - if ((so2 = unp_solock_peer(unp->unp_socket))){ + if (unp->unp_conn != NULL) { + so2 = unp->unp_conn->unp_socket; socantrcvmore(so2); - sounlock(so2); } return (0); diff --git a/sys/nfs/krpc_subr.c b/sys/nfs/krpc_subr.c index 13a1c967b..06d5a99f4 100644 --- a/sys/nfs/krpc_subr.c +++ b/sys/nfs/krpc_subr.c @@ -1,4 +1,4 @@ -/* $OpenBSD: krpc_subr.c,v 1.38 2023/08/03 09:49:09 mvs Exp $ */ +/* $OpenBSD: krpc_subr.c,v 1.39 2024/05/01 13:15:59 jsg Exp $ */ /* $NetBSD: krpc_subr.c,v 1.12.4.1 1996/06/07 00:52:26 cgd Exp $ */ /* @@ -45,12 +45,8 @@ #include #include -#include -#include #include -#include #include -#include #include #include diff --git a/sys/nfs/nfs_bio.c b/sys/nfs/nfs_bio.c index 158210fb7..d26b2cd3c 100644 --- a/sys/nfs/nfs_bio.c +++ b/sys/nfs/nfs_bio.c @@ -1,4 +1,4 @@ -/* $OpenBSD: nfs_bio.c,v 1.84 2019/07/25 01:43:21 cheloha Exp $ */ +/* $OpenBSD: nfs_bio.c,v 1.86 2024/05/01 13:15:59 jsg Exp $ */ /* $NetBSD: nfs_bio.c,v 1.25.4.2 1996/07/08 20:47:04 jtc Exp $ */ /* @@ -37,14 +37,11 @@ #include #include -#include #include #include #include #include #include -#include -#include #include #include @@ -331,7 +328,7 @@ again: np->n_flag |= NMODIFIED; if (uio->uio_offset + n > np->n_size) { np->n_size = uio->uio_offset + n; - uvm_vnp_setsize(vp, (u_long)np->n_size); + uvm_vnp_setsize(vp, np->n_size); extended = 1; } else if (uio->uio_offset + n < np->n_size) truncated = 1; diff --git a/sys/nfs/nfs_boot.c b/sys/nfs/nfs_boot.c index 6cb57e61c..02f0b8d8b 100644 --- a/sys/nfs/nfs_boot.c +++ b/sys/nfs/nfs_boot.c @@ -1,4 +1,4 @@ -/* $OpenBSD: nfs_boot.c,v 1.48 2022/03/05 09:50:49 jsg Exp $ */ +/* $OpenBSD: nfs_boot.c,v 1.49 2024/05/01 13:15:59 jsg Exp $ */ /* $NetBSD: nfs_boot.c,v 1.26 1996/05/07 02:51:25 thorpej Exp $ */ /* @@ -31,11 +31,9 @@ #include #include #include -#include #include #include #include -#include #include #include #include diff --git a/sys/nfs/nfs_debug.c b/sys/nfs/nfs_debug.c index 74d36722c..0e73ebf7d 100644 --- a/sys/nfs/nfs_debug.c +++ b/sys/nfs/nfs_debug.c @@ -1,4 +1,4 @@ -/* $OpenBSD: nfs_debug.c,v 1.6 2014/09/14 14:17:26 jsg Exp $ */ +/* $OpenBSD: nfs_debug.c,v 1.7 2024/05/01 13:15:59 jsg Exp $ */ /* * Copyright (c) 2009 Thordur I. Bjornsson. * @@ -16,18 +16,13 @@ */ #include #include -#include #include -#include #include #include -#include #include #include #include -#include -#include #include #include diff --git a/sys/nfs/nfs_kq.c b/sys/nfs/nfs_kq.c index 7e5d3c743..41bf8b89a 100644 --- a/sys/nfs/nfs_kq.c +++ b/sys/nfs/nfs_kq.c @@ -1,4 +1,4 @@ -/* $OpenBSD: nfs_kq.c,v 1.36 2023/09/08 20:00:28 mvs Exp $ */ +/* $OpenBSD: nfs_kq.c,v 1.37 2024/05/01 13:15:59 jsg Exp $ */ /* $NetBSD: nfs_kq.c,v 1.7 2003/10/30 01:43:10 simonb Exp $ */ /*- @@ -32,18 +32,15 @@ #include #include -#include #include #include #include #include -#include #include #include #include #include -#include #include #include #include diff --git a/sys/nfs/nfs_node.c b/sys/nfs/nfs_node.c index c8ac3b9bb..26a910eb6 100644 --- a/sys/nfs/nfs_node.c +++ b/sys/nfs/nfs_node.c @@ -1,4 +1,4 @@ -/* $OpenBSD: nfs_node.c,v 1.75 2022/06/27 13:39:58 visa Exp $ */ +/* $OpenBSD: nfs_node.c,v 1.76 2024/05/01 13:15:59 jsg Exp $ */ /* $NetBSD: nfs_node.c,v 1.16 1996/02/18 11:53:42 fvdl Exp $ */ /* @@ -43,13 +43,10 @@ #include #include #include -#include #include #include #include -#include -#include #include #include #include diff --git a/sys/nfs/nfs_serv.c b/sys/nfs/nfs_serv.c index 7b28664c2..b03d4a5f4 100644 --- a/sys/nfs/nfs_serv.c +++ b/sys/nfs/nfs_serv.c @@ -1,4 +1,4 @@ -/* $OpenBSD: nfs_serv.c,v 1.123 2024/03/25 17:57:07 guenther Exp $ */ +/* $OpenBSD: nfs_serv.c,v 1.126 2024/05/01 13:15:59 jsg Exp $ */ /* $NetBSD: nfs_serv.c,v 1.34 1997/05/12 23:37:12 fvdl Exp $ */ /* @@ -43,16 +43,15 @@ * (surprisingly ?? many are very similar to syscalls in vfs_syscalls.c) * 3 - build the rpc reply in an mbuf list * nb: - * - do not mix the phases, since the nfsm_?? macros can return failures - * on a bad rpc or similar and do not do any vrele() or vput()'s - * - * - the nfsm_reply() macro generates an nfs rpc reply with the nfs - * error number iff error != 0 whereas - * returning an error from the server function implies a fatal error - * such as a badly constructed rpc request that should be dropped without - * a reply. - * For Version 3, nfsm_reply() does not return for the error case, since - * most version 3 rpcs return more than the status for error cases. + * - do not mix the phases, since use of the nfsm_?? functions can cause + * us to return failures on a bad rpc or similar without doing any + * vrele() or vput()'s + * - the nfsm_reply() function generates an nfs rpc reply with the nfs + * error number iff error != 0 whereas returning an error from the + * server function implies a fatal error such as a badly constructed rpc + * request that should be dropped without a reply. + * For Version 3, we do not return after nfsm_reply() for the error case, + * since most version 3 rpcs return more than the status for error cases. */ #include @@ -67,9 +66,7 @@ #include #include #include -#include #include -#include #include #include @@ -77,19 +74,67 @@ #include #include #include -#include #include +#include /* Global vars */ extern u_int32_t nfs_xdrneg1; extern u_int32_t nfs_false, nfs_true; -extern enum vtype nv3tov_type[8]; +extern const enum vtype nv3tov_type[8]; extern struct nfsstats nfsstats; -extern nfstype nfsv2_type[9]; -extern nfstype nfsv3_type[9]; int nfsrv_access(struct vnode *, int, struct ucred *, int, struct proc *, int); +static inline int +nfsm_reply(struct nfsm_info *infop, struct nfsrv_descript *nfsd, + struct nfssvc_sock *slp, struct mbuf **mrq, int error, int statuslen) +{ + nfsd->nd_repstat = error; + if (error && !infop->nmi_v3) + statuslen = 0; + (void)nfs_rephead(statuslen, nfsd, slp, error, + &infop->nmi_mreq, &infop->nmi_mb); + if (infop->nmi_mrep != NULL) { + m_freem(infop->nmi_mrep); + infop->nmi_mrep = NULL; + } + *mrq = infop->nmi_mreq; + if (error && (!infop->nmi_v3 || error == EBADRPC)) + return error; + return 0; +} + +static inline int +nfsm_srvmtofh1(struct nfsm_info *infop, struct nfsrv_descript *nfsd, + struct nfssvc_sock *slp, struct mbuf **mrq) +{ + if (infop->nmi_v3) { + uint32_t *tl = (uint32_t *)nfsm_dissect(infop, NFSX_UNSIGNED); + if (tl == NULL) + return 0; /* *infop->nmi_errorp set */ + if (fxdr_unsigned(int, *tl) != NFSX_V3FH) { + *infop->nmi_errorp = EBADRPC; + return nfsm_reply(infop, nfsd, slp, mrq, + *infop->nmi_errorp, 0); + } + } + return 0; +} + +static inline int +nfsm_srvmtofh2(struct nfsm_info *infop, fhandle_t *fhp) +{ + uint32_t *tl = (uint32_t *)nfsm_dissect(infop, NFSX_V3FH); + if (tl == NULL) + return 1; + bcopy(tl, fhp, NFSX_V3FH); + if (infop->nmi_v3 == 0) { + if (nfsm_adv(infop, NFSX_V2FH - NFSX_V3FH) != 0) + return 1; + } + return 0; +} + /* * nfs v3 access service */ @@ -104,9 +149,7 @@ nfsrv3_access(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, nfsfh_t nfh; fhandle_t *fhp; u_int32_t *tl; - int32_t t1; int error = 0, rdonly, getret; - char *cp2; struct vattr va; u_long testmode, nfsmode; @@ -114,13 +157,24 @@ nfsrv3_access(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, info.nmi_mrep = nfsd->nd_mrep; info.nmi_md = nfsd->nd_md; info.nmi_dpos = nfsd->nd_dpos; + info.nmi_v3 = (nfsd->nd_flag & ND_NFSV3); + info.nmi_errorp = &error; + if (nfsm_srvmtofh1(&info, nfsd, slp, mrq) != 0) + return 0; + else if (error != 0) + goto nfsmout; fhp = &nfh.fh_generic; - nfsm_srvmtofh(fhp); - nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED); + if (nfsm_srvmtofh2(&info, fhp) != 0) + goto nfsmout; + tl = (uint32_t *)nfsm_dissect(&info, NFSX_UNSIGNED); + if (tl == NULL) + goto nfsmout; error = nfsrv_fhtovp(fhp, 1, &vp, cred, slp, nam, &rdonly); if (error) { - nfsm_reply(NFSX_UNSIGNED); + if (nfsm_reply(&info, nfsd, slp, mrq, error, + NFSX_UNSIGNED) != 0) + return 0; nfsm_srvpostop_attr(nfsd, 1, NULL, &info); error = 0; goto nfsmout; @@ -146,7 +200,9 @@ nfsrv3_access(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, nfsmode &= ~testmode; getret = VOP_GETATTR(vp, &va, cred, procp); vput(vp); - nfsm_reply(NFSX_POSTOPATTR(1) + NFSX_UNSIGNED); + if (nfsm_reply(&info, nfsd, slp, mrq, error, + NFSX_POSTOPATTR(1) + NFSX_UNSIGNED) != 0) + return 0; nfsm_srvpostop_attr(nfsd, getret, &va, &info); tl = nfsm_build(&info.nmi_mb, NFSX_UNSIGNED); *tl = txdr_unsigned(nfsmode); @@ -169,28 +225,34 @@ nfsrv_getattr(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, struct vnode *vp; nfsfh_t nfh; fhandle_t *fhp; - u_int32_t *tl; - int32_t t1; int error = 0, rdonly; - char *cp2; info.nmi_mreq = NULL; info.nmi_mrep = nfsd->nd_mrep; info.nmi_md = nfsd->nd_md; info.nmi_dpos = nfsd->nd_dpos; info.nmi_v3 = (nfsd->nd_flag & ND_NFSV3); + info.nmi_errorp = &error; + if (nfsm_srvmtofh1(&info, nfsd, slp, mrq) != 0) + return 0; + else if (error != 0) + goto nfsmout; fhp = &nfh.fh_generic; - nfsm_srvmtofh(fhp); + if (nfsm_srvmtofh2(&info, fhp) != 0) + goto nfsmout; error = nfsrv_fhtovp(fhp, 1, &vp, cred, slp, nam, &rdonly); if (error) { - nfsm_reply(0); + if (nfsm_reply(&info, nfsd, slp, mrq, error, 0) != 0) + return 0; error = 0; goto nfsmout; } error = VOP_GETATTR(vp, &va, cred, procp); vput(vp); - nfsm_reply(NFSX_FATTR(nfsd->nd_flag & ND_NFSV3)); + if (nfsm_reply(&info, nfsd, slp, mrq, error, + NFSX_FATTR(nfsd->nd_flag & ND_NFSV3)) != 0) + return 0; if (error) { error = 0; goto nfsmout; @@ -218,10 +280,8 @@ nfsrv_setattr(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, nfsfh_t nfh; fhandle_t *fhp; u_int32_t *tl; - int32_t t1; int error = 0, rdonly, preat_ret = 1, postat_ret = 1; int gcheck = 0; - char *cp2; struct timespec guard; info.nmi_mreq = NULL; @@ -229,23 +289,35 @@ nfsrv_setattr(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, info.nmi_md = nfsd->nd_md; info.nmi_dpos = nfsd->nd_dpos; info.nmi_v3 = (nfsd->nd_flag & ND_NFSV3); + info.nmi_errorp = &error; + if (nfsm_srvmtofh1(&info, nfsd, slp, mrq) != 0) + return 0; + else if (error != 0) + goto nfsmout; fhp = &nfh.fh_generic; - nfsm_srvmtofh(fhp); + if (nfsm_srvmtofh2(&info, fhp) != 0) + goto nfsmout; VATTR_NULL(&va); if (info.nmi_v3) { va.va_vaflags |= VA_UTIMES_NULL; error = nfsm_srvsattr(&info.nmi_md, &va, info.nmi_mrep, &info.nmi_dpos); if (error) goto nfsmout; - nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED); + tl = (uint32_t *)nfsm_dissect(&info, NFSX_UNSIGNED); + if (tl == NULL) + goto nfsmout; gcheck = fxdr_unsigned(int, *tl); if (gcheck) { - nfsm_dissect(tl, u_int32_t *, 2 * NFSX_UNSIGNED); + tl = (uint32_t *)nfsm_dissect(&info, 2 * NFSX_UNSIGNED); + if (tl == NULL) + goto nfsmout; fxdr_nfsv3time(tl, &guard); } } else { - nfsm_dissect(sp, struct nfsv2_sattr *, NFSX_V2SATTR); + sp = (struct nfsv2_sattr *)nfsm_dissect(&info, NFSX_V2SATTR); + if (sp == NULL) + goto nfsmout; /* * Nah nah nah nah na nah * There is a bug in the Sun client that puts 0xffff in the mode @@ -280,7 +352,9 @@ nfsrv_setattr(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, */ error = nfsrv_fhtovp(fhp, 1, &vp, cred, slp, nam, &rdonly); if (error) { - nfsm_reply(2 * NFSX_UNSIGNED); + if (nfsm_reply(&info, nfsd, slp, mrq, error, + 2 * NFSX_UNSIGNED) != 0) + return 0; nfsm_srvwcc(nfsd, preat_ret, &preat, postat_ret, &va, &info); error = 0; goto nfsmout; @@ -293,7 +367,9 @@ nfsrv_setattr(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, error = NFSERR_NOT_SYNC; if (error) { vput(vp); - nfsm_reply(NFSX_WCCDATA(info.nmi_v3)); + if (nfsm_reply(&info, nfsd, slp, mrq, error, + NFSX_WCCDATA(info.nmi_v3)) != 0) + return 0; nfsm_srvwcc(nfsd, preat_ret, &preat, postat_ret, &va, &info); error = 0; @@ -324,7 +400,9 @@ nfsrv_setattr(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, error = postat_ret; out: vput(vp); - nfsm_reply(NFSX_WCCORFATTR(info.nmi_v3)); + if (nfsm_reply(&info, nfsd, slp, mrq, error, + NFSX_WCCORFATTR(info.nmi_v3)) != 0) + return 0; if (info.nmi_v3) { nfsm_srvwcc(nfsd, preat_ret, &preat, postat_ret, &va, &info); @@ -338,6 +416,25 @@ nfsmout: return(error); } +static inline int +nfsm_srvnamesiz(struct nfsm_info *infop, int *lenp) +{ + int len; + uint32_t *tl = (uint32_t *)nfsm_dissect(infop, NFSX_UNSIGNED); + if (tl == NULL) + return 1; + len = fxdr_unsigned(int32_t, *tl); + if (len > NFS_MAXNAMLEN) + *infop->nmi_errorp = NFSERR_NAMETOL; + else if (len <= 0) + *infop->nmi_errorp = EBADRPC; + else { + *infop->nmi_errorp = 0; + *lenp = len; + } + return 0; +} + /* * nfs lookup rpc */ @@ -353,11 +450,8 @@ nfsrv_lookup(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, struct nfsm_info info; nfsfh_t nfh; fhandle_t *fhp; - u_int32_t *tl; - int32_t t1; int error = 0, len, dirattr_ret = 1; int v3 = (nfsd->nd_flag & ND_NFSV3); - char *cp2; struct vattr va, dirattr; info.nmi_mrep = nfsd->nd_mrep; @@ -365,10 +459,21 @@ nfsrv_lookup(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, info.nmi_md = nfsd->nd_md; info.nmi_dpos = nfsd->nd_dpos; info.nmi_v3 = (nfsd->nd_flag & ND_NFSV3); + info.nmi_errorp = &error; + if (nfsm_srvmtofh1(&info, nfsd, slp, mrq) != 0) + return 0; + else if (error != 0) + goto nfsmout; fhp = &nfh.fh_generic; - nfsm_srvmtofh(fhp); - nfsm_srvnamesiz(len); + if (nfsm_srvmtofh2(&info, fhp) != 0) + goto nfsmout; + if (nfsm_srvnamesiz(&info, &len) != 0) + goto nfsmout; + if (error) { + if (nfsm_reply(&info, nfsd, slp, mrq, error, 0) != 0) + return 0; + } NDINIT(&nd, LOOKUP, LOCKLEAF | SAVESTART, UIO_SYSSPACE, NULL, procp); nd.ni_cnd.cn_cred = cred; @@ -380,7 +485,9 @@ nfsrv_lookup(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, vrele(dirp); } if (error) { - nfsm_reply(NFSX_POSTOPATTR(info.nmi_v3)); + if (nfsm_reply(&info, nfsd, slp, mrq, error, + NFSX_POSTOPATTR(info.nmi_v3)) != 0) + return 0; nfsm_srvpostop_attr(nfsd, dirattr_ret, &dirattr, &info); return (0); } @@ -393,8 +500,10 @@ nfsrv_lookup(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, if (!error) error = VOP_GETATTR(vp, &va, cred, procp); vput(vp); - nfsm_reply(NFSX_SRVFH(info.nmi_v3) + NFSX_POSTOPORFATTR(info.nmi_v3) - + NFSX_POSTOPATTR(info.nmi_v3)); + if (nfsm_reply(&info, nfsd, slp, mrq, error, + NFSX_SRVFH(info.nmi_v3) + NFSX_POSTOPORFATTR(info.nmi_v3) + + NFSX_POSTOPATTR(info.nmi_v3)) != 0) + return 0; if (error) { nfsm_srvpostop_attr(nfsd, dirattr_ret, &dirattr, &info); error = 0; @@ -425,9 +534,7 @@ nfsrv_readlink(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, struct mbuf *mp = NULL; struct nfsm_info info; u_int32_t *tl; - int32_t t1; int error = 0, rdonly, tlen, len = 0, getret; - char *cp2; struct vnode *vp; struct vattr attr; nfsfh_t nfh; @@ -439,14 +546,22 @@ nfsrv_readlink(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, info.nmi_md = nfsd->nd_md; info.nmi_dpos = nfsd->nd_dpos; info.nmi_v3 = (nfsd->nd_flag & ND_NFSV3); + info.nmi_errorp = &error; memset(&uio, 0, sizeof(uio)); + if (nfsm_srvmtofh1(&info, nfsd, slp, mrq) != 0) + return 0; + else if (error != 0) + goto nfsmout; fhp = &nfh.fh_generic; - nfsm_srvmtofh(fhp); + if (nfsm_srvmtofh2(&info, fhp) != 0) + goto nfsmout; error = nfsrv_fhtovp(fhp, 1, &vp, cred, slp, nam, &rdonly); if (error) { - nfsm_reply(2 * NFSX_UNSIGNED); + if (nfsm_reply(&info, nfsd, slp, mrq, error, + 2 * NFSX_UNSIGNED) != 0) + return 0; nfsm_srvpostop_attr(nfsd, 1, NULL, &info); error = 0; goto nfsmout; @@ -480,7 +595,9 @@ out: vput(vp); if (error) m_freem(mp); - nfsm_reply(NFSX_POSTOPATTR(info.nmi_v3) + NFSX_UNSIGNED); + if (nfsm_reply(&info, nfsd, slp, mrq, error, + NFSX_POSTOPATTR(info.nmi_v3) + NFSX_UNSIGNED) != 0) + return 0; if (info.nmi_v3) { nfsm_srvpostop_attr(nfsd, getret, &attr, &info); if (error) { @@ -514,10 +631,8 @@ nfsrv_read(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, struct nfs_fattr *fp; struct nfsm_info info; u_int32_t *tl; - int32_t t1; int i, reqlen; int error = 0, rdonly, cnt, len, left, siz, tlen, getret = 1; - char *cp2; struct mbuf *m2; struct vnode *vp; nfsfh_t nfh; @@ -531,22 +646,35 @@ nfsrv_read(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, info.nmi_md = nfsd->nd_md; info.nmi_dpos = nfsd->nd_dpos; info.nmi_v3 = (nfsd->nd_flag & ND_NFSV3); + info.nmi_errorp = &error; + if (nfsm_srvmtofh1(&info, nfsd, slp, mrq) != 0) + return 0; + else if (error != 0) + goto nfsmout; fhp = &nfh.fh_generic; - nfsm_srvmtofh(fhp); + if (nfsm_srvmtofh2(&info, fhp) != 0) + goto nfsmout; if (info.nmi_v3) { - nfsm_dissect(tl, u_int32_t *, 2 * NFSX_UNSIGNED); + tl = (uint32_t *)nfsm_dissect(&info, 2 * NFSX_UNSIGNED); + if (tl == NULL) + goto nfsmout; off = fxdr_hyper(tl); } else { - nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED); + tl = (uint32_t *)nfsm_dissect(&info, NFSX_UNSIGNED); + if (tl == NULL) + goto nfsmout; off = (off_t)fxdr_unsigned(u_int32_t, *tl); } - nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED); + tl = (uint32_t *)nfsm_dissect(&info, NFSX_UNSIGNED); + if (tl == NULL) + goto nfsmout; reqlen = fxdr_unsigned(int32_t, *tl); if (reqlen > (NFS_SRVMAXDATA(nfsd)) || reqlen <= 0) { error = EBADRPC; - nfsm_reply(0); + if (nfsm_reply(&info, nfsd, slp, mrq, error, 0) != 0) + return 0; } error = nfsrv_fhtovp(fhp, 1, &vp, cred, slp, nam, &rdonly); @@ -575,7 +703,10 @@ nfsrv_read(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, cnt = va.va_size - off; else cnt = reqlen; - nfsm_reply(NFSX_POSTOPORFATTR(info.nmi_v3) + 3 * NFSX_UNSIGNED+nfsm_rndup(cnt)); + if (nfsm_reply(&info, nfsd, slp, mrq, error, + NFSX_POSTOPORFATTR(info.nmi_v3) + + 3 * NFSX_UNSIGNED+nfsm_rndup(cnt)) != 0) + return 0; if (info.nmi_v3) { tl = nfsm_build(&info.nmi_mb, NFSX_V3FATTR + 4 * NFSX_UNSIGNED); *tl++ = nfs_true; @@ -667,7 +798,8 @@ nfsmout: vbad: vput(vp); bad: - nfsm_reply(0); + if (nfsm_reply(&info, nfsd, slp, mrq, error, 0) != 0) + return 0; nfsm_srvpostop_attr(nfsd, getret, &va, &info); return (0); } @@ -688,11 +820,9 @@ nfsrv_write(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, struct timeval boottime; struct vattr va, forat; u_int32_t *tl; - int32_t t1; int error = 0, rdonly, len, forat_ret = 1; int ioflags, aftat_ret = 1, retlen, zeroing, adjust; int stable = NFSV3WRITE_FILESYNC; - char *cp2; struct vnode *vp; nfsfh_t nfh; fhandle_t *fhp; @@ -704,20 +834,30 @@ nfsrv_write(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, info.nmi_md = nfsd->nd_md; info.nmi_dpos = nfsd->nd_dpos; info.nmi_v3 = (nfsd->nd_flag & ND_NFSV3); + info.nmi_errorp = &error; if (info.nmi_mrep == NULL) { *mrq = NULL; return (0); } + if (nfsm_srvmtofh1(&info, nfsd, slp, mrq) != 0) + return 0; + else if (error != 0) + goto nfsmout; fhp = &nfh.fh_generic; - nfsm_srvmtofh(fhp); + if (nfsm_srvmtofh2(&info, fhp) != 0) + goto nfsmout; if (info.nmi_v3) { - nfsm_dissect(tl, u_int32_t *, 5 * NFSX_UNSIGNED); + tl = (uint32_t *)nfsm_dissect(&info, 5 * NFSX_UNSIGNED); + if (tl == NULL) + goto nfsmout; off = fxdr_hyper(tl); tl += 3; stable = fxdr_unsigned(int, *tl++); } else { - nfsm_dissect(tl, u_int32_t *, 4 * NFSX_UNSIGNED); + tl = (uint32_t *)nfsm_dissect(&info, 4 * NFSX_UNSIGNED); + if (tl == NULL) + goto nfsmout; off = (off_t)fxdr_unsigned(u_int32_t, *++tl); tl += 2; } @@ -811,8 +951,10 @@ nfsrv_write(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, vput(vp); if (!error) error = aftat_ret; - nfsm_reply(NFSX_PREOPATTR(info.nmi_v3) + NFSX_POSTOPORFATTR(info.nmi_v3) + - 2 * NFSX_UNSIGNED + NFSX_WRITEVERF(info.nmi_v3)); + if (nfsm_reply(&info, nfsd, slp, mrq, error, + NFSX_PREOPATTR(info.nmi_v3) + NFSX_POSTOPORFATTR(info.nmi_v3) + + 2 * NFSX_UNSIGNED + NFSX_WRITEVERF(info.nmi_v3)) != 0) + return 0; if (info.nmi_v3) { nfsm_srvwcc(nfsd, forat_ret, &forat, aftat_ret, &va, &info); if (error) { @@ -843,11 +985,23 @@ nfsmout: vbad: vput(vp); bad: - nfsm_reply(0); + if (nfsm_reply(&info, nfsd, slp, mrq, error, 0) != 0) + return 0; nfsm_srvwcc(nfsd, forat_ret, &forat, aftat_ret, &va, &info); return (0); } +static inline void +nfsm_srvpostop_fh(struct nfsm_info *infop, fhandle_t *fhp) +{ + uint32_t *tl; + + tl = nfsm_build(&infop->nmi_mb, 2 * NFSX_UNSIGNED + NFSX_V3FH); + *tl++ = nfs_true; + *tl++ = txdr_unsigned(NFSX_V3FH); + bcopy(fhp, tl, NFSX_V3FH); +} + /* * nfs create service * now does a truncate to 0 length via. setattr if it already exists @@ -865,11 +1019,9 @@ nfsrv_create(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, u_int32_t *tl; struct nameidata nd; caddr_t cp; - int32_t t1; int error = 0, len, tsize, dirfor_ret = 1, diraft_ret = 1; dev_t rdev = 0; int how, exclusive_flag = 0; - char *cp2; struct vnode *vp = NULL, *dirp = NULL; nfsfh_t nfh; fhandle_t *fhp; @@ -881,10 +1033,21 @@ nfsrv_create(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, info.nmi_md = nfsd->nd_md; info.nmi_dpos = nfsd->nd_dpos; info.nmi_v3 = (nfsd->nd_flag & ND_NFSV3); + info.nmi_errorp = &error; + if (nfsm_srvmtofh1(&info, nfsd, slp, mrq) != 0) + return 0; + else if (error != 0) + goto nfsmout; fhp = &nfh.fh_generic; - nfsm_srvmtofh(fhp); - nfsm_srvnamesiz(len); + if (nfsm_srvmtofh2(&info, fhp) != 0) + goto nfsmout; + if (nfsm_srvnamesiz(&info, &len) != 0) + goto nfsmout; + if (error) { + if (nfsm_reply(&info, nfsd, slp, mrq, error, 0) != 0) + return 0; + } NDINIT(&nd, CREATE, LOCKPARENT | LOCKLEAF | SAVESTART, UIO_SYSSPACE, NULL, procp); @@ -900,7 +1063,9 @@ nfsrv_create(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, } } if (error) { - nfsm_reply(NFSX_WCCDATA(info.nmi_v3)); + if (nfsm_reply(&info, nfsd, slp, mrq, error, + NFSX_WCCDATA(info.nmi_v3)) != 0) + return 0; nfsm_srvwcc(nfsd, dirfor_ret, &dirfor, diraft_ret, &diraft, &info); if (dirp) @@ -910,7 +1075,9 @@ nfsrv_create(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, VATTR_NULL(&va); if (info.nmi_v3) { - nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED); + tl = (uint32_t *)nfsm_dissect(&info, NFSX_UNSIGNED); + if (tl == NULL) + goto nfsmout; how = fxdr_unsigned(int, *tl); switch (how) { case NFSV3CREATE_GUARDED: @@ -925,7 +1092,9 @@ nfsrv_create(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, goto nfsmout; break; case NFSV3CREATE_EXCLUSIVE: - nfsm_dissect(cp, caddr_t, NFSX_V3CREATEVERF); + cp = (caddr_t)nfsm_dissect(&info, NFSX_V3CREATEVERF); + if (cp == NULL) + goto nfsmout; bcopy(cp, cverf, NFSX_V3CREATEVERF); exclusive_flag = 1; if (nd.ni_vp == NULL) @@ -934,7 +1103,9 @@ nfsrv_create(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, }; va.va_type = VREG; } else { - nfsm_dissect(sp, struct nfsv2_sattr *, NFSX_V2SATTR); + sp = (struct nfsv2_sattr *)nfsm_dissect(&info, NFSX_V2SATTR); + if (sp == NULL) + goto nfsmout; va.va_type = IFTOVT(fxdr_unsigned(u_int32_t, sp->sa_mode)); if (va.va_type == VNON) va.va_type = VREG; @@ -990,7 +1161,9 @@ nfsrv_create(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, } VOP_ABORTOP(nd.ni_dvp, &nd.ni_cnd); vput(nd.ni_dvp); - nfsm_reply(0); + if (nfsm_reply(&info, nfsd, slp, mrq, error, + 0) != 0) + return 0; error = 0; goto nfsmout; } else @@ -1004,7 +1177,9 @@ nfsrv_create(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, pool_put(&namei_pool, nd.ni_cnd.cn_pnbuf); nd.ni_cnd.cn_flags &= ~HASBUF; } - nfsm_reply(0); + if (nfsm_reply(&info, nfsd, slp, mrq, error, + 0) != 0) + return 0; error = 0; goto nfsmout; } @@ -1017,7 +1192,9 @@ nfsrv_create(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, pool_put(&namei_pool, nd.ni_cnd.cn_pnbuf); nd.ni_cnd.cn_flags &= ~HASBUF; } - nfsm_reply(0); + if (nfsm_reply(&info, nfsd, slp, mrq, error, + 0) != 0) + return 0; error = 0; goto nfsmout; } @@ -1028,7 +1205,9 @@ nfsrv_create(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, vput(nd.ni_vp); VOP_ABORTOP(nd.ni_dvp, &nd.ni_cnd); error = EINVAL; - nfsm_reply(0); + if (nfsm_reply(&info, nfsd, slp, mrq, error, + 0) != 0) + return 0; error = 0; goto nfsmout; } @@ -1080,11 +1259,12 @@ nfsrv_create(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, diraft_ret = VOP_GETATTR(dirp, &diraft, cred, procp); vrele(dirp); } - nfsm_reply(NFSX_SRVFH(info.nmi_v3) + NFSX_FATTR(info.nmi_v3) - + NFSX_WCCDATA(info.nmi_v3)); + if (nfsm_reply(&info, nfsd, slp, mrq, error, NFSX_SRVFH(info.nmi_v3) + + NFSX_FATTR(info.nmi_v3) + NFSX_WCCDATA(info.nmi_v3)) != 0) + return 0; if (info.nmi_v3) { if (!error) { - nfsm_srvpostop_fh(fhp); + nfsm_srvpostop_fh(&info, fhp); nfsm_srvpostop_attr(nfsd, 0, &va, &info); } nfsm_srvwcc(nfsd, dirfor_ret, &dirfor, diraft_ret, &diraft, @@ -1128,11 +1308,9 @@ nfsrv_mknod(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, struct nfsm_info info; u_int32_t *tl; struct nameidata nd; - int32_t t1; int error = 0, len, dirfor_ret = 1, diraft_ret = 1; u_int32_t major, minor; enum vtype vtyp; - char *cp2; struct vnode *vp, *dirp = NULL; nfsfh_t nfh; fhandle_t *fhp; @@ -1142,10 +1320,21 @@ nfsrv_mknod(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, info.nmi_md = nfsd->nd_md; info.nmi_dpos = nfsd->nd_dpos; info.nmi_v3 = (nfsd->nd_flag & ND_NFSV3); + info.nmi_errorp = &error; + if (nfsm_srvmtofh1(&info, nfsd, slp, mrq) != 0) + return 0; + else if (error != 0) + goto nfsmout; fhp = &nfh.fh_generic; - nfsm_srvmtofh(fhp); - nfsm_srvnamesiz(len); + if (nfsm_srvmtofh2(&info, fhp) != 0) + goto nfsmout; + if (nfsm_srvnamesiz(&info, &len) != 0) + goto nfsmout; + if (error) { + if (nfsm_reply(&info, nfsd, slp, mrq, error, 0) != 0) + return 0; + } NDINIT(&nd, CREATE, LOCKPARENT | LOCKLEAF | SAVESTART, UIO_SYSSPACE, NULL, procp); @@ -1154,7 +1343,9 @@ nfsrv_mknod(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, if (dirp) dirfor_ret = VOP_GETATTR(dirp, &dirfor, cred, procp); if (error) { - nfsm_reply(NFSX_WCCDATA(1)); + if (nfsm_reply(&info, nfsd, slp, mrq, error, + NFSX_WCCDATA(1)) != 0) + return 0; nfsm_srvwcc(nfsd, dirfor_ret, &dirfor, diraft_ret, &diraft, &info); if (dirp) @@ -1162,7 +1353,9 @@ nfsrv_mknod(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, return (0); } - nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED); + tl = (uint32_t *)nfsm_dissect(&info, NFSX_UNSIGNED); + if (tl == NULL) + goto nfsmout; vtyp = nfsv3tov_type(*tl); if (vtyp != VCHR && vtyp != VBLK && vtyp != VSOCK && vtyp != VFIFO) { vrele(nd.ni_startdir); @@ -1182,7 +1375,9 @@ nfsrv_mknod(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, if (error) goto nfsmout; if (vtyp == VCHR || vtyp == VBLK) { - nfsm_dissect(tl, u_int32_t *, 2 * NFSX_UNSIGNED); + tl = (uint32_t *)nfsm_dissect(&info, 2 * NFSX_UNSIGNED); + if (tl == NULL) + goto nfsmout; major = fxdr_unsigned(u_int32_t, *tl++); minor = fxdr_unsigned(u_int32_t, *tl); va.va_rdev = makedev(major, minor); @@ -1252,9 +1447,11 @@ out: } diraft_ret = VOP_GETATTR(dirp, &diraft, cred, procp); vrele(dirp); - nfsm_reply(NFSX_SRVFH(1) + NFSX_POSTOPATTR(1) + NFSX_WCCDATA(1)); + if (nfsm_reply(&info, nfsd, slp, mrq, error, + NFSX_SRVFH(1) + NFSX_POSTOPATTR(1) + NFSX_WCCDATA(1)) != 0) + return 0; if (!error) { - nfsm_srvpostop_fh(fhp); + nfsm_srvpostop_fh(&info, fhp); nfsm_srvpostop_attr(nfsd, 0, &va, &info); } nfsm_srvwcc(nfsd, dirfor_ret, &dirfor, diraft_ret, &diraft, &info); @@ -1287,10 +1484,7 @@ nfsrv_remove(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, struct ucred *cred = &nfsd->nd_cr; struct nameidata nd; struct nfsm_info info; - u_int32_t *tl; - int32_t t1; int error = 0, len, dirfor_ret = 1, diraft_ret = 1; - char *cp2; struct vnode *vp, *dirp; struct vattr dirfor, diraft; nfsfh_t nfh; @@ -1301,12 +1495,23 @@ nfsrv_remove(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, info.nmi_md = nfsd->nd_md; info.nmi_dpos = nfsd->nd_dpos; info.nmi_v3 = (nfsd->nd_flag & ND_NFSV3); + info.nmi_errorp = &error; vp = NULL; + if (nfsm_srvmtofh1(&info, nfsd, slp, mrq) != 0) + return 0; + else if (error != 0) + goto nfsmout; fhp = &nfh.fh_generic; - nfsm_srvmtofh(fhp); - nfsm_srvnamesiz(len); + if (nfsm_srvmtofh2(&info, fhp) != 0) + goto nfsmout; + if (nfsm_srvnamesiz(&info, &len) != 0) + goto nfsmout; + if (error) { + if (nfsm_reply(&info, nfsd, slp, mrq, error, 0) != 0) + return 0; + } NDINIT(&nd, DELETE, LOCKPARENT | LOCKLEAF, UIO_SYSSPACE, NULL, procp); nd.ni_cnd.cn_cred = cred; @@ -1350,7 +1555,9 @@ out: diraft_ret = VOP_GETATTR(dirp, &diraft, cred, procp); vrele(dirp); } - nfsm_reply(NFSX_WCCDATA(info.nmi_v3)); + if (nfsm_reply(&info, nfsd, slp, mrq, error, + NFSX_WCCDATA(info.nmi_v3)) != 0) + return 0; if (info.nmi_v3) { nfsm_srvwcc(nfsd, dirfor_ret, &dirfor, diraft_ret, &diraft, &info); @@ -1371,11 +1578,8 @@ nfsrv_rename(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, struct mbuf *nam = nfsd->nd_nam; struct ucred *cred = &nfsd->nd_cr; struct nfsm_info info; - u_int32_t *tl; - int32_t t1; int error = 0, len, len2, fdirfor_ret = 1, fdiraft_ret = 1; int tdirfor_ret = 1, tdiraft_ret = 1; - char *cp2; struct nameidata fromnd, tond; struct vnode *fvp = NULL, *tvp, *tdvp, *fdirp = NULL; struct vnode *tdirp = NULL; @@ -1389,11 +1593,21 @@ nfsrv_rename(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, info.nmi_md = nfsd->nd_md; info.nmi_dpos = nfsd->nd_dpos; info.nmi_v3 = (nfsd->nd_flag & ND_NFSV3); + info.nmi_errorp = &error; + if (nfsm_srvmtofh1(&info, nfsd, slp, mrq) != 0) + return 0; + else if (error != 0) + goto nfsmout; ffhp = &fnfh.fh_generic; - tfhp = &tnfh.fh_generic; - nfsm_srvmtofh(ffhp); - nfsm_srvnamesiz(len); + if (nfsm_srvmtofh2(&info, ffhp) != 0) + goto nfsmout; + if (nfsm_srvnamesiz(&info, &len) != 0) + goto nfsmout; + if (error) { + if (nfsm_reply(&info, nfsd, slp, mrq, error, 0) != 0) + return 0; + } /* * Remember our original uid so that we can reset cr_uid before @@ -1416,7 +1630,9 @@ nfsrv_rename(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, } } if (error) { - nfsm_reply(2 * NFSX_WCCDATA(info.nmi_v3)); + if (nfsm_reply(&info, nfsd, slp, mrq, error, + 2 * NFSX_WCCDATA(info.nmi_v3)) != 0) + return 0; nfsm_srvwcc(nfsd, fdirfor_ret, &fdirfor, fdiraft_ret, &fdiraft, &info); nfsm_srvwcc(nfsd, tdirfor_ret, &tdirfor, tdiraft_ret, &tdiraft, @@ -1427,8 +1643,15 @@ nfsrv_rename(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, } fvp = fromnd.ni_vp; - nfsm_srvmtofh(tfhp); - nfsm_strsiz(len2, NFS_MAXNAMLEN); + if (nfsm_srvmtofh1(&info, nfsd, slp, mrq) != 0) + return 0; + else if (error != 0) + goto nfsmout; + tfhp = &tnfh.fh_generic; + if (nfsm_srvmtofh2(&info, tfhp) != 0) + goto nfsmout; + if (nfsm_strsiz(&info, &len2, NFS_MAXNAMLEN) != 0) + goto nfsmout; cred->cr_uid = saved_uid; NDINIT(&tond, RENAME, LOCKPARENT | LOCKLEAF| NOCACHE | SAVESTART, @@ -1520,7 +1743,9 @@ out1: } vrele(fromnd.ni_startdir); pool_put(&namei_pool, fromnd.ni_cnd.cn_pnbuf); - nfsm_reply(2 * NFSX_WCCDATA(info.nmi_v3)); + if (nfsm_reply(&info, nfsd, slp, mrq, error, + 2 * NFSX_WCCDATA(info.nmi_v3)) != 0) + return 0; if (info.nmi_v3) { nfsm_srvwcc(nfsd, fdirfor_ret, &fdirfor, fdiraft_ret, &fdiraft, &info); @@ -1566,11 +1791,8 @@ nfsrv_link(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, struct nfsm_info info; struct ucred *cred = &nfsd->nd_cr; struct nameidata nd; - u_int32_t *tl; - int32_t t1; int error = 0, rdonly, len, dirfor_ret = 1, diraft_ret = 1; int getret = 1; - char *cp2; struct vnode *vp, *xp, *dirp = NULL; struct vattr dirfor, diraft, at; nfsfh_t nfh, dnfh; @@ -1581,17 +1803,35 @@ nfsrv_link(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, info.nmi_md = nfsd->nd_md; info.nmi_dpos = nfsd->nd_dpos; info.nmi_v3 = (nfsd->nd_flag & ND_NFSV3); + info.nmi_errorp = &error; + if (nfsm_srvmtofh1(&info, nfsd, slp, mrq) != 0) + return 0; + else if (error != 0) + goto nfsmout; fhp = &nfh.fh_generic; + if (nfsm_srvmtofh2(&info, fhp) != 0) + goto nfsmout; + if (nfsm_srvmtofh1(&info, nfsd, slp, mrq) != 0) + return 0; + else if (error != 0) + goto nfsmout; dfhp = &dnfh.fh_generic; - nfsm_srvmtofh(fhp); - nfsm_srvmtofh(dfhp); - nfsm_srvnamesiz(len); + if (nfsm_srvmtofh2(&info, dfhp) != 0) + goto nfsmout; + if (nfsm_srvnamesiz(&info, &len) != 0) + goto nfsmout; + if (error) { + if (nfsm_reply(&info, nfsd, slp, mrq, error, 0) != 0) + return 0; + } error = nfsrv_fhtovp(fhp, 0, &vp, cred, slp, nam, &rdonly); if (error) { - nfsm_reply(NFSX_POSTOPATTR(info.nmi_v3) + - NFSX_WCCDATA(info.nmi_v3)); + if (nfsm_reply(&info, nfsd, slp, mrq, error, + NFSX_POSTOPATTR(info.nmi_v3) + + NFSX_WCCDATA(info.nmi_v3)) != 0) + return 0; nfsm_srvpostop_attr(nfsd, getret, &at, &info); nfsm_srvwcc(nfsd, dirfor_ret, &dirfor, diraft_ret, &diraft, &info); @@ -1644,7 +1884,9 @@ out1: vrele(dirp); } vrele(vp); - nfsm_reply(NFSX_POSTOPATTR(info.nmi_v3) + NFSX_WCCDATA(info.nmi_v3)); + if (nfsm_reply(&info, nfsd, slp, mrq, error, + NFSX_POSTOPATTR(info.nmi_v3) + NFSX_WCCDATA(info.nmi_v3)) != 0) + return 0; if (info.nmi_v3) { nfsm_srvpostop_attr(nfsd, getret, &at, &info); nfsm_srvwcc(nfsd, dirfor_ret, &dirfor, diraft_ret, &diraft, @@ -1667,10 +1909,8 @@ nfsrv_symlink(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, struct vattr va, dirfor, diraft; struct nameidata nd; struct nfsm_info info; - u_int32_t *tl; - int32_t t1; struct nfsv2_sattr *sp; - char *pathcp = NULL, *cp2; + char *pathcp = NULL; struct uio io; struct iovec iv; int error = 0, len, pathlen, len2, dirfor_ret = 1, diraft_ret = 1; @@ -1683,10 +1923,21 @@ nfsrv_symlink(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, info.nmi_md = nfsd->nd_md; info.nmi_dpos = nfsd->nd_dpos; info.nmi_v3 = (nfsd->nd_flag & ND_NFSV3); + info.nmi_errorp = &error; + if (nfsm_srvmtofh1(&info, nfsd, slp, mrq) != 0) + return 0; + else if (error != 0) + goto nfsmout; fhp = &nfh.fh_generic; - nfsm_srvmtofh(fhp); - nfsm_srvnamesiz(len); + if (nfsm_srvmtofh2(&info, fhp) != 0) + goto nfsmout; + if (nfsm_srvnamesiz(&info, &len) != 0) + goto nfsmout; + if (error) { + if (nfsm_reply(&info, nfsd, slp, mrq, error, 0) != 0) + return 0; + } NDINIT(&nd, CREATE, LOCKPARENT | SAVESTART, UIO_SYSSPACE, NULL, procp); nd.ni_cnd.cn_cred = cred; @@ -1710,7 +1961,8 @@ nfsrv_symlink(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, if (error) goto nfsmout; } - nfsm_strsiz(len2, NFS_MAXPATHLEN); + if (nfsm_strsiz(&info, &len2, NFS_MAXPATHLEN) != 0) + goto nfsmout; pathlen = len2 + 1; pathcp = malloc(pathlen, M_TEMP, M_WAITOK); iv.iov_base = pathcp; @@ -1722,9 +1974,12 @@ nfsrv_symlink(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, io.uio_segflg = UIO_SYSSPACE; io.uio_rw = UIO_READ; io.uio_procp = NULL; - nfsm_mtouio(&io, len2); + if (nfsm_mtouio(&info, &io, len2) != 0) + goto nfsmout; if (!info.nmi_v3) { - nfsm_dissect(sp, struct nfsv2_sattr *, NFSX_V2SATTR); + sp = (struct nfsv2_sattr *)nfsm_dissect(&info, NFSX_V2SATTR); + if (sp == NULL) + goto nfsmout; va.va_mode = nfstov_mode(sp->sa_mode); } *(pathcp + len2) = '\0'; @@ -1773,11 +2028,12 @@ out: diraft_ret = VOP_GETATTR(dirp, &diraft, cred, procp); vrele(dirp); } - nfsm_reply(NFSX_SRVFH(info.nmi_v3) + NFSX_POSTOPATTR(info.nmi_v3) - + NFSX_WCCDATA(info.nmi_v3)); + if (nfsm_reply(&info, nfsd, slp, mrq, error, NFSX_SRVFH(info.nmi_v3) + + NFSX_POSTOPATTR(info.nmi_v3) + NFSX_WCCDATA(info.nmi_v3)) != 0) + return 0; if (info.nmi_v3) { if (!error) { - nfsm_srvpostop_fh(fhp); + nfsm_srvpostop_fh(&info, fhp); nfsm_srvpostop_attr(nfsd, 0, &va, &info); } nfsm_srvwcc(nfsd, dirfor_ret, &dirfor, diraft_ret, &diraft, @@ -1817,9 +2073,7 @@ nfsrv_mkdir(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, struct nameidata nd; struct nfsm_info info; u_int32_t *tl; - int32_t t1; int error = 0, len, dirfor_ret = 1, diraft_ret = 1; - char *cp2; struct vnode *vp, *dirp = NULL; nfsfh_t nfh; fhandle_t *fhp; @@ -1829,10 +2083,21 @@ nfsrv_mkdir(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, info.nmi_md = nfsd->nd_md; info.nmi_dpos = nfsd->nd_dpos; info.nmi_v3 = (nfsd->nd_flag & ND_NFSV3); + info.nmi_errorp = &error; + if (nfsm_srvmtofh1(&info, nfsd, slp, mrq) != 0) + return 0; + else if (error != 0) + goto nfsmout; fhp = &nfh.fh_generic; - nfsm_srvmtofh(fhp); - nfsm_srvnamesiz(len); + if (nfsm_srvmtofh2(&info, fhp) != 0) + goto nfsmout; + if (nfsm_srvnamesiz(&info, &len) != 0) + goto nfsmout; + if (error) { + if (nfsm_reply(&info, nfsd, slp, mrq, error, 0) != 0) + return 0; + } NDINIT(&nd, CREATE, LOCKPARENT, UIO_SYSSPACE, NULL, procp); nd.ni_cnd.cn_cred = cred; @@ -1847,7 +2112,9 @@ nfsrv_mkdir(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, } } if (error) { - nfsm_reply(NFSX_WCCDATA(info.nmi_v3)); + if (nfsm_reply(&info, nfsd, slp, mrq, error, + NFSX_WCCDATA(info.nmi_v3)) != 0) + return 0; nfsm_srvwcc(nfsd, dirfor_ret, &dirfor, diraft_ret, &diraft, &info); if (dirp) @@ -1862,7 +2129,9 @@ nfsrv_mkdir(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, if (error) goto nfsmout; } else { - nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED); + tl = (uint32_t *)nfsm_dissect(&info, NFSX_UNSIGNED); + if (tl == NULL) + goto nfsmout; va.va_mode = nfstov_mode(*tl++); } va.va_type = VDIR; @@ -1892,11 +2161,12 @@ out: diraft_ret = VOP_GETATTR(dirp, &diraft, cred, procp); vrele(dirp); } - nfsm_reply(NFSX_SRVFH(info.nmi_v3) + NFSX_POSTOPATTR(info.nmi_v3) + - NFSX_WCCDATA(info.nmi_v3)); + if (nfsm_reply(&info, nfsd, slp, mrq, error, NFSX_SRVFH(info.nmi_v3) + + NFSX_POSTOPATTR(info.nmi_v3) + NFSX_WCCDATA(info.nmi_v3)) != 0) + return 0; if (info.nmi_v3) { if (!error) { - nfsm_srvpostop_fh(fhp); + nfsm_srvpostop_fh(&info, fhp); nfsm_srvpostop_attr(nfsd, 0, &va, &info); } nfsm_srvwcc(nfsd, dirfor_ret, &dirfor, diraft_ret, &diraft, @@ -1930,10 +2200,7 @@ nfsrv_rmdir(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, struct mbuf *nam = nfsd->nd_nam; struct ucred *cred = &nfsd->nd_cr; struct nfsm_info info; - u_int32_t *tl; - int32_t t1; int error = 0, len, dirfor_ret = 1, diraft_ret = 1; - char *cp2; struct vnode *vp, *dirp = NULL; struct vattr dirfor, diraft; nfsfh_t nfh; @@ -1945,10 +2212,21 @@ nfsrv_rmdir(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, info.nmi_md = nfsd->nd_md; info.nmi_dpos = nfsd->nd_dpos; info.nmi_v3 = (nfsd->nd_flag & ND_NFSV3); + info.nmi_errorp = &error; + if (nfsm_srvmtofh1(&info, nfsd, slp, mrq) != 0) + return 0; + else if (error != 0) + goto nfsmout; fhp = &nfh.fh_generic; - nfsm_srvmtofh(fhp); - nfsm_srvnamesiz(len); + if (nfsm_srvmtofh2(&info, fhp) != 0) + goto nfsmout; + if (nfsm_srvnamesiz(&info, &len) != 0) + goto nfsmout; + if (error) { + if (nfsm_reply(&info, nfsd, slp, mrq, error, 0) != 0) + return 0; + } NDINIT(&nd, DELETE, LOCKPARENT | LOCKLEAF, UIO_SYSSPACE, NULL, procp); nd.ni_cnd.cn_cred = cred; @@ -1964,7 +2242,9 @@ nfsrv_rmdir(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, } } if (error) { - nfsm_reply(NFSX_WCCDATA(info.nmi_v3)); + if (nfsm_reply(&info, nfsd, slp, mrq, error, + NFSX_WCCDATA(info.nmi_v3)) != 0) + return 0; nfsm_srvwcc(nfsd, dirfor_ret, &dirfor, diraft_ret, &diraft, &info); if (dirp) @@ -2010,7 +2290,9 @@ out: diraft_ret = VOP_GETATTR(dirp, &diraft, cred, procp); vrele(dirp); } - nfsm_reply(NFSX_WCCDATA(info.nmi_v3)); + if (nfsm_reply(&info, nfsd, slp, mrq, error, + NFSX_WCCDATA(info.nmi_v3)) != 0) + return 0; if (info.nmi_v3) { nfsm_srvwcc(nfsd, dirfor_ret, &dirfor, diraft_ret, &diraft, &info); @@ -2065,8 +2347,7 @@ nfsrv_readdir(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, struct dirent *dp; struct nfsm_info info; u_int32_t *tl; - int32_t t1; - char *cpos, *cend, *cp2, *rbuf; + char *cpos, *cend, *rbuf; struct vnode *vp; struct vattr at; nfsfh_t nfh; @@ -2082,17 +2363,27 @@ nfsrv_readdir(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, info.nmi_md = nfsd->nd_md; info.nmi_dpos = nfsd->nd_dpos; info.nmi_v3 = (nfsd->nd_flag & ND_NFSV3); + info.nmi_errorp = &error; + if (nfsm_srvmtofh1(&info, nfsd, slp, mrq) != 0) + return 0; + else if (error != 0) + goto nfsmout; fhp = &nfh.fh_generic; - nfsm_srvmtofh(fhp); + if (nfsm_srvmtofh2(&info, fhp) != 0) + goto nfsmout; if (info.nmi_v3) { - nfsm_dissect(tl, u_int32_t *, 5 * NFSX_UNSIGNED); + tl = (uint32_t *)nfsm_dissect(&info, 5 * NFSX_UNSIGNED); + if (tl == NULL) + goto nfsmout; toff = fxdr_hyper(tl); tl += 2; verf = fxdr_hyper(tl); tl += 2; } else { - nfsm_dissect(tl, u_int32_t *, 2 * NFSX_UNSIGNED); + tl = (uint32_t *)nfsm_dissect(&info, 2 * NFSX_UNSIGNED); + if (tl == NULL) + goto nfsmout; toff = fxdr_unsigned(u_quad_t, *tl++); } off = toff; @@ -2106,7 +2397,9 @@ nfsrv_readdir(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, fullsiz = siz; error = nfsrv_fhtovp(fhp, 1, &vp, cred, slp, nam, &rdonly); if (error) { - nfsm_reply(NFSX_UNSIGNED); + if (nfsm_reply(&info, nfsd, slp, mrq, error, + NFSX_UNSIGNED) != 0) + return 0; nfsm_srvpostop_attr(nfsd, getret, &at, &info); error = 0; goto nfsmout; @@ -2117,7 +2410,9 @@ nfsrv_readdir(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, error = nfsrv_access(vp, VEXEC, cred, rdonly, procp, 0); if (error) { vput(vp); - nfsm_reply(NFSX_POSTOPATTR(info.nmi_v3)); + if (nfsm_reply(&info, nfsd, slp, mrq, error, + NFSX_POSTOPATTR(info.nmi_v3)) != 0) + return 0; nfsm_srvpostop_attr(nfsd, getret, &at, &info); error = 0; goto nfsmout; @@ -2150,7 +2445,9 @@ again: if (error) { vrele(vp); free(rbuf, M_TEMP, fullsiz); - nfsm_reply(NFSX_POSTOPATTR(info.nmi_v3)); + if (nfsm_reply(&info, nfsd, slp, mrq, error, + NFSX_POSTOPATTR(info.nmi_v3)) != 0) + return 0; nfsm_srvpostop_attr(nfsd, getret, &at, &info); error = 0; goto nfsmout; @@ -2164,8 +2461,11 @@ again: */ if (siz == 0) { vrele(vp); - nfsm_reply(NFSX_POSTOPATTR(info.nmi_v3) + NFSX_COOKIEVERF(info.nmi_v3) + - 2 * NFSX_UNSIGNED); + if (nfsm_reply(&info, nfsd, slp, mrq, error, + NFSX_POSTOPATTR(info.nmi_v3) + + NFSX_COOKIEVERF(info.nmi_v3) + + 2 * NFSX_UNSIGNED) != 0) + return 0; if (info.nmi_v3) { nfsm_srvpostop_attr(nfsd, getret, &at, &info); tl = nfsm_build(&info.nmi_mb, 4 * NFSX_UNSIGNED); @@ -2200,7 +2500,10 @@ again: } len = 3 * NFSX_UNSIGNED; /* paranoia, probably can be 0 */ - nfsm_reply(NFSX_POSTOPATTR(info.nmi_v3) + NFSX_COOKIEVERF(info.nmi_v3) + siz); + if (nfsm_reply(&info, nfsd, slp, mrq, error, + NFSX_POSTOPATTR(info.nmi_v3) + + NFSX_COOKIEVERF(info.nmi_v3) + siz) != 0) + return 0; if (info.nmi_v3) { nfsm_srvpostop_attr(nfsd, getret, &at, &info); tl = nfsm_build(&info.nmi_mb, 2 * NFSX_UNSIGNED); @@ -2267,8 +2570,7 @@ nfsrv_readdirplus(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, struct dirent *dp; struct nfsm_info info; u_int32_t *tl; - int32_t t1; - char *cpos, *cend, *cp2, *rbuf; + char *cpos, *cend, *rbuf; struct vnode *vp, *nvp; struct flrep fl; nfsfh_t nfh; @@ -2286,10 +2588,18 @@ nfsrv_readdirplus(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, info.nmi_md = nfsd->nd_md; info.nmi_dpos = nfsd->nd_dpos; info.nmi_v3 = (nfsd->nd_flag & ND_NFSV3); + info.nmi_errorp = &error; + if (nfsm_srvmtofh1(&info, nfsd, slp, mrq) != 0) + return 0; + else if (error != 0) + goto nfsmout; fhp = &nfh.fh_generic; - nfsm_srvmtofh(fhp); - nfsm_dissect(tl, u_int32_t *, 6 * NFSX_UNSIGNED); + if (nfsm_srvmtofh2(&info, fhp) != 0) + goto nfsmout; + tl = (uint32_t *)nfsm_dissect(&info, 6 * NFSX_UNSIGNED); + if (tl == NULL) + goto nfsmout; off = toff = fxdr_hyper(tl); tl += 2; verf = fxdr_hyper(tl); @@ -2305,7 +2615,9 @@ nfsrv_readdirplus(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, fullsiz = siz; error = nfsrv_fhtovp(fhp, 1, &vp, cred, slp, nam, &rdonly); if (error) { - nfsm_reply(NFSX_UNSIGNED); + if (nfsm_reply(&info, nfsd, slp, mrq, error, + NFSX_UNSIGNED) != 0) + return 0; nfsm_srvpostop_attr(nfsd, getret, &at, &info); error = 0; goto nfsmout; @@ -2315,7 +2627,9 @@ nfsrv_readdirplus(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, error = nfsrv_access(vp, VEXEC, cred, rdonly, procp, 0); if (error) { vput(vp); - nfsm_reply(NFSX_V3POSTOPATTR); + if (nfsm_reply(&info, nfsd, slp, mrq, error, + NFSX_V3POSTOPATTR) != 0) + return 0; nfsm_srvpostop_attr(nfsd, getret, &at, &info); error = 0; goto nfsmout; @@ -2348,7 +2662,9 @@ again: if (error) { vrele(vp); free(rbuf, M_TEMP, fullsiz); - nfsm_reply(NFSX_V3POSTOPATTR); + if (nfsm_reply(&info, nfsd, slp, mrq, error, + NFSX_V3POSTOPATTR) != 0) + return 0; nfsm_srvpostop_attr(nfsd, getret, &at, &info); error = 0; goto nfsmout; @@ -2362,8 +2678,10 @@ again: */ if (siz == 0) { vrele(vp); - nfsm_reply(NFSX_V3POSTOPATTR + NFSX_V3COOKIEVERF + - 2 * NFSX_UNSIGNED); + if (nfsm_reply(&info, nfsd, slp, mrq, error, + NFSX_V3POSTOPATTR + NFSX_V3COOKIEVERF + + 2 * NFSX_UNSIGNED) != 0) + return 0; nfsm_srvpostop_attr(nfsd, getret, &at, &info); tl = nfsm_build(&info.nmi_mb, 4 * NFSX_UNSIGNED); txdr_hyper(at.va_filerev, tl); @@ -2407,7 +2725,8 @@ again: * } */ dirlen = len = NFSX_V3POSTOPATTR + NFSX_V3COOKIEVERF + 2 * NFSX_UNSIGNED; - nfsm_reply(cnt); + if (nfsm_reply(&info, nfsd, slp, mrq, error, cnt) != 0) + return 0; nfsm_srvpostop_attr(nfsd, getret, &at, &info); tl = nfsm_build(&info.nmi_mb, 2 * NFSX_UNSIGNED); txdr_hyper(at.va_filerev, tl); @@ -2515,9 +2834,7 @@ nfsrv_commit(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, nfsfh_t nfh; fhandle_t *fhp; u_int32_t *tl; - int32_t t1; int error = 0, rdonly, for_ret = 1, aft_ret = 1, cnt; - char *cp2; u_quad_t off; info.nmi_mreq = NULL; @@ -2525,10 +2842,18 @@ nfsrv_commit(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, info.nmi_md = nfsd->nd_md; info.nmi_dpos = nfsd->nd_dpos; info.nmi_v3 = (nfsd->nd_flag & ND_NFSV3); + info.nmi_errorp = &error; + if (nfsm_srvmtofh1(&info, nfsd, slp, mrq) != 0) + return 0; + else if (error != 0) + goto nfsmout; fhp = &nfh.fh_generic; - nfsm_srvmtofh(fhp); - nfsm_dissect(tl, u_int32_t *, 3 * NFSX_UNSIGNED); + if (nfsm_srvmtofh2(&info, fhp) != 0) + goto nfsmout; + tl = (uint32_t *)nfsm_dissect(&info, 3 * NFSX_UNSIGNED); + if (tl == NULL) + goto nfsmout; /* * XXX At this time VOP_FSYNC() does not accept offset and byte @@ -2541,7 +2866,9 @@ nfsrv_commit(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, cnt = 0; error = nfsrv_fhtovp(fhp, 1, &vp, cred, slp, nam, &rdonly); if (error) { - nfsm_reply(2 * NFSX_UNSIGNED); + if (nfsm_reply(&info, nfsd, slp, mrq, error, + 2 * NFSX_UNSIGNED) != 0) + return 0; nfsm_srvwcc(nfsd, for_ret, &bfor, aft_ret, &aft, &info); error = 0; goto nfsmout; @@ -2550,7 +2877,9 @@ nfsrv_commit(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, error = VOP_FSYNC(vp, cred, MNT_WAIT, procp); aft_ret = VOP_GETATTR(vp, &aft, cred, procp); vput(vp); - nfsm_reply(NFSX_V3WCCDATA + NFSX_V3WRITEVERF); + if (nfsm_reply(&info, nfsd, slp, mrq, error, + NFSX_V3WCCDATA + NFSX_V3WRITEVERF) != 0) + return 0; nfsm_srvwcc(nfsd, for_ret, &bfor, aft_ret, &aft, &info); if (!error) { tl = nfsm_build(&info.nmi_mb, NFSX_V3WRITEVERF); @@ -2575,10 +2904,7 @@ nfsrv_statfs(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, struct statfs *sf; struct nfs_statfs *sfp; struct nfsm_info info; - u_int32_t *tl; - int32_t t1; int error = 0, rdonly, getret = 1; - char *cp2; struct vnode *vp; struct vattr at; nfsfh_t nfh; @@ -2591,12 +2917,20 @@ nfsrv_statfs(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, info.nmi_md = nfsd->nd_md; info.nmi_dpos = nfsd->nd_dpos; info.nmi_v3 = (nfsd->nd_flag & ND_NFSV3); + info.nmi_errorp = &error; + if (nfsm_srvmtofh1(&info, nfsd, slp, mrq) != 0) + return 0; + else if (error != 0) + goto nfsmout; fhp = &nfh.fh_generic; - nfsm_srvmtofh(fhp); + if (nfsm_srvmtofh2(&info, fhp) != 0) + goto nfsmout; error = nfsrv_fhtovp(fhp, 1, &vp, cred, slp, nam, &rdonly); if (error) { - nfsm_reply(NFSX_UNSIGNED); + if (nfsm_reply(&info, nfsd, slp, mrq, error, + NFSX_UNSIGNED) != 0) + return 0; nfsm_srvpostop_attr(nfsd, getret, &at, &info); error = 0; goto nfsmout; @@ -2605,7 +2939,9 @@ nfsrv_statfs(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, error = VFS_STATFS(vp->v_mount, sf, procp); getret = VOP_GETATTR(vp, &at, cred, procp); vput(vp); - nfsm_reply(NFSX_POSTOPATTR(info.nmi_v3) + NFSX_STATFS(info.nmi_v3)); + if (nfsm_reply(&info, nfsd, slp, mrq, error, + NFSX_POSTOPATTR(info.nmi_v3) + NFSX_STATFS(info.nmi_v3)) != 0) + return 0; if (info.nmi_v3) nfsm_srvpostop_attr(nfsd, getret, &at, &info); if (error) { @@ -2650,11 +2986,8 @@ nfsrv_fsinfo(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, struct mbuf *nam = nfsd->nd_nam; struct ucred *cred = &nfsd->nd_cr; struct nfsm_info info; - u_int32_t *tl; struct nfsv3_fsinfo *sip; - int32_t t1; int error = 0, rdonly, getret = 1, pref; - char *cp2; struct vnode *vp; struct vattr at; nfsfh_t nfh; @@ -2665,19 +2998,29 @@ nfsrv_fsinfo(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, info.nmi_md = nfsd->nd_md; info.nmi_dpos = nfsd->nd_dpos; info.nmi_v3 = (nfsd->nd_flag & ND_NFSV3); + info.nmi_errorp = &error; + if (nfsm_srvmtofh1(&info, nfsd, slp, mrq) != 0) + return 0; + else if (error != 0) + goto nfsmout; fhp = &nfh.fh_generic; - nfsm_srvmtofh(fhp); + if (nfsm_srvmtofh2(&info, fhp) != 0) + goto nfsmout; error = nfsrv_fhtovp(fhp, 1, &vp, cred, slp, nam, &rdonly); if (error) { - nfsm_reply(NFSX_UNSIGNED); + if (nfsm_reply(&info, nfsd, slp, mrq, error, + NFSX_UNSIGNED) != 0) + return 0; nfsm_srvpostop_attr(nfsd, getret, &at, &info); error = 0; goto nfsmout; } getret = VOP_GETATTR(vp, &at, cred, procp); vput(vp); - nfsm_reply(NFSX_V3POSTOPATTR + NFSX_V3FSINFO); + if (nfsm_reply(&info, nfsd, slp, mrq, error, + NFSX_V3POSTOPATTR + NFSX_V3FSINFO) != 0) + return 0; nfsm_srvpostop_attr(nfsd, getret, &at, &info); sip = nfsm_build(&info.nmi_mb, NFSX_V3FSINFO); @@ -2718,12 +3061,9 @@ nfsrv_pathconf(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, struct mbuf *nam = nfsd->nd_nam; struct ucred *cred = &nfsd->nd_cr; struct nfsm_info info; - u_int32_t *tl; struct nfsv3_pathconf *pc; - int32_t t1; int error = 0, rdonly, getret = 1; register_t linkmax, namemax, chownres, notrunc; - char *cp2; struct vnode *vp; struct vattr at; nfsfh_t nfh; @@ -2734,12 +3074,20 @@ nfsrv_pathconf(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, info.nmi_md = nfsd->nd_md; info.nmi_dpos = nfsd->nd_dpos; info.nmi_v3 = (nfsd->nd_flag & ND_NFSV3); + info.nmi_errorp = &error; + if (nfsm_srvmtofh1(&info, nfsd, slp, mrq) != 0) + return 0; + else if (error != 0) + goto nfsmout; fhp = &nfh.fh_generic; - nfsm_srvmtofh(fhp); + if (nfsm_srvmtofh2(&info, fhp) != 0) + goto nfsmout; error = nfsrv_fhtovp(fhp, 1, &vp, cred, slp, nam, &rdonly); if (error) { - nfsm_reply(NFSX_UNSIGNED); + if (nfsm_reply(&info, nfsd, slp, mrq, error, + NFSX_UNSIGNED) != 0) + return 0; nfsm_srvpostop_attr(nfsd, getret, &at, &info); error = 0; goto nfsmout; @@ -2753,7 +3101,9 @@ nfsrv_pathconf(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, error = VOP_PATHCONF(vp, _PC_NO_TRUNC, ¬runc); getret = VOP_GETATTR(vp, &at, cred, procp); vput(vp); - nfsm_reply(NFSX_V3POSTOPATTR + NFSX_V3PATHCONF); + if (nfsm_reply(&info, nfsd, slp, mrq, error, + NFSX_V3POSTOPATTR + NFSX_V3PATHCONF) != 0) + return 0; nfsm_srvpostop_attr(nfsd, getret, &at, &info); if (error) { error = 0; @@ -2792,8 +3142,10 @@ nfsrv_null(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, info.nmi_md = nfsd->nd_md; info.nmi_dpos = nfsd->nd_dpos; info.nmi_v3 = (nfsd->nd_flag & ND_NFSV3); + info.nmi_errorp = &error; - nfsm_reply(0); + if (nfsm_reply(&info, nfsd, slp, mrq, error, 0) != 0) + return 0; return (0); } @@ -2812,12 +3164,14 @@ nfsrv_noop(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, info.nmi_md = nfsd->nd_md; info.nmi_dpos = nfsd->nd_dpos; info.nmi_v3 = (nfsd->nd_flag & ND_NFSV3); + info.nmi_errorp = &error; if (nfsd->nd_repstat) error = nfsd->nd_repstat; else error = EPROCUNAVAIL; - nfsm_reply(0); + if (nfsm_reply(&info, nfsd, slp, mrq, error, 0) != 0) + return 0; return (0); } diff --git a/sys/nfs/nfs_socket.c b/sys/nfs/nfs_socket.c index 0a4eb962a..d88109098 100644 --- a/sys/nfs/nfs_socket.c +++ b/sys/nfs/nfs_socket.c @@ -1,4 +1,4 @@ -/* $OpenBSD: nfs_socket.c,v 1.148 2024/04/19 06:50:37 ratchov Exp $ */ +/* $OpenBSD: nfs_socket.c,v 1.150 2024/04/30 17:05:20 miod Exp $ */ /* $NetBSD: nfs_socket.c,v 1.27 1996/04/15 20:20:00 thorpej Exp $ */ /* @@ -63,16 +63,16 @@ #include #include #include -#include #include #include +#include /* External data, mostly RPC constants in XDR form. */ extern u_int32_t rpc_reply, rpc_msgdenied, rpc_mismatch, rpc_vers, rpc_auth_unix, rpc_msgaccepted, rpc_call, rpc_autherr; extern u_int32_t nfs_prog; extern struct nfsstats nfsstats; -extern int nfsv3_procid[NFS_NPROCS]; +extern const int nfsv3_procid[NFS_NPROCS]; extern int nfs_ticks; extern struct pool nfsrv_descript_pl; @@ -92,10 +92,10 @@ extern struct pool nfsrv_descript_pl; */ #define NFS_CWNDSCALE 256 #define NFS_MAXCWND (NFS_CWNDSCALE * 32) -int nfs_backoff[8] = { 2, 4, 8, 16, 32, 64, 128, 256 }; +static const int nfs_backoff[8] = { 2, 4, 8, 16, 32, 64, 128, 256 }; /* RTT estimator */ -enum nfs_rto_timers nfs_ptimers[NFS_NPROCS] = { +static const enum nfs_rto_timers nfs_ptimers[NFS_NPROCS] = { NFS_DEFAULT_TIMER, /* NULL */ NFS_GETATTR_TIMER, /* GETATTR */ NFS_DEFAULT_TIMER, /* SETATTR */ @@ -158,7 +158,7 @@ nfs_init_rtt(struct nfsmount *nmp) * * Use a gain of 0.125 on the mean and a gain of 0.25 on the deviation. * - * NB: Since the timer resolution of NFS_HZ is so course, it can often + * NB: Since the timer resolution of NFS_HZ is so coarse, it can often * result in r_rtt == 0. Since r_rtt == N means that the actual RTT is * between N + dt and N + 2 - dt ticks, add 1 before calculating the * update values. @@ -746,8 +746,7 @@ nfs_reply(struct nfsreq *myrep) struct nfsmount *nmp = myrep->r_nmp; struct nfsm_info info; struct mbuf *nam; - u_int32_t rxid, *tl, t1; - caddr_t cp2; + u_int32_t rxid, *tl; int error; /* @@ -788,7 +787,10 @@ nfs_reply(struct nfsreq *myrep) */ info.nmi_md = info.nmi_mrep; info.nmi_dpos = mtod(info.nmi_md, caddr_t); - nfsm_dissect(tl, u_int32_t *, 2 * NFSX_UNSIGNED); + info.nmi_errorp = &error; + tl = (uint32_t *)nfsm_dissect(&info, 2 * NFSX_UNSIGNED); + if (tl == NULL) + goto nfsmout; rxid = *tl++; if (*tl != rpc_reply) { nfsstats.rpcinvalid++; @@ -861,8 +863,7 @@ nfs_request(struct vnode *vp, int procnum, struct nfsm_info *infop) struct mbuf *m; u_int32_t *tl; struct nfsmount *nmp; - caddr_t cp2; - int t1, i, error = 0; + int i, error = 0; int trylater_delay; struct nfsreq *rep; struct nfsm_info info; @@ -970,6 +971,7 @@ tryagain: info.nmi_mrep = rep->r_mrep; info.nmi_md = rep->r_md; info.nmi_dpos = rep->r_dpos; + info.nmi_errorp = &error; if (error) { infop->nmi_mrep = NULL; goto nfsmout1; @@ -978,7 +980,9 @@ tryagain: /* * break down the rpc header and check if ok */ - nfsm_dissect(tl, u_int32_t *, 3 * NFSX_UNSIGNED); + tl = (uint32_t *)nfsm_dissect(&info, 3 * NFSX_UNSIGNED); + if (tl == NULL) + goto nfsmout; if (*tl++ == rpc_msgdenied) { if (*tl == rpc_mismatch) error = EOPNOTSUPP; @@ -995,13 +999,20 @@ tryagain: */ tl++; /* Step over verifer type */ i = fxdr_unsigned(int32_t, *tl); - if (i > 0) - nfsm_adv(nfsm_rndup(i)); /* Should not happen */ + if (i > 0) { + /* Should not happen */ + if (nfsm_adv(&info, nfsm_rndup(i)) != 0) + goto nfsmout; + } - nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED); + tl = (uint32_t *)nfsm_dissect(&info, NFSX_UNSIGNED); + if (tl == NULL) + goto nfsmout; /* 0 == ok */ if (*tl == 0) { - nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED); + tl = (uint32_t *)nfsm_dissect(&info, NFSX_UNSIGNED); + if (tl == NULL) + goto nfsmout; if (*tl != 0) { error = fxdr_unsigned(int, *tl); if ((nmp->nm_flag & NFSMNT_NFSV3) && @@ -1434,8 +1445,6 @@ nfs_getreq(struct nfsrv_descript *nd, struct nfsd *nfsd, int has_header) { int len, i; u_int32_t *tl; - int32_t t1; - caddr_t cp2; u_int32_t nfsvers, auth_type; int error = 0; struct nfsm_info info; @@ -1443,15 +1452,21 @@ nfs_getreq(struct nfsrv_descript *nd, struct nfsd *nfsd, int has_header) info.nmi_mrep = nd->nd_mrep; info.nmi_md = nd->nd_md; info.nmi_dpos = nd->nd_dpos; + info.nmi_errorp = &error; if (has_header) { - nfsm_dissect(tl, u_int32_t *, 10 * NFSX_UNSIGNED); + tl = (uint32_t *)nfsm_dissect(&info, 10 * NFSX_UNSIGNED); + if (tl == NULL) + goto nfsmout; nd->nd_retxid = fxdr_unsigned(u_int32_t, *tl++); if (*tl++ != rpc_call) { m_freem(info.nmi_mrep); return (EBADRPC); } - } else - nfsm_dissect(tl, u_int32_t *, 8 * NFSX_UNSIGNED); + } else { + tl = (uint32_t *)nfsm_dissect(&info, 8 * NFSX_UNSIGNED); + if (tl == NULL) + goto nfsmout; + } nd->nd_repstat = 0; nd->nd_flag = 0; if (*tl++ != rpc_vers) { @@ -1499,8 +1514,11 @@ nfs_getreq(struct nfsrv_descript *nd, struct nfsd *nfsd, int has_header) m_freem(info.nmi_mrep); return (EBADRPC); } - nfsm_adv(nfsm_rndup(len)); - nfsm_dissect(tl, u_int32_t *, 3 * NFSX_UNSIGNED); + if (nfsm_adv(&info, nfsm_rndup(len)) != 0) + goto nfsmout; + tl = (uint32_t *)nfsm_dissect(&info, 3 * NFSX_UNSIGNED); + if (tl == NULL) + goto nfsmout; memset(&nd->nd_cr, 0, sizeof (struct ucred)); refcnt_init(&nd->nd_cr.cr_refcnt); nd->nd_cr.cr_uid = fxdr_unsigned(uid_t, *tl++); @@ -1510,7 +1528,10 @@ nfs_getreq(struct nfsrv_descript *nd, struct nfsd *nfsd, int has_header) m_freem(info.nmi_mrep); return (EBADRPC); } - nfsm_dissect(tl, u_int32_t *, (len + 2) * NFSX_UNSIGNED); + tl = (uint32_t *) + nfsm_dissect(&info, (len + 2) * NFSX_UNSIGNED); + if (tl == NULL) + goto nfsmout; for (i = 0; i < len; i++) { if (i < NGROUPS_MAX) nd->nd_cr.cr_groups[i] = @@ -1524,8 +1545,10 @@ nfs_getreq(struct nfsrv_descript *nd, struct nfsd *nfsd, int has_header) m_freem(info.nmi_mrep); return (EBADRPC); } - if (len > 0) - nfsm_adv(nfsm_rndup(len)); + if (len > 0) { + if (nfsm_adv(&info, nfsm_rndup(len)) != 0) + goto nfsmout; + } } else { nd->nd_repstat = (NFSERR_AUTHERR | AUTH_REJECTCRED); nd->nd_procnum = NFSPROC_NOOP; diff --git a/sys/nfs/nfs_srvcache.c b/sys/nfs/nfs_srvcache.c index 4a4b07fc2..297d2d593 100644 --- a/sys/nfs/nfs_srvcache.c +++ b/sys/nfs/nfs_srvcache.c @@ -1,4 +1,4 @@ -/* $OpenBSD: nfs_srvcache.c,v 1.29 2019/12/05 10:41:57 mpi Exp $ */ +/* $OpenBSD: nfs_srvcache.c,v 1.31 2024/05/01 13:15:59 jsg Exp $ */ /* $NetBSD: nfs_srvcache.c,v 1.12 1996/02/18 11:53:49 fvdl Exp $ */ /* @@ -42,7 +42,6 @@ */ #include #include -#include #include #include #include @@ -58,7 +57,7 @@ #include extern struct nfsstats nfsstats; -extern int nfsv2_procid[NFS_NPROCS]; +extern const int nfsv2_procid[NFS_NPROCS]; long numnfsrvcache, desirednfsrvcache = NFSRVCACHESIZ; struct nfsrvcache *nfsrv_lookupcache(struct nfsrv_descript *); @@ -75,14 +74,14 @@ u_long nfsrvhash; (((rp)->rc_flag & RC_INETADDR) ? AF_INET : AF_UNSPEC) /* Array that defines which nfs rpc's are nonidempotent */ -int nonidempotent[NFS_NPROCS] = { +static const int nonidempotent[NFS_NPROCS] = { 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0 }; /* True iff the rpc reply is an nfs status ONLY! */ -int nfsv2_repstat[NFS_NPROCS] = { +static const int nfsv2_repstat[NFS_NPROCS] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 1, 0, 0 diff --git a/sys/nfs/nfs_subs.c b/sys/nfs/nfs_subs.c index 1f2399e95..fbae6f2ee 100644 --- a/sys/nfs/nfs_subs.c +++ b/sys/nfs/nfs_subs.c @@ -1,4 +1,4 @@ -/* $OpenBSD: nfs_subs.c,v 1.146 2022/01/12 20:17:08 mbuhl Exp $ */ +/* $OpenBSD: nfs_subs.c,v 1.149 2024/05/01 13:15:59 jsg Exp $ */ /* $NetBSD: nfs_subs.c,v 1.27.4.3 1996/07/08 20:34:24 jtc Exp $ */ /* @@ -37,9 +37,9 @@ /* - * These functions support the macros and help fiddle mbuf chains for - * the nfs op functions. They do things like create the rpc header and - * copy data between mbuf chains and uio lists. + * These functions support the nfsm_subs.h inline functions and help fiddle + * mbuf chains for the nfs op functions. They do things such as creating the + * rpc header and copying data between mbuf chains and uio lists. */ #include #include @@ -59,11 +59,9 @@ #include #include #include -#include #include #include - -#include +#include #include @@ -82,19 +80,21 @@ u_int32_t rpc_call, rpc_vers, rpc_reply, rpc_msgdenied, rpc_autherr, u_int32_t nfs_prog, nfs_true, nfs_false; /* And other global data */ -nfstype nfsv2_type[9] = { NFNON, NFREG, NFDIR, NFBLK, NFCHR, NFLNK, NFNON, - NFCHR, NFNON }; -nfstype nfsv3_type[9] = { NFNON, NFREG, NFDIR, NFBLK, NFCHR, NFLNK, NFSOCK, - NFFIFO, NFNON }; -enum vtype nv2tov_type[8] = { VNON, VREG, VDIR, VBLK, VCHR, VLNK, VNON, VNON }; -enum vtype nv3tov_type[8]={ VNON, VREG, VDIR, VBLK, VCHR, VLNK, VSOCK, VFIFO }; +const nfstype nfsv2_type[9] = + { NFNON, NFREG, NFDIR, NFBLK, NFCHR, NFLNK, NFNON, NFCHR, NFNON }; +const nfstype nfsv3_type[9] = + { NFNON, NFREG, NFDIR, NFBLK, NFCHR, NFLNK, NFSOCK, NFFIFO, NFNON }; +const enum vtype nv2tov_type[8] = + { VNON, VREG, VDIR, VBLK, VCHR, VLNK, VNON, VNON }; +const enum vtype nv3tov_type[8]= + { VNON, VREG, VDIR, VBLK, VCHR, VLNK, VSOCK, VFIFO }; int nfs_ticks; struct nfsstats nfsstats; /* * Mapping of old NFS Version 2 RPC numbers to generic numbers. */ -int nfsv3_procid[NFS_NPROCS] = { +const int nfsv3_procid[NFS_NPROCS] = { NFSPROC_NULL, NFSPROC_GETATTR, NFSPROC_SETATTR, @@ -123,7 +123,7 @@ int nfsv3_procid[NFS_NPROCS] = { /* * and the reverse mapping from generic to Version 2 procedure numbers */ -int nfsv2_procid[NFS_NPROCS] = { +const int nfsv2_procid[NFS_NPROCS] = { NFSV2PROC_NULL, NFSV2PROC_GETATTR, NFSV2PROC_SETATTR, @@ -154,7 +154,7 @@ int nfsv2_procid[NFS_NPROCS] = { * Use NFSERR_IO as the catch all for ones not specifically defined in * RFC 1094. */ -static u_char nfsrv_v2errmap[] = { +static const u_char nfsrv_v2errmap[] = { NFSERR_PERM, NFSERR_NOENT, NFSERR_IO, NFSERR_IO, NFSERR_IO, NFSERR_NXIO, NFSERR_IO, NFSERR_IO, NFSERR_IO, NFSERR_IO, NFSERR_IO, NFSERR_IO, NFSERR_ACCES, NFSERR_IO, NFSERR_IO, @@ -183,12 +183,12 @@ static u_char nfsrv_v2errmap[] = { * The first entry is the default error return and the rest are the valid * errors for that RPC in increasing numeric order. */ -static short nfsv3err_null[] = { +static const short nfsv3err_null[] = { 0, 0, }; -static short nfsv3err_getattr[] = { +static const short nfsv3err_getattr[] = { NFSERR_IO, NFSERR_IO, NFSERR_STALE, @@ -197,7 +197,7 @@ static short nfsv3err_getattr[] = { 0, }; -static short nfsv3err_setattr[] = { +static const short nfsv3err_setattr[] = { NFSERR_IO, NFSERR_PERM, NFSERR_IO, @@ -213,7 +213,7 @@ static short nfsv3err_setattr[] = { 0, }; -static short nfsv3err_lookup[] = { +static const short nfsv3err_lookup[] = { NFSERR_IO, NFSERR_NOENT, NFSERR_IO, @@ -226,7 +226,7 @@ static short nfsv3err_lookup[] = { 0, }; -static short nfsv3err_access[] = { +static const short nfsv3err_access[] = { NFSERR_IO, NFSERR_IO, NFSERR_STALE, @@ -235,7 +235,7 @@ static short nfsv3err_access[] = { 0, }; -static short nfsv3err_readlink[] = { +static const short nfsv3err_readlink[] = { NFSERR_IO, NFSERR_IO, NFSERR_ACCES, @@ -247,7 +247,7 @@ static short nfsv3err_readlink[] = { 0, }; -static short nfsv3err_read[] = { +static const short nfsv3err_read[] = { NFSERR_IO, NFSERR_IO, NFSERR_NXIO, @@ -259,7 +259,7 @@ static short nfsv3err_read[] = { 0, }; -static short nfsv3err_write[] = { +static const short nfsv3err_write[] = { NFSERR_IO, NFSERR_IO, NFSERR_ACCES, @@ -274,7 +274,7 @@ static short nfsv3err_write[] = { 0, }; -static short nfsv3err_create[] = { +static const short nfsv3err_create[] = { NFSERR_IO, NFSERR_IO, NFSERR_ACCES, @@ -291,7 +291,7 @@ static short nfsv3err_create[] = { 0, }; -static short nfsv3err_mkdir[] = { +static const short nfsv3err_mkdir[] = { NFSERR_IO, NFSERR_IO, NFSERR_ACCES, @@ -308,7 +308,7 @@ static short nfsv3err_mkdir[] = { 0, }; -static short nfsv3err_symlink[] = { +static const short nfsv3err_symlink[] = { NFSERR_IO, NFSERR_IO, NFSERR_ACCES, @@ -325,7 +325,7 @@ static short nfsv3err_symlink[] = { 0, }; -static short nfsv3err_mknod[] = { +static const short nfsv3err_mknod[] = { NFSERR_IO, NFSERR_IO, NFSERR_ACCES, @@ -343,7 +343,7 @@ static short nfsv3err_mknod[] = { 0, }; -static short nfsv3err_remove[] = { +static const short nfsv3err_remove[] = { NFSERR_IO, NFSERR_NOENT, NFSERR_IO, @@ -357,7 +357,7 @@ static short nfsv3err_remove[] = { 0, }; -static short nfsv3err_rmdir[] = { +static const short nfsv3err_rmdir[] = { NFSERR_IO, NFSERR_NOENT, NFSERR_IO, @@ -375,7 +375,7 @@ static short nfsv3err_rmdir[] = { 0, }; -static short nfsv3err_rename[] = { +static const short nfsv3err_rename[] = { NFSERR_IO, NFSERR_NOENT, NFSERR_IO, @@ -398,7 +398,7 @@ static short nfsv3err_rename[] = { 0, }; -static short nfsv3err_link[] = { +static const short nfsv3err_link[] = { NFSERR_IO, NFSERR_IO, NFSERR_ACCES, @@ -418,7 +418,7 @@ static short nfsv3err_link[] = { 0, }; -static short nfsv3err_readdir[] = { +static const short nfsv3err_readdir[] = { NFSERR_IO, NFSERR_IO, NFSERR_ACCES, @@ -431,7 +431,7 @@ static short nfsv3err_readdir[] = { 0, }; -static short nfsv3err_readdirplus[] = { +static const short nfsv3err_readdirplus[] = { NFSERR_IO, NFSERR_IO, NFSERR_ACCES, @@ -445,7 +445,7 @@ static short nfsv3err_readdirplus[] = { 0, }; -static short nfsv3err_fsstat[] = { +static const short nfsv3err_fsstat[] = { NFSERR_IO, NFSERR_IO, NFSERR_STALE, @@ -454,7 +454,7 @@ static short nfsv3err_fsstat[] = { 0, }; -static short nfsv3err_fsinfo[] = { +static const short nfsv3err_fsinfo[] = { NFSERR_STALE, NFSERR_STALE, NFSERR_BADHANDLE, @@ -462,7 +462,7 @@ static short nfsv3err_fsinfo[] = { 0, }; -static short nfsv3err_pathconf[] = { +static const short nfsv3err_pathconf[] = { NFSERR_STALE, NFSERR_STALE, NFSERR_BADHANDLE, @@ -470,7 +470,7 @@ static short nfsv3err_pathconf[] = { 0, }; -static short nfsv3err_commit[] = { +static const short nfsv3err_commit[] = { NFSERR_IO, NFSERR_IO, NFSERR_STALE, @@ -479,7 +479,7 @@ static short nfsv3err_commit[] = { 0, }; -static short *nfsrv_v3errmap[] = { +static const short *nfsrv_v3errmap[] = { nfsv3err_null, nfsv3err_getattr, nfsv3err_setattr, @@ -791,8 +791,7 @@ nfsm_strtombuf(struct mbuf **mp, void *str, size_t len) /* * Help break down an mbuf chain by setting the first siz bytes contiguous * pointed to by returned val. - * This is used by the macros nfsm_dissect and nfsm_dissecton for tough - * cases. (The macros use the vars. dpos and dpos2) + * This is used by nfsm_dissect for tough cases. */ int nfsm_disct(struct mbuf **mdp, caddr_t *dposp, int siz, int left, caddr_t *cp2) @@ -824,7 +823,7 @@ nfsm_disct(struct mbuf **mdp, caddr_t *dposp, int siz, int left, caddr_t *cp2) mp = mp2; *cp2 = p = mtod(mp, caddr_t); bcopy(*dposp, p, left); /* Copy what was left */ - siz2 = siz-left; + siz2 = siz - left; p += left; mp2 = mp->m_next; /* Loop around copying up the siz2 bytes */ @@ -939,8 +938,7 @@ nfs_loadattrcache(struct vnode **vpp, struct mbuf **mdp, caddr_t *dposp, struct nfs_fattr *fp; extern const struct vops nfs_specvops; struct nfsnode *np; - int32_t t1; - caddr_t cp2; + int32_t avail; int error = 0; int32_t rdev; struct mbuf *md; @@ -953,11 +951,10 @@ nfs_loadattrcache(struct vnode **vpp, struct mbuf **mdp, caddr_t *dposp, gid_t gid; md = *mdp; - t1 = (mtod(md, caddr_t) + md->m_len) - *dposp; - error = nfsm_disct(mdp, dposp, NFSX_FATTR(v3), t1, &cp2); + avail = (mtod(md, caddr_t) + md->m_len) - *dposp; + error = nfsm_disct(mdp, dposp, NFSX_FATTR(v3), avail, (caddr_t *)&fp); if (error) return (error); - fp = (struct nfs_fattr *)cp2; if (v3) { vtyp = nfsv3tov_type(fp->fa_type); vmode = fxdr_unsigned(mode_t, fp->fa_mode); @@ -1050,34 +1047,29 @@ nfs_loadattrcache(struct vnode **vpp, struct mbuf **mdp, caddr_t *dposp, fxdr_unsigned(int32_t, fp->fa2_blocksize); break; } + vap->va_nlink = fxdr_unsigned(nlink_t, fp->fa_nlink); + vap->va_uid = fxdr_unsigned(uid_t, fp->fa_uid); + vap->va_gid = fxdr_unsigned(gid_t, fp->fa_gid); if (v3) { - vap->va_nlink = fxdr_unsigned(nlink_t, fp->fa_nlink); - vap->va_uid = fxdr_unsigned(uid_t, fp->fa_uid); - vap->va_gid = fxdr_unsigned(gid_t, fp->fa_gid); vap->va_size = fxdr_hyper(&fp->fa3_size); vap->va_bytes = fxdr_hyper(&fp->fa3_used); vap->va_fileid = fxdr_hyper(&fp->fa3_fileid); fxdr_nfsv3time(&fp->fa3_atime, &vap->va_atime); fxdr_nfsv3time(&fp->fa3_ctime, &vap->va_ctime); - vap->va_flags = 0; - vap->va_filerev = 0; } else { - vap->va_nlink = fxdr_unsigned(nlink_t, fp->fa_nlink); - vap->va_uid = fxdr_unsigned(uid_t, fp->fa_uid); - vap->va_gid = fxdr_unsigned(gid_t, fp->fa_gid); vap->va_size = fxdr_unsigned(u_int32_t, fp->fa2_size); vap->va_bytes = (u_quad_t)fxdr_unsigned(int32_t, fp->fa2_blocks) * NFS_FABLKSIZE; vap->va_fileid = fxdr_unsigned(int32_t, fp->fa2_fileid); fxdr_nfsv2time(&fp->fa2_atime, &vap->va_atime); - vap->va_flags = 0; vap->va_ctime.tv_sec = fxdr_unsigned(u_int32_t, fp->fa2_ctime.nfsv2_sec); vap->va_ctime.tv_nsec = 0; vap->va_gen = fxdr_unsigned(u_int32_t,fp->fa2_ctime.nfsv2_usec); - vap->va_filerev = 0; } + vap->va_flags = 0; + vap->va_filerev = 0; if (vap->va_size != np->n_size) { if (vap->va_type == VREG) { @@ -1116,8 +1108,7 @@ nfs_attrtimeo(struct nfsnode *np) if (vp->v_type == VDIR) { maxto = nmp->nm_acdirmax; minto = nmp->nm_acdirmin; - } - else { + } else { maxto = nmp->nm_acregmax; minto = nmp->nm_acregmin; } @@ -1338,7 +1329,7 @@ nfsm_adj(struct mbuf *mp, int len, int nul) } /* - * Make these functions instead of macros, so that the kernel text size + * Make these non-inline functions, so that the kernel text size * doesn't get too big... */ void @@ -1687,7 +1678,7 @@ nfs_del_tobecommitted_range(struct vnode *vp, struct buf *bp) int nfsrv_errmap(struct nfsrv_descript *nd, int err) { - short *defaulterrp, *errp; + const short *defaulterrp, *errp; if (nd->nd_flag & ND_NFSV3) { if (nd->nd_procnum <= NFSPROC_COMMIT) { @@ -1835,44 +1826,64 @@ nfsm_srvsattr(struct mbuf **mp, struct vattr *va, struct mbuf *mrep, caddr_t *dposp) { struct nfsm_info info; - uint32_t *tl, t1; - caddr_t cp2; int error = 0; + uint32_t *tl; info.nmi_md = *mp; info.nmi_dpos = *dposp; info.nmi_mrep = mrep; + info.nmi_errorp = &error; - nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED); + tl = (uint32_t *)nfsm_dissect(&info, NFSX_UNSIGNED); + if (tl == NULL) + return error; if (*tl == nfs_true) { - nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED); + tl = (uint32_t *)nfsm_dissect(&info, NFSX_UNSIGNED); + if (tl == NULL) + return error; va->va_mode = nfstov_mode(*tl); } - nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED); + tl = (uint32_t *)nfsm_dissect(&info, NFSX_UNSIGNED); + if (tl == NULL) + return error; if (*tl == nfs_true) { - nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED); + tl = (uint32_t *)nfsm_dissect(&info, NFSX_UNSIGNED); + if (tl == NULL) + return error; va->va_uid = fxdr_unsigned(uid_t, *tl); } - nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED); + tl = (uint32_t *)nfsm_dissect(&info, NFSX_UNSIGNED); + if (tl == NULL) + return error; if (*tl == nfs_true) { - nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED); + tl = (uint32_t *)nfsm_dissect(&info, NFSX_UNSIGNED); + if (tl == NULL) + return error; va->va_gid = fxdr_unsigned(gid_t, *tl); } - nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED); + tl = (uint32_t *)nfsm_dissect(&info, NFSX_UNSIGNED); + if (tl == NULL) + return error; if (*tl == nfs_true) { - nfsm_dissect(tl, u_int32_t *, 2 * NFSX_UNSIGNED); + tl = (uint32_t *)nfsm_dissect(&info, 2 * NFSX_UNSIGNED); + if (tl == NULL) + return error; va->va_size = fxdr_hyper(tl); } - nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED); + tl = (uint32_t *)nfsm_dissect(&info, NFSX_UNSIGNED); + if (tl == NULL) + return error; switch (fxdr_unsigned(int, *tl)) { case NFSV3SATTRTIME_TOCLIENT: va->va_vaflags |= VA_UTIMES_CHANGE; va->va_vaflags &= ~VA_UTIMES_NULL; - nfsm_dissect(tl, u_int32_t *, 2 * NFSX_UNSIGNED); + tl = (uint32_t *)nfsm_dissect(&info, 2 * NFSX_UNSIGNED); + if (tl == NULL) + return error; fxdr_nfsv3time(tl, &va->va_atime); break; case NFSV3SATTRTIME_TOSERVER: @@ -1881,12 +1892,16 @@ nfsm_srvsattr(struct mbuf **mp, struct vattr *va, struct mbuf *mrep, break; }; - nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED); + tl = (uint32_t *)nfsm_dissect(&info, NFSX_UNSIGNED); + if (tl == NULL) + return error; switch (fxdr_unsigned(int, *tl)) { case NFSV3SATTRTIME_TOCLIENT: va->va_vaflags |= VA_UTIMES_CHANGE; va->va_vaflags &= ~VA_UTIMES_NULL; - nfsm_dissect(tl, u_int32_t *, 2 * NFSX_UNSIGNED); + tl = (uint32_t *)nfsm_dissect(&info, 2 * NFSX_UNSIGNED); + if (tl == NULL) + return error; fxdr_nfsv3time(tl, &va->va_mtime); break; case NFSV3SATTRTIME_TOSERVER: @@ -1897,8 +1912,7 @@ nfsm_srvsattr(struct mbuf **mp, struct vattr *va, struct mbuf *mrep, *dposp = info.nmi_dpos; *mp = info.nmi_md; -nfsmout: - return (error); + return 0; } void diff --git a/sys/nfs/nfs_syscalls.c b/sys/nfs/nfs_syscalls.c index 80b610ad5..71309e420 100644 --- a/sys/nfs/nfs_syscalls.c +++ b/sys/nfs/nfs_syscalls.c @@ -1,4 +1,4 @@ -/* $OpenBSD: nfs_syscalls.c,v 1.124 2024/04/19 06:50:37 ratchov Exp $ */ +/* $OpenBSD: nfs_syscalls.c,v 1.126 2024/05/01 13:15:59 jsg Exp $ */ /* $NetBSD: nfs_syscalls.c,v 1.19 1996/02/18 11:53:52 fvdl Exp $ */ /* @@ -37,14 +37,10 @@ #include #include -#include #include -#include #include #include #include -#include -#include #include #include #include @@ -52,8 +48,6 @@ #include #include #include -#include -#include #include #include #include @@ -63,12 +57,9 @@ #include #include -#include -#include #include #include #include -#include #include #include @@ -84,7 +75,7 @@ struct pool nfsrv_descript_pl; int nfsrv_getslp(struct nfsd *nfsd); static int nfs_numnfsd = 0; -int (*nfsrv3_procs[NFS_NPROCS])(struct nfsrv_descript *, +static int (*const nfsrv3_procs[NFS_NPROCS])(struct nfsrv_descript *, struct nfssvc_sock *, struct proc *, struct mbuf **) = { nfsrv_null, nfsrv_getattr, diff --git a/sys/nfs/nfs_var.h b/sys/nfs/nfs_var.h index 4f0e3bf15..962a94b60 100644 --- a/sys/nfs/nfs_var.h +++ b/sys/nfs/nfs_var.h @@ -1,4 +1,4 @@ -/* $OpenBSD: nfs_var.h,v 1.63 2017/02/22 11:42:46 mpi Exp $ */ +/* $OpenBSD: nfs_var.h,v 1.64 2024/04/30 17:04:23 miod Exp $ */ /* $NetBSD: nfs_var.h,v 1.3 1996/02/18 11:53:54 fvdl Exp $ */ /* @@ -152,7 +152,6 @@ int nfsm_mbuftouio(struct mbuf **, struct uio *, int, caddr_t *); void nfsm_uiotombuf(struct mbuf **, struct uio *, size_t); void nfsm_strtombuf(struct mbuf **, void *, size_t); void nfsm_buftombuf(struct mbuf **, void *, size_t); -int nfsm_disct(struct mbuf **, caddr_t *, int, int, caddr_t *); int nfs_adv(struct mbuf **, caddr_t *, int, int); int nfsm_strtmbuf(struct mbuf **, char **, char *, long); int nfs_vfs_init(struct vfsconf *); @@ -164,6 +163,7 @@ int nfs_namei(struct nameidata *, fhandle_t *, int, struct nfssvc_sock *, struct mbuf *, struct mbuf **, caddr_t *, struct vnode **, struct proc *); void nfsm_v3attrbuild(struct mbuf **, struct vattr *, int); +int nfsm_disct(struct mbuf **, caddr_t *, int, int, caddr_t *); void nfsm_adj(struct mbuf *, int, int); void nfsm_srvwcc(struct nfsrv_descript *, int, struct vattr *, int, struct vattr *, struct nfsm_info *); diff --git a/sys/nfs/nfs_vfsops.c b/sys/nfs/nfs_vfsops.c index e45ed66a6..d39a5f1a3 100644 --- a/sys/nfs/nfs_vfsops.c +++ b/sys/nfs/nfs_vfsops.c @@ -1,4 +1,4 @@ -/* $OpenBSD: nfs_vfsops.c,v 1.128 2023/03/08 04:43:09 guenther Exp $ */ +/* $OpenBSD: nfs_vfsops.c,v 1.130 2024/05/01 13:15:59 jsg Exp $ */ /* $NetBSD: nfs_vfsops.c,v 1.46.4.1 1996/05/25 22:40:35 fvdl Exp $ */ /* @@ -37,16 +37,12 @@ #include #include -#include -#include #include -#include #include #include #include #include #include -#include #include #include #include @@ -57,15 +53,14 @@ #include -#include #include #include #include #include #include -#include #include #include +#include extern struct nfsstats nfsstats; extern int nfs_ticks; @@ -120,15 +115,13 @@ nfs_statfs(struct mount *mp, struct statfs *sbp, struct proc *p) struct vnode *vp; struct nfs_statfs *sfp = NULL; struct nfsm_info info; - u_int32_t *tl; - int32_t t1; - caddr_t cp2; struct nfsmount *nmp = VFSTONFS(mp); int error = 0, retattr; struct ucred *cred; u_quad_t tquad; info.nmi_v3 = (nmp->nm_flag & NFSMNT_NFSV3); + info.nmi_errorp = &error; error = nfs_root(mp, &vp); if (error) @@ -144,14 +137,19 @@ nfs_statfs(struct mount *mp, struct statfs *sbp, struct proc *p) info.nmi_procp = p; info.nmi_cred = cred; error = nfs_request(vp, NFSPROC_FSSTAT, &info); - if (info.nmi_v3) - nfsm_postop_attr(vp, retattr); + if (info.nmi_v3) { + if (nfsm_postop_attr(&info, &vp, &retattr) != 0) + goto nfsmout; + } if (error) { m_freem(info.nmi_mrep); goto nfsmout; } - nfsm_dissect(sfp, struct nfs_statfs *, NFSX_STATFS(info.nmi_v3)); + sfp = (struct nfs_statfs *) + nfsm_dissect(&info, NFSX_STATFS(info.nmi_v3)); + if (sfp == NULL) + goto nfsmout; sbp->f_iosize = min(nmp->nm_rsize, nmp->nm_wsize); if (info.nmi_v3) { sbp->f_bsize = NFS_FABLKSIZE; @@ -193,9 +191,7 @@ nfs_fsinfo(struct nfsmount *nmp, struct vnode *vp, struct ucred *cred, { struct nfsv3_fsinfo *fsp; struct nfsm_info info; - int32_t t1; - u_int32_t *tl, pref, max; - caddr_t cp2; + u_int32_t pref, max; int error = 0, retattr; nfsstats.rpccnt[NFSPROC_FSINFO]++; @@ -204,15 +200,19 @@ nfs_fsinfo(struct nfsmount *nmp, struct vnode *vp, struct ucred *cred, info.nmi_procp = p; info.nmi_cred = cred; + info.nmi_errorp = &error; error = nfs_request(vp, NFSPROC_FSINFO, &info); - nfsm_postop_attr(vp, retattr); + if (nfsm_postop_attr(&info, &vp, &retattr) != 0) + goto nfsmout; if (error) { m_freem(info.nmi_mrep); goto nfsmout; } - nfsm_dissect(fsp, struct nfsv3_fsinfo *, NFSX_V3FSINFO); + fsp = (struct nfsv3_fsinfo *)nfsm_dissect(&info, NFSX_V3FSINFO); + if (fsp == NULL) + goto nfsmout; pref = fxdr_unsigned(u_int32_t, fsp->fs_wtpref); if (pref < nmp->nm_wsize) nmp->nm_wsize = (pref + NFS_FABLKSIZE - 1) & diff --git a/sys/nfs/nfs_vnops.c b/sys/nfs/nfs_vnops.c index 38cffb3be..9668c94aa 100644 --- a/sys/nfs/nfs_vnops.c +++ b/sys/nfs/nfs_vnops.c @@ -1,4 +1,4 @@ -/* $OpenBSD: nfs_vnops.c,v 1.195 2024/04/13 23:44:11 jsg Exp $ */ +/* $OpenBSD: nfs_vnops.c,v 1.198 2024/05/01 13:15:59 jsg Exp $ */ /* $NetBSD: nfs_vnops.c,v 1.62.4.1 1996/07/08 20:26:52 jtc Exp $ */ /* @@ -41,16 +41,13 @@ */ #include -#include #include -#include #include #include #include #include #include #include -#include #include #include #include @@ -63,18 +60,13 @@ #include -#include #include #include #include #include #include -#include #include - -#include - -#include +#include int nfs_access(void *); int nfs_advlock(void *); @@ -259,7 +251,7 @@ const struct vops nfs_fifovops = { extern u_int32_t nfs_true, nfs_false; extern u_int32_t nfs_xdrneg1; extern struct nfsstats nfsstats; -extern nfstype nfsv3_type[9]; +extern const nfstype nfsv3_type[9]; int nfs_numasync = 0; void @@ -289,6 +281,7 @@ nfs_null(struct vnode *vp, struct ucred *cred, struct proc *procp) int error = 0; info.nmi_mb = info.nmi_mreq = nfsm_reqhead(0); + info.nmi_errorp = &error; error = nfs_request(vp, NFSPROC_NULL, &info); m_freem(info.nmi_mrep); return (error); @@ -306,8 +299,6 @@ nfs_access(void *v) struct vop_access_args *ap = v; struct vnode *vp = ap->a_vp; u_int32_t *tl; - int32_t t1; - caddr_t cp2; int error = 0, attrflag; u_int32_t mode, rmode; int v3 = NFS_ISV3(vp); @@ -381,15 +372,19 @@ nfs_access(void *v) info.nmi_procp = ap->a_p; info.nmi_cred = ap->a_cred; + info.nmi_errorp = &error; error = nfs_request(vp, NFSPROC_ACCESS, &info); - nfsm_postop_attr(vp, attrflag); + if (nfsm_postop_attr(&info, &vp, &attrflag) != 0) + goto nfsmout; if (error) { m_freem(info.nmi_mrep); goto nfsmout; } - nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED); + tl = (uint32_t *)nfsm_dissect(&info, NFSX_UNSIGNED); + if (tl == NULL) + goto nfsmout; rmode = fxdr_unsigned(u_int32_t, *tl); /* * The NFS V3 spec does not clarify whether or not @@ -554,6 +549,22 @@ nfs_close(void *v) return (error); } +static inline int +nfsm_loadattr(struct nfsm_info *infop, struct vnode **vpp, struct vattr *vap) +{ + struct vnode *ttvp = *vpp; + int error; + + error = nfs_loadattrcache(&ttvp, &infop->nmi_md, &infop->nmi_dpos, vap); + if (error != 0) { + m_freem(infop->nmi_mrep); + *infop->nmi_errorp = error; + return error; + } + *vpp = ttvp; + return 0; +} + /* * nfs getattr call from vfs. */ @@ -564,7 +575,6 @@ nfs_getattr(void *v) struct vnode *vp = ap->a_vp; struct nfsnode *np = VTONFS(vp); struct nfsm_info info; - int32_t t1; int error = 0; info.nmi_v3 = NFS_ISV3(vp); @@ -585,9 +595,12 @@ nfs_getattr(void *v) nfsm_fhtom(&info, vp, info.nmi_v3); info.nmi_procp = ap->a_p; info.nmi_cred = ap->a_cred; + info.nmi_errorp = &error; error = nfs_request(vp, NFSPROC_GETATTR, &info); - if (!error) - nfsm_loadattr(vp, ap->a_vap); + if (!error) { + if (nfsm_loadattr(&info, &vp, ap->a_vap) != 0) + goto nfsmout; + } m_freem(info.nmi_mrep); nfsmout: return (error); @@ -678,6 +691,42 @@ nfs_setattr(void *v) return (error); } +/* Used as *flagp for nfsm_wcc_data() below */ +#define NFSV3_WCCRATTR 0 +#define NFSV3_WCCCHK 1 + +static inline int +nfsm_wcc_data(struct nfsm_info *infop, struct vnode **vpp, int *flagp) +{ + struct timespec mtime; + int ttattrf, ttretf = 0; + uint32_t *tl; + + if (infop->nmi_mrep == NULL) + return 0; + + tl = (uint32_t *)nfsm_dissect(infop, NFSX_UNSIGNED); + if (tl == NULL) + return 1; + if (*tl == nfs_true) { + tl = (uint32_t *)nfsm_dissect(infop, 6 * NFSX_UNSIGNED); + if (tl == NULL) + return 1; + fxdr_nfsv3time(tl + 2, &mtime); + if (*flagp != NFSV3_WCCRATTR) { + ttretf = + timespeccmp(&VTONFS(*vpp)->n_mtime, &mtime, !=); + } + } + if (nfsm_postop_attr(infop, vpp, &ttattrf) != 0) + return 1; + if (*flagp != NFSV3_WCCRATTR) + *flagp = ttretf; + else + *flagp = ttattrf; + return 0; +} + /* * Do an nfs setattr rpc. */ @@ -687,8 +736,6 @@ nfs_setattrrpc(struct vnode *vp, struct vattr *vap, struct ucred *cred, { struct nfsv2_sattr *sp; struct nfsm_info info; - int32_t t1; - caddr_t cp2; u_int32_t *tl; int error = 0, wccflag = NFSV3_WCCRATTR; int v3 = NFS_ISV3(vp); @@ -698,6 +745,7 @@ nfs_setattrrpc(struct vnode *vp, struct vattr *vap, struct ucred *cred, nfsstats.rpccnt[NFSPROC_SETATTR]++; info.nmi_mb = info.nmi_mreq = nfsm_reqhead(NFSX_FH(v3) + NFSX_SATTR(v3)); nfsm_fhtom(&info, vp, v3); + info.nmi_errorp = &error; if (info.nmi_v3) { nfsm_v3attrbuild(&info.nmi_mb, vap, 1); @@ -726,16 +774,40 @@ nfs_setattrrpc(struct vnode *vp, struct vattr *vap, struct ucred *cred, info.nmi_cred = cred; error = nfs_request(vp, NFSPROC_SETATTR, &info); - if (info.nmi_v3) - nfsm_wcc_data(vp, wccflag); - else if (error == 0) - nfsm_loadattr(vp, NULL); + if (info.nmi_v3) { + if (nfsm_wcc_data(&info, &vp, &wccflag) != 0) + goto nfsmout; + } + else if (error == 0) { + if (nfsm_loadattr(&info, &vp, NULL) != 0) + goto nfsmout; + } m_freem(info.nmi_mrep); nfsmout: return (error); } +static inline nfsfh_t * +nfsm_getfh(struct nfsm_info *infop, int *sizep, int v3) +{ + int size; + if (v3) { + uint32_t *tl = (uint32_t *)nfsm_dissect(infop, NFSX_UNSIGNED); + if (tl == NULL) + return NULL; + size = fxdr_unsigned(int, *tl); + if (size <= 0 || size > NFSX_V3FHMAX) { + m_freem(infop->nmi_mrep); + *infop->nmi_errorp = EBADRPC; + return NULL; + } + } else + size = NFSX_V2FH; + *sizep = size; + return (nfsfh_t *)nfsm_dissect(infop, nfsm_rndup(size)); +} + /* * nfs lookup call, one step at a time... * First look in cache @@ -751,16 +823,14 @@ nfs_lookup(void *v) struct nfsm_info info; int flags; struct vnode *newvp; - u_int32_t *tl; - int32_t t1; struct nfsmount *nmp; - caddr_t cp2; long len; nfsfh_t *fhp; struct nfsnode *np; int lockparent, wantparent, error = 0, attrflag, fhsize; info.nmi_v3 = NFS_ISV3(dvp); + info.nmi_errorp = &error; cnp->cn_flags &= ~PDIRUNLOCK; flags = cnp->cn_flags; @@ -856,20 +926,24 @@ dorpc: info.nmi_mb = info.nmi_mreq = nfsm_reqhead(NFSX_FH(info.nmi_v3) + NFSX_UNSIGNED + nfsm_rndup(len)); nfsm_fhtom(&info, dvp, info.nmi_v3); - nfsm_strtom(cnp->cn_nameptr, len, NFS_MAXNAMLEN); + if (nfsm_strtom(&info, cnp->cn_nameptr, len, NFS_MAXNAMLEN) != 0) + goto nfsmout; info.nmi_procp = cnp->cn_proc; info.nmi_cred = cnp->cn_cred; error = nfs_request(dvp, NFSPROC_LOOKUP, &info); if (error) { - if (info.nmi_v3) - nfsm_postop_attr(dvp, attrflag); + if (info.nmi_v3) { + if (nfsm_postop_attr(&info, &dvp, &attrflag) != 0) + goto nfsmout; + } m_freem(info.nmi_mrep); goto nfsmout; } - nfsm_getfh(fhp, fhsize, info.nmi_v3); + if ((fhp = nfsm_getfh(&info, &fhsize, info.nmi_v3)) == NULL) + goto nfsmout; /* * Handle RENAME case... @@ -886,10 +960,14 @@ dorpc: } newvp = NFSTOV(np); if (info.nmi_v3) { - nfsm_postop_attr(newvp, attrflag); - nfsm_postop_attr(dvp, attrflag); - } else - nfsm_loadattr(newvp, NULL); + if (nfsm_postop_attr(&info, &newvp, &attrflag) != 0) + goto nfsmout; + if (nfsm_postop_attr(&info, &dvp, &attrflag) != 0) + goto nfsmout; + } else { + if (nfsm_loadattr(&info, &newvp, NULL) != 0) + goto nfsmout; + } *vpp = newvp; m_freem(info.nmi_mrep); cnp->cn_flags |= SAVENAME; @@ -910,10 +988,14 @@ dorpc: vref(dvp); newvp = dvp; if (info.nmi_v3) { - nfsm_postop_attr(newvp, attrflag); - nfsm_postop_attr(dvp, attrflag); - } else - nfsm_loadattr(newvp, NULL); + if (nfsm_postop_attr(&info, &newvp, &attrflag) != 0) + goto nfsmout; + if (nfsm_postop_attr(&info, &dvp, &attrflag) != 0) + goto nfsmout; + } else { + if (nfsm_loadattr(&info, &newvp, NULL) != 0) + goto nfsmout; + } } else if (flags & ISDOTDOT) { VOP_UNLOCK(dvp); cnp->cn_flags |= PDIRUNLOCK; @@ -928,10 +1010,14 @@ dorpc: newvp = NFSTOV(np); if (info.nmi_v3) { - nfsm_postop_attr(newvp, attrflag); - nfsm_postop_attr(dvp, attrflag); - } else - nfsm_loadattr(newvp, NULL); + if (nfsm_postop_attr(&info, &newvp, &attrflag) != 0) + goto nfsmout; + if (nfsm_postop_attr(&info, &dvp, &attrflag) != 0) + goto nfsmout; + } else { + if (nfsm_loadattr(&info, &newvp, NULL) != 0) + goto nfsmout; + } if (lockparent && (flags & ISLASTCN)) { if ((error = vn_lock(dvp, LK_EXCLUSIVE))) { @@ -950,10 +1036,14 @@ dorpc: } newvp = NFSTOV(np); if (info.nmi_v3) { - nfsm_postop_attr(newvp, attrflag); - nfsm_postop_attr(dvp, attrflag); - } else - nfsm_loadattr(newvp, NULL); + if (nfsm_postop_attr(&info, &newvp, &attrflag) != 0) + goto nfsmout; + if (nfsm_postop_attr(&info, &dvp, &attrflag) != 0) + goto nfsmout; + } else { + if (nfsm_loadattr(&info, &newvp, NULL) != 0) + goto nfsmout; + } if (!lockparent || !(flags & ISLASTCN)) { VOP_UNLOCK(dvp); cnp->cn_flags |= PDIRUNLOCK; @@ -973,10 +1063,8 @@ dorpc: nfsmout: if (error) { /* - * We get here only because of errors returned by - * the RPC. Otherwise we'll have returned above - * (the nfsm_* macros will jump to nfsmout - * on error). + * We get here only because of errors returned by the RPC. + * Otherwise we'd already have returned. */ if (error == ENOENT && (cnp->cn_flags & MAKEENTRY) && cnp->cn_nameiop != CREATE) { @@ -1075,12 +1163,10 @@ int nfs_readlinkrpc(struct vnode *vp, struct uio *uiop, struct ucred *cred) { struct nfsm_info info; - u_int32_t *tl; - int32_t t1; - caddr_t cp2; int error = 0, len, attrflag; info.nmi_v3 = NFS_ISV3(vp); + info.nmi_errorp = &error; nfsstats.rpccnt[NFSPROC_READLINK]++; info.nmi_mb = info.nmi_mreq = nfsm_reqhead(NFSX_FH(info.nmi_v3)); @@ -1090,11 +1176,15 @@ nfs_readlinkrpc(struct vnode *vp, struct uio *uiop, struct ucred *cred) info.nmi_cred = cred; error = nfs_request(vp, NFSPROC_READLINK, &info); - if (info.nmi_v3) - nfsm_postop_attr(vp, attrflag); + if (info.nmi_v3) { + if (nfsm_postop_attr(&info, &vp, &attrflag) != 0) + goto nfsmout; + } if (!error) { - nfsm_strsiz(len, NFS_MAXPATHLEN); - nfsm_mtouio(uiop, len); + if (nfsm_strsiz(&info, &len, NFS_MAXPATHLEN) != 0) + goto nfsmout; + if (nfsm_mtouio(&info, uiop, len) != 0) + goto nfsmout; } m_freem(info.nmi_mrep); @@ -1112,12 +1202,11 @@ nfs_readrpc(struct vnode *vp, struct uio *uiop) { struct nfsm_info info; u_int32_t *tl; - int32_t t1; - caddr_t cp2; struct nfsmount *nmp; int error = 0, len, retlen, tsiz, eof, attrflag; info.nmi_v3 = NFS_ISV3(vp); + info.nmi_errorp = &error; eof = 0; @@ -1144,22 +1233,29 @@ nfs_readrpc(struct vnode *vp, struct uio *uiop) info.nmi_procp = curproc; info.nmi_cred = VTONFS(vp)->n_rcred; error = nfs_request(vp, NFSPROC_READ, &info); - if (info.nmi_v3) - nfsm_postop_attr(vp, attrflag); + if (info.nmi_v3) { + if (nfsm_postop_attr(&info, &vp, &attrflag) != 0) + goto nfsmout; + } if (error) { m_freem(info.nmi_mrep); goto nfsmout; } if (info.nmi_v3) { - nfsm_dissect(tl, u_int32_t *, 2 * NFSX_UNSIGNED); + tl = (uint32_t *)nfsm_dissect(&info, 2 * NFSX_UNSIGNED); + if (tl == NULL) + goto nfsmout; eof = fxdr_unsigned(int, *(tl + 1)); } else { - nfsm_loadattr(vp, NULL); + if (nfsm_loadattr(&info, &vp, NULL) != 0) + goto nfsmout; } - nfsm_strsiz(retlen, nmp->nm_rsize); - nfsm_mtouio(uiop, retlen); + if (nfsm_strsiz(&info, &retlen, nmp->nm_rsize) != 0) + goto nfsmout; + if (nfsm_mtouio(&info, uiop, retlen) != 0) + goto nfsmout; m_freem(info.nmi_mrep); tsiz -= retlen; if (info.nmi_v3) { @@ -1181,13 +1277,13 @@ nfs_writerpc(struct vnode *vp, struct uio *uiop, int *iomode, int *must_commit) { struct nfsm_info info; u_int32_t *tl; - int32_t t1, backup; - caddr_t cp2; + int32_t backup; struct nfsmount *nmp = VFSTONFS(vp->v_mount); int error = 0, len, tsiz, wccflag = NFSV3_WCCRATTR, rlen, commit; int committed = NFSV3WRITE_FILESYNC; info.nmi_v3 = NFS_ISV3(vp); + info.nmi_errorp = &error; #ifdef DIAGNOSTIC if (uiop->uio_iovcnt != 1) @@ -1230,7 +1326,8 @@ nfs_writerpc(struct vnode *vp, struct uio *uiop, int *iomode, int *must_commit) error = nfs_request(vp, NFSPROC_WRITE, &info); if (info.nmi_v3) { wccflag = NFSV3_WCCCHK; - nfsm_wcc_data(vp, wccflag); + if (nfsm_wcc_data(&info, &vp, &wccflag) != 0) + goto nfsmout; } if (error) { @@ -1240,8 +1337,10 @@ nfs_writerpc(struct vnode *vp, struct uio *uiop, int *iomode, int *must_commit) if (info.nmi_v3) { wccflag = NFSV3_WCCCHK; - nfsm_dissect(tl, u_int32_t *, 2 * NFSX_UNSIGNED - + NFSX_V3WRITEVERF); + tl = (uint32_t *)nfsm_dissect(&info, + 2 * NFSX_UNSIGNED + NFSX_V3WRITEVERF); + if (tl == NULL) + goto nfsmout; rlen = fxdr_unsigned(int, *tl++); if (rlen <= 0) { error = NFSERR_IO; @@ -1278,7 +1377,8 @@ nfs_writerpc(struct vnode *vp, struct uio *uiop, int *iomode, int *must_commit) NFSX_V3WRITEVERF); } } else { - nfsm_loadattr(vp, NULL); + if (nfsm_loadattr(&info, &vp, NULL) != 0) + goto nfsmout; } if (wccflag) VTONFS(vp)->n_mtime = VTONFS(vp)->n_vattr.va_mtime; @@ -1292,6 +1392,56 @@ nfsmout: return (error); } +static inline int +nfsm_mtofh(struct nfsm_info *infop, struct vnode *dvp, struct vnode **vpp, + int *flagp) +{ + struct nfsnode *ttnp; + nfsfh_t *ttfhp; + int ttfhsize; + uint32_t *tl; + int error; + int flag; + + if (infop->nmi_v3) { + tl = (uint32_t *)nfsm_dissect(infop, NFSX_UNSIGNED); + if (tl == NULL) + return 1; + flag = fxdr_unsigned(int, *tl); + } else + flag = 1; + if (flag) { + if ((ttfhp = nfsm_getfh(infop, &ttfhsize, infop->nmi_v3)) == + NULL) { + return 1; + } + error = nfs_nget(dvp->v_mount, ttfhp, ttfhsize, &ttnp); + if (error != 0) { + m_freem(infop->nmi_mrep); + *infop->nmi_errorp = error; + return error; + } + *vpp = NFSTOV(ttnp); + } + if (infop->nmi_v3) { + tl = (uint32_t *)nfsm_dissect(infop, NFSX_UNSIGNED); + if (tl == NULL) + return 1; + if (flag) + flag = fxdr_unsigned(int, *tl); + else if (fxdr_unsigned(int, *tl)) { + if (nfsm_adv(infop, NFSX_V3FATTR) != 0) + return 1; + } + } + if (flag) { + if (nfsm_loadattr(infop, vpp, NULL) != 0) + return 1; + } + *flagp = flag; + return 0; +} + /* * nfs mknod rpc * For NFS v2 this is a kludge. Use a create rpc but with the IFMT bits of the @@ -1304,14 +1454,13 @@ nfs_mknodrpc(struct vnode *dvp, struct vnode **vpp, struct componentname *cnp, struct nfsv2_sattr *sp; struct nfsm_info info; u_int32_t *tl; - int32_t t1; struct vnode *newvp = NULL; struct nfsnode *np = NULL; - char *cp2; int error = 0, wccflag = NFSV3_WCCRATTR, gotvp = 0; u_int32_t rdev; info.nmi_v3 = NFS_ISV3(dvp); + info.nmi_errorp = &error; if (vap->va_type == VCHR || vap->va_type == VBLK) rdev = txdr_unsigned(vap->va_rdev); @@ -1326,7 +1475,9 @@ nfs_mknodrpc(struct vnode *dvp, struct vnode **vpp, struct componentname *cnp, 4 * NFSX_UNSIGNED + nfsm_rndup(cnp->cn_namelen) + NFSX_SATTR(info.nmi_v3)); nfsm_fhtom(&info, dvp, info.nmi_v3); - nfsm_strtom(cnp->cn_nameptr, cnp->cn_namelen, NFS_MAXNAMLEN); + if (nfsm_strtom(&info, cnp->cn_nameptr, cnp->cn_namelen, + NFS_MAXNAMLEN) != 0) + goto nfsmout; if (info.nmi_v3) { tl = nfsm_build(&info.nmi_mb, NFSX_UNSIGNED); @@ -1352,7 +1503,8 @@ nfs_mknodrpc(struct vnode *dvp, struct vnode **vpp, struct componentname *cnp, info.nmi_cred = cnp->cn_cred; error = nfs_request(dvp, NFSPROC_MKNOD, &info); if (!error) { - nfsm_mtofh(dvp, newvp, info.nmi_v3, gotvp); + if (nfsm_mtofh(&info, dvp, &newvp, &gotvp) != 0) + goto nfsmout; if (!gotvp) { error = nfs_lookitup(dvp, cnp->cn_nameptr, cnp->cn_namelen, cnp->cn_cred, cnp->cn_proc, &np); @@ -1360,8 +1512,10 @@ nfs_mknodrpc(struct vnode *dvp, struct vnode **vpp, struct componentname *cnp, newvp = NFSTOV(np); } } - if (info.nmi_v3) - nfsm_wcc_data(dvp, wccflag); + if (info.nmi_v3) { + if (nfsm_wcc_data(&info, &dvp, &wccflag) != 0) + goto nfsmout; + } m_freem(info.nmi_mrep); nfsmout: @@ -1411,13 +1565,12 @@ nfs_create(void *v) struct nfsm_info info; struct timespec ts; u_int32_t *tl; - int32_t t1; struct nfsnode *np = NULL; struct vnode *newvp = NULL; - caddr_t cp2; int error = 0, wccflag = NFSV3_WCCRATTR, gotvp = 0, fmode = 0; info.nmi_v3 = NFS_ISV3(dvp); + info.nmi_errorp = &error; /* * Oops, not for me.. @@ -1434,7 +1587,9 @@ again: 2 * NFSX_UNSIGNED + nfsm_rndup(cnp->cn_namelen) + NFSX_SATTR(info.nmi_v3)); nfsm_fhtom(&info, dvp, info.nmi_v3); - nfsm_strtom(cnp->cn_nameptr, cnp->cn_namelen, NFS_MAXNAMLEN); + if (nfsm_strtom(&info, cnp->cn_nameptr, cnp->cn_namelen, + NFS_MAXNAMLEN) != 0) + goto nfsmout; if (info.nmi_v3) { tl = nfsm_build(&info.nmi_mb, NFSX_UNSIGNED); if (fmode & O_EXCL) { @@ -1460,7 +1615,8 @@ again: info.nmi_cred = cnp->cn_cred; error = nfs_request(dvp, NFSPROC_CREATE, &info); if (!error) { - nfsm_mtofh(dvp, newvp, info.nmi_v3, gotvp); + if (nfsm_mtofh(&info, dvp, &newvp, &gotvp) != 0) + goto nfsmout; if (!gotvp) { error = nfs_lookitup(dvp, cnp->cn_nameptr, cnp->cn_namelen, cnp->cn_cred, cnp->cn_proc, &np); @@ -1468,8 +1624,10 @@ again: newvp = NFSTOV(np); } } - if (info.nmi_v3) - nfsm_wcc_data(dvp, wccflag); + if (info.nmi_v3) { + if (nfsm_wcc_data(&info, &dvp, &wccflag) != 0) + goto nfsmout; + } m_freem(info.nmi_mrep); nfsmout: @@ -1603,24 +1761,25 @@ nfs_removerpc(struct vnode *dvp, char *name, int namelen, struct ucred *cred, struct proc *proc) { struct nfsm_info info; - u_int32_t *tl; - int32_t t1; - caddr_t cp2; int error = 0, wccflag = NFSV3_WCCRATTR; info.nmi_v3 = NFS_ISV3(dvp); + info.nmi_errorp = &error; nfsstats.rpccnt[NFSPROC_REMOVE]++; info.nmi_mb = info.nmi_mreq = nfsm_reqhead(NFSX_FH(info.nmi_v3) + NFSX_UNSIGNED + nfsm_rndup(namelen)); nfsm_fhtom(&info, dvp, info.nmi_v3); - nfsm_strtom(name, namelen, NFS_MAXNAMLEN); + if (nfsm_strtom(&info, name, namelen, NFS_MAXNAMLEN) != 0) + goto nfsmout; info.nmi_procp = proc; info.nmi_cred = cred; error = nfs_request(dvp, NFSPROC_REMOVE, &info); - if (info.nmi_v3) - nfsm_wcc_data(dvp, wccflag); + if (info.nmi_v3) { + if (nfsm_wcc_data(&info, &dvp, &wccflag) != 0) + goto nfsmout; + } m_freem(info.nmi_mrep); nfsmout: @@ -1717,27 +1876,29 @@ nfs_renamerpc(struct vnode *fdvp, char *fnameptr, int fnamelen, struct proc *proc) { struct nfsm_info info; - u_int32_t *tl; - int32_t t1; - caddr_t cp2; int error = 0, fwccflag = NFSV3_WCCRATTR, twccflag = NFSV3_WCCRATTR; info.nmi_v3 = NFS_ISV3(fdvp); + info.nmi_errorp = &error; nfsstats.rpccnt[NFSPROC_RENAME]++; info.nmi_mb = info.nmi_mreq = nfsm_reqhead((NFSX_FH(info.nmi_v3) + NFSX_UNSIGNED) * 2 + nfsm_rndup(fnamelen) + nfsm_rndup(tnamelen)); nfsm_fhtom(&info, fdvp, info.nmi_v3); - nfsm_strtom(fnameptr, fnamelen, NFS_MAXNAMLEN); + if (nfsm_strtom(&info, fnameptr, fnamelen, NFS_MAXNAMLEN) != 0) + goto nfsmout; nfsm_fhtom(&info, tdvp, info.nmi_v3); - nfsm_strtom(tnameptr, tnamelen, NFS_MAXNAMLEN); + if (nfsm_strtom(&info, tnameptr, tnamelen, NFS_MAXNAMLEN) != 0) + goto nfsmout; info.nmi_procp = proc; info.nmi_cred = cred; error = nfs_request(fdvp, NFSPROC_RENAME, &info); if (info.nmi_v3) { - nfsm_wcc_data(fdvp, fwccflag); - nfsm_wcc_data(tdvp, twccflag); + if (nfsm_wcc_data(&info, &fdvp, &fwccflag) != 0) + goto nfsmout; + if (nfsm_wcc_data(&info, &tdvp, &twccflag) != 0) + goto nfsmout; } m_freem(info.nmi_mrep); @@ -1762,12 +1923,10 @@ nfs_link(void *v) struct vnode *dvp = ap->a_dvp; struct componentname *cnp = ap->a_cnp; struct nfsm_info info; - u_int32_t *tl; - int32_t t1; - caddr_t cp2; int error = 0, wccflag = NFSV3_WCCRATTR, attrflag = 0; info.nmi_v3 = NFS_ISV3(vp); + info.nmi_errorp = &error; error = vn_lock(vp, LK_EXCLUSIVE); if (error != 0) { @@ -1788,14 +1947,18 @@ nfs_link(void *v) NFSX_UNSIGNED + nfsm_rndup(cnp->cn_namelen)); nfsm_fhtom(&info, vp, info.nmi_v3); nfsm_fhtom(&info, dvp, info.nmi_v3); - nfsm_strtom(cnp->cn_nameptr, cnp->cn_namelen, NFS_MAXNAMLEN); + if (nfsm_strtom(&info, cnp->cn_nameptr, cnp->cn_namelen, + NFS_MAXNAMLEN) != 0) + goto nfsmout; info.nmi_procp = cnp->cn_proc; info.nmi_cred = cnp->cn_cred; error = nfs_request(vp, NFSPROC_LINK, &info); if (info.nmi_v3) { - nfsm_postop_attr(vp, attrflag); - nfsm_wcc_data(dvp, wccflag); + if (nfsm_postop_attr(&info, &vp, &attrflag) != 0) + goto nfsmout; + if (nfsm_wcc_data(&info, &dvp, &wccflag) != 0) + goto nfsmout; } m_freem(info.nmi_mrep); nfsmout: @@ -1825,13 +1988,11 @@ nfs_symlink(void *v) struct componentname *cnp = ap->a_cnp; struct nfsv2_sattr *sp; struct nfsm_info info; - u_int32_t *tl; - int32_t t1; - caddr_t cp2; int slen, error = 0, wccflag = NFSV3_WCCRATTR, gotvp; struct vnode *newvp = NULL; info.nmi_v3 = NFS_ISV3(dvp); + info.nmi_errorp = &error; nfsstats.rpccnt[NFSPROC_SYMLINK]++; slen = strlen(ap->a_target); @@ -1839,10 +2000,13 @@ nfs_symlink(void *v) 2 * NFSX_UNSIGNED + nfsm_rndup(cnp->cn_namelen) + nfsm_rndup(slen) + NFSX_SATTR(info.nmi_v3)); nfsm_fhtom(&info, dvp, info.nmi_v3); - nfsm_strtom(cnp->cn_nameptr, cnp->cn_namelen, NFS_MAXNAMLEN); + if (nfsm_strtom(&info, cnp->cn_nameptr, cnp->cn_namelen, + NFS_MAXNAMLEN) != 0) + goto nfsmout; if (info.nmi_v3) nfsm_v3attrbuild(&info.nmi_mb, vap, 0); - nfsm_strtom(ap->a_target, slen, NFS_MAXPATHLEN); + if (nfsm_strtom(&info, ap->a_target, slen, NFS_MAXPATHLEN) != 0) + goto nfsmout; if (!info.nmi_v3) { sp = nfsm_build(&info.nmi_mb, NFSX_V2SATTR); sp->sa_mode = vtonfsv2_mode(VLNK, vap->va_mode); @@ -1857,9 +2021,12 @@ nfs_symlink(void *v) info.nmi_cred = cnp->cn_cred; error = nfs_request(dvp, NFSPROC_SYMLINK, &info); if (info.nmi_v3) { - if (!error) - nfsm_mtofh(dvp, newvp, info.nmi_v3, gotvp); - nfsm_wcc_data(dvp, wccflag); + if (!error) { + if (nfsm_mtofh(&info, dvp, &newvp, &gotvp) != 0) + goto nfsmout; + } + if (nfsm_wcc_data(&info, &dvp, &wccflag) != 0) + goto nfsmout; } m_freem(info.nmi_mrep); @@ -1887,23 +2054,22 @@ nfs_mkdir(void *v) struct componentname *cnp = ap->a_cnp; struct nfsv2_sattr *sp; struct nfsm_info info; - u_int32_t *tl; - int32_t t1; int len; struct nfsnode *np = NULL; struct vnode *newvp = NULL; - caddr_t cp2; int error = 0, wccflag = NFSV3_WCCRATTR; int gotvp = 0; info.nmi_v3 = NFS_ISV3(dvp); + info.nmi_errorp = &error; len = cnp->cn_namelen; nfsstats.rpccnt[NFSPROC_MKDIR]++; info.nmi_mb = info.nmi_mreq = nfsm_reqhead(NFSX_FH(info.nmi_v3) + NFSX_UNSIGNED + nfsm_rndup(len) + NFSX_SATTR(info.nmi_v3)); nfsm_fhtom(&info, dvp, info.nmi_v3); - nfsm_strtom(cnp->cn_nameptr, len, NFS_MAXNAMLEN); + if (nfsm_strtom(&info, cnp->cn_nameptr, len, NFS_MAXNAMLEN) != 0) + goto nfsmout; if (info.nmi_v3) { nfsm_v3attrbuild(&info.nmi_mb, vap, 0); @@ -1920,10 +2086,14 @@ nfs_mkdir(void *v) info.nmi_procp = cnp->cn_proc; info.nmi_cred = cnp->cn_cred; error = nfs_request(dvp, NFSPROC_MKDIR, &info); - if (!error) - nfsm_mtofh(dvp, newvp, info.nmi_v3, gotvp); - if (info.nmi_v3) - nfsm_wcc_data(dvp, wccflag); + if (!error) { + if (nfsm_mtofh(&info, dvp, &newvp, &gotvp) != 0) + goto nfsmout; + } + if (info.nmi_v3) { + if (nfsm_wcc_data(&info, &dvp, &wccflag) != 0) + goto nfsmout; + } m_freem(info.nmi_mrep); nfsmout: @@ -1965,24 +2135,26 @@ nfs_rmdir(void *v) struct vnode *dvp = ap->a_dvp; struct componentname *cnp = ap->a_cnp; struct nfsm_info info; - u_int32_t *tl; - int32_t t1; - caddr_t cp2; int error = 0, wccflag = NFSV3_WCCRATTR; info.nmi_v3 = NFS_ISV3(dvp); + info.nmi_errorp = &error; nfsstats.rpccnt[NFSPROC_RMDIR]++; info.nmi_mb = info.nmi_mreq = nfsm_reqhead(NFSX_FH(info.nmi_v3) + NFSX_UNSIGNED + nfsm_rndup(cnp->cn_namelen)); nfsm_fhtom(&info, dvp, info.nmi_v3); - nfsm_strtom(cnp->cn_nameptr, cnp->cn_namelen, NFS_MAXNAMLEN); + if (nfsm_strtom(&info, cnp->cn_nameptr, cnp->cn_namelen, + NFS_MAXNAMLEN) != 0) + goto nfsmout; info.nmi_procp = cnp->cn_proc; info.nmi_cred = cnp->cn_cred; error = nfs_request(dvp, NFSPROC_RMDIR, &info); - if (info.nmi_v3) - nfsm_wcc_data(dvp, wccflag); + if (info.nmi_v3) { + if (nfsm_wcc_data(&info, &dvp, &wccflag) != 0) + goto nfsmout; + } m_freem(info.nmi_mrep); nfsmout: @@ -2159,8 +2331,6 @@ nfs_readdirrpc(struct vnode *vp, struct uio *uiop, struct ucred *cred, struct nfsm_info info; u_int32_t *tl; caddr_t cp; - int32_t t1; - caddr_t cp2; nfsuint64 cookie; struct nfsmount *nmp = VFSTONFS(vp->v_mount); struct nfsnode *dnp = VTONFS(vp); @@ -2169,6 +2339,7 @@ nfs_readdirrpc(struct vnode *vp, struct uio *uiop, struct ucred *cred, int attrflag; info.nmi_v3 = NFS_ISV3(vp); + info.nmi_errorp = &error; #ifdef DIAGNOSTIC if (uiop->uio_iovcnt != 1 || @@ -2209,8 +2380,10 @@ nfs_readdirrpc(struct vnode *vp, struct uio *uiop, struct ucred *cred, info.nmi_procp = uiop->uio_procp; info.nmi_cred = cred; error = nfs_request(vp, NFSPROC_READDIR, &info); - if (info.nmi_v3) - nfsm_postop_attr(vp, attrflag); + if (info.nmi_v3) { + if (nfsm_postop_attr(&info, &vp, &attrflag) != 0) + goto nfsmout; + } if (error) { m_freem(info.nmi_mrep); @@ -2218,25 +2391,32 @@ nfs_readdirrpc(struct vnode *vp, struct uio *uiop, struct ucred *cred, } if (info.nmi_v3) { - nfsm_dissect(tl, u_int32_t *, - 2 * NFSX_UNSIGNED); + tl = (uint32_t *)nfsm_dissect(&info, 2 * NFSX_UNSIGNED); + if (tl == NULL) + goto nfsmout; dnp->n_cookieverf.nfsuquad[0] = *tl++; dnp->n_cookieverf.nfsuquad[1] = *tl; } - nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED); + tl = (uint32_t *)nfsm_dissect(&info, NFSX_UNSIGNED); + if (tl == NULL) + goto nfsmout; more_dirs = fxdr_unsigned(int, *tl); /* loop thru the dir entries, doctoring them to dirent form */ while (more_dirs && bigenough) { if (info.nmi_v3) { - nfsm_dissect(tl, u_int32_t *, + tl = (uint32_t *)nfsm_dissect(&info, 3 * NFSX_UNSIGNED); + if (tl == NULL) + goto nfsmout; fileno = fxdr_hyper(tl); len = fxdr_unsigned(int, *(tl + 2)); } else { - nfsm_dissect(tl, u_int32_t *, + tl = (uint32_t *)nfsm_dissect(&info, 2 * NFSX_UNSIGNED); + if (tl == NULL) + goto nfsmout; fileno = fxdr_unsigned(u_quad_t, *tl++); len = fxdr_unsigned(int, *tl); } @@ -2272,22 +2452,27 @@ nfs_readdirrpc(struct vnode *vp, struct uio *uiop, struct ucred *cred, (char *)uiop->uio_iov->iov_base + NFS_DIRHDSIZ; uiop->uio_iov->iov_len -= NFS_DIRHDSIZ; - nfsm_mtouio(uiop, len); + if (nfsm_mtouio(&info, uiop, len) != 0) + goto nfsmout; cp = uiop->uio_iov->iov_base; tlen -= NFS_DIRHDSIZ + len; *cp = '\0'; /* null terminate */ uiop->uio_iov->iov_base += tlen; uiop->uio_iov->iov_len -= tlen; uiop->uio_resid -= tlen; - } else - nfsm_adv(nfsm_rndup(len)); + } else { + if (nfsm_adv(&info, nfsm_rndup(len)) != 0) + goto nfsmout; + } if (info.nmi_v3) { - nfsm_dissect(tl, u_int32_t *, + tl = (uint32_t *)nfsm_dissect(&info, 3 * NFSX_UNSIGNED); } else { - nfsm_dissect(tl, u_int32_t *, + tl = (uint32_t *)nfsm_dissect(&info, 2 * NFSX_UNSIGNED); } + if (tl == NULL) + goto nfsmout; if (bigenough) { if (info.nmi_v3) { ndp->cookie[0] = cookie.nfsuquad[0] = @@ -2306,7 +2491,9 @@ nfs_readdirrpc(struct vnode *vp, struct uio *uiop, struct ucred *cred, * If at end of rpc data, get the eof boolean */ if (!more_dirs) { - nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED); + tl = (uint32_t *)nfsm_dissect(&info, NFSX_UNSIGNED); + if (tl == NULL) + goto nfsmout; more_dirs = (fxdr_unsigned(int, *tl) == 0); } m_freem(info.nmi_mrep); @@ -2353,9 +2540,8 @@ nfs_readdirplusrpc(struct vnode *vp, struct uio *uiop, struct ucred *cred, struct nfsm_info info; u_int32_t *tl; caddr_t cp; - int32_t t1; struct vnode *newvp; - caddr_t cp2, dpossav1, dpossav2; + caddr_t dpossav1, dpossav2; struct mbuf *mdsav1, *mdsav2; struct nameidata nami, *ndp = &nami; struct componentname *cnp = &ndp->ni_cnd; @@ -2403,21 +2589,27 @@ nfs_readdirplusrpc(struct vnode *vp, struct uio *uiop, struct ucred *cred, info.nmi_procp = uiop->uio_procp; info.nmi_cred = cred; + info.nmi_errorp = &error; error = nfs_request(vp, NFSPROC_READDIRPLUS, &info); - nfsm_postop_attr(vp, attrflag); + if (nfsm_postop_attr(&info, &vp, &attrflag) != 0) + goto nfsmout; if (error) { m_freem(info.nmi_mrep); goto nfsmout; } - nfsm_dissect(tl, u_int32_t *, 3 * NFSX_UNSIGNED); + tl = (uint32_t *)nfsm_dissect(&info, 3 * NFSX_UNSIGNED); + if (tl == NULL) + goto nfsmout; dnp->n_cookieverf.nfsuquad[0] = *tl++; dnp->n_cookieverf.nfsuquad[1] = *tl++; more_dirs = fxdr_unsigned(int, *tl); /* loop thru the dir entries, doctoring them to 4bsd form */ while (more_dirs && bigenough) { - nfsm_dissect(tl, u_int32_t *, 3 * NFSX_UNSIGNED); + tl = (uint32_t *)nfsm_dissect(&info, 3 * NFSX_UNSIGNED); + if (tl == NULL) + goto nfsmout; fileno = fxdr_hyper(tl); len = fxdr_unsigned(int, *(tl + 2)); if (len <= 0 || len > NFS_MAXNAMLEN) { @@ -2455,16 +2647,21 @@ nfs_readdirplusrpc(struct vnode *vp, struct uio *uiop, struct ucred *cred, uiop->uio_iov->iov_len -= NFS_DIRHDSIZ; cnp->cn_nameptr = uiop->uio_iov->iov_base; cnp->cn_namelen = len; - nfsm_mtouio(uiop, len); + if (nfsm_mtouio(&info, uiop, len) != 0) + goto nfsmout; cp = uiop->uio_iov->iov_base; tlen -= NFS_DIRHDSIZ + len; *cp = '\0'; uiop->uio_iov->iov_base += tlen; uiop->uio_iov->iov_len -= tlen; uiop->uio_resid -= tlen; - } else - nfsm_adv(nfsm_rndup(len)); - nfsm_dissect(tl, u_int32_t *, 3 * NFSX_UNSIGNED); + } else { + if (nfsm_adv(&info, nfsm_rndup(len)) != 0) + goto nfsmout; + } + tl = (uint32_t *)nfsm_dissect(&info, 3 * NFSX_UNSIGNED); + if (tl == NULL) + goto nfsmout; if (bigenough) { ndirp->cookie[0] = cookie.nfsuquad[0] = *tl++; ndirp->cookie[1] = cookie.nfsuquad[1] = *tl++; @@ -2480,11 +2677,18 @@ nfs_readdirplusrpc(struct vnode *vp, struct uio *uiop, struct ucred *cred, if (attrflag) { dpossav1 = info.nmi_dpos; mdsav1 = info.nmi_md; - nfsm_adv(NFSX_V3FATTR); - nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED); + if (nfsm_adv(&info, NFSX_V3FATTR) != 0) + goto nfsmout; + tl = (uint32_t *) + nfsm_dissect(&info, NFSX_UNSIGNED); + if (tl == NULL) + goto nfsmout; doit = fxdr_unsigned(int, *tl); if (doit) { - nfsm_getfh(fhp, fhsize, 1); + if ((fhp = + nfsm_getfh(&info, &fhsize, 1)) == + NULL) + goto nfsmout; if (NFS_CMPFH(dnp, fhp, fhsize)) { vref(vp); newvp = vp; @@ -2503,7 +2707,9 @@ nfs_readdirplusrpc(struct vnode *vp, struct uio *uiop, struct ucred *cred, info.nmi_dpos = dpossav1; mdsav2 = info.nmi_md; info.nmi_md = mdsav1; - nfsm_loadattr(newvp, NULL); + if (nfsm_loadattr(&info, &newvp, + NULL) != 0) + goto nfsmout; info.nmi_dpos = dpossav2; info.nmi_md = mdsav2; dp->d_type = IFTODT( @@ -2518,10 +2724,15 @@ nfs_readdirplusrpc(struct vnode *vp, struct uio *uiop, struct ucred *cred, } } else { /* Just skip over the file handle */ - nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED); + tl = (uint32_t *) + nfsm_dissect(&info, NFSX_UNSIGNED); + if (tl == NULL) + goto nfsmout; i = fxdr_unsigned(int, *tl); - if (i > 0) - nfsm_adv(nfsm_rndup(i)); + if (i > 0) { + if (nfsm_adv(&info, nfsm_rndup(i)) != 0) + goto nfsmout; + } } if (newvp != NULLVP) { if (newvp == vp) @@ -2530,14 +2741,18 @@ nfs_readdirplusrpc(struct vnode *vp, struct uio *uiop, struct ucred *cred, vput(newvp); newvp = NULLVP; } - nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED); + tl = (uint32_t *)nfsm_dissect(&info, NFSX_UNSIGNED); + if (tl == NULL) + goto nfsmout; more_dirs = fxdr_unsigned(int, *tl); } /* * If at end of rpc data, get the eof boolean */ if (!more_dirs) { - nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED); + tl = (uint32_t *)nfsm_dissect(&info, NFSX_UNSIGNED); + if (tl == NULL) + goto nfsmout; more_dirs = (fxdr_unsigned(int, *tl) == 0); } m_freem(info.nmi_mrep); @@ -2650,21 +2865,20 @@ nfs_lookitup(struct vnode *dvp, char *name, int len, struct ucred *cred, struct proc *procp, struct nfsnode **npp) { struct nfsm_info info; - u_int32_t *tl; - int32_t t1; struct vnode *newvp = NULL; struct nfsnode *np, *dnp = VTONFS(dvp); - caddr_t cp2; int error = 0, fhlen, attrflag = 0; nfsfh_t *nfhp; info.nmi_v3 = NFS_ISV3(dvp); + info.nmi_errorp = &error; nfsstats.rpccnt[NFSPROC_LOOKUP]++; info.nmi_mb = info.nmi_mreq = nfsm_reqhead(NFSX_FH(info.nmi_v3) + NFSX_UNSIGNED + nfsm_rndup(len)); nfsm_fhtom(&info, dvp, info.nmi_v3); - nfsm_strtom(name, len, NFS_MAXNAMLEN); + if (nfsm_strtom(&info, name, len, NFS_MAXNAMLEN) != 0) + goto nfsmout; info.nmi_procp = procp; info.nmi_cred = cred; @@ -2675,7 +2889,8 @@ nfs_lookitup(struct vnode *dvp, char *name, int len, struct ucred *cred, } if (npp && !error) { - nfsm_getfh(nfhp, fhlen, info.nmi_v3); + if ((nfhp = nfsm_getfh(&info, &fhlen, info.nmi_v3)) == NULL) + goto nfsmout; if (*npp) { np = *npp; np->n_fhp = &np->n_fh; @@ -2695,7 +2910,8 @@ nfs_lookitup(struct vnode *dvp, char *name, int len, struct ucred *cred, newvp = NFSTOV(np); } if (info.nmi_v3) { - nfsm_postop_attr(newvp, attrflag); + if (nfsm_postop_attr(&info, &newvp, &attrflag) != 0) + goto nfsmout; if (!attrflag && *npp == NULL) { m_freem(info.nmi_mrep); if (newvp == dvp) @@ -2704,8 +2920,10 @@ nfs_lookitup(struct vnode *dvp, char *name, int len, struct ucred *cred, vput(newvp); return (ENOENT); } - } else - nfsm_loadattr(newvp, NULL); + } else { + if (nfsm_loadattr(&info, &newvp, NULL) != 0) + goto nfsmout; + } } m_freem(info.nmi_mrep); nfsmout: @@ -2729,9 +2947,7 @@ nfs_commit(struct vnode *vp, u_quad_t offset, int cnt, struct proc *procp) { struct nfsm_info info; u_int32_t *tl; - int32_t t1; struct nfsmount *nmp = VFSTONFS(vp->v_mount); - caddr_t cp2; int error = 0, wccflag = NFSV3_WCCRATTR; if ((nmp->nm_flag & NFSMNT_HASWRITEVERF) == 0) @@ -2739,6 +2955,7 @@ nfs_commit(struct vnode *vp, u_quad_t offset, int cnt, struct proc *procp) nfsstats.rpccnt[NFSPROC_COMMIT]++; info.nmi_mb = info.nmi_mreq = nfsm_reqhead(NFSX_FH(1)); nfsm_fhtom(&info, vp, 1); + info.nmi_errorp = &error; tl = nfsm_build(&info.nmi_mb, 3 * NFSX_UNSIGNED); txdr_hyper(offset, tl); @@ -2748,10 +2965,13 @@ nfs_commit(struct vnode *vp, u_quad_t offset, int cnt, struct proc *procp) info.nmi_procp = procp; info.nmi_cred = VTONFS(vp)->n_wcred; error = nfs_request(vp, NFSPROC_COMMIT, &info); - nfsm_wcc_data(vp, wccflag); + if (nfsm_wcc_data(&info, &vp, &wccflag) != 0) + goto nfsmout; if (!error) { - nfsm_dissect(tl, u_int32_t *, NFSX_V3WRITEVERF); + tl = (uint32_t *)nfsm_dissect(&info, NFSX_V3WRITEVERF); + if (tl == NULL) + goto nfsmout; if (bcmp(nmp->nm_verf, tl, NFSX_V3WRITEVERF)) { bcopy(tl, nmp->nm_verf, diff --git a/sys/nfs/nfsm_subs.h b/sys/nfs/nfsm_subs.h index c34c4698d..86413d527 100644 --- a/sys/nfs/nfsm_subs.h +++ b/sys/nfs/nfsm_subs.h @@ -1,4 +1,4 @@ -/* $OpenBSD: nfsm_subs.h,v 1.47 2019/01/18 13:59:18 bluhm Exp $ */ +/* $OpenBSD: nfsm_subs.h,v 1.48 2024/04/30 17:04:23 miod Exp $ */ /* $NetBSD: nfsm_subs.h,v 1.10 1996/03/20 21:59:56 fvdl Exp $ */ /* @@ -40,217 +40,140 @@ #define _NFS_NFSM_SUBS_H_ struct nfsm_info { - struct mbuf *nmi_mreq; - struct mbuf *nmi_mrep; + struct mbuf *nmi_mreq; + struct mbuf *nmi_mrep; - struct proc *nmi_procp; /* XXX XXX XXX */ - struct ucred *nmi_cred; /* XXX XXX XXX */ + struct proc *nmi_procp; /* XXX XXX XXX */ + struct ucred *nmi_cred; /* XXX XXX XXX */ /* Setting up / Tearing down. */ - struct mbuf *nmi_md; - struct mbuf *nmi_mb; - caddr_t nmi_dpos; + struct mbuf *nmi_md; + struct mbuf *nmi_mb; + caddr_t nmi_dpos; - int nmi_v3; + int nmi_v3; + + int *nmi_errorp; }; -#define nfsm_dissect(a, c, s) { \ - t1 = mtod(info.nmi_md, caddr_t) + info.nmi_md->m_len - \ - info.nmi_dpos; \ - if (t1 >= (s)) { \ - (a) = (c)(info.nmi_dpos); \ - info.nmi_dpos += (s); \ - } else if ((t1 = \ - nfsm_disct(&info.nmi_md, &info.nmi_dpos, (s), t1, \ - &cp2)) != 0) { \ - error = t1; \ - m_freem(info.nmi_mrep); \ - goto nfsmout; \ - } else { \ - (a) = (c)cp2; \ - } \ -} +static inline void * +nfsm_dissect(struct nfsm_info *infop, int s) +{ + caddr_t ret; + int avail, error; -#define nfsm_srvpostop_fh(f) { \ - tl = nfsm_build(&info.nmi_mb, 2 * NFSX_UNSIGNED + NFSX_V3FH); \ - *tl++ = nfs_true; \ - *tl++ = txdr_unsigned(NFSX_V3FH); \ - bcopy((f), tl, NFSX_V3FH); \ -} - -#define nfsm_mtofh(d, v, v3, f) { \ - struct nfsnode *ttnp; nfsfh_t *ttfhp; int ttfhsize; \ - if (v3) { \ - nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED); \ - (f) = fxdr_unsigned(int, *tl); \ - } else \ - (f) = 1; \ - if (f) { \ - nfsm_getfh(ttfhp, ttfhsize, (v3)); \ - if ((t1 = nfs_nget((d)->v_mount, ttfhp, ttfhsize, \ - &ttnp)) != 0) { \ - error = t1; \ - m_freem(info.nmi_mrep); \ - goto nfsmout; \ - } \ - (v) = NFSTOV(ttnp); \ - } \ - if (v3) { \ - nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED); \ - if (f) \ - (f) = fxdr_unsigned(int, *tl); \ - else if (fxdr_unsigned(int, *tl)) \ - nfsm_adv(NFSX_V3FATTR); \ - } \ - if (f) \ - nfsm_loadattr((v), NULL); \ -} - -#define nfsm_getfh(f, s, v3) { \ - if (v3) { \ - nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED); \ - if (((s) = fxdr_unsigned(int, *tl)) <= 0 || \ - (s) > NFSX_V3FHMAX) { \ - m_freem(info.nmi_mrep); \ - error = EBADRPC; \ - goto nfsmout; \ - } \ - } else \ - (s) = NFSX_V2FH; \ - nfsm_dissect((f), nfsfh_t *, nfsm_rndup(s)); \ -} - -#define nfsm_loadattr(v, a) { \ - struct vnode *ttvp = (v); \ - if ((t1 = nfs_loadattrcache(&ttvp, &info.nmi_md, \ - &info.nmi_dpos, (a))) != 0) { \ - error = t1; \ - m_freem(info.nmi_mrep); \ - goto nfsmout; \ - } \ - (v) = ttvp; \ -} - -#define nfsm_postop_attr(v, f) { if (info.nmi_mrep != NULL) { \ - struct vnode *ttvp = (v); \ - nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED); \ - if (((f) = fxdr_unsigned(int, *tl)) != 0) { \ - if ((t1 = nfs_loadattrcache(&ttvp, &info.nmi_md, \ - &info.nmi_dpos, NULL)) != 0) { \ - error = t1; \ - (f) = 0; \ - m_freem(info.nmi_mrep); \ - goto nfsmout; \ - } \ - (v) = ttvp; \ - } \ -} } - -/* Used as (f) for nfsm_wcc_data() */ -#define NFSV3_WCCRATTR 0 -#define NFSV3_WCCCHK 1 - -#define nfsm_wcc_data(v, f) do { if (info.nmi_mrep != NULL) { \ - struct timespec _mtime; \ - int ttattrf, ttretf = 0; \ - \ - nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED); \ - if (*tl == nfs_true) { \ - nfsm_dissect(tl, u_int32_t *, 6 * NFSX_UNSIGNED); \ - fxdr_nfsv3time(tl + 2, &_mtime); \ - if (f) { \ - ttretf = timespeccmp(&VTONFS(v)->n_mtime, \ - &_mtime, !=); \ - } \ - } \ - nfsm_postop_attr((v), ttattrf); \ - if (f) { \ - (f) = ttretf; \ - } else { \ - (f) = ttattrf; \ - } \ -} } while (0) - -#define nfsm_strsiz(s, m) { \ - nfsm_dissect(tl, u_int32_t *,NFSX_UNSIGNED); \ - if (((s) = fxdr_unsigned(int32_t, *tl)) < 0 || (s) > (m)) { \ - m_freem(info.nmi_mrep); \ - error = EBADRPC; \ - goto nfsmout; \ - } \ -} - -#define nfsm_srvnamesiz(s) { \ - nfsm_dissect(tl, u_int32_t *,NFSX_UNSIGNED); \ - if (((s) = fxdr_unsigned(int32_t, *tl)) > NFS_MAXNAMLEN) \ - error = NFSERR_NAMETOL; \ - if ((s) <= 0) \ - error = EBADRPC; \ - if (error) \ - nfsm_reply(0); \ -} - -#define nfsm_mtouio(p, s) \ - if ((s) > 0 && \ - (t1 = nfsm_mbuftouio(&info.nmi_md, (p), (s), \ - &info.nmi_dpos)) != 0) { \ - error = t1; \ - m_freem(info.nmi_mrep); \ - goto nfsmout; \ + avail = mtod(infop->nmi_md, caddr_t) + infop->nmi_md->m_len - + infop->nmi_dpos; + if (avail >= s) { + ret = infop->nmi_dpos; + infop->nmi_dpos += s; + return ret; } + error = nfsm_disct(&infop->nmi_md, &infop->nmi_dpos, s, avail, &ret); + if (error != 0) { + m_freem(infop->nmi_mrep); + *infop->nmi_errorp = error; + return NULL; + } else { + return ret; + } +} #define nfsm_rndup(a) (((a)+3)&(~0x3)) -#define nfsm_strtom(a, s, m) \ - if ((s) > (m)) { \ - m_freem(info.nmi_mreq); \ - error = ENAMETOOLONG; \ - goto nfsmout; \ - } \ - nfsm_strtombuf(&info.nmi_mb, (a), (s)) - -#define nfsm_reply(s) { \ - nfsd->nd_repstat = error; \ - if (error && !(nfsd->nd_flag & ND_NFSV3)) \ - (void) nfs_rephead(0, nfsd, slp, error, \ - &info.nmi_mreq, &info.nmi_mb); \ - else \ - (void) nfs_rephead((s), nfsd, slp, error, \ - &info.nmi_mreq, &info.nmi_mb); \ - if (info.nmi_mrep != NULL) { \ - m_freem(info.nmi_mrep); \ - info.nmi_mrep = NULL; \ - } \ - *mrq = info.nmi_mreq; \ - if (error && (!(nfsd->nd_flag & ND_NFSV3) || error == EBADRPC)) \ - return(0); \ +static inline int +nfsm_adv(struct nfsm_info *infop, int s) +{ + int avail, error; + + avail = mtod(infop->nmi_md, caddr_t) + infop->nmi_md->m_len - + infop->nmi_dpos; + if (avail >= s) { + infop->nmi_dpos += s; + return 0; + } + error = nfs_adv(&infop->nmi_md, &infop->nmi_dpos, s, avail); + if (error != 0) { + m_freem(infop->nmi_mrep); + *infop->nmi_errorp = error; + return error; + } + return 0; } -#define nfsm_adv(s) { \ - t1 = mtod(info.nmi_md, caddr_t) + info.nmi_md->m_len - \ - info.nmi_dpos; \ - if (t1 >= (s)) { \ - info.nmi_dpos += (s); \ - } else if ((t1 = nfs_adv(&info.nmi_md, &info.nmi_dpos, \ - (s), t1)) != 0) { \ - error = t1; \ - m_freem(info.nmi_mrep); \ - goto nfsmout; \ - } \ +static inline int +nfsm_postop_attr(struct nfsm_info *infop, struct vnode **vpp, int *attrflagp) +{ + uint32_t *tl; + struct vnode *ttvp; + int attrflag, error; + + if (infop->nmi_mrep == NULL) + return 0; + + ttvp = *vpp; + tl = (uint32_t *)nfsm_dissect(infop, NFSX_UNSIGNED); + if (tl == NULL) + return 1; /* anything nonzero */ + attrflag = fxdr_unsigned(int, *tl); + if (attrflag != 0) { + error = nfs_loadattrcache(&ttvp, &infop->nmi_md, + &infop->nmi_dpos, NULL); + if (error != 0) { + m_freem(infop->nmi_mrep); + *infop->nmi_errorp = error; + return error; + } + *vpp = ttvp; + } + *attrflagp = attrflag; + return 0; } -#define nfsm_srvmtofh(f) { \ - if (nfsd->nd_flag & ND_NFSV3) { \ - nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED); \ - if (fxdr_unsigned(int, *tl) != NFSX_V3FH) { \ - error = EBADRPC; \ - nfsm_reply(0); \ - } \ - } \ - nfsm_dissect(tl, u_int32_t *, NFSX_V3FH); \ - bcopy(tl, (f), NFSX_V3FH); \ - if ((nfsd->nd_flag & ND_NFSV3) == 0) \ - nfsm_adv(NFSX_V2FH - NFSX_V3FH); \ +static inline int +nfsm_strsiz(struct nfsm_info *infop, int *lenp, int maxlen) +{ + uint32_t *tl = (uint32_t *)nfsm_dissect(infop, NFSX_UNSIGNED); + int len; + if (tl == NULL) + return 1; + len = fxdr_unsigned(int32_t, *tl); + if (len < 0 || len > maxlen) { + m_freem(infop->nmi_mrep); + *infop->nmi_errorp = EBADRPC; + return 1; + } + *lenp = len; + return 0; +} + +static inline int +nfsm_mtouio(struct nfsm_info *infop, struct uio *uiop, int len) +{ + int error; + + if (len <= 0) + return 0; + + error = nfsm_mbuftouio(&infop->nmi_md, uiop, len, &infop->nmi_dpos); + if (error != 0) { + m_freem(infop->nmi_mrep); + *infop->nmi_errorp = error; + return error; + } + return 0; +} + +static inline int +nfsm_strtom(struct nfsm_info *infop, char *str, size_t len, size_t maxlen) +{ + if (len > maxlen) { + m_freem(infop->nmi_mreq); + *infop->nmi_errorp = ENAMETOOLONG; + return 1; + } + nfsm_strtombuf(&infop->nmi_mb, str, len); + return 0; } #endif diff --git a/sys/nfs/nfsnode.h b/sys/nfs/nfsnode.h index c8a635dfb..26fe4e388 100644 --- a/sys/nfs/nfsnode.h +++ b/sys/nfs/nfsnode.h @@ -1,4 +1,4 @@ -/* $OpenBSD: nfsnode.h,v 1.42 2021/03/11 13:31:35 jsg Exp $ */ +/* $OpenBSD: nfsnode.h,v 1.43 2024/04/30 17:04:23 miod Exp $ */ /* $NetBSD: nfsnode.h,v 1.16 1996/02/18 11:54:04 fvdl Exp $ */ /* @@ -62,12 +62,6 @@ struct sillyrename { * There is a unique nfsnode allocated for each active file, * each current directory, each mounted-on file, text file, and the root. * An nfsnode is 'named' by its file handle. (nget/nfs_node.c) - * If this structure exceeds 256 bytes (it is currently 256 using 4.4BSD-Lite - * type definitions), file handles of > 32 bytes should probably be split out - * into a separate malloc()'d data structure. (Reduce the size of nfsfh_t by - * changing the definition in sys/mount.h of NFS_SMALLFH.) - * NB: Hopefully the current order of the fields is such that everything will - * be well aligned and, therefore, tightly packed. */ struct nfsnode { RB_ENTRY(nfsnode) n_entry; /* filehandle/node tree. */ diff --git a/sys/nfs/nfsproto.h b/sys/nfs/nfsproto.h index 9f0357575..610f6767d 100644 --- a/sys/nfs/nfsproto.h +++ b/sys/nfs/nfsproto.h @@ -1,4 +1,4 @@ -/* $OpenBSD: nfsproto.h,v 1.10 2009/07/08 14:39:31 thib Exp $ */ +/* $OpenBSD: nfsproto.h,v 1.11 2024/04/30 17:06:00 miod Exp $ */ /* $NetBSD: nfsproto.h,v 1.1 1996/02/18 11:54:06 fvdl Exp $ */ /* @@ -220,7 +220,7 @@ txdr_unsigned(((t) == VFIFO) ? MAKEIMODE(VCHR, (m)) : \ MAKEIMODE((t), (m))) #define vtonfsv3_mode(m) txdr_unsigned((m) & 07777) -#define nfstov_mode(a) (fxdr_unsigned(u_int16_t, (a))&07777) +#define nfstov_mode(a) (fxdr_unsigned(mode_t, (a))&07777) #define vtonfsv2_type(a) txdr_unsigned(nfsv2_type[((int32_t)(a))]) #define vtonfsv3_type(a) txdr_unsigned(nfsv3_type[((int32_t)(a))]) #define nfsv2tov_type(a) nv2tov_type[fxdr_unsigned(u_int32_t,(a))&0x7] diff --git a/sys/sys/msg.h b/sys/sys/msg.h index d7ebe4684..f93c27b92 100644 --- a/sys/sys/msg.h +++ b/sys/sys/msg.h @@ -1,4 +1,4 @@ -/* $OpenBSD: msg.h,v 1.20 2022/09/16 15:57:23 mbuhl Exp $ */ +/* $OpenBSD: msg.h,v 1.21 2024/04/30 17:03:05 op Exp $ */ /* $NetBSD: msg.h,v 1.9 1996/02/09 18:25:18 christos Exp $ */ /* @@ -32,13 +32,16 @@ #define MSG_NOERROR 010000 /* don't complain about too long msgs */ +typedef unsigned long msgqnum_t; +typedef unsigned long msglen_t; + struct msqid_ds { struct ipc_perm msg_perm; /* msg queue permission bits */ struct msg *msg_first; /* first message in the queue */ struct msg *msg_last; /* last message in the queue */ - unsigned long msg_cbytes; /* number of bytes in use on the queue */ - unsigned long msg_qnum; /* number of msgs in the queue */ - unsigned long msg_qbytes; /* max # of bytes on the queue */ + msglen_t msg_cbytes; /* number of bytes in use on the queue */ + msgqnum_t msg_qnum; /* number of msgs in the queue */ + msglen_t msg_qbytes; /* max # of bytes on the queue */ pid_t msg_lspid; /* pid of last msgsnd() */ pid_t msg_lrpid; /* pid of last msgrcv() */ time_t msg_stime; /* time of last msgsnd() */ diff --git a/sys/uvm/uvm_page.c b/sys/uvm/uvm_page.c index 5ae624499..9bb4b6d07 100644 --- a/sys/uvm/uvm_page.c +++ b/sys/uvm/uvm_page.c @@ -1,4 +1,4 @@ -/* $OpenBSD: uvm_page.c,v 1.176 2024/04/19 10:22:51 mpi Exp $ */ +/* $OpenBSD: uvm_page.c,v 1.177 2024/05/01 12:54:27 mpi Exp $ */ /* $NetBSD: uvm_page.c,v 1.44 2000/11/27 08:40:04 chs Exp $ */ /* @@ -877,13 +877,11 @@ uvm_pagerealloc_multi(struct uvm_object *obj, voff_t off, vsize_t size, * => only one of obj or anon can be non-null * => caller must activate/deactivate page if it is not wired. */ - struct vm_page * uvm_pagealloc(struct uvm_object *obj, voff_t off, struct vm_anon *anon, int flags) { - struct vm_page *pg; - struct pglist pgl; + struct vm_page *pg = NULL; int pmr_flags; KASSERT(obj == NULL || anon == NULL); @@ -906,13 +904,10 @@ uvm_pagealloc(struct uvm_object *obj, voff_t off, struct vm_anon *anon, if (flags & UVM_PGA_ZERO) pmr_flags |= UVM_PLA_ZERO; - TAILQ_INIT(&pgl); - if (uvm_pmr_getpages(1, 0, 0, 1, 0, 1, pmr_flags, &pgl) != 0) - goto fail; - - pg = TAILQ_FIRST(&pgl); - KASSERT(pg != NULL && TAILQ_NEXT(pg, pageq) == NULL); + pg = uvm_pmr_cache_get(pmr_flags); + if (pg == NULL) + return NULL; uvm_pagealloc_pg(pg, obj, off, anon); KASSERT((pg->pg_flags & PG_DEV) == 0); if (flags & UVM_PGA_ZERO) @@ -921,9 +916,6 @@ uvm_pagealloc(struct uvm_object *obj, voff_t off, struct vm_anon *anon, atomic_setbits_int(&pg->pg_flags, PG_CLEAN); return pg; - -fail: - return NULL; } /* @@ -1025,7 +1017,7 @@ void uvm_pagefree(struct vm_page *pg) { uvm_pageclean(pg); - uvm_pmr_freepages(pg, 1); + uvm_pmr_cache_put(pg); } /* diff --git a/sys/uvm/uvm_pdaemon.c b/sys/uvm/uvm_pdaemon.c index 334ce6bbe..8201e022d 100644 --- a/sys/uvm/uvm_pdaemon.c +++ b/sys/uvm/uvm_pdaemon.c @@ -1,4 +1,4 @@ -/* $OpenBSD: uvm_pdaemon.c,v 1.113 2024/04/19 10:22:51 mpi Exp $ */ +/* $OpenBSD: uvm_pdaemon.c,v 1.114 2024/05/01 12:54:27 mpi Exp $ */ /* $NetBSD: uvm_pdaemon.c,v 1.23 2000/08/20 10:24:14 bjh21 Exp $ */ /* @@ -262,6 +262,8 @@ uvm_pageout(void *arg) #if NDRM > 0 drmbackoff(size * 2); #endif + uvm_pmr_cache_drain(); + /* * scan if needed */ diff --git a/sys/uvm/uvm_percpu.h b/sys/uvm/uvm_percpu.h index e69de29bb..ceb110a8b 100644 --- a/sys/uvm/uvm_percpu.h +++ b/sys/uvm/uvm_percpu.h @@ -0,0 +1,48 @@ +/* $OpenBSD: uvm_percpu.h,v 1.3 2024/05/01 12:54:27 mpi Exp $ */ + +/* + * Copyright (c) 2024 Martin Pieuchot + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef _UVM_UVM_PCPU_H_ +#define _UVM_UVM_PCPU_H_ + +struct vm_page; + +/* + * The number of pages per magazine should be large enough to get rid of the + * contention in the pmemrange allocator during concurrent page faults and + * small enough to limit fragmentation. + */ +#define UVM_PMR_CACHEMAGSZ 8 + +/* + * Magazine + */ +struct uvm_pmr_cache_item { + struct vm_page *upci_pages[UVM_PMR_CACHEMAGSZ]; + int upci_npages; /* # of pages in magazine */ +}; + +/* + * Per-CPU cache of physical pages. + */ +struct uvm_pmr_cache { + struct uvm_pmr_cache_item upc_magz[2]; /* magazines */ + int upc_actv; /* index of active magazine */ + +}; + +#endif /* _UVM_UVM_PCPU_H_ */ diff --git a/sys/uvm/uvm_pmemrange.c b/sys/uvm/uvm_pmemrange.c index a1cc8c954..6222bfa15 100644 --- a/sys/uvm/uvm_pmemrange.c +++ b/sys/uvm/uvm_pmemrange.c @@ -1,6 +1,7 @@ -/* $OpenBSD: uvm_pmemrange.c,v 1.65 2024/04/19 10:22:51 mpi Exp $ */ +/* $OpenBSD: uvm_pmemrange.c,v 1.66 2024/05/01 12:54:27 mpi Exp $ */ /* + * Copyright (c) 2024 Martin Pieuchot * Copyright (c) 2009, 2010 Ariane van der Steldt * * Permission to use, copy, modify, and distribute this software for any @@ -1261,6 +1262,28 @@ out: return 0; } +/* + * Acquire a single page. + * + * flags: UVM_PLA_* flags + * result: returned page. + */ +struct vm_page * +uvm_pmr_getone(int flags) +{ + struct vm_page *pg; + struct pglist pgl; + + TAILQ_INIT(&pgl); + if (uvm_pmr_getpages(1, 0, 0, 1, 0, 1, flags, &pgl) != 0) + return NULL; + + pg = TAILQ_FIRST(&pgl); + KASSERT(pg != NULL && TAILQ_NEXT(pg, pageq) == NULL); + + return pg; +} + /* * Free a number of contig pages (invoked by uvm_page_init). */ @@ -2190,3 +2213,147 @@ uvm_pagezero_thread(void *arg) yield(); } } + +#if defined(MULTIPROCESSOR) && defined(__HAVE_UVM_PERCPU) +int +uvm_pmr_cache_alloc(struct uvm_pmr_cache_item *upci) +{ + struct vm_page *pg; + struct pglist pgl; + int flags = UVM_PLA_NOWAIT|UVM_PLA_NOWAKE; + int npages = UVM_PMR_CACHEMAGSZ; + + splassert(IPL_VM); + KASSERT(upci->upci_npages == 0); + + TAILQ_INIT(&pgl); + if (uvm_pmr_getpages(npages, 0, 0, 1, 0, npages, flags, &pgl)) + return -1; + + while ((pg = TAILQ_FIRST(&pgl)) != NULL) { + TAILQ_REMOVE(&pgl, pg, pageq); + upci->upci_pages[upci->upci_npages] = pg; + upci->upci_npages++; + } + atomic_add_int(&uvmexp.percpucaches, npages); + + return 0; +} + +struct vm_page * +uvm_pmr_cache_get(int flags) +{ + struct uvm_pmr_cache *upc = &curcpu()->ci_uvm; + struct uvm_pmr_cache_item *upci; + struct vm_page *pg; + int s; + + s = splvm(); + upci = &upc->upc_magz[upc->upc_actv]; + if (upci->upci_npages == 0) { + unsigned int prev; + + prev = (upc->upc_actv == 0) ? 1 : 0; + upci = &upc->upc_magz[prev]; + if (upci->upci_npages == 0) { + atomic_inc_int(&uvmexp.pcpmiss); + if (uvm_pmr_cache_alloc(upci)) { + splx(s); + return uvm_pmr_getone(flags); + } + } + /* Swap magazines */ + upc->upc_actv = prev; + } else { + atomic_inc_int(&uvmexp.pcphit); + } + + atomic_dec_int(&uvmexp.percpucaches); + upci->upci_npages--; + pg = upci->upci_pages[upci->upci_npages]; + splx(s); + + if (flags & UVM_PLA_ZERO) + uvm_pagezero(pg); + + return pg; +} + +void +uvm_pmr_cache_free(struct uvm_pmr_cache_item *upci) +{ + struct pglist pgl; + unsigned int i; + + splassert(IPL_VM); + + TAILQ_INIT(&pgl); + for (i = 0; i < upci->upci_npages; i++) + TAILQ_INSERT_TAIL(&pgl, upci->upci_pages[i], pageq); + + uvm_pmr_freepageq(&pgl); + + atomic_sub_int(&uvmexp.percpucaches, upci->upci_npages); + upci->upci_npages = 0; + memset(upci->upci_pages, 0, sizeof(upci->upci_pages)); +} + +void +uvm_pmr_cache_put(struct vm_page *pg) +{ + struct uvm_pmr_cache *upc = &curcpu()->ci_uvm; + struct uvm_pmr_cache_item *upci; + int s; + + s = splvm(); + upci = &upc->upc_magz[upc->upc_actv]; + if (upci->upci_npages >= UVM_PMR_CACHEMAGSZ) { + unsigned int prev; + + prev = (upc->upc_actv == 0) ? 1 : 0; + upci = &upc->upc_magz[prev]; + if (upci->upci_npages > 0) + uvm_pmr_cache_free(upci); + + /* Swap magazines */ + upc->upc_actv = prev; + KASSERT(upci->upci_npages == 0); + } + + upci->upci_pages[upci->upci_npages] = pg; + upci->upci_npages++; + atomic_inc_int(&uvmexp.percpucaches); + splx(s); +} + +void +uvm_pmr_cache_drain(void) +{ + struct uvm_pmr_cache *upc = &curcpu()->ci_uvm; + int s; + + s = splvm(); + uvm_pmr_cache_free(&upc->upc_magz[0]); + uvm_pmr_cache_free(&upc->upc_magz[1]); + splx(s); +} + +#else /* !(MULTIPROCESSOR && __HAVE_UVM_PERCPU) */ + +struct vm_page * +uvm_pmr_cache_get(int flags) +{ + return uvm_pmr_getone(flags); +} + +void +uvm_pmr_cache_put(struct vm_page *pg) +{ + uvm_pmr_freepages(pg, 1); +} + +void +uvm_pmr_cache_drain(void) +{ +} +#endif diff --git a/sys/uvm/uvm_pmemrange.h b/sys/uvm/uvm_pmemrange.h index e70a96423..45912df96 100644 --- a/sys/uvm/uvm_pmemrange.h +++ b/sys/uvm/uvm_pmemrange.h @@ -1,4 +1,4 @@ -/* $OpenBSD: uvm_pmemrange.h,v 1.16 2024/04/19 10:22:51 mpi Exp $ */ +/* $OpenBSD: uvm_pmemrange.h,v 1.17 2024/05/01 12:54:27 mpi Exp $ */ /* * Copyright (c) 2009 Ariane van der Steldt @@ -147,5 +147,9 @@ void uvm_pmr_remove(struct uvm_pmemrange *, struct vm_page *uvm_pmr_extract_range(struct uvm_pmemrange *, struct vm_page *, paddr_t, paddr_t, struct pglist *); +struct vm_page *uvm_pmr_cache_get(int); +void uvm_pmr_cache_put(struct vm_page *); +void uvm_pmr_cache_drain(void); + #endif /* _UVM_UVM_PMEMRANGE_H_ */ diff --git a/sys/uvm/uvmexp.h b/sys/uvm/uvmexp.h index d34aea71b..ccd87b302 100644 --- a/sys/uvm/uvmexp.h +++ b/sys/uvm/uvmexp.h @@ -1,4 +1,4 @@ -/* $OpenBSD: uvmexp.h,v 1.14 2024/04/19 10:22:51 mpi Exp $ */ +/* $OpenBSD: uvmexp.h,v 1.15 2024/05/01 12:54:27 mpi Exp $ */ #ifndef _UVM_UVMEXP_ #define _UVM_UVMEXP_ @@ -66,7 +66,7 @@ struct uvmexp { int zeropages; /* [F] number of zero'd pages */ int reserve_pagedaemon; /* [I] # of pages reserved for pagedaemon */ int reserve_kernel; /* [I] # of pages reserved for kernel */ - int unused01; /* formerly anonpages */ + int percpucaches; /* [a] # of pages in per-CPU caches */ int vnodepages; /* XXX # of pages used by vnode page cache */ int vtextpages; /* XXX # of pages used by vtext vnodes */ @@ -101,8 +101,8 @@ struct uvmexp { int syscalls; /* system calls */ int pageins; /* [p] pagein operation count */ /* pageouts are in pdpageouts below */ - int unused07; /* formerly obsolete_swapins */ - int unused08; /* formerly obsolete_swapouts */ + int pcphit; /* [a] # of pagealloc from per-CPU cache */ + int pcpmiss; /* [a] # of times a per-CPU cache was empty */ int pgswapin; /* pages swapped in */ int pgswapout; /* pages swapped out */ int forks; /* forks */ diff --git a/usr.bin/sndiod/midi.c b/usr.bin/sndiod/midi.c index 371a83090..3290e6b5f 100644 --- a/usr.bin/sndiod/midi.c +++ b/usr.bin/sndiod/midi.c @@ -1,4 +1,4 @@ -/* $OpenBSD: midi.c,v 1.29 2021/11/01 14:43:25 ratchov Exp $ */ +/* $OpenBSD: midi.c,v 1.30 2024/05/03 05:18:09 ratchov Exp $ */ /* * Copyright (c) 2008-2012 Alexandre Ratchov * @@ -154,6 +154,23 @@ midi_link(struct midi *ep, struct midi *peer) } } +/* + * return the list of endpoints the given one receives from + */ +unsigned int +midi_rxmask(struct midi *ep) +{ + int i, rxmask; + + for (rxmask = 0, i = 0; i < MIDI_NEP; i++) { + if ((midi_ep[i].txmask & ep->self) == 0) + continue; + rxmask |= midi_ep[i].self; + } + + return rxmask; +} + /* * add the midi endpoint in the ``tag'' midi thru box */ diff --git a/usr.bin/sndiod/midi.h b/usr.bin/sndiod/midi.h index cd398de4c..7872f5b7f 100644 --- a/usr.bin/sndiod/midi.h +++ b/usr.bin/sndiod/midi.h @@ -1,4 +1,4 @@ -/* $OpenBSD: midi.h,v 1.15 2021/11/01 14:43:25 ratchov Exp $ */ +/* $OpenBSD: midi.h,v 1.16 2024/05/03 05:18:09 ratchov Exp $ */ /* * Copyright (c) 2008-2012 Alexandre Ratchov * @@ -112,6 +112,7 @@ void midi_send(struct midi *, unsigned char *, int); void midi_fill(struct midi *); void midi_tag(struct midi *, unsigned int); unsigned int midi_tags(struct midi *); +unsigned int midi_rxmask(struct midi *); void midi_link(struct midi *, struct midi *); void midi_abort(struct midi *); void midi_migrate(struct midi *, struct midi *); diff --git a/usr.bin/sndiod/sndiod.c b/usr.bin/sndiod/sndiod.c index b1719f154..9b138b710 100644 --- a/usr.bin/sndiod/sndiod.c +++ b/usr.bin/sndiod/sndiod.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sndiod.c,v 1.48 2022/03/07 08:58:33 ratchov Exp $ */ +/* $OpenBSD: sndiod.c,v 1.49 2024/05/03 05:18:09 ratchov Exp $ */ /* * Copyright (c) 2008-2012 Alexandre Ratchov * @@ -254,6 +254,89 @@ opt_mode(void) return mode; } +/* + * Open all devices. Possibly switch to the new devices if they have higher + * priorities than the current ones. + */ +static void +reopen_devs(void) +{ + struct opt *o; + struct dev *d, *a; + + for (o = opt_list; o != NULL; o = o->next) { + + /* skip unused logical devices and ones with fixed hardware */ + if (o->refcnt == 0 || strcmp(o->name, o->dev->name) == 0) + continue; + + /* circulate to the device with the highest prio */ + a = o->alt_first; + for (d = a; d->alt_next != a; d = d->alt_next) { + if (d->num > o->alt_first->num) + o->alt_first = d; + } + + /* switch to the first working one, in pririty order */ + d = o->alt_first; + while (d != o->dev) { + if (opt_setdev(o, d)) + break; + d = d->alt_next; + } + } + + /* + * retry to open the remaining devices that are not used but need + * to stay open (ex. '-a on') + */ + for (d = dev_list; d != NULL; d = d->next) { + if (d->refcnt > 0 && d->pstate == DEV_CFG) + dev_open(d); + } +} + +/* + * For each port, open the alt with the highest priority and switch to it + */ +static void +reopen_ports(void) +{ + struct port *p, *a, *apri; + int inuse; + + for (p = port_list; p != NULL; p = a->next) { + + /* skip unused ports */ + inuse = 0; + a = p; + while (1) { + if (midi_rxmask(a->midi) || a->midi->txmask) + inuse = 1; + if (a->alt_next == p) + break; + a = a->alt_next; + } + if (!inuse) + continue; + + /* open the alt with the highest prio */ + apri = port_alt_ref(p->num); + + /* switch to it */ + a = p; + while (1) { + if (a != apri) { + midi_migrate(a->midi, apri->midi); + port_unref(a); + } + if (a->alt_next == p) + break; + a = a->alt_next; + } + } +} + void setsig(void) { @@ -461,7 +544,6 @@ main(int argc, char **argv) char base[SOCKPATH_MAX], path[SOCKPATH_MAX]; unsigned int mode, dup, mmc, vol; unsigned int hold, autovol, bufsz, round, rate; - unsigned int reopen_list; const char *str; struct aparams par; struct opt *o; @@ -712,33 +794,14 @@ main(int argc, char **argv) if (pledge("stdio audio recvfd unix", NULL) == -1) err(1, "pledge"); } + for (;;) { if (quit_flag) break; if (reopen_flag) { reopen_flag = 0; - - reopen_list = 0; - for (d = dev_list; d != NULL; d = d->next) { - if (d->pstate != DEV_CFG) - reopen_list |= (1 << d->num); - } - for (d = dev_list; d != NULL; d = d->next) { - if (reopen_list & (1 << d->num)) - dev_migrate(d); - } - - reopen_list = 0; - for (p = port_list; p != NULL; p = p->next) { - if (p->state != PORT_CFG) - reopen_list |= (1 << p->num); - } - for (p = port_list; p != NULL; p = p->next) { - if (reopen_list & (1 << p->num)) { - if (port_migrate(p) != p) - port_close(p); - } - } + reopen_devs(); + reopen_ports(); } if (!fdpass_peer) break; diff --git a/usr.bin/ssh/PROTOCOL.agent b/usr.bin/ssh/PROTOCOL.agent index 7637882f1..9ae16bf2b 100644 --- a/usr.bin/ssh/PROTOCOL.agent +++ b/usr.bin/ssh/PROTOCOL.agent @@ -49,10 +49,13 @@ Where a constraint consists of: string from_username (must be empty) string from_hostname + string reserved keyspec[] from_hostkeys string to_username string to_hostname + string reserved keyspec[] to_hostkeys + string reserved And a keyspec consists of: @@ -112,4 +115,4 @@ A SSH_AGENTC_ADD_SMARTCARD_KEY_CONSTRAINED will return SSH_AGENT_SUCCESS if any key (plain private or certificate) was successfully loaded, or SSH_AGENT_FAILURE if no key was loaded. -$OpenBSD: PROTOCOL.agent,v 1.22 2023/12/20 00:06:25 jsg Exp $ +$OpenBSD: PROTOCOL.agent,v 1.23 2024/04/30 05:45:56 djm Exp $ diff --git a/usr.bin/ssh/clientloop.c b/usr.bin/ssh/clientloop.c index 31eaa9500..79bffbc00 100644 --- a/usr.bin/ssh/clientloop.c +++ b/usr.bin/ssh/clientloop.c @@ -1,4 +1,4 @@ -/* $OpenBSD: clientloop.c,v 1.403 2024/02/21 05:57:34 djm Exp $ */ +/* $OpenBSD: clientloop.c,v 1.405 2024/04/30 02:14:10 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -1576,7 +1576,7 @@ client_loop(struct ssh *ssh, int have_pty, int escape_char_arg, client_wait_until_can_do_something(ssh, &pfd, &npfd_alloc, &npfd_active, channel_did_enqueue, &osigset, &conn_in_ready, &conn_out_ready); - if (sigprocmask(SIG_UNBLOCK, &bsigset, &osigset) == -1) + if (sigprocmask(SIG_SETMASK, &osigset, NULL) == -1) error_f("osigset sigprocmask: %s", strerror(errno)); if (quit_pending) @@ -2426,25 +2426,6 @@ client_global_hostkeys_prove_confirm(struct ssh *ssh, int type, client_repledge(); } -/* - * Returns non-zero if the key is accepted by HostkeyAlgorithms. - * Made slightly less trivial by the multiple RSA signature algorithm names. - */ -static int -key_accepted_by_hostkeyalgs(const struct sshkey *key) -{ - const char *ktype = sshkey_ssh_name(key); - const char *hostkeyalgs = options.hostkeyalgorithms; - - if (key->type == KEY_UNSPEC) - return 0; - if (key->type == KEY_RSA && - (match_pattern_list("rsa-sha2-256", hostkeyalgs, 0) == 1 || - match_pattern_list("rsa-sha2-512", hostkeyalgs, 0) == 1)) - return 1; - return match_pattern_list(ktype, hostkeyalgs, 0) == 1; -} - /* * Handle hostkeys-00@openssh.com global request to inform the client of all * the server's hostkeys. The keys are checked against the user's @@ -2489,7 +2470,7 @@ client_input_hostkeys(struct ssh *ssh) debug3_f("received %s key %s", sshkey_type(key), fp); free(fp); - if (!key_accepted_by_hostkeyalgs(key)) { + if (!hostkey_accepted_by_hostkeyalgs(key)) { debug3_f("%s key not permitted by " "HostkeyAlgorithms", sshkey_ssh_name(key)); continue; diff --git a/usr.bin/ssh/serverloop.c b/usr.bin/ssh/serverloop.c index c669c02ee..2e3101ebf 100644 --- a/usr.bin/ssh/serverloop.c +++ b/usr.bin/ssh/serverloop.c @@ -1,4 +1,4 @@ -/* $OpenBSD: serverloop.c,v 1.237 2023/08/21 04:59:54 djm Exp $ */ +/* $OpenBSD: serverloop.c,v 1.238 2024/04/30 02:14:10 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -374,7 +374,7 @@ server_loop2(struct ssh *ssh, Authctxt *authctxt) wait_until_can_do_something(ssh, connection_in, connection_out, &pfd, &npfd_alloc, &npfd_active, &osigset, &conn_in_ready, &conn_out_ready); - if (sigprocmask(SIG_UNBLOCK, &bsigset, &osigset) == -1) + if (sigprocmask(SIG_SETMASK, &osigset, NULL) == -1) error_f("osigset sigprocmask: %s", strerror(errno)); if (received_sigterm) { diff --git a/usr.bin/ssh/sftp-server.c b/usr.bin/ssh/sftp-server.c index 51258d9e8..b45abefd9 100644 --- a/usr.bin/ssh/sftp-server.c +++ b/usr.bin/ssh/sftp-server.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sftp-server.c,v 1.147 2023/04/12 08:53:54 jsg Exp $ */ +/* $OpenBSD: sftp-server.c,v 1.148 2024/04/30 06:23:51 djm Exp $ */ /* * Copyright (c) 2000-2004 Markus Friedl. All rights reserved. * @@ -1673,14 +1673,16 @@ process_extended_home_directory(u_int32_t id) fatal_fr(r, "parse"); debug3("request %u: home-directory \"%s\"", id, username); - if ((user_pw = getpwnam(username)) == NULL) { + if (username[0] == '\0') { + user_pw = pw; + } else if ((user_pw = getpwnam(username)) == NULL) { send_status(id, SSH2_FX_FAILURE); goto out; } - verbose("home-directory \"%s\"", pw->pw_dir); + verbose("home-directory \"%s\"", user_pw->pw_dir); attrib_clear(&s.attrib); - s.name = s.long_name = pw->pw_dir; + s.name = s.long_name = user_pw->pw_dir; send_names(id, 1, &s); out: free(username); diff --git a/usr.bin/ssh/sftp.c b/usr.bin/ssh/sftp.c index 44b81a3a0..67b0fcfbf 100644 --- a/usr.bin/ssh/sftp.c +++ b/usr.bin/ssh/sftp.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sftp.c,v 1.237 2024/02/01 02:37:33 djm Exp $ */ +/* $OpenBSD: sftp.c,v 1.238 2024/04/30 06:16:55 djm Exp $ */ /* * Copyright (c) 2001-2004 Damien Miller * @@ -2272,8 +2272,10 @@ interactive_loop(struct sftp_conn *conn, char *file1, char *file2) break; } if (el == NULL) { - if (interactive) + if (interactive) { printf("sftp> "); + fflush(stdout); + } if (fgets(cmd, sizeof(cmd), infile) == NULL) { if (interactive) printf("\n"); diff --git a/usr.bin/ssh/ssh-keyscan.c b/usr.bin/ssh/ssh-keyscan.c index 825220fb1..7fb8c9e33 100644 --- a/usr.bin/ssh/ssh-keyscan.c +++ b/usr.bin/ssh/ssh-keyscan.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh-keyscan.c,v 1.155 2024/01/11 01:45:36 djm Exp $ */ +/* $OpenBSD: ssh-keyscan.c,v 1.156 2024/04/30 15:40:43 tobias Exp $ */ /* * Copyright 1995, 1996 by David Mazieres . * @@ -826,7 +826,8 @@ main(int argc, char **argv) if (argv[j] == NULL) fp = stdin; else if ((fp = fopen(argv[j], "r")) == NULL) - fatal("%s: %s: %s", __progname, argv[j], strerror(errno)); + fatal("%s: %s: %s", __progname, + fp == stdin ? "" : argv[j], strerror(errno)); while (getline(&line, &linesize, fp) != -1) { /* Chomp off trailing whitespace and comments */ @@ -848,9 +849,11 @@ main(int argc, char **argv) } if (ferror(fp)) - fatal("%s: %s: %s", __progname, argv[j], strerror(errno)); + fatal("%s: %s: %s", __progname, + fp == stdin ? "" : argv[j], strerror(errno)); - fclose(fp); + if (fp != stdin) + fclose(fp); } free(line); diff --git a/usr.bin/ssh/ssh-keysign.c b/usr.bin/ssh/ssh-keysign.c index 97a117ed9..434c7503f 100644 --- a/usr.bin/ssh/ssh-keysign.c +++ b/usr.bin/ssh/ssh-keysign.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh-keysign.c,v 1.73 2024/01/11 01:51:16 djm Exp $ */ +/* $OpenBSD: ssh-keysign.c,v 1.74 2024/04/30 05:53:03 djm Exp $ */ /* * Copyright (c) 2002 Markus Friedl. All rights reserved. * @@ -265,7 +265,7 @@ main(int argc, char **argv) __progname, rver, version); if ((r = sshbuf_get_u32(b, (u_int *)&fd)) != 0) fatal_r(r, "%s: buffer error", __progname); - if (fd < 0 || fd == STDIN_FILENO || fd == STDOUT_FILENO) + if (fd <= STDERR_FILENO) fatal("%s: bad fd = %d", __progname, fd); if ((host = get_local_name(fd)) == NULL) fatal("%s: cannot get local name for fd", __progname); diff --git a/usr.bin/ssh/sshconnect.c b/usr.bin/ssh/sshconnect.c index 8ff922852..4cc597c49 100644 --- a/usr.bin/ssh/sshconnect.c +++ b/usr.bin/ssh/sshconnect.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sshconnect.c,v 1.367 2024/04/23 13:34:50 jsg Exp $ */ +/* $OpenBSD: sshconnect.c,v 1.368 2024/04/30 02:10:49 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -45,6 +45,7 @@ #include "sshconnect.h" #include "hostfile.h" #include "log.h" +#include "match.h" #include "misc.h" #include "readconf.h" #include "atomicio.h" @@ -679,6 +680,29 @@ try_tilde_unexpand(const char *path) return ret; } +/* + * Returns non-zero if the key is accepted by HostkeyAlgorithms. + * Made slightly less trivial by the multiple RSA signature algorithm names. + */ +int +hostkey_accepted_by_hostkeyalgs(const struct sshkey *key) +{ + const char *ktype = sshkey_ssh_name(key); + const char *hostkeyalgs = options.hostkeyalgorithms; + + if (key->type == KEY_UNSPEC) + return 0; + if (key->type == KEY_RSA && + (match_pattern_list("rsa-sha2-256", hostkeyalgs, 0) == 1 || + match_pattern_list("rsa-sha2-512", hostkeyalgs, 0) == 1)) + return 1; + if (key->type == KEY_RSA_CERT && + (match_pattern_list("rsa-sha2-512-cert-v01@openssh.com", hostkeyalgs, 0) == 1 || + match_pattern_list("rsa-sha2-256-cert-v01@openssh.com", hostkeyalgs, 0) == 1)) + return 1; + return match_pattern_list(ktype, hostkeyalgs, 0) == 1; +} + static int hostkeys_find_by_key_cb(struct hostkey_foreach_line *l, void *_ctx) { @@ -979,6 +1003,12 @@ check_host_key(char *hostname, const struct ssh_conn_info *cinfo, } retry: + if (!hostkey_accepted_by_hostkeyalgs(host_key)) { + error("host key %s not permitted by HostkeyAlgorithms", + sshkey_ssh_name(host_key)); + goto fail; + } + /* Reload these as they may have changed on cert->key downgrade */ want_cert = sshkey_is_cert(host_key); type = sshkey_type(host_key); diff --git a/usr.bin/ssh/sshconnect.h b/usr.bin/ssh/sshconnect.h index 79d35cc19..8b0466f29 100644 --- a/usr.bin/ssh/sshconnect.h +++ b/usr.bin/ssh/sshconnect.h @@ -1,4 +1,4 @@ -/* $OpenBSD: sshconnect.h,v 1.47 2023/10/12 02:18:18 djm Exp $ */ +/* $OpenBSD: sshconnect.h,v 1.48 2024/04/30 02:10:49 djm Exp $ */ /* * Copyright (c) 2000 Markus Friedl. All rights reserved. @@ -24,6 +24,8 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +struct sshkey; + typedef struct Sensitive Sensitive; struct Sensitive { struct sshkey **keys; @@ -94,3 +96,5 @@ void maybe_add_key_to_agent(const char *, struct sshkey *, void load_hostkeys_command(struct hostkeys *, const char *, const char *, const struct ssh_conn_info *, const struct sshkey *, const char *); + +int hostkey_accepted_by_hostkeyalgs(const struct sshkey *); diff --git a/usr.bin/systat/uvm.c b/usr.bin/systat/uvm.c index 811f76300..fbf8d6e2a 100644 --- a/usr.bin/systat/uvm.c +++ b/usr.bin/systat/uvm.c @@ -1,4 +1,4 @@ -/* $OpenBSD: uvm.c,v 1.8 2024/04/19 10:22:51 mpi Exp $ */ +/* $OpenBSD: uvm.c,v 1.9 2024/05/01 12:54:27 mpi Exp $ */ /* * Copyright (c) 2008 Can Erkin Acar * Copyright (c) 2018 Kenneth R Westerback @@ -80,11 +80,10 @@ struct uvmline uvmline[] = { { &uvmexp.zeropages, &last_uvmexp.zeropages, "zeropages", &uvmexp.pageins, &last_uvmexp.pageins, "pageins", &uvmexp.fltrelckok, &last_uvmexp.fltrelckok, "fltrelckok" }, - { &uvmexp.reserve_pagedaemon, &last_uvmexp.reserve_pagedaemon, - "reserve_pagedaemon", + { &uvmexp.percpucaches, &last_uvmexp.percpucaches, "percpucaches", &uvmexp.pgswapin, &last_uvmexp.pgswapin, "pgswapin", &uvmexp.fltanget, &last_uvmexp.fltanget, "fltanget" }, - { &uvmexp.reserve_kernel, &last_uvmexp.reserve_kernel, "reserve_kernel", + { NULL, NULL, NULL, &uvmexp.pgswapout, &last_uvmexp.pgswapout, "pgswapout", &uvmexp.fltanretry, &last_uvmexp.fltanretry, "fltanretry" }, { NULL, NULL, NULL, @@ -143,13 +142,13 @@ struct uvmline uvmline[] = { NULL, NULL, NULL }, { &uvmexp.pagesize, &last_uvmexp.pagesize, "pagesize", &uvmexp.pdpending, &last_uvmexp.pdpending, "pdpending", - NULL, NULL, NULL }, + NULL, NULL, "Per-CPU Counters" }, { &uvmexp.pagemask, &last_uvmexp.pagemask, "pagemask", &uvmexp.pddeact, &last_uvmexp.pddeact, "pddeact", - NULL, NULL, NULL }, + &uvmexp.pcphit, &last_uvmexp.pcphit, "pcphit" }, { &uvmexp.pageshift, &last_uvmexp.pageshift, "pageshift", NULL, NULL, NULL, - NULL, NULL, NULL } + &uvmexp.pcpmiss, &last_uvmexp.pcpmiss, "pcpmiss" } }; field_def fields_uvm[] = { diff --git a/usr.bin/vmstat/vmstat.c b/usr.bin/vmstat/vmstat.c index dcc999bd0..00bd52feb 100644 --- a/usr.bin/vmstat/vmstat.c +++ b/usr.bin/vmstat/vmstat.c @@ -1,5 +1,5 @@ /* $NetBSD: vmstat.c,v 1.29.4.1 1996/06/05 00:21:05 cgd Exp $ */ -/* $OpenBSD: vmstat.c,v 1.157 2024/04/19 10:22:51 mpi Exp $ */ +/* $OpenBSD: vmstat.c,v 1.158 2024/05/01 12:54:27 mpi Exp $ */ /* * Copyright (c) 1980, 1986, 1991, 1993 @@ -513,7 +513,12 @@ dosum(void) uvmexp.reserve_pagedaemon); (void)printf("%11u pages reserved for kernel\n", uvmexp.reserve_kernel); + (void)printf("%11u pages in per-cpu caches\n", + uvmexp.percpucaches); + /* per-cpu cache */ + (void)printf("%11u per-cpu cache hits\n", uvmexp.pcphit); + (void)printf("%11u per-cpu cache misses\n", uvmexp.pcpmiss); /* swap */ (void)printf("%11u swap pages\n", uvmexp.swpages); (void)printf("%11u swap pages in use\n", uvmexp.swpginuse); diff --git a/usr.sbin/pkg_add/OpenBSD/PackingElement.pm b/usr.sbin/pkg_add/OpenBSD/PackingElement.pm index 82bdd7e79..f7a6610c3 100644 --- a/usr.sbin/pkg_add/OpenBSD/PackingElement.pm +++ b/usr.sbin/pkg_add/OpenBSD/PackingElement.pm @@ -1,5 +1,5 @@ # ex:ts=8 sw=4: -# $OpenBSD: PackingElement.pm,v 1.290 2023/11/22 11:18:37 espie Exp $ +# $OpenBSD: PackingElement.pm,v 1.291 2024/04/30 14:26:50 sthen Exp $ # # Copyright (c) 2003-2014 Marc Espie # @@ -1957,7 +1957,9 @@ sub iso8601($self) sub _iso8601_to_time($s) { - if ($s =~ m/^(\d{4})\-(\d{2})\-(\d{2})T(\d{2})\:(\d{2})\:(\d{2})Z$/) { + # XXX RFC 9557 explicitly wants +00:00 instead of Z for UTC, + # so recognize both + if ($s =~ m/^(\d{4})\-(\d{2})\-(\d{2})T(\d{2})\:(\d{2})\:(\d{2})(?:Z|\+00\:00)$/) { my ($year, $month, $day, $hour, $min, $sec) = ($1 - 1900, $2-1, $3, $4, $5, $6); require POSIX; diff --git a/usr.sbin/smtpd/table.5 b/usr.sbin/smtpd/table.5 index 65dca359f..3f4d40938 100644 --- a/usr.sbin/smtpd/table.5 +++ b/usr.sbin/smtpd/table.5 @@ -1,4 +1,4 @@ -.\" $OpenBSD: table.5,v 1.13 2023/12/27 11:29:56 op Exp $ +.\" $OpenBSD: table.5,v 1.14 2024/05/02 18:14:33 op Exp $ .\" .\" Copyright (c) 2013 Eric Faurot .\" Copyright (c) 2013 Gilles Chehade @@ -16,7 +16,7 @@ .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. .\" .\" -.Dd $Mdocdate: December 27 2023 $ +.Dd $Mdocdate: May 2 2024 $ .Dt TABLE 5 .Os .Sh NAME @@ -173,10 +173,11 @@ of addresses in the table until a match is found. A netaddr table can contain exact addresses or netmasks, and looks as follow: .Bd -literal -offset indent 192.168.1.1 -::1 -ipv6:::1 +[::1] 192.168.1.0/24 .Ed +.Pp +IPv6 addresses must be enclosed in square brackets. .Ss Userinfo tables Userinfo tables are used in rule context to specify an alternate userbase, mapping virtual users to local system users by UID, GID and home directory. @@ -214,11 +215,11 @@ A source table looks as follow: .Bd -literal -offset indent 192.168.1.2 192.168.1.3 -::1 -::2 -ipv6:::3 -ipv6:::4 +[::1] +[::2] .Ed +.Pp +IPv6 address must be enclosed in square brackets. .Ss Mailaddr tables Mailaddr tables are lists of email addresses. They can be used in the following contexts: @@ -254,10 +255,12 @@ outgoing connection. .Pp The format is a mapping from inet4 or inet6 addresses to hostnames: .Bd -literal -offset indent -::1 localhost +[::1] localhost 127.0.0.1 localhost 88.190.23.165 www.opensmtpd.org .Ed +.Pp +IPv6 addresses must be enclosed in square brackets. .Sh SEE ALSO .Xr smtpd.conf 5 , .Xr makemap 8 , diff --git a/usr.sbin/smtpd/util.c b/usr.sbin/smtpd/util.c index d481162c8..e2e03222a 100644 --- a/usr.sbin/smtpd/util.c +++ b/usr.sbin/smtpd/util.c @@ -1,4 +1,4 @@ -/* $OpenBSD: util.c,v 1.156 2024/02/11 09:24:26 op Exp $ */ +/* $OpenBSD: util.c,v 1.157 2024/05/02 18:14:33 op Exp $ */ /* * Copyright (c) 2000,2001 Markus Friedl. All rights reserved. @@ -855,7 +855,7 @@ int parse_table_line(FILE *fp, char **line, size_t *linesize, int *type, char **key, char **val, int *malformed) { - char *keyp, *valp, *p; + char *keyp, *valp; ssize_t linelen; *key = NULL; @@ -885,16 +885,17 @@ parse_table_line(FILE *fp, char **line, size_t *linesize, return 0; } - if (*type == T_NONE) { - for (p = keyp; *p; p++) { - if (*p == ' ' || *p == '\t' || *p == ':') { - *type = T_HASH; - break; - } + if (*keyp == '[') { + if ((valp = strchr(keyp, ']')) == NULL) { + *malformed = 1; + return (0); } - if (*type == T_NONE) - *type = T_LIST; - } + valp++; + } else + valp = keyp + strcspn(keyp, " \t:"); + + if (*type == T_NONE) + *type = (*valp == '\0') ? T_LIST : T_HASH; if (*type == T_LIST) { *key = keyp; @@ -902,20 +903,11 @@ parse_table_line(FILE *fp, char **line, size_t *linesize, } /* T_HASH */ - valp = keyp; - strsep(&valp, " \t:"); - if (valp) { - while (*valp) { - if (!isspace((unsigned char)*valp) && - !(*valp == ':' && - isspace((unsigned char)*(valp + 1)))) - break; - ++valp; - } - if (*valp == '\0') - valp = NULL; + if (*valp != '\0') { + *valp++ = '\0'; + valp += strspn(valp, " \t"); } - if (valp == NULL) + if (*valp == '\0') *malformed = 1; *key = keyp; diff --git a/usr.sbin/vmctl/main.c b/usr.sbin/vmctl/main.c index 6621169dc..2b951ea4f 100644 --- a/usr.sbin/vmctl/main.c +++ b/usr.sbin/vmctl/main.c @@ -1,4 +1,4 @@ -/* $OpenBSD: main.c,v 1.76 2024/04/10 13:03:41 dv Exp $ */ +/* $OpenBSD: main.c,v 1.77 2024/05/02 15:46:10 mlarkin Exp $ */ /* * Copyright (c) 2015 Reyk Floeter @@ -45,6 +45,7 @@ static const char *socket_name = SOCKET_NAME; static int ctl_sock = -1; static int tty_autoconnect = 0; +int stat_rflag; __dead void usage(void); __dead void ctl_usage(struct ctl_command *); @@ -82,7 +83,7 @@ struct ctl_command ctl_commands[] = { { "start", CMD_START, ctl_start, "[-cL] [-B device] [-b path] [-d disk] [-i count]\n" "\t\t[-m size] [-n switch] [-r path] [-t name] id | name", 1}, - { "status", CMD_STATUS, ctl_status, "[id]" }, + { "status", CMD_STATUS, ctl_status, "[-r] [id]" }, { "stop", CMD_STOP, ctl_stop, "[-fw] [id | -a]" }, { "unpause", CMD_UNPAUSE, ctl_unpause, "id" }, { "wait", CMD_WAITFOR, ctl_waitfor, "id" }, @@ -744,10 +745,25 @@ ctl_convert(const char *srcfile, const char *dstfile, int dsttype, size_t dstsiz int ctl_status(struct parse_result *res, int argc, char *argv[]) { - if (argc == 2) { - if (parse_vmid(res, argv[1], 0) == -1) - errx(1, "invalid id: %s", argv[1]); - } else if (argc > 2) + char ch; + + while ((ch = getopt(argc, argv, "r")) != -1) { + switch (ch) { + case 'r': + stat_rflag = 1; + break; + default: + ctl_usage(res->ctl); + /* NOTREACHED */ + } + } + argc -= optind; + argv += optind; + + if (argc == 1) { + if (parse_vmid(res, argv[0], 0) == -1) + errx(1, "invalid id: %s", argv[0]); + } else if (argc > 1) ctl_usage(res->ctl); return (vmmaction(res)); diff --git a/usr.sbin/vmctl/vmctl.8 b/usr.sbin/vmctl/vmctl.8 index 146ef3da8..607816cc5 100644 --- a/usr.sbin/vmctl/vmctl.8 +++ b/usr.sbin/vmctl/vmctl.8 @@ -1,4 +1,4 @@ -.\" $OpenBSD: vmctl.8,v 1.76 2024/02/16 01:48:06 jsg Exp $ +.\" $OpenBSD: vmctl.8,v 1.77 2024/05/02 15:46:10 mlarkin Exp $ .\" .\" Copyright (c) 2015-2024 Mike Larkin .\" @@ -14,7 +14,7 @@ .\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. .\" -.Dd $Mdocdate: February 16 2024 $ +.Dd $Mdocdate: May 2 2024 $ .Dt VMCTL 8 .Os .Sh NAME @@ -245,9 +245,12 @@ The instance will inherit settings from the parent VM, except for exclusive options such as disk, interface lladdr, and interface names. .El -.It Cm status Op Ar id +.It Cm status Oo Fl r Oc Op Ar id List VMs running on the host, optionally listing just the selected VM .Ar id . +If the +.Fl r +flag is present, the output will only contain running VMs. .It Cm stop Oo Fl fw Oc Oo Fl a | Ar id Oc Stop (terminate) a VM defined by the specified VM .Ar id diff --git a/usr.sbin/vmctl/vmctl.c b/usr.sbin/vmctl/vmctl.c index ba05a7322..e08f032c0 100644 --- a/usr.sbin/vmctl/vmctl.c +++ b/usr.sbin/vmctl/vmctl.c @@ -1,4 +1,4 @@ -/* $OpenBSD: vmctl.c,v 1.89 2023/11/09 12:26:08 dv Exp $ */ +/* $OpenBSD: vmctl.c,v 1.90 2024/05/02 15:46:10 mlarkin Exp $ */ /* * Copyright (c) 2014 Mike Larkin @@ -779,6 +779,7 @@ print_vm_info(struct vmop_info_result *list, size_t ct) char user[16], group[16]; const char *name; int running; + extern int stat_rflag; printf("%5s %5s %5s %7s %7s %7s %12s %8s %s\n", "ID", "PID", "VCPUS", "MAXMEM", "CURMEM", "TTY", "OWNER", "STATE", "NAME"); @@ -787,6 +788,8 @@ print_vm_info(struct vmop_info_result *list, size_t ct) vmi = &list[i]; vir = &vmi->vir_info; running = (vir->vir_creator_pid != 0 && vir->vir_id != 0); + if (!running && stat_rflag) + continue; if (check_info_id(vir->vir_name, vir->vir_id)) { /* get user name */ name = user_from_uid(vmi->vir_uid, 1);