Page MenuHomeFreeBSD

D43720.id133787.diff
No OneTemporary

D43720.id133787.diff

diff --git a/sys/compat/linuxkpi/common/include/linux/devcoredump.h b/sys/compat/linuxkpi/common/include/linux/devcoredump.h
--- a/sys/compat/linuxkpi/common/include/linux/devcoredump.h
+++ b/sys/compat/linuxkpi/common/include/linux/devcoredump.h
@@ -35,6 +35,11 @@
#include <linux/scatterlist.h>
#include <linux/device.h>
+typedef int(*dev_coredump_cb)(void *, size_t, struct vnode *);
+
+int lkpi_dev_coredumpsg(void *, size_t, struct vnode *);
+int lkpi_dev_coredump(struct device *, void *, size_t, dev_coredump_cb);
+
static inline void
_lkpi_dev_coredumpsg_free(struct scatterlist *table)
{
@@ -54,20 +59,26 @@
}
static inline void
-dev_coredumpv(struct device *dev __unused, void *data, size_t datalen __unused,
+dev_coredumpv(struct device *dev, void *data, size_t datalen,
gfp_t gfp __unused)
{
+ dev_notice(dev, "%s: TODO datalen %zu\n", __func__, datalen);
/* UNIMPLEMENTED */
vfree(data);
}
static inline void
-dev_coredumpsg(struct device *dev __unused, struct scatterlist *table,
- size_t datalen __unused, gfp_t gfp __unused)
+dev_coredumpsg(struct device *dev, struct scatterlist *table,
+ size_t datalen, gfp_t gfp __unused)
{
+ int error;
+
+ error = lkpi_dev_coredump(dev, (void *)table, datalen, &lkpi_dev_coredumpsg);
+ if (error != 0)
+ dev_warn(dev, "%s: coredump failed, datalen %zu: %d\n",
+ __func__, datalen, error);
- /* UNIMPLEMENTED */
_lkpi_dev_coredumpsg_free(table);
}
diff --git a/sys/compat/linuxkpi/common/src/linux_devcorefile.c b/sys/compat/linuxkpi/common/src/linux_devcorefile.c
new file mode 100644
--- /dev/null
+++ b/sys/compat/linuxkpi/common/src/linux_devcorefile.c
@@ -0,0 +1,221 @@
+/*-
+ * SPDX-License-Identifier: BSD-3-Clause and BSD-2-Clause
+ *
+ * For sys/kern/kern_sig.c:
+ *
+ * Copyright (c) 1982, 1986, 1989, 1991, 1993
+ * The Regents of the University of California. All rights reserved.
+ * (c) UNIX System Laboratories, Inc.
+ * All or some portions of this file are derived from material licensed
+ * to the University of California by American Telephone and Telegraph
+ * Co. or Unix System Laboratories, Inc. and are reproduced herein with
+ * the permission of UNIX System Laboratories, Inc.
+ *
+ * For sys/kern/imgact_elf.c:
+ *
+ * Copyright (c) 2017 Dell EMC
+ * Copyright (c) 2000-2001, 2003 David O'Brien
+ * Copyright (c) 1995-1996 Søren Schmidt
+ * Copyright (c) 1996 Peter Wemm
+ * All rights reserved.
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+/*-
+ * Copyright 2024 Bjoern A. Zeeb
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The implementation is modelled losely after our normal corefile code.
+ * We really should have a user space handler to open the file, pass the
+ * file descriptor and then fget() and use that for IO instead of doing all
+ * the hustle and magic here.
+ * That would likely also solve the entire problem with the hard coded
+ * directory prefix and file name.
+ */
+
+#include <sys/types.h>
+#include <sys/fcntl.h>
+#include <sys/mount.h>
+#include <sys/namei.h>
+#include <sys/proc.h>
+#include <sys/vnode.h>
+#include <sys/unistd.h>
+
+#include <sys/systm.h> /* hexdump(9) */
+
+#include <linux/gfp.h>
+#include <linux/devcoredump.h>
+#include <linux/scatterlist.h>
+#include <linux/device.h>
+
+int
+lkpi_dev_coredumpsg(void *arg, size_t datalen, struct vnode *vp)
+{
+ struct scatterlist *table, *iter;
+ struct page *p;
+ off_t offset;
+ size_t left, resid;
+ int error, i;
+
+ table = arg;
+ left = datalen;
+ offset = 0;
+ resid = 0;
+ for_each_sg(table, iter, sg_nents(table), i) {
+ p = sg_page(iter);
+ if (p) {
+ int len;
+
+ len = MIN(PAGE_SIZE, left);
+ //hexdump(linux_page_address(p), len, "DEVCORE: ", 0);
+ //printf("%s: seg len %d\n", __func__, len);
+ error = vn_rdwr_inchunks(UIO_WRITE, vp, linux_page_address(p), len, offset, UIO_SYSSPACE,
+ IO_UNIT | IO_DIRECT | IO_RANGELOCKED, curthread->td_ucred, curthread->td_ucred, &resid, curthread);
+ if (error != 0)
+ return (error);
+
+ left -= len;
+ offset += len;
+ }
+ }
+
+ return (0);
+}
+
+int
+lkpi_dev_coredump(struct device *dev, void *arg, size_t datalen, dev_coredump_cb cb)
+{
+ struct proc *p;
+ struct ucred *cred;
+ struct vnode *vp;
+ struct nameidata nd;
+ struct flock lf;
+ struct vattr vattr;
+ void *rl_cookie;
+ char *name;
+ int cmode, error, error1, flags, oflags, locked;
+
+ name = malloc(MAXPATHLEN, M_TEMP, M_WAITOK | M_ZERO); /* gpf_t ? */
+
+ /* XXX /var/crash hardcoded. */
+ snprintf(name, MAXPATHLEN, "/var/crash/%s.%ju",
+ device_get_nameunit(dev->bsddev), (uintmax_t)ticks);
+
+ cmode = S_IRUSR | S_IWUSR;
+ oflags = VN_OPEN_NOAUDIT | VN_OPEN_NAMECACHE |
+ ((1 /*capmode_coredump */) ? VN_OPEN_NOCAPCHECK : 0); /* XXX FIXME */
+ flags = O_CREAT | FWRITE | O_NOFOLLOW | O_EXCL;
+
+ NDINIT(&nd, LOOKUP, NOFOLLOW, UIO_SYSSPACE, name);
+ error = vn_open_cred(&nd, &flags, cmode, oflags, curthread->td_ucred,
+ NULL);
+ if (error != 0)
+ goto out;
+ vp = nd.ni_vp;
+ NDFREE_PNBUF(&nd);
+
+ cred = curthread->td_ucred;
+
+ /*
+ * Don't dump to non-regular files or files with links.
+ * Do not dump into system files. Effective user must own the corefile.
+ */
+ if (vp->v_type != VREG || VOP_GETATTR(vp, &vattr, cred) != 0 ||
+ vattr.va_nlink != 1 || (vp->v_vflag & VV_SYSTEM) != 0 ||
+ vattr.va_uid != cred->cr_uid) {
+ VOP_UNLOCK(vp);
+ error = EFAULT;
+ goto out;
+ }
+
+ VOP_UNLOCK(vp);
+
+ /* Postpone other writers, including core dumps of other processes. */
+ rl_cookie = vn_rangelock_wlock(vp, 0, OFF_MAX);
+
+ p = curthread->td_proc;
+
+ lf.l_whence = SEEK_SET;
+ lf.l_start = 0;
+ lf.l_len = 0;
+ lf.l_type = F_WRLCK;
+ locked = (VOP_ADVLOCK(vp, (caddr_t)p, F_SETLK, &lf, F_FLOCK) == 0);
+
+ VATTR_NULL(&vattr);
+ vattr.va_size = 0;
+ if (1 /*set_core_nodump_flag */) /* XXX */
+ vattr.va_flags = UF_NODUMP;
+ vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
+ VOP_SETATTR(vp, &vattr, cred);
+ VOP_UNLOCK(vp);
+
+ if (cb != NULL)
+ error = cb(arg, datalen, vp);
+ else
+ error = ENOSYS;
+
+ if (locked) {
+ lf.l_type = F_UNLCK;
+ VOP_ADVLOCK(vp, (caddr_t)p, F_UNLCK, &lf, F_FLOCK);
+ }
+ vn_rangelock_unlock(vp, rl_cookie);
+
+ error1 = vn_close(vp, FWRITE, cred, curthread);
+ if (error == 0)
+ error = error1;
+
+out:
+#if 0 && defined(AUDIT)
+ audit_devcoredump(dev->bsddev, name, error);
+#endif
+
+ /* XXX log possible error */
+ free(name, M_TEMP);
+
+ return (error);
+}
+
+
diff --git a/sys/conf/files b/sys/conf/files
--- a/sys/conf/files
+++ b/sys/conf/files
@@ -4548,6 +4548,8 @@
compile-with "${LINUXKPI_C}"
compat/linuxkpi/common/src/linux_current.c optional compat_linuxkpi \
compile-with "${LINUXKPI_C}"
+compat/linuxkpi/common/src/linux_devcorefile.c optional compat_linuxkpi \
+ compile-with "${LINUXKPI_C}"
compat/linuxkpi/common/src/linux_devres.c optional compat_linuxkpi \
compile-with "${LINUXKPI_C}"
compat/linuxkpi/common/src/linux_dmi.c optional compat_linuxkpi \
diff --git a/sys/modules/linuxkpi/Makefile b/sys/modules/linuxkpi/Makefile
--- a/sys/modules/linuxkpi/Makefile
+++ b/sys/modules/linuxkpi/Makefile
@@ -3,6 +3,7 @@
KMOD= linuxkpi
SRCS= linux_compat.c \
linux_current.c \
+ linux_devcorefile.c \
linux_devres.c \
linux_dmi.c \
linux_domain.c \

File Metadata

Mime Type
text/plain
Expires
Sun, Jan 18, 11:13 PM (1 h, 16 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
27722587
Default Alt Text
D43720.id133787.diff (9 KB)

Event Timeline