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()

Reply via email to