Project

General

Profile

Actions

Bug #8816

closed

Tempfile.new may return the same name for parallel calls

Added by 375gnu (Hleb Valoshka) over 11 years ago. Updated over 11 years ago.

Status:
Third Party's Issue
Assignee:
-
Target version:
-
ruby -v:
ruby 1.9.3p194 (2012-04-20 revision 35410) [x86_64-linux]
[ruby-core:56795]

Description

Two simultaneous call to Tempfile.new may return the same name. This may lead
to race conditions.

There some examples of such races (unix socket can't be unlinked because it was
unlinked by another test case):

https://buildd.debian.org/status/fetch.php?pkg=ruby-kgio&arch=ia64&ver=2.8.0-1&stamp=1376819434
https://buildd.debian.org/status/fetch.php?pkg=ruby-kgio&arch=kfreebsd-i386&ver=2.8.0-1&stamp=1376820662

Updated by akr (Akira Tanaka) over 11 years ago

  • Status changed from Open to Third Party's Issue

Tempfile.new creates a normal file, not unix socket.
So, your report is questionable.

Note that Tempfile uses O_EXCL to exclusive file creation.
If it doesn't work, it is a problem of kernel.

I checked kgio.
It seems the temporary file created by Tempfile.new is removed and
unix socket is created the name.

http://bogomips.org/kgio.git/tree/test/test_unix_connect.rb :

class TestKgioUnixConnect < Test::Unit::TestCase

def setup
  tmp = Tempfile.new('kgio_unix')
  @path = tmp.path
  File.unlink(@path)
  tmp.close rescue nil
  @srv = Kgio::UNIXServer.new(@path)
  @addr = Socket.pack_sockaddr_un(@path)
end

The race condition should be solved by application.
Because another process may creates the file between unlink and unix socket creation.
Tempfile cannot do anything between them because Tempfile methods are not running at that time.

Updated by normalperson (Eric Wong) over 11 years ago

"akr (Akira Tanaka)" wrote:

http://bogomips.org/kgio.git/tree/test/test_unix_connect.rb :

class TestKgioUnixConnect < Test::Unit::TestCase

def setup
  tmp = Tempfile.new('kgio_unix')
  @path = tmp.path
  File.unlink(@path)
  tmp.close rescue nil
  @srv = Kgio::UNIXServer.new(@path)
  @addr = Socket.pack_sockaddr_un(@path)
end

The race condition should be solved by application.

Agreed (kgio maintainer here).

Hleb: can you send me a patch to retry on bind failure?

I'm a little surprised it happens since $$ is in the Tempfile name and
the tests are not multi-threaded (but optionally multi-process).

Because another process may creates the file between unlink and unix
socket creation.
Tempfile cannot do anything between them because Tempfile methods are
not running at that time.

Right. I do this often in test cases, but I'm lazy and have never hit
a problem even though I know it's there :x

Updated by nobu (Nobuyoshi Nakada) over 11 years ago

Tempfile.create may help you to create unique file name, but it's your task to guarantee that it doesn't conflict.

Actions

Also available in: Atom PDF

Like0
Like0Like0Like0