PERFORCE change 114776 for review
Jung-uk Kim
jkim at FreeBSD.org
Tue Feb 20 23:42:45 UTC 2007
http://perforce.freebsd.org/chv.cgi?CH=114776
Change 114776 by jkim at 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 at 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 at 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) <<<
More information about the p4-projects
mailing list