Date: Tue, 20 Feb 2007 23:42:44 GMT From: Jung-uk Kim <jkim@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 114776 for review Message-ID: <200702202342.l1KNgiGr056886@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=114776 Change 114776 by jkim@jkim_hammer on 2007/02/20 23:41:57 IFC Affected files ... .. //depot/projects/linuxolator/src/sys/dev/iwi/if_iwi.c#8 integrate .. //depot/projects/linuxolator/src/sys/dev/iwi/if_iwireg.h#3 integrate .. //depot/projects/linuxolator/src/sys/dev/iwi/if_iwivar.h#3 integrate .. //depot/projects/linuxolator/src/sys/kern/kern_jail.c#6 integrate .. //depot/projects/linuxolator/src/sys/kern/sysv_ipc.c#4 integrate .. //depot/projects/linuxolator/src/sys/kern/sysv_shm.c#4 integrate .. //depot/projects/linuxolator/src/sys/kern/uipc_usrreq.c#8 integrate .. //depot/projects/linuxolator/src/sys/net/if_ppp.c#6 integrate .. //depot/projects/linuxolator/src/sys/netinet/tcp_input.c#8 integrate .. //depot/projects/linuxolator/src/sys/netinet/udp.h#2 integrate .. //depot/projects/linuxolator/src/sys/netinet/udp_usrreq.c#6 integrate .. //depot/projects/linuxolator/src/sys/netinet/udp_var.h#2 integrate .. //depot/projects/linuxolator/src/sys/netinet6/udp6_usrreq.c#4 integrate .. //depot/projects/linuxolator/src/sys/security/audit/audit_arg.c#5 integrate .. //depot/projects/linuxolator/src/sys/security/mac_bsdextended/mac_bsdextended.c#5 integrate .. //depot/projects/linuxolator/src/sys/sys/priv.h#3 integrate Differences ... ==== //depot/projects/linuxolator/src/sys/dev/iwi/if_iwi.c#8 (text+ko) ==== @@ -27,7 +27,7 @@ */ #include <sys/cdefs.h> -__FBSDID("$FreeBSD: src/sys/dev/iwi/if_iwi.c,v 1.46 2007/02/15 17:21:31 luigi Exp $"); +__FBSDID("$FreeBSD: src/sys/dev/iwi/if_iwi.c,v 1.48 2007/02/20 17:32:30 luigi Exp $"); /*- * Intel(R) PRO/Wireless 2200BG/2225BG/2915ABG driver @@ -157,6 +157,7 @@ static int iwi_reset(struct iwi_softc *); static int iwi_load_ucode(struct iwi_softc *, const struct iwi_fw *); static int iwi_load_firmware(struct iwi_softc *, const struct iwi_fw *); +static void iwi_release_fw_dma(struct iwi_softc *sc); static int iwi_config(struct iwi_softc *); static int iwi_get_firmware(struct iwi_softc *); static void iwi_put_firmware(struct iwi_softc *); @@ -331,34 +332,17 @@ goto fail; } - error = iwi_alloc_tx_ring(sc, &sc->txq[0], IWI_TX_RING_COUNT, - IWI_CSR_TX1_RIDX, IWI_CSR_TX1_WIDX); - if (error != 0) { - device_printf(dev, "could not allocate Tx ring 1\n"); - goto fail; + for (i = 0; i < 4; i++) { + error = iwi_alloc_tx_ring(sc, &sc->txq[i], IWI_TX_RING_COUNT, + IWI_CSR_TX1_RIDX + i * 4, + IWI_CSR_TX1_WIDX + i * 4); + if (error != 0) { + device_printf(dev, "could not allocate Tx ring %d\n", + i+i); + goto fail; + } } - error = iwi_alloc_tx_ring(sc, &sc->txq[1], IWI_TX_RING_COUNT, - IWI_CSR_TX2_RIDX, IWI_CSR_TX2_WIDX); - if (error != 0) { - device_printf(dev, "could not allocate Tx ring 2\n"); - goto fail; - } - - error = iwi_alloc_tx_ring(sc, &sc->txq[2], IWI_TX_RING_COUNT, - IWI_CSR_TX3_RIDX, IWI_CSR_TX3_WIDX); - if (error != 0) { - device_printf(dev, "could not allocate Tx ring 3\n"); - goto fail; - } - - error = iwi_alloc_tx_ring(sc, &sc->txq[3], IWI_TX_RING_COUNT, - IWI_CSR_TX4_RIDX, IWI_CSR_TX4_WIDX); - if (error != 0) { - device_printf(dev, "could not allocate Tx ring 4\n"); - goto fail; - } - if (iwi_alloc_rx_ring(sc, &sc->rxq, IWI_RX_RING_COUNT) != 0) { device_printf(dev, "could not allocate Rx ring\n"); goto fail; @@ -496,6 +480,7 @@ ieee80211_ifdetach(ic); } iwi_put_firmware(sc); + iwi_release_fw_dma(sc); iwi_free_cmd_ring(sc, &sc->cmdq); iwi_free_tx_ring(sc, &sc->txq[0]); @@ -970,6 +955,7 @@ struct ifnet *ifp = ic->ic_ifp; struct iwi_softc *sc = ifp->if_softc; + IWI_LOCK_CHECK(sc); DPRINTF(("%s: %s -> %s flags 0x%x\n", __func__, ieee80211_state_name[ic->ic_state], ieee80211_state_name[nstate], sc->flags)); @@ -1216,6 +1202,7 @@ { struct ieee80211com *ic = &sc->sc_ic; + IWI_LOCK_CHECK(sc); ic->ic_curchan = &ic->ic_channels[chan]; sc->curchan = chan; @@ -1709,6 +1696,8 @@ { struct iwi_cmd_desc *desc; + IWI_LOCK_CHECK(sc); + if (sc->flags & IWI_FLAG_BUSY) { device_printf(sc->sc_dev, "%s: cmd %d not sent, busy\n", __func__, type); @@ -1771,6 +1760,7 @@ int error, nsegs, hdrlen, i; int ismcast, flags, xflags, staid; + IWI_LOCK_CHECK(sc); wh = mtod(m0, const struct ieee80211_frame *); /* NB: only data frames use this path */ hdrlen = ieee80211_hdrsize(wh); @@ -2064,6 +2054,13 @@ IWI_LOCK(sc); + /* + * wait until pending iwi_cmd() are completed, to avoid races + * that could cause problems. + */ + while (sc->flags & IWI_FLAG_BUSY) + msleep(sc, &sc->sc_mtx, 0, "iwiioctl", hz); + switch (cmd) { case SIOCSIFFLAGS: if (ifp->if_flags & IFF_UP) { @@ -2080,7 +2077,6 @@ */ sc->sc_rfkill_timer = 0; } - iwi_put_firmware(sc); } break; @@ -2107,6 +2103,8 @@ uint32_t tmp; int ntries; + IWI_LOCK_CHECK(sc); + /* disable interrupts */ CSR_WRITE_4(sc, IWI_CSR_INTR_MASK, 0); @@ -2223,6 +2221,7 @@ * This is necessary because we re-init the device sometimes * from a context where we cannot read from the filesystem * (e.g. from the taskqueue thread when rfkill is re-enabled). + * XXX return 0 on success, 1 on error. * * NB: the order of get'ing and put'ing images here is * intentional to support handling firmware images bundled @@ -2306,33 +2305,38 @@ /* * Check and setup combined image. */ - if (fp->datasize < sizeof(hdr)) { + if (fp->datasize < sizeof(struct iwi_firmware_hdr)) { device_printf(sc->sc_dev, "image '%s' too small\n", fp->name); goto bad; } hdr = (const struct iwi_firmware_hdr *)fp->data; - if (fp->datasize < sizeof(*hdr) + hdr->bsize + hdr->usize + hdr->fsize) { + if (fp->datasize < sizeof(*hdr) + le32toh(hdr->bsize) + le32toh(hdr->usize) + + le32toh(hdr->fsize)) { device_printf(sc->sc_dev, "image '%s' too small (2)\n", fp->name); goto bad; } sc->fw_boot.data = ((const char *) fp->data) + sizeof(*hdr); - sc->fw_boot.size = hdr->bsize; + sc->fw_boot.size = le32toh(hdr->bsize); sc->fw_boot.name = fp->name; sc->fw_uc.data = sc->fw_boot.data + sc->fw_boot.size; - sc->fw_uc.size = hdr->usize; + sc->fw_uc.size = le32toh(hdr->usize); sc->fw_uc.name = fp->name; sc->fw_fw.data = sc->fw_uc.data + sc->fw_uc.size; - sc->fw_fw.size = hdr->fsize; + sc->fw_fw.size = le32toh(hdr->fsize); sc->fw_fw.name = fp->name; } +#if 0 + device_printf(sc->sc_dev, "boot %d ucode %d fw %d bytes\n", + sc->fw_boot.size, sc->fw_uc.size, sc->fw_fw.size); +#endif sc->fw_mode = ic->ic_opmode; - return 1; + return 0; bad: iwi_put_firmware(sc); - return 0; + return 1; } static void @@ -2367,6 +2371,7 @@ size_t size = fw->size; int i, ntries, error; + IWI_LOCK_CHECK(sc); error = 0; CSR_WRITE_4(sc, IWI_CSR_RST, CSR_READ_4(sc, IWI_CSR_RST) | IWI_RST_STOP_MASTER); @@ -2439,6 +2444,7 @@ uint32_t sentinel, ctl, src, dst, sum, len, mlen, tmp; int ntries, error; + IWI_LOCK_CHECK(sc); /* copy firmware image to DMA memory */ memcpy(sc->fw_virtaddr, fw->data, fw->size); @@ -2498,12 +2504,13 @@ break; DELAY(100); } + /* sync dma, just in case */ + bus_dmamap_sync(sc->fw_dmat, sc->fw_map, BUS_DMASYNC_POSTWRITE); if (ntries == 400) { device_printf(sc->sc_dev, "timeout processing command blocks for %s firmware\n", fw->name); - error = EIO; - goto fail5; + return EIO; } /* we're done with command blocks processing */ @@ -2524,7 +2531,6 @@ "initialization to complete\n", fw->name); } -fail5: return error; } @@ -2580,6 +2586,7 @@ struct iwi_txpower power; uint32_t data; int error, i; + IWI_LOCK_CHECK(sc); IEEE80211_ADDR_COPY(ic->ic_myaddr, IF_LLADDR(ifp)); DPRINTF(("Setting MAC address to %6D\n", ic->ic_myaddr, ":")); @@ -2707,6 +2714,8 @@ struct iwi_scan_ext scan; int i, ix, start, scan_type, error; + IWI_LOCK_CHECK(sc); + memset(&scan, 0, sizeof scan); /* XXX different dwell times for different scan types */ @@ -2908,7 +2917,8 @@ struct iwi_rateset rs; uint16_t capinfo; int error; - + + IWI_LOCK_CHECK(sc); if (IEEE80211_IS_CHAN_2GHZ(ni->ni_chan)) { memset(&config, 0, sizeof config); config.bluetooth_coexistence = sc->bluetooth; @@ -3077,6 +3087,66 @@ IWI_UNLOCK(sc); } +/* + * release dma resources for the firmware + */ +static void +iwi_release_fw_dma(struct iwi_softc *sc) +{ + if (sc->fw_flags & IWI_FW_HAVE_PHY) + bus_dmamap_unload(sc->fw_dmat, sc->fw_map); + if (sc->fw_flags & IWI_FW_HAVE_MAP) + bus_dmamem_free(sc->fw_dmat, sc->fw_virtaddr, sc->fw_map); + if (sc->fw_flags & IWI_FW_HAVE_DMAT) + bus_dma_tag_destroy(sc->fw_dmat); + + sc->fw_flags = 0; + sc->fw_dma_size = 0; + sc->fw_dmat = NULL; + sc->fw_map = NULL; + sc->fw_physaddr = 0; + sc->fw_virtaddr = NULL; +} + +/* + * allocate the dma descriptor for the firmware. + * Return 0 on success, 1 on error. + * Must be called unlocked, protected by IWI_FLAG_FW_LOADING. + */ +static int +iwi_init_fw_dma(struct iwi_softc *sc, int size) +{ + if (sc->fw_dma_size > size) + return 0; + if (bus_dma_tag_create(bus_get_dma_tag(sc->sc_dev), 4, 0, + BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL, + size, 1, size, 0, NULL, NULL, &sc->fw_dmat) != 0) { + device_printf(sc->sc_dev, + "could not create firmware DMA tag\n"); + goto error; + } + sc->fw_flags |= IWI_FW_HAVE_DMAT; + if (bus_dmamem_alloc(sc->fw_dmat, &sc->fw_virtaddr, 0, + &sc->fw_map) != 0) { + device_printf(sc->sc_dev, + "could not allocate firmware DMA memory\n"); + goto error; + } + sc->fw_flags |= IWI_FW_HAVE_MAP; + if (bus_dmamap_load(sc->fw_dmat, sc->fw_map, sc->fw_virtaddr, + size, iwi_dma_map_addr, &sc->fw_physaddr, 0) != 0) { + device_printf(sc->sc_dev, "could not load firmware DMA map\n"); + goto error; + } + sc->fw_flags |= IWI_FW_HAVE_PHY; + sc->fw_dma_size = size; + return 0; + +error: + iwi_release_fw_dma(sc); + return 1; +} + static void iwi_init_locked(void *priv, int force) { @@ -3087,8 +3157,11 @@ int i; IWI_LOCK_DECL; - if (sc->flags & IWI_FLAG_FW_LOADING) + IWI_LOCK_CHECK(sc); + if (sc->flags & IWI_FLAG_FW_LOADING) { + device_printf(sc->sc_dev, "%s: already loading\n", __func__); return; /* XXX: condvar? */ + } iwi_stop(sc); @@ -3100,53 +3173,34 @@ sc->flags |= IWI_FLAG_FW_LOADING; IWI_UNLOCK(sc); - if (!iwi_get_firmware(sc)) { + if (iwi_get_firmware(sc)) { IWI_LOCK(sc); goto fail; } /* allocate DMA memory for mapping firmware image */ - if (sc->fw_boot.size > sc->fw_dma_size) - sc->fw_dma_size = sc->fw_boot.size; - if (sc->fw_fw.size > sc->fw_dma_size) - sc->fw_dma_size = sc->fw_fw.size; - if (sc->fw_uc.size > sc->fw_dma_size) - sc->fw_dma_size = sc->fw_uc.size; - - if (bus_dma_tag_create(bus_get_dma_tag(sc->sc_dev), 4, 0, - BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL, - sc->fw_dma_size, 1, sc->fw_dma_size, 0, NULL, NULL, - &sc->fw_dmat) != 0) { - device_printf(sc->sc_dev, - "could not create firmware DMA tag\n"); + i = sc->fw_fw.size; + if (sc->fw_boot.size > i) + i = sc->fw_boot.size; + /* XXX do we dma the ucode as well ? */ + if (sc->fw_uc.size > i) + i = sc->fw_uc.size; + if (iwi_init_fw_dma(sc, i)) { IWI_LOCK(sc); goto fail; } - if (bus_dmamem_alloc(sc->fw_dmat, &sc->fw_virtaddr, 0, - &sc->fw_map) != 0) { - device_printf(sc->sc_dev, - "could not allocate firmware DMA memory\n"); - IWI_LOCK(sc); - goto fail2; - } - if (bus_dmamap_load(sc->fw_dmat, sc->fw_map, sc->fw_virtaddr, - sc->fw_dma_size, iwi_dma_map_addr, &sc->fw_physaddr, 0) != 0) { - device_printf(sc->sc_dev, "could not load firmware DMA map\n"); - IWI_LOCK(sc); - goto fail3; - } IWI_LOCK(sc); if (iwi_load_firmware(sc, &sc->fw_boot) != 0) { device_printf(sc->sc_dev, "could not load boot firmware %s\n", sc->fw_boot.name); - goto fail4; + goto fail; } if (iwi_load_ucode(sc, &sc->fw_uc) != 0) { device_printf(sc->sc_dev, "could not load microcode %s\n", sc->fw_uc.name); - goto fail4; + goto fail; } iwi_stop_master(sc); @@ -3181,15 +3235,10 @@ if (iwi_load_firmware(sc, &sc->fw_fw) != 0) { device_printf(sc->sc_dev, "could not load main firmware %s\n", sc->fw_fw.name); - goto fail4; + goto fail; } sc->flags |= IWI_FLAG_FW_INITED; - bus_dmamap_sync(sc->fw_dmat, sc->fw_map, BUS_DMASYNC_POSTWRITE); - bus_dmamap_unload(sc->fw_dmat, sc->fw_map); - bus_dmamem_free(sc->fw_dmat, sc->fw_virtaddr, sc->fw_map); - bus_dma_tag_destroy(sc->fw_dmat); - if (iwi_config(sc) != 0) { device_printf(sc->sc_dev, "device configuration failed\n"); goto fail; @@ -3213,10 +3262,6 @@ sc->flags &= ~IWI_FLAG_FW_LOADING; return; -fail4: bus_dmamap_sync(sc->fw_dmat, sc->fw_map, BUS_DMASYNC_POSTWRITE); - bus_dmamap_unload(sc->fw_dmat, sc->fw_map); -fail3: bus_dmamem_free(sc->fw_dmat, sc->fw_virtaddr, sc->fw_map); -fail2: bus_dma_tag_destroy(sc->fw_dmat); fail: ifp->if_flags &= ~IFF_UP; sc->flags &= ~IWI_FLAG_FW_LOADING; iwi_stop(sc); @@ -3230,6 +3275,7 @@ struct ieee80211com *ic = &sc->sc_ic; struct ifnet *ifp = ic->ic_ifp; + IWI_LOCK_CHECK(sc); /* XXX: pretty sure this triggers */ if (sc->sc_softled) { callout_stop(&sc->sc_ledtimer); sc->sc_blinking = 0; ==== //depot/projects/linuxolator/src/sys/dev/iwi/if_iwireg.h#3 (text+ko) ==== @@ -1,4 +1,4 @@ -/* $FreeBSD: src/sys/dev/iwi/if_iwireg.h,v 1.13 2006/10/23 00:34:07 mlaier Exp $ */ +/* $FreeBSD: src/sys/dev/iwi/if_iwireg.h,v 1.14 2007/02/20 14:29:09 luigi Exp $ */ /*- * Copyright (c) 2004, 2005 @@ -134,7 +134,10 @@ #define IWI_RATE_OFDM48 1 #define IWI_RATE_OFDM54 3 -/* firmware binary image header, fields in little endian */ +/* + * Old version firmware images start with this header, + * fields are in little endian (le32) format. + */ struct iwi_firmware_ohdr { uint32_t version; uint32_t mode; @@ -150,6 +153,11 @@ #define IWI_FW_MODE_IBSS 1 #define IWI_FW_MODE_MONITOR 2 +/* + * New version firmware images contain boot, ucode and firmware + * all in one chunk. The header at the beginning gives the version + * and the size of each (sub)image, in le32 format. + */ struct iwi_firmware_hdr { uint32_t version; /* version stamp */ uint32_t bsize; /* size of boot image */ ==== //depot/projects/linuxolator/src/sys/dev/iwi/if_iwivar.h#3 (text+ko) ==== @@ -1,4 +1,4 @@ -/* $FreeBSD: src/sys/dev/iwi/if_iwivar.h,v 1.12 2007/02/15 17:21:31 luigi Exp $ */ +/* $FreeBSD: src/sys/dev/iwi/if_iwivar.h,v 1.14 2007/02/20 17:32:30 luigi Exp $ */ /*- * Copyright (c) 2004, 2005 @@ -149,7 +149,22 @@ int mem_rid; int irq_rid; + /* + * The card needs external firmware images to work, which is made of a + * bootloader, microcode and firmware proper. In version 3.00 and + * above, all pieces are contained in a single image, preceded by a + * struct iwi_firmware_hdr indicating the size of the 3 pieces. + * Old firmware < 3.0 has separate boot and ucode, so we need to + * load all of them explicitly. + * To avoid issues related to fragmentation, we keep the block of + * dma-ble memory around until detach time, and reallocate it when + * it becomes too small. fw_dma_size is the size currently allocated. + */ int fw_dma_size; + uint32_t fw_flags; /* allocation status */ +#define IWI_FW_HAVE_DMAT 0x01 +#define IWI_FW_HAVE_MAP 0x02 +#define IWI_FW_HAVE_PHY 0x04 bus_dma_tag_t fw_dmat; bus_dmamap_t fw_map; bus_addr_t fw_physaddr; @@ -216,6 +231,10 @@ * and must be kept in sync. */ #define IWI_LOCK_DECL int __waslocked = 0 +#define IWI_LOCK_CHECK(sc) do { \ + if (!mtx_owned(&(sc)->sc_mtx)) \ + DPRINTF(("%s iwi_lock not held\n", __func__)); \ +} while (0) #define IWI_LOCK(sc) do { \ if (!(__waslocked = mtx_owned(&(sc)->sc_mtx))) \ mtx_lock(&(sc)->sc_mtx); \ ==== //depot/projects/linuxolator/src/sys/kern/kern_jail.c#6 (text+ko) ==== @@ -8,7 +8,7 @@ */ #include <sys/cdefs.h> -__FBSDID("$FreeBSD: src/sys/kern/kern_jail.c,v 1.57 2007/02/19 13:33:09 rwatson Exp $"); +__FBSDID("$FreeBSD: src/sys/kern/kern_jail.c,v 1.58 2007/02/20 00:12:52 rwatson Exp $"); #include "opt_mac.h" @@ -596,7 +596,6 @@ */ case PRIV_IPC_READ: case PRIV_IPC_WRITE: - case PRIV_IPC_EXEC: case PRIV_IPC_ADMIN: case PRIV_IPC_MSGSIZE: case PRIV_MQ_ADMIN: ==== //depot/projects/linuxolator/src/sys/kern/sysv_ipc.c#4 (text+ko) ==== @@ -1,8 +1,12 @@ /* $NetBSD: sysv_ipc.c,v 1.7 1994/06/29 06:33:11 cgd Exp $ */ /*- * Copyright (c) 1994 Herb Peyerl <hpeyerl@novatel.ca> + * Copyright (c) 2006 nCircle Network Security, Inc. * All rights reserved. * + * This software was developed by Robert N. M. Watson for the TrustedBSD + * Project under contract to nCircle Network Security, Inc. + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: @@ -30,7 +34,7 @@ */ #include <sys/cdefs.h> -__FBSDID("$FreeBSD: src/sys/kern/sysv_ipc.c,v 1.31 2006/12/16 11:30:54 rwatson Exp $"); +__FBSDID("$FreeBSD: src/sys/kern/sysv_ipc.c,v 1.33 2007/02/20 00:06:59 rwatson Exp $"); #include "opt_sysvipc.h" @@ -39,6 +43,7 @@ #include <sys/sem.h> #include <sys/shm.h> #include <sys/ipc.h> +#include <sys/priv.h> #include <sys/proc.h> #include <sys/ucred.h> @@ -72,50 +77,76 @@ * Note: The MAC Framework does not require any modifications to the * ipcperm() function, as access control checks are performed throughout the * implementation of each primitive. Those entry point calls complement the - * ipcperm() discertionary checks. + * ipcperm() discertionary checks. Unlike file system discretionary access + * control, the original create of an object is given the same rights as the + * current owner. */ int -ipcperm(td, perm, mode) - struct thread *td; - struct ipc_perm *perm; - int mode; +ipcperm(struct thread *td, struct ipc_perm *perm, int acc_mode) { struct ucred *cred = td->td_ucred; - int error; + int error, obj_mode, dac_granted, priv_granted; - if (cred->cr_uid != perm->cuid && cred->cr_uid != perm->uid) { - /* - * For a non-create/owner, we require privilege to - * modify the object protections. Note: some other - * implementations permit IPC_M to be delegated to - * unprivileged non-creator/owner uids/gids. - */ - if (mode & IPC_M) { - error = suser(td); - if (error) - return (error); - } - /* - * Try to match against creator/owner group; if not, fall - * back on other. - */ - mode >>= 3; - if (!groupmember(perm->gid, cred) && - !groupmember(perm->cgid, cred)) - mode >>= 3; + dac_granted = 0; + if (cred->cr_uid == perm->cuid || cred->cr_uid == perm->uid) { + obj_mode = perm->mode; + dac_granted |= IPC_M; + } else if (groupmember(perm->gid, cred) || + groupmember(perm->cgid, cred)) { + obj_mode = perm->mode; + obj_mode <<= 3; } else { - /* - * Always permit the creator/owner to update the object - * protections regardless of whether the object mode - * permits it. - */ - if (mode & IPC_M) - return (0); + obj_mode = perm->mode; + obj_mode <<= 6; + } + + /* + * While the System V IPC permission model allows IPC_M to be + * granted, as part of the mode, our implementation requires + * privilege to adminster the object if not the owner or creator. + */ +#if 0 + if (obj_mode & IPC_M) + dac_granted |= IPC_M; +#endif + if (obj_mode & IPC_R) + dac_granted |= IPC_R; + if (obj_mode & IPC_W) + dac_granted |= IPC_W; + + /* + * Simple case: all required rights are granted by DAC. + */ + if ((dac_granted & acc_mode) == acc_mode) + return (0); + + /* + * Privilege is required to satisfy the request. + */ + priv_granted = 0; + if ((acc_mode & IPC_M) && !(dac_granted & IPC_M)) { + error = priv_check_cred(td->td_ucred, PRIV_IPC_ADMIN, + SUSER_ALLOWJAIL); + if (error == 0) + priv_granted |= IPC_M; + } + + if ((acc_mode & IPC_R) && !(dac_granted & IPC_R)) { + error = priv_check_cred(td->td_ucred, PRIV_IPC_READ, + SUSER_ALLOWJAIL); + if (error == 0) + priv_granted |= IPC_R; } - if ((mode & perm->mode) != mode) { - if (suser(td) != 0) - return (EACCES); + if ((acc_mode & IPC_W) && !(dac_granted & IPC_W)) { + error = priv_check_cred(td->td_ucred, PRIV_IPC_WRITE, + SUSER_ALLOWJAIL); + if (error == 0) + priv_granted |= IPC_W; } - return (0); + + if (((dac_granted | priv_granted) & acc_mode) == acc_mode) + return (0); + else + return (EACCES); } ==== //depot/projects/linuxolator/src/sys/kern/sysv_shm.c#4 (text+ko) ==== @@ -60,7 +60,7 @@ */ #include <sys/cdefs.h> -__FBSDID("$FreeBSD: src/sys/kern/sysv_shm.c,v 1.108 2006/10/22 11:52:13 rwatson Exp $"); +__FBSDID("$FreeBSD: src/sys/kern/sysv_shm.c,v 1.109 2007/02/19 22:56:10 rwatson Exp $"); #include "opt_compat.h" #include "opt_sysvipc.h" @@ -722,9 +722,6 @@ if (error != 0) return (error); #endif - error = ipcperm(td, &shmseg->u.shm_perm, mode); - if (error) - return (error); if (uap->size && uap->size > shmseg->u.shm_segsz) return (EINVAL); td->td_retval[0] = IXSEQ_TO_IPCID(segnum, shmseg->u.shm_perm); ==== //depot/projects/linuxolator/src/sys/kern/uipc_usrreq.c#8 (text+ko) ==== @@ -41,12 +41,13 @@ * connected in pairs (socketpair(2)), or bound/connected to using the file * system name space. For most purposes, only the receive socket buffer is * used, as sending on one socket delivers directly to the receive socket - * buffer of a second socket. The implementation is substantially - * complicated by the fact that "ancillary data", such as file descriptors or - * credentials, may be passed across UNIX domain sockets. The potential for - * passing UNIX domain sockets over other UNIX domain sockets requires the - * implementation of a simple garbage collector to find and tear down cycles - * of disconnected sockets. + * buffer of a second socket. + * + * The implementation is substantially complicated by the fact that + * "ancillary data", such as file descriptors or credentials, may be passed + * across UNIX domain sockets. The potential for passing UNIX domain sockets + * over other UNIX domain sockets requires the implementation of a simple + * garbage collector to find and tear down cycles of disconnected sockets. * * TODO: * SEQPACKET, RDM @@ -56,7 +57,7 @@ */ #include <sys/cdefs.h> -__FBSDID("$FreeBSD: src/sys/kern/uipc_usrreq.c,v 1.194 2007/02/14 15:05:40 rwatson Exp $"); +__FBSDID("$FreeBSD: src/sys/kern/uipc_usrreq.c,v 1.195 2007/02/20 10:50:02 rwatson Exp $"); #include "opt_mac.h" @@ -184,7 +185,7 @@ static int unp_internalize(struct mbuf **, struct thread *); static int unp_listen(struct socket *, struct unpcb *, int, struct thread *); -struct mbuf *unp_addsockcred(struct thread *, struct mbuf *); +static struct mbuf *unp_addsockcred(struct thread *, struct mbuf *); /* * Definitions of protocols supported in the LOCAL domain. @@ -461,10 +462,6 @@ unp->unp_gencnt = ++unp_gencnt; --unp_count; if ((vp = unp->unp_vnode) != NULL) { - /* - * XXXRW: should v_socket be frobbed only while holding - * Giant? - */ unp->unp_vnode->v_socket = NULL; unp->unp_vnode = NULL; } @@ -1557,7 +1554,7 @@ return (error); } -struct mbuf * +static struct mbuf * unp_addsockcred(struct thread *td, struct mbuf *control) { struct mbuf *m, *n, *n_prev; ==== //depot/projects/linuxolator/src/sys/net/if_ppp.c#6 (text+ko) ==== @@ -71,7 +71,7 @@ * Paul Mackerras (paulus@cs.anu.edu.au). */ -/* $FreeBSD: src/sys/net/if_ppp.c,v 1.119 2006/12/05 18:54:21 ume Exp $ */ +/* $FreeBSD: src/sys/net/if_ppp.c,v 1.120 2007/02/20 15:20:36 rwatson Exp $ */ /* from if_sl.c,v 1.11 84/10/04 12:54:47 rick Exp */ /* from NetBSD: if_ppp.c,v 1.15.2.2 1994/07/28 05:17:58 cgd Exp */ @@ -719,7 +719,8 @@ * XXXRW: Isn't this suser() check redundant to the one at the ifnet * layer? */ - if ((error = suser(td)) != 0) + error = priv_check(td, PRIV_NET_SETIFMTU); + if (error) break; if (ifr->ifr_mtu > PPP_MAXMTU) error = EINVAL; ==== //depot/projects/linuxolator/src/sys/netinet/tcp_input.c#8 (text+ko) ==== @@ -27,7 +27,7 @@ * SUCH DAMAGE. * * @(#)tcp_input.c 8.12 (Berkeley) 5/24/95 - * $FreeBSD: src/sys/netinet/tcp_input.c,v 1.312 2007/02/01 18:32:13 andre Exp $ + * $FreeBSD: src/sys/netinet/tcp_input.c,v 1.313 2007/02/20 10:20:02 rwatson Exp $ */ #include "opt_ipfw.h" /* for ipfw_fwd */ @@ -105,9 +105,9 @@ SYSCTL_STRUCT(_net_inet_tcp, TCPCTL_STATS, stats, CTLFLAG_RW, &tcpstat , tcpstat, "TCP statistics (struct tcpstat, netinet/tcp_var.h)"); -static int log_in_vain = 0; +static int tcp_log_in_vain = 0; SYSCTL_INT(_net_inet_tcp, OID_AUTO, log_in_vain, CTLFLAG_RW, - &log_in_vain, 0, "Log all incoming TCP connections"); + &tcp_log_in_vain, 0, "Log all incoming TCP connections"); static int blackhole = 0; SYSCTL_INT(_net_inet_tcp, OID_AUTO, blackhole, CTLFLAG_RW, @@ -714,7 +714,7 @@ * but should either do a listen or a connect soon. */ if (inp == NULL) { - if (log_in_vain) { + if (tcp_log_in_vain) { #ifdef INET6 char dbuf[INET6_ADDRSTRLEN+2], sbuf[INET6_ADDRSTRLEN+2]; #else @@ -736,7 +736,7 @@ strcpy(dbuf, inet_ntoa(ip->ip_dst)); strcpy(sbuf, inet_ntoa(ip->ip_src)); } - switch (log_in_vain) { + switch (tcp_log_in_vain) { case 1: if ((thflags & TH_SYN) == 0) break; ==== //depot/projects/linuxolator/src/sys/netinet/udp.h#2 (text+ko) ==== @@ -1,6 +1,7 @@ /*- * Copyright (c) 1982, 1986, 1993 - * The Regents of the University of California. All rights reserved. + * The Regents of the University of California. + * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -27,14 +28,14 @@ * SUCH DAMAGE. * * @(#)udp.h 8.1 (Berkeley) 6/10/93 - * $FreeBSD: src/sys/netinet/udp.h,v 1.9 2005/01/07 01:45:45 imp Exp $ + * $FreeBSD: src/sys/netinet/udp.h,v 1.10 2007/02/20 10:13:11 rwatson Exp $ */ #ifndef _NETINET_UDP_H_ -#define _NETINET_UDP_H_ +#define _NETINET_UDP_H_ /* - * Udp protocol header. + * UDP protocol header. * Per RFC 768, September, 1981. */ struct udphdr { ==== //depot/projects/linuxolator/src/sys/netinet/udp_usrreq.c#6 (text+ko) ==== @@ -1,6 +1,7 @@ /*- * Copyright (c) 1982, 1986, 1988, 1990, 1993, 1995 - * The Regents of the University of California. All rights reserved. + * The Regents of the University of California. + * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -27,7 +28,7 @@ * SUCH DAMAGE. * * @(#)udp_usrreq.c 8.6 (Berkeley) 5/23/95 - * $FreeBSD: src/sys/netinet/udp_usrreq.c,v 1.200 2007/01/06 13:12:24 maxim Exp $ + * $FreeBSD: src/sys/netinet/udp_usrreq.c,v 1.202 2007/02/20 10:20:02 rwatson Exp $ */ #include "opt_ipfw.h" @@ -79,11 +80,11 @@ #ifdef FAST_IPSEC #include <netipsec/ipsec.h> -#endif /*FAST_IPSEC*/ +#endif #ifdef IPSEC #include <netinet6/ipsec.h> -#endif /*IPSEC*/ +#endif #include <machine/in_cksum.h> @@ -95,33 +96,28 @@ */ /* - * BSD 4.2 defaulted the udp checksum to be off. Turning off udp - * checksums removes the only data integrity mechanism for packets and - * malformed packets that would otherwise be discarded by bad checksums - * may cause problems (especially for NFS data blocks). + * BSD 4.2 defaulted the udp checksum to be off. Turning off udp checksums + * removes the only data integrity mechanism for packets and malformed + * packets that would otherwise be discarded by bad checksums may cause + * problems (especially for NFS data blocks). */ -#ifndef COMPAT_42 static int udpcksum = 1; -#else -static int udpcksum = 0; -#endif -SYSCTL_INT(_net_inet_udp, UDPCTL_CHECKSUM, checksum, CTLFLAG_RW, - &udpcksum, 0, ""); +SYSCTL_INT(_net_inet_udp, UDPCTL_CHECKSUM, checksum, CTLFLAG_RW, &udpcksum, + 0, ""); -int log_in_vain = 0; +int udp_log_in_vain = 0; SYSCTL_INT(_net_inet_udp, OID_AUTO, log_in_vain, CTLFLAG_RW, - &log_in_vain, 0, "Log all incoming UDP packets"); + &udp_log_in_vain, 0, "Log all incoming UDP packets"); static int blackhole = 0; -SYSCTL_INT(_net_inet_udp, OID_AUTO, blackhole, CTLFLAG_RW, - &blackhole, 0, "Do not send port unreachables for refused connects"); +SYSCTL_INT(_net_inet_udp, OID_AUTO, blackhole, CTLFLAG_RW, &blackhole, 0, + "Do not send port unreachables for refused connects"); static int strict_mcast_mship = 0; SYSCTL_INT(_net_inet_udp, OID_AUTO, strict_mcast_mship, CTLFLAG_RW, - &strict_mcast_mship, 0, "Only send multicast to member sockets"); + &strict_mcast_mship, 0, "Only send multicast to member sockets"); struct inpcbhead udb; /* from udp_var.h */ -#define udb6 udb /* for KAME src sync over BSD*'s */ struct inpcbinfo udbinfo; #ifndef UDBHASHSIZE @@ -129,15 +125,15 @@ #endif struct udpstat udpstat; /* from udp_var.h */ -SYSCTL_STRUCT(_net_inet_udp, UDPCTL_STATS, stats, CTLFLAG_RW, - &udpstat, udpstat, "UDP statistics (struct udpstat, netinet/udp_var.h)"); +SYSCTL_STRUCT(_net_inet_udp, UDPCTL_STATS, stats, CTLFLAG_RW, &udpstat, + udpstat, "UDP statistics (struct udpstat, netinet/udp_var.h)"); -static void udp_append(struct inpcb *last, struct ip *ip, struct mbuf *n, - int off, struct sockaddr_in *udp_in); +static void udp_append(struct inpcb *last, struct ip *ip, struct mbuf *n, + int off, struct sockaddr_in *udp_in); -static void udp_detach(struct socket *so); -static int udp_output(struct inpcb *, struct mbuf *, struct sockaddr *, - struct mbuf *, struct thread *); +static void udp_detach(struct socket *so); +static int udp_output(struct inpcb *, struct mbuf *, struct sockaddr *, + struct mbuf *, struct thread *); static void udp_zone_change(void *tag) @@ -163,7 +159,7 @@ udbinfo.listhead = &udb; udbinfo.hashbase = hashinit(UDBHASHSIZE, M_PCB, &udbinfo.hashmask); udbinfo.porthashbase = hashinit(UDBHASHSIZE, M_PCB, - &udbinfo.porthashmask); + &udbinfo.porthashmask); udbinfo.ipi_zone = uma_zcreate("udpcb", sizeof(struct inpcb), NULL, NULL, udp_inpcb_init, NULL, UMA_ALIGN_PTR, UMA_ZONE_NOFREE); uma_zone_set_max(udbinfo.ipi_zone, maxsockets); @@ -172,14 +168,12 @@ } void -udp_input(m, off) - register struct mbuf *m; - int off; >>> TRUNCATED FOR MAIL (1000 lines) <<<
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200702202342.l1KNgiGr056886>
