[PATCH 0/2] MAP_VALIDATE and mmap flags validation
by Dan Williams
As noted in patch2:
The mmap(2) syscall suffers from the ABI anti-pattern of not validating
unknown flags. However, proposals like MAP_SYNC and MAP_DIRECT need a
mechanism to define new behavior that is known to fail on older kernels
without the support. Define a new MAP_VALIDATE flag pattern that is
guaranteed to fail on all legacy mmap implementations.
On the assumption that it is too late to finalize either MAP_SYNC or
MAP_DIRECT for 4.14 inclusion I would still like to pursue getting at
least patch1 in for 4.14. This allows development of these new flags for
4.15 without worrying about new ->mmap() operation instances added
during the cycle. I.e. I would rebase these from v4.13-rc5 to the state
of the tree right before v4.14-rc1 and re-run the Coccinelle script.
Questions:
1/ Are there any objections to MAP_VALIDATE? I think we bottomed out on
the parisc compatibility concern with the realization that it is
missing fundamental pmem pre-requisite features, like ZONE_DEVICE,
and can otherwise define a new mmap syscall variant.
2/ Linus, are you open to taking a rebased version of patch1 late in the
4.14 window, or have a different suggestion?
---
Dan Williams (2):
vfs: add flags parameter to ->mmap() in 'struct file_operations'
mm: introduce MAP_VALIDATE, a mechanism for for safely defining new mmap flags
arch/arc/kernel/arc_hostlink.c | 3 +
arch/mips/kernel/vdso.c | 2 -
arch/powerpc/kernel/proc_powerpc.c | 3 +
arch/powerpc/kvm/book3s_64_vio.c | 3 +
arch/powerpc/platforms/cell/spufs/file.c | 21 ++++++--
arch/powerpc/platforms/powernv/opal-prd.c | 3 +
arch/um/drivers/mmapper_kern.c | 3 +
drivers/android/binder.c | 3 +
drivers/char/agp/frontend.c | 3 +
drivers/char/bsr.c | 3 +
drivers/char/hpet.c | 6 ++
drivers/char/mbcs.c | 3 +
drivers/char/mbcs.h | 3 +
drivers/char/mem.c | 11 +++-
drivers/char/mspec.c | 9 ++--
drivers/char/uv_mmtimer.c | 6 ++
drivers/dax/device.c | 3 +
drivers/dma-buf/dma-buf.c | 4 +-
drivers/firewire/core-cdev.c | 3 +
drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c | 3 +
drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h | 3 +
drivers/gpu/drm/amd/amdkfd/kfd_chardev.c | 5 +-
drivers/gpu/drm/arc/arcpgu_drv.c | 5 +-
drivers/gpu/drm/ast/ast_drv.h | 3 +
drivers/gpu/drm/ast/ast_ttm.c | 3 +
drivers/gpu/drm/bochs/bochs.h | 3 +
drivers/gpu/drm/bochs/bochs_mm.c | 3 +
drivers/gpu/drm/cirrus/cirrus_drv.h | 3 +
drivers/gpu/drm/cirrus/cirrus_ttm.c | 3 +
drivers/gpu/drm/drm_gem.c | 3 +
drivers/gpu/drm/drm_gem_cma_helper.c | 6 ++
drivers/gpu/drm/drm_vm.c | 3 +
drivers/gpu/drm/etnaviv/etnaviv_drv.h | 3 +
drivers/gpu/drm/etnaviv/etnaviv_gem.c | 5 +-
drivers/gpu/drm/exynos/exynos_drm_gem.c | 5 +-
drivers/gpu/drm/exynos/exynos_drm_gem.h | 3 +
drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.h | 3 +
drivers/gpu/drm/hisilicon/hibmc/hibmc_ttm.c | 3 +
drivers/gpu/drm/i810/i810_dma.c | 3 +
drivers/gpu/drm/i915/i915_gem_dmabuf.c | 2 -
drivers/gpu/drm/mediatek/mtk_drm_gem.c | 5 +-
drivers/gpu/drm/mediatek/mtk_drm_gem.h | 3 +
drivers/gpu/drm/mgag200/mgag200_drv.h | 3 +
drivers/gpu/drm/mgag200/mgag200_ttm.c | 3 +
drivers/gpu/drm/msm/msm_drv.h | 3 +
drivers/gpu/drm/msm/msm_gem.c | 5 +-
drivers/gpu/drm/nouveau/nouveau_ttm.c | 5 +-
drivers/gpu/drm/nouveau/nouveau_ttm.h | 2 -
drivers/gpu/drm/omapdrm/omap_drv.h | 3 +
drivers/gpu/drm/omapdrm/omap_gem.c | 5 +-
drivers/gpu/drm/qxl/qxl_drv.h | 3 +
drivers/gpu/drm/qxl/qxl_ttm.c | 3 +
drivers/gpu/drm/radeon/radeon_drv.c | 3 +
drivers/gpu/drm/radeon/radeon_ttm.c | 3 +
drivers/gpu/drm/rockchip/rockchip_drm_gem.c | 5 +-
drivers/gpu/drm/rockchip/rockchip_drm_gem.h | 3 +
drivers/gpu/drm/tegra/gem.c | 5 +-
drivers/gpu/drm/tegra/gem.h | 3 +
drivers/gpu/drm/udl/udl_drv.h | 3 +
drivers/gpu/drm/udl/udl_gem.c | 5 +-
drivers/gpu/drm/vc4/vc4_bo.c | 5 +-
drivers/gpu/drm/vc4/vc4_drv.h | 3 +
drivers/gpu/drm/vgem/vgem_drv.c | 7 ++-
drivers/gpu/drm/virtio/virtgpu_drv.h | 3 +
drivers/gpu/drm/virtio/virtgpu_ttm.c | 3 +
drivers/gpu/drm/vmwgfx/vmwgfx_drv.h | 3 +
drivers/gpu/drm/vmwgfx/vmwgfx_ttm_glue.c | 3 +
drivers/hsi/clients/cmt_speech.c | 3 +
drivers/hwtracing/intel_th/msu.c | 3 +
drivers/hwtracing/stm/core.c | 3 +
drivers/infiniband/core/uverbs_main.c | 3 +
drivers/infiniband/hw/hfi1/file_ops.c | 6 ++
drivers/infiniband/hw/qib/qib_file_ops.c | 5 +-
drivers/media/v4l2-core/v4l2-dev.c | 3 +
drivers/misc/aspeed-lpc-ctrl.c | 3 +
drivers/misc/cxl/api.c | 5 +-
drivers/misc/cxl/cxl.h | 3 +
drivers/misc/cxl/file.c | 3 +
drivers/misc/genwqe/card_dev.c | 3 +
drivers/misc/mic/scif/scif_fd.c | 3 +
drivers/misc/mic/vop/vop_vringh.c | 3 +
drivers/misc/sgi-gru/grufile.c | 3 +
drivers/mtd/mtdchar.c | 3 +
drivers/pci/proc.c | 3 +
drivers/rapidio/devices/rio_mport_cdev.c | 3 +
drivers/sbus/char/flash.c | 3 +
drivers/sbus/char/jsflash.c | 3 +
drivers/scsi/cxlflash/superpipe.c | 5 +-
drivers/scsi/sg.c | 3 +
drivers/staging/android/ashmem.c | 3 +
drivers/staging/comedi/comedi_fops.c | 3 +
.../staging/lustre/lustre/llite/llite_internal.h | 3 +
drivers/staging/lustre/lustre/llite/llite_mmap.c | 5 +-
drivers/staging/vboxvideo/vbox_drv.h | 3 +
drivers/staging/vboxvideo/vbox_ttm.c | 3 +
drivers/staging/vme/devices/vme_user.c | 3 +
drivers/uio/uio.c | 3 +
drivers/usb/core/devio.c | 3 +
drivers/usb/mon/mon_bin.c | 3 +
drivers/vfio/vfio.c | 7 ++-
drivers/video/fbdev/core/fbmem.c | 3 +
drivers/video/fbdev/pxa3xx-gcu.c | 3 +
drivers/xen/gntalloc.c | 3 +
drivers/xen/gntdev.c | 3 +
drivers/xen/privcmd.c | 3 +
drivers/xen/xenbus/xenbus_dev_backend.c | 3 +
drivers/xen/xenfs/xenstored.c | 3 +
fs/9p/vfs_file.c | 10 ++--
fs/aio.c | 3 +
fs/btrfs/file.c | 3 +
fs/ceph/addr.c | 3 +
fs/ceph/super.h | 3 +
fs/cifs/cifsfs.h | 6 ++
fs/cifs/file.c | 10 ++--
fs/coda/file.c | 5 +-
fs/ecryptfs/file.c | 5 +-
fs/ext2/file.c | 5 +-
fs/ext4/file.c | 3 +
fs/f2fs/file.c | 3 +
fs/fuse/file.c | 8 ++-
fs/gfs2/file.c | 3 +
fs/hugetlbfs/inode.c | 3 +
fs/kernfs/file.c | 3 +
fs/ncpfs/mmap.c | 3 +
fs/ncpfs/ncp_fs.h | 2 -
fs/nfs/file.c | 5 +-
fs/nfs/internal.h | 2 -
fs/nilfs2/file.c | 3 +
fs/ocfs2/mmap.c | 3 +
fs/ocfs2/mmap.h | 3 +
fs/orangefs/file.c | 5 +-
fs/proc/inode.c | 7 ++-
fs/proc/vmcore.c | 6 ++
fs/ramfs/file-nommu.c | 6 ++
fs/romfs/mmap-nommu.c | 3 +
fs/ubifs/file.c | 5 +-
fs/xfs/xfs_file.c | 5 +-
include/drm/drm_gem.h | 3 +
include/drm/drm_gem_cma_helper.h | 3 +
include/drm/drm_legacy.h | 3 +
include/linux/fs.h | 14 ++++--
include/linux/mm.h | 2 -
include/linux/mman.h | 50 ++++++++++++++++++++
include/misc/cxl.h | 3 +
include/uapi/asm-generic/mman-common.h | 1
ipc/shm.c | 5 +-
kernel/events/core.c | 3 +
kernel/kcov.c | 3 +
kernel/relay.c | 3 +
mm/filemap.c | 14 ++++--
mm/mmap.c | 22 ++++++++-
mm/nommu.c | 4 +-
mm/shmem.c | 3 +
net/socket.c | 6 ++
security/selinux/selinuxfs.c | 6 ++
sound/core/compress_offload.c | 3 +
sound/core/hwdep.c | 3 +
sound/core/info.c | 3 +
sound/core/init.c | 3 +
sound/core/oss/pcm_oss.c | 3 +
sound/core/pcm_native.c | 3 +
sound/oss/soundcard.c | 3 +
sound/oss/swarm_cs4297a.c | 3 +
virt/kvm/kvm_main.c | 3 +
164 files changed, 481 insertions(+), 231 deletions(-)
3 years, 4 months
[RFC patch 3/4]ndctl: nvdimmd: notify/monitor the feathers of over threshold event
by Qi, Fuli
Nvdimmd.service is the unit file of systemd for nvdimmd service.
Sign-off-by: QI Fuli <qi.fuli(a)jp.fujitsu.com>
---
nvdimmd/Makefile | 4 ++++
nvdimmd/nvdimmd.service | 7 +++++++
2 files changed, 11 insertions(+)
diff --git a/nvdimmd/Makefile b/nvdimmd/Makefile
index 3908e5d..df7eb46 100644
--- a/nvdimmd/Makefile
+++ b/nvdimmd/Makefile
@@ -1,5 +1,6 @@
CC = gcc
LIBS = -ludev -luuid -lkmod
+DEST = /usr/bin
OBJS = ../ndctl/lib/.libs/libndctl.o ../daxctl/lib/.libs/libdaxctl.o ../util/.libs/sysfs.o ../util/.libs/log.o ../ndctl/lib/.libs/libndctl-smart.o
IDIR = -I../ -I../ndctl
PROGRAM = nvdimmd
@@ -11,5 +12,8 @@ libnvdimmd.o: libnvdimmd.c
$(CC) -o libnvdimmd.o $(IDIR) -c libnvdimmd.c
nvdimmd.o: nvdimmd.c
$(CC) -o nvdimmd.o $(IDIR) -c nvdimmd.c
+install: nvdimmd nvdimmd.service
+ install -s nvdimmd $(DEST)
+ cp nvdimmd.service /usr/lib/systemd/system/
clean:
rm -rf *.o $(PROGRAM)
diff --git a/nvdimmd/nvdimmd.service b/nvdimmd/nvdimmd.service
new file mode 100644
index 0000000..0b96aaa
--- /dev/null
+++ b/nvdimmd/nvdimmd.service
@@ -0,0 +1,7 @@
+[Unit]
+Description=Nvdimm Daemon
+
+[Service]
+Type=forking
+ExecStart=/usr/bin/nvdimmd
+ExecStop=/usr/bin/kill ${MAINPID}
--
QI Fuli <qi.fuli(a)jp.fujitsu.com>
3 years, 4 months
[PATCH] libnvdimm: fix integer overflow static analysis warning
by Dan Williams
Dan reports:
The patch 62232e45f4a2: "libnvdimm: control (ioctl) messages for
nvdimm_bus and nvdimm devices" from Jun 8, 2015, leads to the
following static checker warning:
drivers/nvdimm/bus.c:1018 __nd_ioctl()
warn: integer overflows 'buf_len'
From a casual review, this seems like it might be a real bug. On
the first iteration we load some data into in_env[]. On the second
iteration we read a use controlled "in_size" from nd_cmd_in_size().
It can go up to UINT_MAX - 1. A high number means we will fill the
whole in_env[] buffer. But we potentially keep looping and adding
more to in_len so now it can be any value.
It simple enough to change, but it feels weird that we keep looping
even though in_env is totally full. Shouldn't we just return an
error if we don't have space for desc->in_num.
We keep looping because the size of the total input is allowed to be
bigger than the 'envelope' which is a subset of the payload that tells
us how much data to expect. For safety explicitly check that buf_len
does not overflow which is what the checker flagged.
Cc: <stable(a)vger.kernel.org>
Fixes: 62232e45f4a2: "libnvdimm: control (ioctl) messages for nvdimm_bus..."
Reported-by: Dan Carpenter <dan.carpenter(a)oracle.com>
Signed-off-by: Dan Williams <dan.j.williams(a)intel.com>
---
drivers/nvdimm/bus.c | 17 +++++++++--------
1 file changed, 9 insertions(+), 8 deletions(-)
diff --git a/drivers/nvdimm/bus.c b/drivers/nvdimm/bus.c
index a18c2914f4b6..66586ce23f1b 100644
--- a/drivers/nvdimm/bus.c
+++ b/drivers/nvdimm/bus.c
@@ -911,19 +911,20 @@ static int __nd_ioctl(struct nvdimm_bus *nvdimm_bus, struct nvdimm *nvdimm,
int read_only, unsigned int ioctl_cmd, unsigned long arg)
{
struct nvdimm_bus_descriptor *nd_desc = nvdimm_bus->nd_desc;
- size_t buf_len = 0, in_len = 0, out_len = 0;
static char out_env[ND_CMD_MAX_ENVELOPE];
static char in_env[ND_CMD_MAX_ENVELOPE];
const struct nd_cmd_desc *desc = NULL;
unsigned int cmd = _IOC_NR(ioctl_cmd);
- unsigned int func = cmd;
- void __user *p = (void __user *) arg;
struct device *dev = &nvdimm_bus->dev;
- struct nd_cmd_pkg pkg;
+ void __user *p = (void __user *) arg;
const char *cmd_name, *dimm_name;
+ u32 in_len = 0, out_len = 0;
+ unsigned int func = cmd;
unsigned long cmd_mask;
- void *buf;
+ struct nd_cmd_pkg pkg;
int rc, i, cmd_rc;
+ u64 buf_len = 0;
+ void *buf;
if (nvdimm) {
desc = nd_cmd_dimm_desc(cmd);
@@ -983,7 +984,7 @@ static int __nd_ioctl(struct nvdimm_bus *nvdimm_bus, struct nvdimm *nvdimm,
if (cmd == ND_CMD_CALL) {
func = pkg.nd_command;
- dev_dbg(dev, "%s:%s, idx: %llu, in: %zu, out: %zu, len %zu\n",
+ dev_dbg(dev, "%s:%s, idx: %llu, in: %u, out: %u, len %llu\n",
__func__, dimm_name, pkg.nd_command,
in_len, out_len, buf_len);
@@ -1013,9 +1014,9 @@ static int __nd_ioctl(struct nvdimm_bus *nvdimm_bus, struct nvdimm *nvdimm,
out_len += out_size;
}
- buf_len = out_len + in_len;
+ buf_len = (u64) out_len + (u64) in_len;
if (buf_len > ND_IOCTL_MAX_BUFLEN) {
- dev_dbg(dev, "%s:%s cmd: %s buf_len: %zu > %d\n", __func__,
+ dev_dbg(dev, "%s:%s cmd: %s buf_len: %llu > %d\n", __func__,
dimm_name, cmd_name, buf_len,
ND_IOCTL_MAX_BUFLEN);
return -EINVAL;
3 years, 4 months
[PATCH] ndctl, create-namespace: support sector size settings for pmem
by Dan Williams
Starting with v1.2 namespace label support it is permissible for pmem
namespaces to have a sector size. Per UEFI 2.7 the default should be 4K
for inter-OS compatibility.
Reported-by: Juston Li <juston.li(a)intel.com>
Signed-off-by: Dan Williams <dan.j.williams(a)intel.com>
---
ndctl/namespace.c | 35 ++++++++++++++++++++++++-----------
1 file changed, 24 insertions(+), 11 deletions(-)
diff --git a/ndctl/namespace.c b/ndctl/namespace.c
index 55645d868b60..115119a84431 100644
--- a/ndctl/namespace.c
+++ b/ndctl/namespace.c
@@ -248,12 +248,6 @@ static int set_defaults(enum namespace_action mode)
error("invalid sector size: %s\n", param.sector_size);
rc = -EINVAL;
}
-
- if (param.type && param.mode && strcmp(param.type, "pmem") == 0
- && strcmp(param.mode, "safe") != 0) {
- error("'pmem' namespaces do not support setting 'sector size'\n");
- rc = -EINVAL;
- }
} else if (!param.reconfig
&& ((param.type && strcmp(param.type, "blk") == 0)
|| (param.mode
@@ -360,7 +354,7 @@ static int setup_namespace(struct ndctl_region *region,
try(ndctl_namespace, set_size, ndns, p->size);
}
- if (ndctl_namespace_get_type(ndns) == ND_DEVICE_NAMESPACE_BLK)
+ if (p->sector_size && p->sector_size < UINT_MAX)
try(ndctl_namespace, set_sector_size, ndns, p->sector_size);
uuid_generate(uuid);
@@ -394,6 +388,13 @@ static int setup_namespace(struct ndctl_region *region,
} else if (p->mode == NDCTL_NS_MODE_SAFE) {
struct ndctl_btt *btt = ndctl_region_get_btt_seed(region);
+ /*
+ * Handle the case of btt on a pmem namespace where the
+ * pmem kernel support is pre-v1.2 namespace labels
+ * support (does not support sector size settings).
+ */
+ if (p->sector_size == UINT_MAX)
+ p->sector_size = 4096;
try(ndctl_btt, set_uuid, btt, uuid);
try(ndctl_btt, set_sector_size, btt, p->sector_size);
try(ndctl_btt, set_namespace, btt, ndns);
@@ -632,11 +633,23 @@ static int validate_namespace_options(struct ndctl_region *region,
if (btt)
p->sector_size = ndctl_btt_get_sector_size(btt);
- else if (ndctl_namespace_get_type(ndns)
- == ND_DEVICE_NAMESPACE_BLK)
+ else
p->sector_size = ndctl_namespace_get_sector_size(ndns);
- else if (p->mode == NDCTL_NS_MODE_SAFE)
- p->sector_size = 4096;
+ } else {
+ struct ndctl_namespace *seed;
+
+ seed = ndctl_region_get_namespace_seed(region);
+ if (ndctl_namespace_get_type(seed) == ND_DEVICE_NAMESPACE_BLK)
+ debug("%s: set_defaults() should preclude this?\n",
+ ndctl_region_get_devname(region));
+ /*
+ * Pick a default sector size for a pmem namespace based
+ * on what the kernel supports.
+ */
+ if (ndctl_namespace_get_num_sector_sizes(seed) == 0)
+ p->sector_size = UINT_MAX;
+ else
+ p->sector_size = 512;
}
if (param.map) {
3 years, 4 months
[PATCH] ndctl: make ndctl_namspace_set_sector_size() more verbose
by Dan Williams
Since we already walk all the supported sector sizes in the success
case, move that loop to the start of the routine and use it for logging
bad input parameters.
Signed-off-by: Dan Williams <dan.j.williams(a)intel.com>
---
ndctl/lib/libndctl.c | 16 +++++++++++-----
1 file changed, 11 insertions(+), 5 deletions(-)
diff --git a/ndctl/lib/libndctl.c b/ndctl/lib/libndctl.c
index f52ecfe9d142..4361cd8f26c5 100644
--- a/ndctl/lib/libndctl.c
+++ b/ndctl/lib/libndctl.c
@@ -3549,8 +3549,15 @@ NDCTL_EXPORT int ndctl_namespace_set_sector_size(struct ndctl_namespace *ndns,
char sector_str[40];
int i;
- if (ndns->lbasize.num == 0)
- return -ENXIO;
+ for (i = 0; i < ndns->lbasize.num; i++)
+ if (ndns->lbasize.supported[i] == sector_size)
+ break;
+
+ if (i > ndns->lbasize.num) {
+ err(ctx, "%s: unsupported sector size %d\n",
+ ndctl_namespace_get_devname(ndns), sector_size);
+ return -EOPNOTSUPP;
+ }
if (snprintf(path, len, "%s/sector_size", ndns->ndns_path) >= len) {
err(ctx, "%s: buffer too small!\n",
@@ -3563,9 +3570,8 @@ NDCTL_EXPORT int ndctl_namespace_set_sector_size(struct ndctl_namespace *ndns,
if (rc != 0)
return rc;
- for (i = 0; i < ndns->lbasize.num; i++)
- if (ndns->lbasize.supported[i] == sector_size)
- ndns->lbasize.select = i;
+ ndns->lbasize.select = i;
+
return 0;
}
3 years, 4 months