* [Qemu-devel] [PATCH] linux-user: identify running binary in /proc/$$/exe
@ 2013-03-11 17:19 Andreas Schwab
2013-04-18 14:56 ` Peter Maydell
0 siblings, 1 reply; 4+ messages in thread
From: Andreas Schwab @ 2013-03-11 17:19 UTC (permalink / raw)
To: qemu-devel
Some applications like to test /proc/$$/exe (where $$ is the own pid) to
find out who they are. Handle it like /proc/self/exe.
Also, do the same handling in readlinkat.
Signed-off-by: Andreas Schwab <schwab@suse.de>
---
linux-user/syscall.c | 22 ++++++++++++++++++----
1 file changed, 18 insertions(+), 4 deletions(-)
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 19630ea..3e5a6ae 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -6413,7 +6413,10 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
if (!p || !p2)
ret = -TARGET_EFAULT;
else {
- if (strncmp((const char *)p, "/proc/self/exe", 14) == 0) {
+ char myself[PATH_MAX];
+ snprintf(myself, sizeof(myself), "/proc/%d/exe", getpid());
+ if (strncmp((const char *)p, "/proc/self/exe", 14) == 0 ||
+ strcmp((const char *)p, myself) == 0) {
char real[PATH_MAX];
temp = realpath(exec_path,real);
ret = (temp==NULL) ? get_errno(-1) : strlen(real) ;
@@ -6429,13 +6432,24 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
#if defined(TARGET_NR_readlinkat) && defined(__NR_readlinkat)
case TARGET_NR_readlinkat:
{
- void *p2;
+ void *p2, *temp;
p = lock_user_string(arg2);
p2 = lock_user(VERIFY_WRITE, arg3, arg4, 0);
if (!p || !p2)
ret = -TARGET_EFAULT;
- else
- ret = get_errno(sys_readlinkat(arg1, path(p), p2, arg4));
+ else {
+ char myself[PATH_MAX];
+ snprintf(myself, sizeof(myself), "/proc/%d/exe", getpid());
+ if (strncmp((const char *)p, "/proc/self/exe", 14) == 0 ||
+ strcmp((const char *)p, myself) == 0) {
+ char real[PATH_MAX];
+ temp = realpath(exec_path,real);
+ ret = (temp==NULL) ? get_errno(-1) : strlen(real) ;
+ snprintf((char *)p2, arg3, "%s", real);
+ }
+ else
+ ret = get_errno(sys_readlinkat(arg1, path(p), p2, arg4));
+ }
unlock_user(p2, arg3, ret);
unlock_user(p, arg2, 0);
}
--
1.8.1.5
--
Andreas Schwab, SUSE Labs, schwab@suse.de
GPG Key fingerprint = 0196 BAD8 1CE9 1970 F4BE 1748 E4D4 88E3 0EEA B9D7
"And now for something completely different."
^ permalink raw reply related [flat|nested] 4+ messages in thread
* Re: [Qemu-devel] [PATCH] linux-user: identify running binary in /proc/$$/exe
2013-03-11 17:19 [Qemu-devel] [PATCH] linux-user: identify running binary in /proc/$$/exe Andreas Schwab
@ 2013-04-18 14:56 ` Peter Maydell
2013-05-08 10:31 ` [Qemu-devel] [PATCH] linux-user: handle /proc/$$ like /proc/self Andreas Schwab
0 siblings, 1 reply; 4+ messages in thread
From: Peter Maydell @ 2013-04-18 14:56 UTC (permalink / raw)
To: Andreas Schwab; +Cc: qemu-devel
On 11 March 2013 17:19, Andreas Schwab <schwab@suse.de> wrote:
> Some applications like to test /proc/$$/exe (where $$ is the own pid) to
> find out who they are. Handle it like /proc/self/exe.
>
> Also, do the same handling in readlinkat.
Sorry I didn't get round to reviewing this earlier; I think
it slipped through the cracks :-(
> diff --git a/linux-user/syscall.c b/linux-user/syscall.c
> index 19630ea..3e5a6ae 100644
> --- a/linux-user/syscall.c
> +++ b/linux-user/syscall.c
> @@ -6413,7 +6413,10 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
> if (!p || !p2)
> ret = -TARGET_EFAULT;
> else {
> - if (strncmp((const char *)p, "/proc/self/exe", 14) == 0) {
> + char myself[PATH_MAX];
> + snprintf(myself, sizeof(myself), "/proc/%d/exe", getpid());
> + if (strncmp((const char *)p, "/proc/self/exe", 14) == 0 ||
> + strcmp((const char *)p, myself) == 0) {
> char real[PATH_MAX];
> temp = realpath(exec_path,real);
> ret = (temp==NULL) ? get_errno(-1) : strlen(real) ;
> @@ -6429,13 +6432,24 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
> #if defined(TARGET_NR_readlinkat) && defined(__NR_readlinkat)
> case TARGET_NR_readlinkat:
> {
> - void *p2;
> + void *p2, *temp;
> p = lock_user_string(arg2);
> p2 = lock_user(VERIFY_WRITE, arg3, arg4, 0);
> if (!p || !p2)
> ret = -TARGET_EFAULT;
> - else
> - ret = get_errno(sys_readlinkat(arg1, path(p), p2, arg4));
You could add braces on the 'then' part of this if() and get rid
of the stray hardcoded tab in the existing code. (not a requirement
but since we're in the area anyway...)
> + else {
> + char myself[PATH_MAX];
> + snprintf(myself, sizeof(myself), "/proc/%d/exe", getpid());
> + if (strncmp((const char *)p, "/proc/self/exe", 14) == 0 ||
> + strcmp((const char *)p, myself) == 0) {
> + char real[PATH_MAX];
> + temp = realpath(exec_path,real);
> + ret = (temp==NULL) ? get_errno(-1) : strlen(real) ;
> + snprintf((char *)p2, arg3, "%s", real);
This seems to be a fair chunk of code in common with the readlink
case above -- can we abstract it out? (ideally to a function
somewhere in the same area of this file as the code that handles
intercepting /proc/ calls for open().)
It would be consistent to support /proc/$$/ for all the open()
intercepts too.
> + }
> + else
> + ret = get_errno(sys_readlinkat(arg1, path(p), p2, arg4));
> + }
> unlock_user(p2, arg3, ret);
> unlock_user(p, arg2, 0);
> }
> --
> 1.8.1.5
thanks
-- PMM
^ permalink raw reply [flat|nested] 4+ messages in thread
* [Qemu-devel] [PATCH] linux-user: handle /proc/$$ like /proc/self
2013-04-18 14:56 ` Peter Maydell
@ 2013-05-08 10:31 ` Andreas Schwab
2013-06-27 17:09 ` Peter Maydell
0 siblings, 1 reply; 4+ messages in thread
From: Andreas Schwab @ 2013-05-08 10:31 UTC (permalink / raw)
To: Peter Maydell; +Cc: qemu-devel
Some applications use /proc/$$/... (where $$ is the own pid) instead of
/proc/self/... to refer to their own proc files. Extend the interception
for open and readlink to handle this case. Also, do the same interception
in readlinkat.
Signed-off-by: Andreas Schwab <schwab@suse.de>
---
linux-user/syscall.c | 63 +++++++++++++++++++++++++++++++++++++---------------
1 file changed, 45 insertions(+), 18 deletions(-)
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 84dfbf5..d5db6bf 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -5157,6 +5157,30 @@ static int open_self_auxv(void *cpu_env, int fd)
return 0;
}
+static int is_proc_myself(const char *filename, const char *entry)
+{
+ if (!strncmp(filename, "/proc/", strlen("/proc/"))) {
+ filename += strlen("/proc/");
+ if (!strncmp(filename, "self/", strlen("self/"))) {
+ filename += strlen("self/");
+ } else if (*filename >= '1' && *filename <= '9') {
+ char myself[80];
+ snprintf(myself, sizeof(myself), "%d/", getpid());
+ if (!strncmp(filename, myself, strlen(myself))) {
+ filename += strlen(myself);
+ } else {
+ return 0;
+ }
+ } else {
+ return 0;
+ }
+ if (!strcmp(filename, entry)) {
+ return 1;
+ }
+ }
+ return 0;
+}
+
static int do_open(void *cpu_env, const char *pathname, int flags, mode_t mode)
{
struct fake_open {
@@ -5165,15 +5189,14 @@ static int do_open(void *cpu_env, const char *pathname, int flags, mode_t mode)
};
const struct fake_open *fake_open;
static const struct fake_open fakes[] = {
- { "/proc/self/maps", open_self_maps },
- { "/proc/self/stat", open_self_stat },
- { "/proc/self/auxv", open_self_auxv },
+ { "maps", open_self_maps },
+ { "stat", open_self_stat },
+ { "auxv", open_self_auxv },
{ NULL, NULL }
};
for (fake_open = fakes; fake_open->filename; fake_open++) {
- if (!strncmp(pathname, fake_open->filename,
- strlen(fake_open->filename))) {
+ if (is_proc_myself(pathname, fake_open->filename)) {
break;
}
}
@@ -6468,20 +6491,18 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
#endif
case TARGET_NR_readlink:
{
- void *p2, *temp;
+ void *p2;
p = lock_user_string(arg1);
p2 = lock_user(VERIFY_WRITE, arg2, arg3, 0);
- if (!p || !p2)
+ if (!p || !p2) {
ret = -TARGET_EFAULT;
- else {
- if (strncmp((const char *)p, "/proc/self/exe", 14) == 0) {
- char real[PATH_MAX];
- temp = realpath(exec_path,real);
- ret = (temp==NULL) ? get_errno(-1) : strlen(real) ;
- snprintf((char *)p2, arg3, "%s", real);
- }
- else
- ret = get_errno(readlink(path(p), p2, arg3));
+ } else if (is_proc_myself((const char *)p, "exe")) {
+ char real[PATH_MAX], *temp;
+ temp = realpath(exec_path, real);
+ ret = temp == NULL ? get_errno(-1) : strlen(real) ;
+ snprintf((char *)p2, arg3, "%s", real);
+ } else {
+ ret = get_errno(readlink(path(p), p2, arg3));
}
unlock_user(p2, arg2, ret);
unlock_user(p, arg1, 0);
@@ -6493,10 +6514,16 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
void *p2;
p = lock_user_string(arg2);
p2 = lock_user(VERIFY_WRITE, arg3, arg4, 0);
- if (!p || !p2)
+ if (!p || !p2) {
ret = -TARGET_EFAULT;
- else
+ } else if (is_proc_myself((const char *)p, "exe")) {
+ char real[PATH_MAX], *temp;
+ temp = realpath(exec_path, real);
+ ret = temp == NULL ? get_errno(-1) : strlen(real) ;
+ snprintf((char *)p2, arg4, "%s", real);
+ } else {
ret = get_errno(sys_readlinkat(arg1, path(p), p2, arg4));
+ }
unlock_user(p2, arg3, ret);
unlock_user(p, arg2, 0);
}
--
1.8.2.2
--
Andreas Schwab, SUSE Labs, schwab@suse.de
GPG Key fingerprint = 0196 BAD8 1CE9 1970 F4BE 1748 E4D4 88E3 0EEA B9D7
"And now for something completely different."
^ permalink raw reply related [flat|nested] 4+ messages in thread
* Re: [Qemu-devel] [PATCH] linux-user: handle /proc/$$ like /proc/self
2013-05-08 10:31 ` [Qemu-devel] [PATCH] linux-user: handle /proc/$$ like /proc/self Andreas Schwab
@ 2013-06-27 17:09 ` Peter Maydell
0 siblings, 0 replies; 4+ messages in thread
From: Peter Maydell @ 2013-06-27 17:09 UTC (permalink / raw)
To: Andreas Schwab; +Cc: Riku Voipio, qemu-devel
On 8 May 2013 11:31, Andreas Schwab <schwab@suse.de> wrote:
> Some applications use /proc/$$/... (where $$ is the own pid) instead of
> /proc/self/... to refer to their own proc files. Extend the interception
> for open and readlink to handle this case. Also, do the same interception
> in readlinkat.
>
> Signed-off-by: Andreas Schwab <schwab@suse.de>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
(assuming the necessary fixups post-rebase.)
-- PMM
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2013-06-27 17:09 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-03-11 17:19 [Qemu-devel] [PATCH] linux-user: identify running binary in /proc/$$/exe Andreas Schwab
2013-04-18 14:56 ` Peter Maydell
2013-05-08 10:31 ` [Qemu-devel] [PATCH] linux-user: handle /proc/$$ like /proc/self Andreas Schwab
2013-06-27 17:09 ` Peter Maydell
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.