Initial commit

This commit is contained in:
domenico
2025-06-24 13:14:22 +02:00
commit 4002f145fc
9002 changed files with 1731834 additions and 0 deletions

32
target/linux/uml/Makefile Normal file
View File

@@ -0,0 +1,32 @@
# SPDX-License-Identifier: GPL-2.0-only
#
# Copyright (C) 2006-2011 OpenWrt.org
include $(TOPDIR)/rules.mk
# UML only makes sense on linux
ifeq ($(HOST_OS),Linux)
ARCH:=$(shell uname -m | sed \
-e 's/i[3-9]86/i386/' \
-e 's/mipsel/mips/' \
-e 's/mipseb/mips/' \
-e 's/powerpc/ppc/' \
-e 's/sh[234]/sh/' \
-e 's/armeb/arm/' \
)
BOARD:=uml
BOARDNAME:=User Mode Linux
FEATURES:=squashfs ext4 audio source-only
KERNEL_PATCHVER:=5.4
include $(INCLUDE_DIR)/target.mk
LINUX_TARGET_CONFIG:=$(CURDIR)/config/$(ARCH)
DEFAULT_PACKAGES += wpad-basic-wolfssl kmod-mac80211-hwsim mkf2fs e2fsprogs
endif
$(eval $(call BuildTarget))

46
target/linux/uml/README Normal file
View File

@@ -0,0 +1,46 @@
OpenWrt inside a user mode linux. Why would we even want this many ask?
There are potentially a lot of reasons, one obvious one to me, it allows
folks to 'kick the tires' without actually flashing up any hardware. It's
also a great environment for porting over packages, you can get a package
fully functional in the uclibc root environment inside a uml without actually
disturbing your 'real router', and then rebuild for a specific target once
it's fully tested.
This is a first stab at a build that 'just works' and there will be more
cleanup to come. The simple directions are:-
Configure for uml target
Configure with an ext4 root file system
build it all
In your bin directory you will find a kernel and an ext4 root file system
when it's finished. Just run it like this:-
bin/targets/uml/generic/lede-uml-vmlinux
ubd0=bin/targets/uml/generic/openwrt-uml-ext4.img
The uml will start, and eventually the serial console of the uml will be at your
console prompt. If you would like it in xterms, substitute con=xterm and con0=xterm.
No networking is configured, but, it's a starting point. The resulting file system
has just enough free space to start kicking the tires and playing in the world of
'embedded routers' along with all the resource restrictions that come with that
world.
To configure networking and more, refer to the user mode linux documentation online.
A quick start goes along this line. install the uml-utilities packages so you have
the uml switch in and running, then add a command param to your uml start like this
eth0=daemon,00:01:01:01:01:01,unix,/<your uml switch control socket here>
With that in, and uml networking actually functional (can be a challenge at times),
you should be able to ifconfig the interface and talk to the host side, or, if you
bridged the uml switch to your host network, you should be able to run udhcp and be
away with networking off to the world. Again, if you are unfamiliar with uml and
uml networking, please read the docs and how-to stuff available on the net. It does
take some fiddling to get it started and working right the first time, but after that,
it opens up a whole new world of virtual machines.
http://user-mode-linux.sourceforge.net/

View File

@@ -0,0 +1,4 @@
# Copyright (c) 2013 The Linux Foundation. All rights reserved.
::sysinit:/etc/init.d/rcS S boot
::shutdown:/etc/init.d/rcS K shutdown
tty0::askfirst:/usr/libexec/login.sh

View File

@@ -0,0 +1,142 @@
# CONFIG_3_LEVEL_PGTABLES is not set
# CONFIG_64BIT is not set
CONFIG_ARCH_DEFCONFIG="arch/um/configs/i386_defconfig"
CONFIG_ARCH_HAS_KCOV=y
CONFIG_ARCH_NO_PREEMPT=y
CONFIG_BLK_DEV_COW_COMMON=y
CONFIG_BLK_DEV_LOOP=y
CONFIG_BLK_DEV_UBD=y
CONFIG_BLK_DEV_UBD_SYNC=y
CONFIG_BLK_MQ_VIRTIO=y
CONFIG_CC_HAS_KASAN_GENERIC=y
CONFIG_CON_CHAN="xterm"
CONFIG_CON_ZERO_CHAN="fd:0,fd:1"
CONFIG_CPU_SUP_AMD=y
CONFIG_CPU_SUP_CENTAUR=y
CONFIG_CPU_SUP_HYGON=y
CONFIG_CPU_SUP_INTEL=y
CONFIG_CPU_SUP_ZHAOXIN=y
CONFIG_CRC16=y
CONFIG_CRYPTO_CRC32=y
CONFIG_CRYPTO_CRC32C=y
CONFIG_CRYPTO_HASH=y
CONFIG_CRYPTO_HASH2=y
CONFIG_CRYPTO_RNG2=y
CONFIG_CRYPTO_SHA1=y
CONFIG_DEBUG_MEMORY_INIT=y
CONFIG_DECOMPRESS_BZIP2=y
CONFIG_DECOMPRESS_GZIP=y
CONFIG_DNOTIFY=y
# CONFIG_EARLY_PRINTK is not set
CONFIG_EXT4_FS=y
CONFIG_F2FS_FS=y
CONFIG_FAILOVER=y
CONFIG_FS_IOMAP=y
CONFIG_FS_MBCACHE=y
CONFIG_FW_LOADER_PAGED_BUF=y
CONFIG_GENERIC_CLOCKEVENTS=y
# CONFIG_GENERIC_CPU is not set
CONFIG_GENERIC_CPU_DEVICES=y
CONFIG_GENERIC_FIND_FIRST_BIT=y
CONFIG_GENERIC_IRQ_SHOW=y
CONFIG_HAVE_ARCH_AUDITSYSCALL=y
CONFIG_HAVE_ARCH_SECCOMP_FILTER=y
CONFIG_HAVE_ASM_MODVERSIONS=y
CONFIG_HAVE_COPY_THREAD_TLS=y
CONFIG_HAVE_DEBUG_BUGVERBOSE=y
CONFIG_HAVE_DEBUG_KMEMLEAK=y
CONFIG_HAVE_FUTEX_CMPXCHG=y
CONFIG_HAVE_NET_DSA=y
CONFIG_HAVE_UID16=y
CONFIG_HAVE_VIRT_CPU_ACCOUNTING_GEN=y
CONFIG_HOSTFS=y
CONFIG_HVC_DRIVER=y
CONFIG_HZ_PERIODIC=y
CONFIG_INITRAMFS_SOURCE=""
CONFIG_INIT_ENV_ARG_LIMIT=128
CONFIG_IRQ_WORK=y
CONFIG_ISO9660_FS=y
CONFIG_JBD2=y
# CONFIG_JFFS2_FS is not set
CONFIG_KALLSYMS=y
CONFIG_KERNEL_STACK_ORDER=2
CONFIG_LD_SCRIPT_STATIC=y
CONFIG_LOCK_DEBUGGING_SUPPORT=y
# CONFIG_MATOM is not set
CONFIG_MCONSOLE=y
# CONFIG_MCORE2 is not set
CONFIG_MEMFD_CREATE=y
CONFIG_MIGRATION=y
CONFIG_MK8=y
# CONFIG_MMAPPER is not set
CONFIG_MODULES_USE_ELF_RELA=y
# CONFIG_MPSC is not set
CONFIG_NAMESPACES=y
CONFIG_NEED_PER_CPU_KM=y
CONFIG_NET_FAILOVER=y
# CONFIG_NET_NS is not set
CONFIG_NLS=y
CONFIG_NO_DMA=y
CONFIG_NO_IOMEM=y
CONFIG_NR_CPUS=1
CONFIG_NULL_CHAN=y
# CONFIG_OF is not set
CONFIG_PGTABLE_LEVELS=3
CONFIG_PHYS_ADDR_T_64BIT=y
CONFIG_PORT_CHAN=y
CONFIG_POSIX_MQUEUE=y
CONFIG_POSIX_MQUEUE_SYSCTL=y
# CONFIG_PROCESSOR_SELECT is not set
CONFIG_PROC_PAGE_MONITOR=y
CONFIG_PTY_CHAN=y
CONFIG_RD_BZIP2=y
CONFIG_RD_GZIP=y
CONFIG_RELAY=y
CONFIG_SOFT_WATCHDOG=m
CONFIG_SRCU=y
CONFIG_SSL=y
CONFIG_SSL_CHAN="pty"
CONFIG_STACKTRACE=y
CONFIG_STATIC_LINK=y
CONFIG_STDERR_CONSOLE=y
CONFIG_TICK_CPU_ACCOUNTING=y
CONFIG_TINY_SRCU=y
CONFIG_TTY_CHAN=y
CONFIG_UML=y
CONFIG_UML_NET=y
CONFIG_UML_NET_DAEMON=y
CONFIG_UML_NET_DETERMINISTIC_MAC=y
CONFIG_UML_NET_ETHERTAP=y
CONFIG_UML_NET_MCAST=y
# CONFIG_UML_NET_PCAP is not set
CONFIG_UML_NET_SLIP=y
CONFIG_UML_NET_SLIRP=y
CONFIG_UML_NET_TUNTAP=y
# CONFIG_UML_NET_VDE is not set
CONFIG_UML_NET_VECTOR=y
CONFIG_UML_RANDOM=y
# CONFIG_UML_SOUND is not set
CONFIG_UML_TIME_TRAVEL_SUPPORT=y
CONFIG_UML_WATCHDOG=y
CONFIG_UML_X86=y
# CONFIG_USER_NS is not set
CONFIG_VIRTIO=y
CONFIG_VIRTIO_BLK=y
CONFIG_VIRTIO_CONSOLE=y
CONFIG_VIRTIO_NET=y
CONFIG_VIRTIO_UML=y
CONFIG_VM_EVENT_COUNTERS=y
CONFIG_WATCHDOG_CORE=y
CONFIG_X86_32=y
# CONFIG_X86_64 is not set
CONFIG_X86_CMOV=y
CONFIG_X86_CMPXCHG64=y
CONFIG_X86_GENERIC=y
CONFIG_X86_INTEL_USERCOPY=y
CONFIG_X86_INTERNODE_CACHE_SHIFT=6
CONFIG_X86_L1_CACHE_SHIFT=6
CONFIG_X86_MINIMUM_CPU_FAMILY=5
CONFIG_X86_TSC=y
CONFIG_X86_USE_PPRO_CHECKSUM=y
CONFIG_XTERM_CHAN=y
CONFIG_ZLIB_INFLATE=y

View File

@@ -0,0 +1,142 @@
CONFIG_3_LEVEL_PGTABLES=y
CONFIG_64BIT=y
CONFIG_ARCH_DEFCONFIG="arch/um/configs/x86_64_defconfig"
CONFIG_ARCH_DMA_ADDR_T_64BIT=y
CONFIG_ARCH_HAS_KCOV=y
CONFIG_ARCH_NO_PREEMPT=y
CONFIG_BLK_DEV_COW_COMMON=y
CONFIG_BLK_DEV_LOOP=y
CONFIG_BLK_DEV_UBD=y
CONFIG_BLK_DEV_UBD_SYNC=y
CONFIG_BLK_MQ_VIRTIO=y
CONFIG_CC_HAS_KASAN_GENERIC=y
CONFIG_CON_CHAN="xterm"
CONFIG_CON_ZERO_CHAN="fd:0,fd:1"
CONFIG_CPU_SUP_AMD=y
CONFIG_CPU_SUP_CENTAUR=y
CONFIG_CPU_SUP_HYGON=y
CONFIG_CPU_SUP_INTEL=y
CONFIG_CPU_SUP_ZHAOXIN=y
CONFIG_CRC16=y
CONFIG_CRYPTO_CRC32=y
CONFIG_CRYPTO_CRC32C=y
CONFIG_CRYPTO_HASH=y
CONFIG_CRYPTO_HASH2=y
CONFIG_CRYPTO_RNG2=y
CONFIG_CRYPTO_SHA1=y
# CONFIG_CRYPTO_TWOFISH_X86_64 is not set
CONFIG_DEBUG_MEMORY_INIT=y
CONFIG_DECOMPRESS_BZIP2=y
CONFIG_DECOMPRESS_GZIP=y
CONFIG_DNOTIFY=y
# CONFIG_EARLY_PRINTK is not set
CONFIG_EXT4_FS=y
CONFIG_F2FS_FS=y
CONFIG_FAILOVER=y
CONFIG_FS_IOMAP=y
CONFIG_FS_MBCACHE=y
CONFIG_FW_LOADER_PAGED_BUF=y
CONFIG_GENERIC_CLOCKEVENTS=y
# CONFIG_GENERIC_CPU is not set
CONFIG_GENERIC_CPU_DEVICES=y
CONFIG_GENERIC_FIND_FIRST_BIT=y
CONFIG_GENERIC_IRQ_SHOW=y
CONFIG_HAVE_ARCH_AUDITSYSCALL=y
CONFIG_HAVE_ARCH_SECCOMP_FILTER=y
CONFIG_HAVE_ASM_MODVERSIONS=y
CONFIG_HAVE_COPY_THREAD_TLS=y
CONFIG_HAVE_DEBUG_BUGVERBOSE=y
CONFIG_HAVE_DEBUG_KMEMLEAK=y
CONFIG_HAVE_FUTEX_CMPXCHG=y
CONFIG_HAVE_NET_DSA=y
CONFIG_HAVE_UID16=y
CONFIG_HAVE_VIRT_CPU_ACCOUNTING_GEN=y
CONFIG_HOSTFS=y
CONFIG_HVC_DRIVER=y
CONFIG_HZ_PERIODIC=y
CONFIG_INITRAMFS_SOURCE=""
CONFIG_INIT_ENV_ARG_LIMIT=128
CONFIG_IRQ_WORK=y
CONFIG_ISO9660_FS=y
CONFIG_JBD2=y
# CONFIG_JFFS2_FS is not set
CONFIG_KALLSYMS=y
CONFIG_KERNEL_STACK_ORDER=2
CONFIG_LD_SCRIPT_STATIC=y
CONFIG_LOCK_DEBUGGING_SUPPORT=y
# CONFIG_MATOM is not set
CONFIG_MCONSOLE=y
# CONFIG_MCORE2 is not set
CONFIG_MEMFD_CREATE=y
CONFIG_MIGRATION=y
CONFIG_MK8=y
# CONFIG_MMAPPER is not set
CONFIG_MODULES_USE_ELF_RELA=y
# CONFIG_MPSC is not set
CONFIG_NAMESPACES=y
CONFIG_NEED_PER_CPU_KM=y
CONFIG_NET_FAILOVER=y
# CONFIG_NET_NS is not set
CONFIG_NLS=y
CONFIG_NO_DMA=y
CONFIG_NO_IOMEM=y
CONFIG_NR_CPUS=1
CONFIG_NULL_CHAN=y
# CONFIG_OF is not set
CONFIG_PGTABLE_LEVELS=3
CONFIG_PHYS_ADDR_T_64BIT=y
CONFIG_PORT_CHAN=y
CONFIG_POSIX_MQUEUE=y
CONFIG_POSIX_MQUEUE_SYSCTL=y
# CONFIG_PROCESSOR_SELECT is not set
CONFIG_PROC_PAGE_MONITOR=y
CONFIG_PTY_CHAN=y
CONFIG_RD_BZIP2=y
CONFIG_RD_GZIP=y
CONFIG_RELAY=y
CONFIG_SOFT_WATCHDOG=m
CONFIG_SRCU=y
CONFIG_SSL=y
CONFIG_SSL_CHAN="pty"
CONFIG_STACKTRACE=y
CONFIG_STATIC_LINK=y
CONFIG_STDERR_CONSOLE=y
CONFIG_TICK_CPU_ACCOUNTING=y
CONFIG_TINY_SRCU=y
CONFIG_TTY_CHAN=y
CONFIG_UML=y
CONFIG_UML_NET=y
CONFIG_UML_NET_DAEMON=y
CONFIG_UML_NET_DETERMINISTIC_MAC=y
CONFIG_UML_NET_ETHERTAP=y
CONFIG_UML_NET_MCAST=y
# CONFIG_UML_NET_PCAP is not set
CONFIG_UML_NET_SLIP=y
CONFIG_UML_NET_SLIRP=y
CONFIG_UML_NET_TUNTAP=y
# CONFIG_UML_NET_VDE is not set
CONFIG_UML_NET_VECTOR=y
CONFIG_UML_RANDOM=y
# CONFIG_UML_SOUND is not set
CONFIG_UML_TIME_TRAVEL_SUPPORT=y
CONFIG_UML_WATCHDOG=y
CONFIG_UML_X86=y
# CONFIG_USER_NS is not set
CONFIG_VIRTIO=y
CONFIG_VIRTIO_BLK=y
CONFIG_VIRTIO_CONSOLE=y
CONFIG_VIRTIO_NET=y
CONFIG_VIRTIO_UML=y
CONFIG_VM_EVENT_COUNTERS=y
CONFIG_WATCHDOG_CORE=y
CONFIG_X86_64=y
CONFIG_X86_CMOV=y
CONFIG_X86_CMPXCHG64=y
CONFIG_X86_INTEL_USERCOPY=y
CONFIG_X86_INTERNODE_CACHE_SHIFT=6
CONFIG_X86_L1_CACHE_SHIFT=6
CONFIG_X86_MINIMUM_CPU_FAMILY=64
CONFIG_X86_TSC=y
CONFIG_X86_USE_PPRO_CHECKSUM=y
CONFIG_XTERM_CHAN=y
CONFIG_ZLIB_INFLATE=y

View File

@@ -0,0 +1,33 @@
# SPDX-License-Identifier: GPL-2.0-only
#
# Copyright (C) 2006-2010 OpenWrt.org
include $(TOPDIR)/rules.mk
include $(INCLUDE_DIR)/image.mk
define Image/Prepare
cp $(LINUX_DIR)/linux $(KDIR)/vmlinux.elf
endef
define Image/Build/squashfs
dd if=/dev/zero of=$(KDIR)/root.squashfs bs=1024k count=0 seek=$(CONFIG_TARGET_ROOTFS_PARTSIZE)
endef
define Image/Build
$(call Image/Build/$(1))
cp $(KDIR)/root.$(1) $(BIN_DIR)/$(IMG_PREFIX)-$(1).img
cp $(KDIR)/vmlinux.elf $(BIN_DIR)/$(IMG_PREFIX)-vmlinux
endef
$(eval $(call BuildImage))
# UML requires linking against several glibc static libraries: libutil, librt
# and libpthread, check that here. We do not check against libpthread
# specifically because getting something to build that references a libpthread
# symbol is pretty involved and Linux distributions package these 3 libraries
# in the same package.
$(eval $(call TestHostCommand,glibc-static, \
Please install a static glibc package. (Missing libutil.a, librt.a or libpthread.a), \
echo 'int main(int argc, char **argv) { login(0); timer_gettime(0, 0); return 0; }' | \
gcc -include utmp.h -x c -o $(TMP_DIR)/a.out - -static -lutil -lrt))

View File

@@ -0,0 +1,205 @@
#
# Minimalist mconsole exec patch
#
# 3.10 version (with bit more synchronous behavior) by fingon at iki dot fi
# Adaptation to kernel 3.3.8 made by David Fernández (david at dit.upm.es) for
# Starting point: mconsole-exec-2.6.30.patch for kernel 2.6.30
# Author of original patch: Paolo Giarrusso, aka Blaisorblade
# (http://www.user-mode-linux.org/~blaisorblade)
#
# Known misfeatures:
#
# - If output is too long, blocks (and breaks horribly)
# (this misfeature from 3.10 patches, when minimalizing the patch;
# workaround: redirect to a shared filesystem if long output is expected)
#
# - Nothing useful is done with stdin
#
--- a/arch/um/drivers/mconsole.h
+++ b/arch/um/drivers/mconsole.h
@@ -85,6 +85,7 @@ extern void mconsole_cad(struct mc_reque
extern void mconsole_stop(struct mc_request *req);
extern void mconsole_go(struct mc_request *req);
extern void mconsole_log(struct mc_request *req);
+extern void mconsole_exec(struct mc_request *req);
extern void mconsole_proc(struct mc_request *req);
extern void mconsole_stack(struct mc_request *req);
--- a/arch/um/drivers/mconsole_kern.c
+++ b/arch/um/drivers/mconsole_kern.c
@@ -4,6 +4,7 @@
* Copyright (C) 2001 - 2008 Jeff Dike (jdike@{addtoit,linux.intel}.com)
*/
+#include <linux/kmod.h>
#include <linux/console.h>
#include <linux/ctype.h>
#include <linux/string.h>
@@ -26,6 +27,7 @@
#include <linux/mount.h>
#include <linux/file.h>
#include <linux/uaccess.h>
+#include <linux/completion.h>
#include <asm/switch_to.h>
#include <init.h>
@@ -121,6 +123,59 @@ void mconsole_log(struct mc_request *req
mconsole_reply(req, "", 0, 0);
}
+void mconsole_exec(struct mc_request *req)
+{
+ struct subprocess_info *sub_info;
+ int res, len;
+ struct file *out;
+ char buf[MCONSOLE_MAX_DATA];
+
+ char *envp[] = {
+ "HOME=/", "TERM=linux",
+ "PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin",
+ NULL
+ };
+ char *argv[] = {
+ "/bin/sh", "-c",
+ req->request.data + strlen("exec "),
+ NULL
+ };
+
+ sub_info = call_usermodehelper_setup("/bin/sh", argv, envp, GFP_ATOMIC, NULL, NULL, NULL);
+ if (sub_info == NULL) {
+ mconsole_reply(req, "call_usermodehelper_setup failed", 1, 0);
+ return;
+ }
+ res = call_usermodehelper_stdoutpipe(sub_info, &out);
+ if (res < 0) {
+ kfree(sub_info);
+ mconsole_reply(req, "call_usermodehelper_stdoutpipe failed", 1, 0);
+ return;
+ }
+
+ res = call_usermodehelper_exec(sub_info, UMH_WAIT_PROC);
+ if (res < 0) {
+ kfree(sub_info);
+ mconsole_reply(req, "call_usermodehelper_exec failed", 1, 0);
+ return;
+ }
+
+ for (;;) {
+ len = out->f_op->read(out, buf, sizeof(buf), &out->f_pos);
+ if (len < 0) {
+ mconsole_reply(req, "reading output failed", 1, 0);
+ break;
+ }
+ if (len == 0)
+ break;
+ mconsole_reply_len(req, buf, len, 0, 1);
+ }
+ fput(out);
+
+ mconsole_reply_len(req, NULL, 0, 0, 0);
+}
+
+
void mconsole_proc(struct mc_request *req)
{
struct vfsmount *mnt = task_active_pid_ns(current)->proc_mnt;
@@ -183,6 +238,7 @@ void mconsole_proc(struct mc_request *re
stop - pause the UML; it will do nothing until it receives a 'go' \n\
go - continue the UML after a 'stop' \n\
log <string> - make UML enter <string> into the kernel log\n\
+ exec <string> - pass <string> to /bin/sh -c synchronously\n\
proc <file> - returns the contents of the UML's /proc/<file>\n\
stack <pid> - returns the stack of the specified pid\n\
"
--- a/arch/um/drivers/mconsole_user.c
+++ b/arch/um/drivers/mconsole_user.c
@@ -30,6 +30,7 @@ static struct mconsole_command commands[
{ "stop", mconsole_stop, MCONSOLE_PROC },
{ "go", mconsole_go, MCONSOLE_INTR },
{ "log", mconsole_log, MCONSOLE_INTR },
+ { "exec", mconsole_exec, MCONSOLE_PROC },
{ "proc", mconsole_proc, MCONSOLE_PROC },
{ "stack", mconsole_stack, MCONSOLE_INTR },
};
--- a/arch/um/os-Linux/file.c
+++ b/arch/um/os-Linux/file.c
@@ -557,6 +557,8 @@ int os_create_unix_socket(const char *fi
addr.sun_family = AF_UNIX;
+ if (len > sizeof(addr.sun_path))
+ len = sizeof(addr.sun_path);
snprintf(addr.sun_path, len, "%s", file);
err = bind(sock, (struct sockaddr *) &addr, sizeof(addr));
--- a/include/linux/kmod.h
+++ b/include/linux/kmod.h
@@ -32,4 +32,6 @@ static inline int request_module_nowait(
#define try_then_request_module(x, mod...) (x)
#endif
+int call_usermodehelper_stdoutpipe(struct subprocess_info *sub_info, struct file **filp);
+
#endif /* __LINUX_KMOD_H__ */
--- a/include/linux/umh.h
+++ b/include/linux/umh.h
@@ -23,6 +23,7 @@ struct subprocess_info {
char **argv;
char **envp;
struct file *file;
+ struct file *stdout;
int wait;
int retval;
pid_t pid;
--- a/kernel/umh.c
+++ b/kernel/umh.c
@@ -76,6 +76,28 @@ static int call_usermodehelper_exec_asyn
flush_signal_handlers(current, 1);
spin_unlock_irq(&current->sighand->siglock);
+ /* Install output when needed */
+ if (sub_info->stdout) {
+ struct files_struct *f = current->files;
+ struct fdtable *fdt;
+
+ sys_close(1);
+ sys_close(2);
+ get_file(sub_info->stdout);
+ fd_install(1, sub_info->stdout);
+ fd_install(2, sub_info->stdout);
+ spin_lock(&f->file_lock);
+ fdt = files_fdtable(f);
+ __set_bit(1, fdt->open_fds);
+ __clear_bit(1, fdt->close_on_exec);
+ __set_bit(2, fdt->open_fds);
+ __clear_bit(2, fdt->close_on_exec);
+ spin_unlock(&f->file_lock);
+
+ /* disallow core files */
+ current->signal->rlim[RLIMIT_CORE] = (struct rlimit){0, 0};
+ }
+
/*
* Initial kernel threads share ther FS with init, in order to
* get the init root directory. But we've now created a new
@@ -362,6 +384,20 @@ static void helper_unlock(void)
wake_up(&running_helpers_waitq);
}
+int call_usermodehelper_stdoutpipe(struct subprocess_info *sub_info,
+ struct file **filp)
+{
+ struct file *f[2];
+
+ if (create_pipe_files(f, 0) < 0)
+ return PTR_ERR(f);
+
+ sub_info->stdout = f[1];
+ *filp = f[0];
+ return 0;
+}
+EXPORT_SYMBOL(call_usermodehelper_stdoutpipe);
+
/**
* call_usermodehelper_setup - prepare to call a usermode helper
* @path: path to usermode executable

View File

@@ -0,0 +1,130 @@
===============================================================================
This patch makes MAC addresses of network interfaces predictable. In
particular, it adds a small routine that computes MAC addresses of based on
a SHA1 hash of the virtual machine name and interface ID.
TECHNICAL INFORMATION:
Applies to vanilla kernel 3.9.4.
===============================================================================
--- a/arch/um/drivers/Kconfig
+++ b/arch/um/drivers/Kconfig
@@ -146,6 +146,20 @@ config UML_NET
enable at least one of the following transport options to actually
make use of UML networking.
+config UML_NET_DETERMINISTIC_MAC
+ bool "Use deterministic MAC addresses for network interfaces"
+ default y
+ depends on UML_NET
+ select CRYPTO_SHA1
+ help
+ Virtual network devices inside a User-Mode Linux instance must be
+ assigned a MAC (Ethernet) address. If none is specified on the UML
+ command line, one must be automatically computed. If this option is
+ enabled, a randomly generated address is used. Otherwise, if this
+ option is disabled, the address is generated from a SHA1 hash of
+ the umid of the UML instance and the interface name. The latter choice
+ is useful to make MAC addresses predictable.
+
config UML_NET_ETHERTAP
bool "Ethertap transport"
depends on UML_NET
--- a/arch/um/drivers/net_kern.c
+++ b/arch/um/drivers/net_kern.c
@@ -25,6 +25,14 @@
#include <net_kern.h>
#include <net_user.h>
+#include <crypto/sha.h>
+#include <crypto/hash.h>
+#include <linux/string.h>
+#include <linux/crypto.h>
+#include <linux/err.h>
+#include <linux/scatterlist.h>
+#include "os.h"
+
#define DRIVER_NAME "uml-netdev"
static DEFINE_SPINLOCK(opened_lock);
@@ -286,9 +294,51 @@ static void uml_net_user_timer_expire(st
#endif
}
+#ifdef CONFIG_UML_NET_DETERMINISTIC_MAC
+
+/* Compute a SHA1 hash of the UML instance's id and
+ * * an interface name. */
+static int compute_hash(const char *umid, const char *ifname, char *hash)
+{
+ struct ahash_request *desc;
+ struct crypto_ahash *tfm;
+ struct scatterlist sg;
+ char vmif[1024];
+ int ret;
+
+ strcpy (vmif, umid);
+ strcat (vmif, ifname);
+
+ tfm = crypto_alloc_ahash("sha1", 0, CRYPTO_ALG_ASYNC);
+ if (IS_ERR(tfm))
+ return -ENOMEM;
+
+ desc = ahash_request_alloc(tfm, GFP_KERNEL);
+ if (!desc) {
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ crypto_ahash_clear_flags(tfm, ~0);
+
+ sg_init_table(&sg, 1);
+ sg_set_buf(&sg, vmif, strlen(vmif));
+
+ ahash_request_set_crypt(desc, &sg, hash, strlen(vmif));
+
+ ret = crypto_ahash_digest(desc);
+out:
+ crypto_free_ahash(tfm);
+
+ return ret;
+}
+
+#endif
+
void uml_net_setup_etheraddr(struct net_device *dev, char *str)
{
unsigned char *addr = dev->dev_addr;
+ u8 hash[SHA1_DIGEST_SIZE];
char *end;
int i;
@@ -331,9 +381,26 @@ void uml_net_setup_etheraddr(struct net_
return;
random:
+#ifndef CONFIG_UML_NET_DETERMINISTIC_MAC
printk(KERN_INFO
"Choosing a random ethernet address for device %s\n", dev->name);
eth_hw_addr_random(dev);
+#else
+ printk(KERN_INFO
+ "Computing a digest to use as ethernet address for device %s\n", dev->name);
+ if (compute_hash(get_umid(), dev->name, hash) < 0) {
+ printk(KERN_WARNING
+ "Could not compute digest to use as ethernet address for device %s. "
+ "Using random address instead.\n", dev->name);
+ random_ether_addr(addr);
+ }
+ else {
+ for (i=0; i < 6; i++)
+ addr[i] = (hash[i] + hash[i+6]) % 0x100;
+ }
+ addr [0] &= 0xfe; /* clear multicast bit */
+ addr [0] |= 0x02; /* set local assignment bit (IEEE802) */
+#endif
}
static DEFINE_SPINLOCK(devices_lock);