Package: python2.5
Version: 2.5-5
Severity: important
Hi,
the mailbox._singlefileMailbox class is not safe with concurrent access,
because mailbox._singlefileMailbox.flush() replaces the underlying file
with a new copy by constructing a temporary file and then renaming it.
This breaks all other class instances which have this mailbox open. I'm
attaching a script demonstrating the problem.
I think it's a bad idea to use rename(2) here; overwriting the file
content would fix the race condition, and #451274 too[1].
Nikolaus
[1] "python2.5: [mailbox] cannot modify mailboxes in system mail spool"
http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=451274
-- System Information:
Debian Release: 4.0
APT prefers stable
APT policy: (500, 'stable')
Architecture: i386 (i686)
Shell: /bin/sh linked to /bin/bash
Kernel: Linux 2.6.18-5-k7
Locale: [EMAIL PROTECTED], [EMAIL PROTECTED] (charmap=ISO-8859-15)
Versions of packages python2.5 depends on:
ii libbz2-1.0 1.0.3-6 high-quality block-sorting file co
ii libc6 2.3.6.ds1-13etch2 GNU C Library: Shared libraries
ii libdb4.4 4.4.20-8 Berkeley v4.4 Database Libraries [
ii libncursesw5 5.5-5 Shared libraries for terminal hand
ii libreadline5 5.2-2 GNU readline and history libraries
ii libsqlite3-0 3.3.8-1.1 SQLite 3 shared library
ii libssl0.9.8 0.9.8c-4etch1 SSL shared libraries
ii mime-support 3.39-1 MIME files 'mime.types' & 'mailcap
ii python2.5-minimal 2.5-5 A minimal subset of the Python lan
python2.5 recommends no packages.
-- no debconf information
#!/usr/bin/python2.5
import mailbox
import os
import time
import tempfile
msg_text = ("""Subject: Ghost message
This message should be deleted.
""",
"""Subject: New message
This message should be the only one in the mailbox.
""")
mbox_name = tempfile.mkstemp(prefix="race-mbox")[1]
def printmbox(m):
if not mbox: print("<empty>")
else:
for msg in mbox: print(msg)
print
if os.fork():
# first mbox user
mbox = mailbox.mbox(mbox_name)
mbox.lock()
mbox.add(msg_text[0])
mbox.clear()
print("=== mbox after first client finished:\n")
printmbox(mbox) # now empty
mbox.close()
os.wait()
mbox = mailbox.mbox(mbox_name)
print("=== mbox after second client finished:\n")
printmbox(mbox) # has now both messages.
os.remove(mbox_name)
else:
# second mbox user
mbox = mailbox.mbox(mbox_name)
time.sleep(1)
mbox.lock()
mbox.add(msg_text[1])
mbox.close()