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/syscall.c (-50 / +19 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-7477 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
        int execfd = qemu_getauxval(AT_EXECFD);
7476
        return execfd ? execfd : safe_openat(dirfd, exec_path, flags, mode);
7445
        return execfd ? execfd : safe_openat(dirfd, exec_path, flags, mode);
7477
    }
7446
    }
Lines 9031-9037 static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1, Link Here
9031
            } else if (!arg3) {
9000
            } else if (!arg3) {
9032
                /* Short circuit this for the magic exe check. */
9001
                /* Short circuit this for the magic exe check. */
9033
                ret = -TARGET_EINVAL;
9002
                ret = -TARGET_EINVAL;
9034
            } else if (is_proc_myself((const char *)p, "exe")) {
9003
            } else if (is_proc_myself_exe((const char *)p)) {
9035
                char real[PATH_MAX], *temp;
9004
                char real[PATH_MAX], *temp;
9036
                temp = realpath(exec_path, real);
9005
                temp = realpath(exec_path, real);
9037
                /* Return value is # of bytes that we wrote to the buffer. */
9006
                /* 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);
9029
            p2 = lock_user(VERIFY_WRITE, arg3, arg4, 0);
9061
            if (!p || !p2) {
9030
            if (!p || !p2) {
9062
                ret = -TARGET_EFAULT;
9031
                ret = -TARGET_EFAULT;
9063
            } else if (is_proc_myself((const char *)p, "exe")) {
9032
            } else if (is_proc_myself_exe((const char *)p)) {
9064
                char real[PATH_MAX], *temp;
9033
                char real[PATH_MAX], *temp;
9065
                temp = realpath(exec_path, real);
9034
                temp = realpath(exec_path, real);
9066
                ret = temp == NULL ? get_errno(-1) : strlen(real) ;
9035
                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)));
10816
        return get_errno(fchown(arg1, low2highuid(arg2), low2highgid(arg3)));
10848
#if defined(TARGET_NR_fchownat)
10817
#if defined(TARGET_NR_fchownat)
10849
    case TARGET_NR_fchownat:
10818
    case TARGET_NR_fchownat:
10850
        if (!(p = lock_user_string(arg2))) 
10819
        if (!(p = lock_user_string(arg2)))
10851
            return -TARGET_EFAULT;
10820
            return -TARGET_EFAULT;
10852
        ret = get_errno(fchownat(arg1, p, low2highuid(arg3),
10821
        ret = get_errno(fchownat(arg1, p, low2highuid(arg3),
10853
                                 low2highgid(arg4), arg5));
10822
                                 low2highgid(arg4), arg5));
(-)a/linux-user/syscall_proc.c (+95 lines)
Line 0 Link Here
1
#include "syscall_proc.h"
2
#include "qemu/osdep.h"
3
#include "elf.h"
4
5
#define PROC "/proc/"
6
#define SELF "self/"
7
8
#define STARTS_WITH(path, CONSTANT) \
9
  strlen(path) >= strlen(CONSTANT) && strncmp(path, CONSTANT, strlen(CONSTANT)) == 0
10
11
static inline char *scope_to_proc(const char *path)
12
{
13
    if (STARTS_WITH(path, PROC)) {
14
        return (char *)path + strlen(PROC);
15
    }
16
17
    return NULL;
18
}
19
20
static inline char *scope_to_proc_myself(const char *path)
21
{
22
    char *scope_path = scope_to_proc(path);
23
    if (scope_path == NULL) {
24
        return NULL;
25
    }
26
27
    if (STARTS_WITH(scope_path, SELF)) {
28
        return scope_path + strlen(SELF);
29
    }
30
31
    if (strlen(scope_path) >= 1 && *scope_path >= '1' && *scope_path <= '9') {
32
        char pid_path[80];
33
        snprintf(pid_path, sizeof(pid_path), "%d/", getpid());
34
        if (STARTS_WITH(scope_path, pid_path)) {
35
            return scope_path + strlen(pid_path);
36
        }
37
    }
38
39
    return NULL;
40
}
41
42
int is_proc(const char *path, const char *entry)
43
{
44
    char *scope_path = scope_to_proc(path);
45
    if (scope_path == NULL) {
46
        return 0;
47
    }
48
49
    return strcmp(scope_path, entry) == 0;
50
}
51
52
int is_proc_myself(const char *path, const char *entry)
53
{
54
    char *scope_path = scope_to_proc_myself(path);
55
    if (scope_path == NULL) {
56
        return 0;
57
    }
58
59
    return strcmp(scope_path, entry) == 0;
60
}
61
62
int is_proc_myself_exe(const char *path)
63
{
64
    char *scope_path = scope_to_proc_myself(path);
65
    if (scope_path == NULL) {
66
        return 0;
67
    }
68
69
    // Kernel creates "fd/#{number}" link after opening "exe" link.
70
    // Both "exe" and "fd/#{number}" can be used by application.
71
72
    // Kernel can provide infinite amount of fd numbers.
73
    // Qemu is going to always return single global execfd.
74
75
    // So we need to check "exe" and "fd/#{global_execfd}" only.
76
77
    if (strcmp(scope_path, "exe") == 0) {
78
        return 1;
79
    }
80
81
    if (STARTS_WITH(scope_path, "fd/")) {
82
        scope_path += strlen("fd/");
83
84
        int execfd = qemu_getauxval(AT_EXECFD);
85
        if (strlen(scope_path) >= 1 && *scope_path >= '1' && *scope_path <= '9' && execfd) {
86
            char execfd_path[80];
87
            snprintf(execfd_path, sizeof(execfd_path), "%d", execfd);
88
            if (strcmp(scope_path, execfd_path) == 0) {
89
                return 1;
90
            }
91
        }
92
    }
93
94
    return 0;
95
}
(-)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