corbinlc / gnuroot

154 stars 29 forks source link

problems with mutt temporary files #34

Open felixpinkert opened 9 years ago

felixpinkert commented 9 years ago

Thank you very much for a great project!

I'm trying to run mutt on debian testing, and run into the following problem: When trying to read an email, mutt tells me "Could not create temporary file". When trying to write an email, it tells me "Too many levels of symbolic links (errno = 40)" I take it that the problem has to do with mutt creating temporary lock files to know which emails are opened. I have checked that I have write permission for the directory specified in the "tmpdir" variable. Mutt also manages to create size 0 files with long random names there. Furthermore, mutt does work under Debian Noroot, so I guess it must be an issue with the precise setup of proot / the parameters passed on to it. Unfortunately, I don't see a way for me to modify what gnuroot actually does upon starting rootfs.

Please let me know if you need me to do any more testing, and again, many thanks!

cedric-vincent commented 9 years ago

Mutt on Android: I definitely like this idea so it has to work! :) Under PRoot on x86_64, mutt works fine both for reading and writing emails, using standard configuration.

@felixpinkert, what are the error messages on Debian noroot?

@pelya, do you have any ideas?

pelya commented 9 years ago

I never used mutt, so there's not much that I can help with, sorry. Does it create any Unix sockets with long filenames? I think that issue was fixed in latest proot anyway.

felixpinkert commented 9 years ago

Thanks for your quick responses, that's awesome!

@pelya Mutt does create files with long filenames, which I take to be lockfiles (probably to tell it which emails are opened?).

@cedric-vincent For testing, I run mutt without any settings of my own, so it creates /home/Mail. I can then change the mailbox to a local mbox directory, and it displays all emails therein correctly. When I then want to view an email, I get "Could not create temporary file!" When I try to write a new email, I get "/tmp/mutt-localhost-[longnumber]: Too many levels of symbolic links (errno = 40).

Looking for these errors in mutt forums, it typically is an issue with the temporary directory not being writeable. However, /tmp is writeable for the user on gnuroot, and changing the tmpdir to elsewhere, e.g. the sdcard or /home/newfolder does not help

Note: I'm on a Galaxy Note Pro 12.2, with Android 4.4.2, on gnuroot wheezy, upgraded to debian testing. I have created a new user in gnuroot with the uid of the user that I got when not starting it as fakeroot. not sure if that changes anything. I'll try it from a clean install of gnuroot wheezyx and let you know the outcome shortly.

felixpinkert commented 9 years ago

PS: Same problem with "too many symbolic links" persists with a fresh install in debian stable on gnuroot wheezyx. I can't test the other problem right now, but assume that it's the same.

cedric-vincent commented 9 years ago

@felixpinkert, could you please try these commands (in order):

umask
touch /tmp/mutt-localhost-1000-12027-1222911629440682461
ls - l /tmp/mutt-localhost-1000-12027-1222911629440682461

then:

umask 077
touch /tmp/mutt-localhost-1000-12027-5255832041394588129
ls -l /tmp/mutt-localhost-1000-12027-5255832041394588129
felixpinkert commented 9 years ago

@cedric-vincent: Here are the commands with the output I get:

umask output> 0077 touch /tmp/mutt-localhost-1000-12027-1222911629440682461 ls - l /tmp/mutt-localhost-1000-12027-1222911629440682461 output> -rw--------. 1 felix felix 0 [date] /tmp/...

umask 077 output> [nothing] touch /tmp/mutt-localhost-1000-12027-5255832041394588129 ls -l /tmp/mutt-localhost-1000-12027-5255832041394588129 output> -rw--------. felix felix 0 [date] /tmp/...

cedric-vincent commented 9 years ago

Hum, this is not consistent with the observed behavior of Mutt...

@felixpinkert: do you confirm Mutt has exactly the same behaviour with the latest version of Debian noroot? (it uses the latest version of PRoot)

Also, could you please test this in GNURoot:

rm -f /tmp/mutt-localhost-1000-12027-5255832041394588129
cat -> /tmp/mutt-localhost-1000-12027-5255832041394588129 &
NEW_PID=$!
ls -l /proc/${NEW_PID}/fd
rm -f /tmp/mutt-localhost-1000-12027-5255832041394588129
ls -l /proc/${NEW_PID}/fd
fg
^D
cedric-vincent commented 9 years ago

Good news: I'm able to reproduce this issue on my workstation using the version of PRoot patched for GNURoot (commit f0ce4388). That means it's either due to the special extension developed for GNURoot (link2symlink) or to an old bug in PRoot.

cedric-vincent commented 9 years ago

I confirm this bug is due to the link2symlink extension.

felixpinkert commented 9 years ago

@cedric-vincent thanks for looking into this so quickly. Do you still want me to perform the tests, and if so, do you mean me to run an instance of mutt first to generate these lock files?

cedric-vincent commented 9 years ago

Do you still want me to perform the tests

@felixpinkert, so far there's still one thing I'm not sure of: you said "mutt does work under Debian Noroot". Do you mean Mutt has exactly the same behaviour with the latest version of Debian noroot? Ie. Does it fail to read emails because of the error "Could not create temporary file"?

(I can't do this test by myself since I don't own any Android devices).

felixpinkert commented 9 years ago

@cedric-vincent sorry for not having been clear: No, Mutt does work as it should, i.e. without the above errors, on Debian Noroot.

cedric-vincent commented 9 years ago

@felixpinkert, I misread your first post (you wrote "does work" but I read "does not work"), my mistake!

cedric-vincent commented 9 years ago

For information, this problem is now well understood, and I tested a quick n' dirty fix with success (ie. Mutt now works when link2symlink is enabled, and PRoot's testsuite does not report any regressions). More details tomorrow.

felixpinkert commented 9 years ago

Great, many thanks for your quick responses! Let me know if you need me to test anything on my Android machine.

corbinlc commented 9 years ago

Looks like I may actually be breaking free and getting some cycles to work on this. I won't have a ton of time right away, but I can incorporate a bug fix, test it and then create a new release of GNURoot. Then I will update to the latest PRoot and then test and release again.

corbinlc commented 9 years ago

Btw... Thanks so much to all three of you.

cedric-vincent commented 9 years ago

Hello @corbinlc,

I won't be able to provide you a clean patch today. For information, the problem happens when the flag NOFOLLOW is specified and the accesses path is a hard-link that was converted into a symbolic link. In this case, the link2symlink extension has to substitute the path to the "hard->sym-link" with the path to the linked content (".l2s.{original_name}.{link_counter}" IIRC) in order to preserve the semantic of NOFOLLOW.

I could provide you the right fix later if you wish, in the mean time here follows a quick n' dirty fix (dirty because it doesn't preserve the semantic of NOFOLLOW):

@@ -390,6 +408,8 @@ int link2symlink_callback(Extension *extension, ExtensionEvent event,
                        { PR_stat64,            FILTER_SYSEXIT },
                        { PR_rename,            FILTER_SYSEXIT },
                        { PR_renameat,          FILTER_SYSEXIT },
+                       { PR_open,              0 },
+                       { PR_openat,            0 },
                        FILTERED_SYSNUM_END,
                };
                extension->filtered_sysnums = filtered_sysnums;
@@ -398,8 +418,19 @@ int link2symlink_callback(Extension *extension, ExtensionEvent event,

        case SYSCALL_ENTER_END: {
                Tracee *tracee = TRACEE(extension);
+               word_t sysnum;
+
+               sysnum = get_sysnum(tracee, ORIGINAL);
+               switch (sysnum) {
+               case PR_open:
+               case PR_openat: {
+                       const Reg sysarg   = (sysnum == PR_open ? SYSARG_2 : SYSARG_3);
+                       const word_t flags = peek_reg(tracee, CURRENT, sysarg);
+
+                       poke_reg(tracee, sysarg, flags & ~O_NOFOLLOW);
+                       break;
+               }

-               switch (get_sysnum(tracee, ORIGINAL)) {
corbinlc commented 9 years ago

@cedric-vincent That is ok. First, I will get the link2symlink branch updated to work with the latest version of PRoot. Then I will triage remaining issues and go from there. You are already closer to an answer on this issue, but if you need/want to pass it to me, that works too. Thanks!

cedric-vincent commented 9 years ago

@corbinlc, here is the link2symlink branch merged with v5.0.0 https://github.com/cedric-vincent/PRoot/tree/link2symlink.

cedric-vincent commented 9 years ago

@corbinlc, I'll fix this one soon, so you have more time to spend on something else ;)

corbinlc commented 9 years ago

@cedric-vincent great! I will rebuild today, release a new versions of the apps after a little testing and then pull in your fix whenever it is ready.

corbinlc commented 9 years ago

@cedric-vincent have you cross compiled recently off of the latest link2symlink branch for armel?

I am getting errors I wasn't before. They are happening while it is compiling the loader. x86 compilation is working fine. Problem exists even in a newly created armel rootfs. Has the process for building changed, or are there new environment variable settings that are needed?

root@debian:/git/PRoot/src# make make: [.check_process_vm] Error 1 (ignored) make: [.check_seccomp_filter.o] Error 1 (ignored) make: [.check_seccomp_filter] Error 1 (ignored) GEN build.h CC cli/cli.o CC cli/proot.o CC cli/note.o CC execve/enter.o CC execve/exit.o CC execve/shebang.o CC execve/elf.o CC execve/ldso.o CC execve/auxv.o CC execve/aoxp.o CC path/binding.o CC path/glue.o CC path/canon.o CC path/path.o CC path/proc.o CC path/temp.o CC syscall/seccomp.o CC syscall/syscall.o CC syscall/chain.o CC syscall/enter.o CC syscall/exit.o CC syscall/sysnum.o CC syscall/socket.o CC syscall/heap.o CC tracee/tracee.o CC tracee/mem.o CC tracee/reg.o CC tracee/event.o CC ptrace/ptrace.o CC ptrace/user.o CC ptrace/wait.o CC ptrace/direct_ptracee.o CC extension/extension.o CC extension/kompat/kompat.o CC extension/fake_id0/fake_id0.o CC extension/link2symlink/link2symlink.o CC loader/loader.o /tmp/ccJsqJmZ.s: Assembler messages: /tmp/ccJsqJmZ.s:179: Error: junk at end of line, first unrecognized character is /' /tmp/ccJsqJmZ.s:182: Error: junk at end of line, first unrecognized character is/' /tmp/ccJsqJmZ.s:185: Error: junk at end of line, first unrecognized character is `/' make: *\ [loader/loader.o] Error 1

cedric-vincent commented 9 years ago
root@debian:/git/PRoot/src# make
make: [.check_process_vm] Error 1 (ignored)
make: [.check_seccomp_filter.o] Error 1 (ignored)
make: [.check_seccomp_filter] Error 1 (ignored)

These errors are not a problem. They were already there previously but silent.

/tmp/ccJsqJmZ.s: Assembler messages:
/tmp/ccJsqJmZ.s:179: Error: junk at end of line, first unrecognized character is /'
/tmp/ccJsqJmZ.s:182: Error: junk at end of line, first unrecognized character is/'
/tmp/ccJsqJmZ.s:185: Error: junk at end of line, first unrecognized character is `/'
make: *** [loader/loader.o] Error 1

This is a known issue with old ARM cross-toolchains. I forgot to fix it. You just have to remove these 3 inlined comments:

src/loader/assembly-arm.h:32:           "// Restore initial stack pointer.      \n\t"   \
src/loader/assembly-arm.h:35:           "// Clear rtld_fini.                    \n\t"   \
src/loader/assembly-arm.h:38:           "// Start the program.                  \n\t"   \
corbinlc commented 9 years ago

@cedric-vincent Sorry, I wasn't clear. I was only concerned with the Assembler message errors at the end. Also, I am not cross-compiling. I am running an arm rootfs with qemu and then compiling using the current standard compiler for wheezy. Regardless, your suggestion of removing the comments worked. Thanks!

felixpinkert commented 9 years ago

Thank you both for working on this issue -- I'm sorry I can only be a spectator at present. However, I'd be very happy to test any updated version before you release it.

corbinlc commented 9 years ago

@cedric-vincent Do you have the proper fix for this now? Sounded like you were going to run with this one.

cedric-vincent commented 9 years ago

On Wed, Jan 07, 2015 at 08:49:09PM -0800, corbinlc wrote:

@cedric-vincent Do you have the proper fix for this now? Sounded like you were going to run with this one.

No code yet, sorry.

In order to preserve the semantic of NOFOLLOW, the generic solution is to substitute at the end of the canonicalization loop any faked hard-link with the path it references. This should be done in the HOST_PATH event when "finality != NOT_FINAL".

I'll try to write this patch today.

cedric-vincent commented 9 years ago

@corbinlc,

I merged version 5.1 of PRoot in my "link2symlink" branch, then added a generic fix to preserve NOFOLLOW semantic under link2symlink. However, a new issue was exposed with Mutt under link2symlink when sending a mail:

Can't stat /tmp/mutt-reddwarf-1000-29576-18073505631850109378: No such file or directory
corbinlc commented 9 years ago

@cedric-vincent Thanks! I will probably finish testing and pushing out proot 5.0 along with some other changes outside of proot. Then I will come back and pick up 5.1 as well as your modification to link2symlink.

mayureshw commented 9 years ago

Seems an old thread. I came across the same issue when trying to use mutt. Is above fix supposed to be released or not yet?

Also, is there any other workaround to use mutt on gnuroot?