aboutsummaryrefslogtreecommitdiff
path: root/linux-user
diff options
context:
space:
mode:
Diffstat (limited to 'linux-user')
-rw-r--r--linux-user/fd-trans.h10
-rw-r--r--linux-user/gen-vdso.c16
-rw-r--r--linux-user/main.c2
-rw-r--r--linux-user/meson.build5
-rw-r--r--linux-user/mips/target_signal.h1
-rw-r--r--linux-user/plugin-api.c1
-rw-r--r--linux-user/syscall.c26
-rw-r--r--linux-user/syscall_defs.h4
8 files changed, 52 insertions, 13 deletions
diff --git a/linux-user/fd-trans.h b/linux-user/fd-trans.h
index 910faaf..e14f960 100644
--- a/linux-user/fd-trans.h
+++ b/linux-user/fd-trans.h
@@ -36,6 +36,16 @@ static inline void fd_trans_init(void)
qemu_mutex_init(&target_fd_trans_lock);
}
+static inline void fd_trans_prefork(void)
+{
+ qemu_mutex_lock(&target_fd_trans_lock);
+}
+
+static inline void fd_trans_postfork(void)
+{
+ qemu_mutex_unlock(&target_fd_trans_lock);
+}
+
static inline TargetFdDataFunc fd_trans_target_to_host_data(int fd)
{
if (fd < 0) {
diff --git a/linux-user/gen-vdso.c b/linux-user/gen-vdso.c
index fce9d5c..aeaa927 100644
--- a/linux-user/gen-vdso.c
+++ b/linux-user/gen-vdso.c
@@ -113,9 +113,21 @@ int main(int argc, char **argv)
* We expect the vdso to be small, on the order of one page,
* therefore we do not expect a partial read.
*/
- fseek(inf, 0, SEEK_END);
+ if (fseek(inf, 0, SEEK_END) < 0) {
+ goto perror_inf;
+ }
total_len = ftell(inf);
- fseek(inf, 0, SEEK_SET);
+ if (total_len < 0) {
+ goto perror_inf;
+ }
+ if (fseek(inf, 0, SEEK_SET) < 0) {
+ goto perror_inf;
+ }
+
+ if (total_len < EI_NIDENT) {
+ fprintf(stderr, "%s: file too small (truncated?)\n", inf_name);
+ return EXIT_FAILURE;
+ }
buf = malloc(total_len);
if (buf == NULL) {
diff --git a/linux-user/main.c b/linux-user/main.c
index a9142ee..f4f2007 100644
--- a/linux-user/main.c
+++ b/linux-user/main.c
@@ -149,12 +149,14 @@ void fork_start(void)
cpu_list_lock();
qemu_plugin_user_prefork_lock();
gdbserver_fork_start();
+ fd_trans_prefork();
}
void fork_end(pid_t pid)
{
bool child = pid == 0;
+ fd_trans_postfork();
qemu_plugin_user_postfork(child);
mmap_fork_end(child);
if (child) {
diff --git a/linux-user/meson.build b/linux-user/meson.build
index f47a213..efca843 100644
--- a/linux-user/meson.build
+++ b/linux-user/meson.build
@@ -27,7 +27,10 @@ linux_user_ss.add(libdw)
linux_user_ss.add(when: 'TARGET_HAS_BFLT', if_true: files('flatload.c'))
linux_user_ss.add(when: 'TARGET_I386', if_true: files('vm86.c'))
linux_user_ss.add(when: 'CONFIG_ARM_COMPATIBLE_SEMIHOSTING', if_true: files('semihost.c'))
-linux_user_ss.add(when: 'CONFIG_TCG_PLUGINS', if_true: files('plugin-api.c'))
+
+if get_option('plugins')
+ linux_user_ss.add(files('plugin-api.c'))
+endif
syscall_nr_generators = {}
diff --git a/linux-user/mips/target_signal.h b/linux-user/mips/target_signal.h
index fa542c1..4481426 100644
--- a/linux-user/mips/target_signal.h
+++ b/linux-user/mips/target_signal.h
@@ -64,7 +64,6 @@ typedef struct target_sigaltstack {
#define TARGET_SA_NODEFER 0x40000000
#define TARGET_SA_RESTART 0x10000000
#define TARGET_SA_RESETHAND 0x80000000
-#define TARGET_SA_RESTORER 0x04000000 /* Only for O32 */
#define TARGET_MINSIGSTKSZ 2048
diff --git a/linux-user/plugin-api.c b/linux-user/plugin-api.c
index 66755df..8d6fbb6 100644
--- a/linux-user/plugin-api.c
+++ b/linux-user/plugin-api.c
@@ -12,4 +12,5 @@
#include "qemu/osdep.h"
#include "qemu.h"
+#include "loader.h"
#include "common-user/plugin-api.c.inc"
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index fc37028..91360a0 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -790,6 +790,10 @@ safe_syscall6(ssize_t, copy_file_range, int, infd, loff_t *, pinoff,
int, outfd, loff_t *, poutoff, size_t, length,
unsigned int, flags)
#endif
+#if defined(TARGET_NR_fchmodat2) && defined(__NR_fchmodat2)
+safe_syscall4(int, fchmodat2, int, dfd, const char *, filename,
+ unsigned short, mode, unsigned int, flags)
+#endif
/* We do ioctl like this rather than via safe_syscall3 to preserve the
* "third argument might be integer or pointer or not present" behaviour of
@@ -6743,10 +6747,9 @@ static int do_fork(CPUArchState *env, unsigned int flags, abi_ulong newsp,
int pid_child = ret;
pid_fd = pidfd_open(pid_child, 0);
if (pid_fd >= 0) {
- fcntl(pid_fd, F_SETFD, fcntl(pid_fd, F_GETFL)
- | FD_CLOEXEC);
+ qemu_set_cloexec(pid_fd);
} else {
- pid_fd = 0;
+ pid_fd = 0;
}
#endif
put_user_u32(pid_fd, parent_tidptr);
@@ -10714,6 +10717,15 @@ static abi_long do_syscall1(CPUArchState *cpu_env, int num, abi_long arg1,
unlock_user(p, arg2, 0);
return ret;
#endif
+#if defined(TARGET_NR_fchmodat2) && defined(__NR_fchmodat2)
+ case TARGET_NR_fchmodat2:
+ if (!(p = lock_user_string(arg2))) {
+ return -TARGET_EFAULT;
+ }
+ ret = get_errno(safe_fchmodat2(arg1, p, arg3, arg4));
+ unlock_user(p, arg2, 0);
+ return ret;
+#endif
case TARGET_NR_getpriority:
/* Note that negative values are valid for getpriority, so we must
differentiate based on errno settings. */
@@ -11630,10 +11642,14 @@ static abi_long do_syscall1(CPUArchState *cpu_env, int num, abi_long arg1,
case TARGET_NR_nanosleep:
{
struct timespec req, rem;
- target_to_host_timespec(&req, arg1);
+ if (target_to_host_timespec(&req, arg1)) {
+ return -TARGET_EFAULT;
+ }
ret = get_errno(safe_nanosleep(&req, &rem));
if (is_error(ret) && arg2) {
- host_to_target_timespec(arg2, &rem);
+ if (host_to_target_timespec(arg2, &rem)) {
+ return -TARGET_EFAULT;
+ }
}
}
return ret;
diff --git a/linux-user/syscall_defs.h b/linux-user/syscall_defs.h
index 5d22759..df26a2d 100644
--- a/linux-user/syscall_defs.h
+++ b/linux-user/syscall_defs.h
@@ -515,10 +515,6 @@ struct target_sigaction {
abi_ulong _sa_handler;
#endif
target_sigset_t sa_mask;
-#ifdef TARGET_ARCH_HAS_SA_RESTORER
- /* ??? This is always present, but ignored unless O32. */
- abi_ulong sa_restorer;
-#endif
};
#else
struct target_old_sigaction {