Gentoo Websites Logo
Go to: Gentoo Home Documentation Forums Lists Bugs Planet Store Wiki Get Gentoo!
View | Details | Raw Unified | Return to bug 587230 | Differences between
and this patch

Collapse All | Expand All

(-)a/linux-user/Makefile.objs (-2 / +3 lines)
Lines 1-7 Link Here
1
obj-y = main.o syscall.o strace.o mmap.o signal.o \
1
obj-y = main.o syscall.o strace.o mmap.o signal.o \
2
	elfload.o linuxload.o uaccess.o uname.o \
2
	elfload.o linuxload.o uaccess.o uname.o \
3
	safe-syscall.o $(TARGET_ABI_DIR)/signal.o \
3
	safe-syscall.o syscall_proc.o \
4
        $(TARGET_ABI_DIR)/cpu_loop.o exit.o fd-trans.o
4
	$(TARGET_ABI_DIR)/cpu_loop.o $(TARGET_ABI_DIR)/signal.o \
5
	exit.o fd-trans.o
5
6
6
obj-$(TARGET_HAS_BFLT) += flatload.o
7
obj-$(TARGET_HAS_BFLT) += flatload.o
7
obj-$(TARGET_I386) += vm86.o
8
obj-$(TARGET_I386) += vm86.o
(-)a/linux-user/elfload.c (-2 / +5 lines)
Lines 2319-2325 exit_errmsg: Link Here
2319
   buffer is sufficiently aligned to present no problems to the host
2319
   buffer is sufficiently aligned to present no problems to the host
2320
   in accessing data at aligned offsets within the buffer.
2320
   in accessing data at aligned offsets within the buffer.
2321
2321
2322
   On return: INFO values will be filled in, as necessary or available.  */
2322
   On return: INFO values will be filled in, as necessary or available.
2323
2324
   WARNING: this function won't close "image_fd".
2325
*/
2323
2326
2324
static void load_elf_image(const char *image_name, int image_fd,
2327
static void load_elf_image(const char *image_name, int image_fd,
2325
                           struct image_info *info, char **pinterp_name,
2328
                           struct image_info *info, char **pinterp_name,
Lines 2576-2582 static void load_elf_image(const char *image_name, int image_fd, Link Here
2576
2579
2577
    mmap_unlock();
2580
    mmap_unlock();
2578
2581
2579
    close(image_fd);
2580
    return;
2582
    return;
2581
2583
2582
 exit_read:
2584
 exit_read:
Lines 2610-2615 static void load_elf_interp(const char *filename, struct image_info *info, Link Here
2610
    }
2612
    }
2611
2613
2612
    load_elf_image(filename, fd, info, NULL, bprm_buf);
2614
    load_elf_image(filename, fd, info, NULL, bprm_buf);
2615
    close(fd);
2613
    return;
2616
    return;
2614
2617
2615
 exit_perror:
2618
 exit_perror:
(-)a/linux-user/exit.c (-2 / +5 lines)
Lines 28-39 extern void __gcov_dump(void); Link Here
28
28
29
void preexit_cleanup(CPUArchState *env, int code)
29
void preexit_cleanup(CPUArchState *env, int code)
30
{
30
{
31
    close(execfd);
32
31
#ifdef CONFIG_GPROF
33
#ifdef CONFIG_GPROF
32
        _mcleanup();
34
        _mcleanup();
33
#endif
35
#endif
34
#ifdef CONFIG_GCOV
36
#ifdef CONFIG_GCOV
35
        __gcov_dump();
37
        __gcov_dump();
36
#endif
38
#endif
37
        gdb_exit(env, code);
39
38
        qemu_plugin_atexit_cb();
40
    gdb_exit(env, code);
41
    qemu_plugin_atexit_cb();
39
}
42
}
(-)a/linux-user/main.c (-1 / +1 lines)
Lines 48-53 Link Here
48
#include "crypto/init.h"
48
#include "crypto/init.h"
49
49
50
char *exec_path;
50
char *exec_path;
51
int execfd;
51
52
52
int singlestep;
53
int singlestep;
53
static const char *argv0;
54
static const char *argv0;
Lines 628-634 int main(int argc, char **argv, char **envp) Link Here
628
    int target_argc;
629
    int target_argc;
629
    int i;
630
    int i;
630
    int ret;
631
    int ret;
631
    int execfd;
632
    int log_mask;
632
    int log_mask;
633
    unsigned long max_reserved_va;
633
    unsigned long max_reserved_va;
634
634
(-)a/linux-user/qemu.h (+1 lines)
Lines 156-161 typedef struct TaskState { Link Here
156
} __attribute__((aligned(16))) TaskState;
156
} __attribute__((aligned(16))) TaskState;
157
157
158
extern char *exec_path;
158
extern char *exec_path;
159
extern int execfd;
159
void init_task_state(TaskState *ts);
160
void init_task_state(TaskState *ts);
160
void task_settid(TaskState *);
161
void task_settid(TaskState *);
161
void stop_all_tasks(void);
162
void stop_all_tasks(void);
(-)a/linux-user/syscall.c (-54 / +31 lines)
Lines 122-127 Link Here
122
#include "qapi/error.h"
122
#include "qapi/error.h"
123
#include "fd-trans.h"
123
#include "fd-trans.h"
124
#include "tcg/tcg.h"
124
#include "tcg/tcg.h"
125
#include "syscall_proc.h"
125
126
126
#ifndef CLONE_IO
127
#ifndef CLONE_IO
127
#define CLONE_IO                0x80000000      /* Clone io context */
128
#define CLONE_IO                0x80000000      /* Clone io context */
Lines 1104-1110 static inline rlim_t target_to_host_rlim(abi_ulong target_rlim) Link Here
1104
{
1105
{
1105
    abi_ulong target_rlim_swap;
1106
    abi_ulong target_rlim_swap;
1106
    rlim_t result;
1107
    rlim_t result;
1107
    
1108
1108
    target_rlim_swap = tswapal(target_rlim);
1109
    target_rlim_swap = tswapal(target_rlim);
1109
    if (target_rlim_swap == TARGET_RLIM_INFINITY)
1110
    if (target_rlim_swap == TARGET_RLIM_INFINITY)
1110
        return RLIM_INFINITY;
1111
        return RLIM_INFINITY;
Lines 1112-1118 static inline rlim_t target_to_host_rlim(abi_ulong target_rlim) Link Here
1112
    result = target_rlim_swap;
1113
    result = target_rlim_swap;
1113
    if (target_rlim_swap != (rlim_t)result)
1114
    if (target_rlim_swap != (rlim_t)result)
1114
        return RLIM_INFINITY;
1115
        return RLIM_INFINITY;
1115
    
1116
1116
    return result;
1117
    return result;
1117
}
1118
}
1118
#endif
1119
#endif
Lines 1122-1134 static inline abi_ulong host_to_target_rlim(rlim_t rlim) Link Here
1122
{
1123
{
1123
    abi_ulong target_rlim_swap;
1124
    abi_ulong target_rlim_swap;
1124
    abi_ulong result;
1125
    abi_ulong result;
1125
    
1126
1126
    if (rlim == RLIM_INFINITY || rlim != (abi_long)rlim)
1127
    if (rlim == RLIM_INFINITY || rlim != (abi_long)rlim)
1127
        target_rlim_swap = TARGET_RLIM_INFINITY;
1128
        target_rlim_swap = TARGET_RLIM_INFINITY;
1128
    else
1129
    else
1129
        target_rlim_swap = rlim;
1130
        target_rlim_swap = rlim;
1130
    result = tswapal(target_rlim_swap);
1131
    result = tswapal(target_rlim_swap);
1131
    
1132
1132
    return result;
1133
    return result;
1133
}
1134
}
1134
#endif
1135
#endif
Lines 1615-1623 static inline abi_long target_to_host_cmsg(struct msghdr *msgh, Link Here
1615
    abi_ulong target_cmsg_addr;
1616
    abi_ulong target_cmsg_addr;
1616
    struct target_cmsghdr *target_cmsg, *target_cmsg_start;
1617
    struct target_cmsghdr *target_cmsg, *target_cmsg_start;
1617
    socklen_t space = 0;
1618
    socklen_t space = 0;
1618
    
1619
1619
    msg_controllen = tswapal(target_msgh->msg_controllen);
1620
    msg_controllen = tswapal(target_msgh->msg_controllen);
1620
    if (msg_controllen < sizeof (struct target_cmsghdr)) 
1621
    if (msg_controllen < sizeof (struct target_cmsghdr))
1621
        goto the_end;
1622
        goto the_end;
1622
    target_cmsg_addr = tswapal(target_msgh->msg_control);
1623
    target_cmsg_addr = tswapal(target_msgh->msg_control);
1623
    target_cmsg = lock_user(VERIFY_READ, target_cmsg_addr, msg_controllen, 1);
1624
    target_cmsg = lock_user(VERIFY_READ, target_cmsg_addr, msg_controllen, 1);
Lines 1703-1709 static inline abi_long host_to_target_cmsg(struct target_msghdr *target_msgh, Link Here
1703
    socklen_t space = 0;
1704
    socklen_t space = 0;
1704
1705
1705
    msg_controllen = tswapal(target_msgh->msg_controllen);
1706
    msg_controllen = tswapal(target_msgh->msg_controllen);
1706
    if (msg_controllen < sizeof (struct target_cmsghdr)) 
1707
    if (msg_controllen < sizeof (struct target_cmsghdr))
1707
        goto the_end;
1708
        goto the_end;
1708
    target_cmsg_addr = tswapal(target_msgh->msg_control);
1709
    target_cmsg_addr = tswapal(target_msgh->msg_control);
1709
    target_cmsg = lock_user(VERIFY_WRITE, target_cmsg_addr, msg_controllen, 0);
1710
    target_cmsg = lock_user(VERIFY_WRITE, target_cmsg_addr, msg_controllen, 0);
Lines 5750-5756 abi_long do_set_thread_area(CPUX86State *env, abi_ulong ptr) Link Here
5750
    }
5751
    }
5751
    unlock_user_struct(target_ldt_info, ptr, 1);
5752
    unlock_user_struct(target_ldt_info, ptr, 1);
5752
5753
5753
    if (ldt_info.entry_number < TARGET_GDT_ENTRY_TLS_MIN || 
5754
    if (ldt_info.entry_number < TARGET_GDT_ENTRY_TLS_MIN ||
5754
        ldt_info.entry_number > TARGET_GDT_ENTRY_TLS_MAX)
5755
        ldt_info.entry_number > TARGET_GDT_ENTRY_TLS_MAX)
5755
           return -TARGET_EINVAL;
5756
           return -TARGET_EINVAL;
5756
    seg_32bit = ldt_info.flags & 1;
5757
    seg_32bit = ldt_info.flags & 1;
Lines 5828-5834 static abi_long do_get_thread_area(CPUX86State *env, abi_ulong ptr) Link Here
5828
    lp = (uint32_t *)(gdt_table + idx);
5829
    lp = (uint32_t *)(gdt_table + idx);
5829
    entry_1 = tswap32(lp[0]);
5830
    entry_1 = tswap32(lp[0]);
5830
    entry_2 = tswap32(lp[1]);
5831
    entry_2 = tswap32(lp[1]);
5831
    
5832
5832
    read_exec_only = ((entry_2 >> 9) & 1) ^ 1;
5833
    read_exec_only = ((entry_2 >> 9) & 1) ^ 1;
5833
    contents = (entry_2 >> 10) & 3;
5834
    contents = (entry_2 >> 10) & 3;
5834
    seg_not_present = ((entry_2 >> 15) & 1) ^ 1;
5835
    seg_not_present = ((entry_2 >> 15) & 1) ^ 1;
Lines 5844-5851 static abi_long do_get_thread_area(CPUX86State *env, abi_ulong ptr) Link Here
5844
        (read_exec_only << 3) | (limit_in_pages << 4) |
5845
        (read_exec_only << 3) | (limit_in_pages << 4) |
5845
        (seg_not_present << 5) | (useable << 6) | (lm << 7);
5846
        (seg_not_present << 5) | (useable << 6) | (lm << 7);
5846
    limit = (entry_1 & 0xffff) | (entry_2  & 0xf0000);
5847
    limit = (entry_1 & 0xffff) | (entry_2  & 0xf0000);
5847
    base_addr = (entry_1 >> 16) | 
5848
    base_addr = (entry_1 >> 16) |
5848
        (entry_2 & 0xff000000) | 
5849
        (entry_2 & 0xff000000) |
5849
        ((entry_2 & 0xff) << 16);
5850
        ((entry_2 & 0xff) << 16);
5850
    target_ldt_info->base_addr = tswapal(base_addr);
5851
    target_ldt_info->base_addr = tswapal(base_addr);
5851
    target_ldt_info->limit = tswap32(limit);
5852
    target_ldt_info->limit = tswap32(limit);
Lines 7353-7390 static int open_self_auxv(void *cpu_env, int fd) Link Here
7353
    return 0;
7354
    return 0;
7354
}
7355
}
7355
7356
7356
static int is_proc_myself(const char *filename, const char *entry)
7357
{
7358
    if (!strncmp(filename, "/proc/", strlen("/proc/"))) {
7359
        filename += strlen("/proc/");
7360
        if (!strncmp(filename, "self/", strlen("self/"))) {
7361
            filename += strlen("self/");
7362
        } else if (*filename >= '1' && *filename <= '9') {
7363
            char myself[80];
7364
            snprintf(myself, sizeof(myself), "%d/", getpid());
7365
            if (!strncmp(filename, myself, strlen(myself))) {
7366
                filename += strlen(myself);
7367
            } else {
7368
                return 0;
7369
            }
7370
        } else {
7371
            return 0;
7372
        }
7373
        if (!strcmp(filename, entry)) {
7374
            return 1;
7375
        }
7376
    }
7377
    return 0;
7378
}
7379
7380
#if defined(HOST_WORDS_BIGENDIAN) != defined(TARGET_WORDS_BIGENDIAN) || \
7381
    defined(TARGET_SPARC) || defined(TARGET_M68K)
7382
static int is_proc(const char *filename, const char *entry)
7383
{
7384
    return strcmp(filename, entry) == 0;
7385
}
7386
#endif
7387
7388
#if defined(HOST_WORDS_BIGENDIAN) != defined(TARGET_WORDS_BIGENDIAN)
7357
#if defined(HOST_WORDS_BIGENDIAN) != defined(TARGET_WORDS_BIGENDIAN)
7389
static int open_net_route(void *cpu_env, int fd)
7358
static int open_net_route(void *cpu_env, int fd)
7390
{
7359
{
Lines 7460-7479 static int do_openat(void *cpu_env, int dirfd, const char *pathname, int flags, Link Here
7460
        { "auxv", open_self_auxv, is_proc_myself },
7429
        { "auxv", open_self_auxv, is_proc_myself },
7461
        { "cmdline", open_self_cmdline, is_proc_myself },
7430
        { "cmdline", open_self_cmdline, is_proc_myself },
7462
#if defined(HOST_WORDS_BIGENDIAN) != defined(TARGET_WORDS_BIGENDIAN)
7431
#if defined(HOST_WORDS_BIGENDIAN) != defined(TARGET_WORDS_BIGENDIAN)
7463
        { "/proc/net/route", open_net_route, is_proc },
7432
        { "net/route", open_net_route, is_proc },
7464
#endif
7433
#endif
7465
#if defined(TARGET_SPARC)
7434
#if defined(TARGET_SPARC)
7466
        { "/proc/cpuinfo", open_cpuinfo, is_proc },
7435
        { "cpuinfo", open_cpuinfo, is_proc },
7467
#endif
7436
#endif
7468
#if defined(TARGET_M68K)
7437
#if defined(TARGET_M68K)
7469
        { "/proc/hardware", open_hardware, is_proc },
7438
        { "hardware", open_hardware, is_proc },
7470
#endif
7439
#endif
7471
        { NULL, NULL, NULL }
7440
        { NULL, NULL, NULL }
7472
    };
7441
    };
7473
7442
7474
    if (is_proc_myself(pathname, "exe")) {
7443
    if (is_proc_myself_exe(pathname)) {
7475
        int execfd = qemu_getauxval(AT_EXECFD);
7444
        return execfd;
7476
        return execfd ? execfd : safe_openat(dirfd, exec_path, flags, mode);
7477
    }
7445
    }
7478
7446
7479
    for (fake_open = fakes; fake_open->filename; fake_open++) {
7447
    for (fake_open = fakes; fake_open->filename; fake_open++) {
Lines 7728-7735 static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1, Link Here
7728
        return ret;
7696
        return ret;
7729
#endif
7697
#endif
7730
    case TARGET_NR_close:
7698
    case TARGET_NR_close:
7731
        fd_trans_unregister(arg1);
7699
        {
7732
        return get_errno(close(arg1));
7700
            int fd = arg1;
7701
            if (fd == execfd) {
7702
                // We don't need to close execfd.
7703
                // It will be closed on qemu exit.
7704
                return 0;
7705
            }
7706
7707
            fd_trans_unregister(fd);
7708
            return get_errno(close(fd));
7709
        }
7733
7710
7734
    case TARGET_NR_brk:
7711
    case TARGET_NR_brk:
7735
        return do_brk(arg1);
7712
        return do_brk(arg1);
Lines 9031-9037 static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1, Link Here
9031
            } else if (!arg3) {
9008
            } else if (!arg3) {
9032
                /* Short circuit this for the magic exe check. */
9009
                /* Short circuit this for the magic exe check. */
9033
                ret = -TARGET_EINVAL;
9010
                ret = -TARGET_EINVAL;
9034
            } else if (is_proc_myself((const char *)p, "exe")) {
9011
            } else if (is_proc_myself_exe((const char *)p)) {
9035
                char real[PATH_MAX], *temp;
9012
                char real[PATH_MAX], *temp;
9036
                temp = realpath(exec_path, real);
9013
                temp = realpath(exec_path, real);
9037
                /* Return value is # of bytes that we wrote to the buffer. */
9014
                /* Return value is # of bytes that we wrote to the buffer. */
Lines 9060-9066 static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1, Link Here
9060
            p2 = lock_user(VERIFY_WRITE, arg3, arg4, 0);
9037
            p2 = lock_user(VERIFY_WRITE, arg3, arg4, 0);
9061
            if (!p || !p2) {
9038
            if (!p || !p2) {
9062
                ret = -TARGET_EFAULT;
9039
                ret = -TARGET_EFAULT;
9063
            } else if (is_proc_myself((const char *)p, "exe")) {
9040
            } else if (is_proc_myself_exe((const char *)p)) {
9064
                char real[PATH_MAX], *temp;
9041
                char real[PATH_MAX], *temp;
9065
                temp = realpath(exec_path, real);
9042
                temp = realpath(exec_path, real);
9066
                ret = temp == NULL ? get_errno(-1) : strlen(real) ;
9043
                ret = temp == NULL ? get_errno(-1) : strlen(real) ;
Lines 10847-10853 static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1, Link Here
10847
        return get_errno(fchown(arg1, low2highuid(arg2), low2highgid(arg3)));
10824
        return get_errno(fchown(arg1, low2highuid(arg2), low2highgid(arg3)));
10848
#if defined(TARGET_NR_fchownat)
10825
#if defined(TARGET_NR_fchownat)
10849
    case TARGET_NR_fchownat:
10826
    case TARGET_NR_fchownat:
10850
        if (!(p = lock_user_string(arg2))) 
10827
        if (!(p = lock_user_string(arg2)))
10851
            return -TARGET_EFAULT;
10828
            return -TARGET_EFAULT;
10852
        ret = get_errno(fchownat(arg1, p, low2highuid(arg3),
10829
        ret = get_errno(fchownat(arg1, p, low2highuid(arg3),
10853
                                 low2highgid(arg4), arg5));
10830
                                 low2highgid(arg4), arg5));
(-)a/linux-user/syscall_proc.c (+96 lines)
Line 0 Link Here
1
#include "qemu/osdep.h"
2
#include "elf.h"
3
4
#include "syscall_proc.h"
5
#include "qemu.h"
6
7
#define PROC "/proc/"
8
#define SELF "self/"
9
10
#define STARTS_WITH(path, CONSTANT) \
11
  strlen(path) >= strlen(CONSTANT) && strncmp(path, CONSTANT, strlen(CONSTANT)) == 0
12
13
static inline char *scope_to_proc(const char *path)
14
{
15
    if (STARTS_WITH(path, PROC)) {
16
        return (char *)path + strlen(PROC);
17
    }
18
19
    return NULL;
20
}
21
22
static inline char *scope_to_proc_myself(const char *path)
23
{
24
    char *scope_path = scope_to_proc(path);
25
    if (scope_path == NULL) {
26
        return NULL;
27
    }
28
29
    if (STARTS_WITH(scope_path, SELF)) {
30
        return scope_path + strlen(SELF);
31
    }
32
33
    if (strlen(scope_path) >= 1 && *scope_path >= '1' && *scope_path <= '9') {
34
        char pid_path[80];
35
        snprintf(pid_path, sizeof(pid_path), "%d/", getpid());
36
        if (STARTS_WITH(scope_path, pid_path)) {
37
            return scope_path + strlen(pid_path);
38
        }
39
    }
40
41
    return NULL;
42
}
43
44
int is_proc(const char *path, const char *entry)
45
{
46
    char *scope_path = scope_to_proc(path);
47
    if (scope_path == NULL) {
48
        return 0;
49
    }
50
51
    return strcmp(scope_path, entry) == 0;
52
}
53
54
int is_proc_myself(const char *path, const char *entry)
55
{
56
    char *scope_path = scope_to_proc_myself(path);
57
    if (scope_path == NULL) {
58
        return 0;
59
    }
60
61
    return strcmp(scope_path, entry) == 0;
62
}
63
64
int is_proc_myself_exe(const char *path)
65
{
66
    char *scope_path = scope_to_proc_myself(path);
67
    if (scope_path == NULL) {
68
        return 0;
69
    }
70
71
    // Kernel creates "fd/#{number}" link after opening "exe" link.
72
    // Both "exe" and "fd/#{number}" can be used by application.
73
74
    // Kernel can provide infinite amount of fd numbers.
75
    // Qemu is going to always return single global execfd.
76
77
    // So we need to check "exe" and "fd/#{execfd}" only.
78
79
    if (strcmp(scope_path, "exe") == 0) {
80
        return 1;
81
    }
82
83
    if (STARTS_WITH(scope_path, "fd/")) {
84
        scope_path += strlen("fd/");
85
86
        if (strlen(scope_path) >= 1 && *scope_path >= '1' && *scope_path <= '9') {
87
            char execfd_path[80];
88
            snprintf(execfd_path, sizeof(execfd_path), "%d", execfd);
89
            if (strcmp(scope_path, execfd_path) == 0) {
90
                return 1;
91
            }
92
        }
93
    }
94
95
    return 0;
96
}
(-)a/linux-user/syscall_proc.h (+8 lines)
Line 0 Link Here
1
#ifndef SYSCALL_PROC_H
2
#define SYSCALL_PROC_H
3
4
int is_proc(const char *path, const char *entry);
5
int is_proc_myself(const char *path, const char *entry);
6
int is_proc_myself_exe(const char *path);
7
8
#endif

Return to bug 587230