blob: ec473e9cb1eb0f0ef34bad61e7475de4423c4977
1 | /* vi: set sw=4 ts=4: */ |
2 | /* |
3 | * linux32/linux64 allows for changing uname emulation. |
4 | * |
5 | * Copyright 2002 Andi Kleen, SuSE Labs. |
6 | * |
7 | * Licensed under GPLv2 or later, see file LICENSE in this source tree. |
8 | */ |
9 | //config:config SETARCH |
10 | //config: bool "setarch" |
11 | //config: default y |
12 | //config: select PLATFORM_LINUX |
13 | //config: help |
14 | //config: The linux32 utility is used to create a 32bit environment for the |
15 | //config: specified program (usually a shell). It only makes sense to have |
16 | //config: this util on a system that supports both 64bit and 32bit userland |
17 | //config: (like amd64/x86, ppc64/ppc, sparc64/sparc, etc...). |
18 | //config: |
19 | //config:config LINUX32 |
20 | //config: bool "linux32" |
21 | //config: default y |
22 | //config: select PLATFORM_LINUX |
23 | //config: help |
24 | //config: Alias to "setarch linux32". |
25 | //config: |
26 | //config:config LINUX64 |
27 | //config: bool "linux64" |
28 | //config: default y |
29 | //config: select PLATFORM_LINUX |
30 | //config: help |
31 | //config: Alias to "setarch linux64". |
32 | |
33 | //applet:IF_SETARCH(APPLET(setarch, BB_DIR_BIN, BB_SUID_DROP)) |
34 | //applet:IF_LINUX32(APPLET_ODDNAME(linux32, setarch, BB_DIR_BIN, BB_SUID_DROP, linux32)) |
35 | //applet:IF_LINUX64(APPLET_ODDNAME(linux64, setarch, BB_DIR_BIN, BB_SUID_DROP, linux64)) |
36 | |
37 | //kbuild:lib-$(CONFIG_SETARCH) += setarch.o |
38 | //kbuild:lib-$(CONFIG_LINUX32) += setarch.o |
39 | //kbuild:lib-$(CONFIG_LINUX64) += setarch.o |
40 | |
41 | //usage:#define setarch_trivial_usage |
42 | //usage: "PERSONALITY [-R] PROG ARGS" |
43 | //usage:#define setarch_full_usage "\n\n" |
44 | //usage: "PERSONALITY may be:" |
45 | //usage: "\n"" linux32 Set 32bit uname emulation" |
46 | //usage: "\n"" linux64 Set 64bit uname emulation" |
47 | //usage: "\n" |
48 | //usage: "\n"" -R Disable address space randomization" |
49 | //usage: |
50 | //usage:#define linux32_trivial_usage NOUSAGE_STR |
51 | //usage:#define linux32_full_usage "" |
52 | //usage: |
53 | //usage:#define linux64_trivial_usage NOUSAGE_STR |
54 | //usage:#define linux64_full_usage "" |
55 | |
56 | #include "libbb.h" |
57 | #include <sys/personality.h> |
58 | |
59 | #ifndef ADDR_NO_RANDOMIZE |
60 | # define ADDR_NO_RANDOMIZE 0x0040000 |
61 | #endif |
62 | |
63 | int setarch_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; |
64 | int setarch_main(int argc UNUSED_PARAM, char **argv) |
65 | { |
66 | unsigned opts; |
67 | unsigned long pers; |
68 | |
69 | /* Figure out what personality we are supposed to switch to ... |
70 | * we can be invoked as either: |
71 | * argv[0],argv[1] == "setarch","personality" |
72 | * argv[0] == "personality" |
73 | */ |
74 | if (ENABLE_SETARCH && applet_name[0] == 's' |
75 | && argv[1] && is_prefixed_with(argv[1], "linux") |
76 | ) { |
77 | argv++; |
78 | applet_name = argv[0]; |
79 | } |
80 | if ((!ENABLE_SETARCH && !ENABLE_LINUX32) || applet_name[5] == '6') |
81 | /* linux64 */ |
82 | pers = PER_LINUX; |
83 | else |
84 | if ((!ENABLE_SETARCH && !ENABLE_LINUX64) || applet_name[5] == '3') |
85 | /* linux32 */ |
86 | pers = PER_LINUX32; |
87 | else |
88 | bb_show_usage(); |
89 | |
90 | opts = getopt32(argv, "+R"); /* '+': stop at first non-option */ |
91 | if (opts) |
92 | pers |= ADDR_NO_RANDOMIZE; |
93 | |
94 | /* Try to set personality */ |
95 | if (personality(pers) < 0) |
96 | bb_perror_msg_and_die("personality(0x%lx)", pers); |
97 | |
98 | argv += optind; |
99 | if (!argv[0]) |
100 | (--argv)[0] = (char*)"/bin/sh"; |
101 | |
102 | /* Try to execute the program */ |
103 | BB_EXECVP_or_die(argv); |
104 | } |
105 |