Qual é a diferença entre / tmp e / run?

35

De acordo com FHS-3.0 , /tmp é para arquivos temporários e /run é para dados variáveis de tempo de execução. Os dados em /run devem ser excluídos na próxima inicialização, o que não é necessário para /tmp , mas ainda assim os programas não devem presumir que os dados em /tmp estarão disponíveis no próximo início do programa. Tudo isso parece muito parecido comigo.

Então, qual é a diferença entre os dois? Por qual critério um programa deve decidir se coloca dados temporários em /tmp ou em /run ?

De acordo com a ESF:

Programs may have a subdirectory of /run; this is encouraged for programs that use more than one run-time file.

Isso indica que a distinção entre "programas do sistema" e "programas comuns" não é um critério, nem o tempo de vida do programa (como o processo de longa duração versus o de execução curta).

Embora o seguinte raciocínio não seja fornecido no FHS, /run foi introduzido para superar o problema de que /var foi montado muito tarde, de modo que truques sujos eram necessários para tornar /var/run disponível com antecedência suficiente. No entanto, agora com o /run sendo introduzido, e dada sua descrição na ESF, não parece haver uma razão clara para ter ambos /run e /tmp .

    
por Dirk Herrmann 13.10.2016 / 13:46

4 respostas

13

Não há razão para ter os dois / run e / tmp

Eu acho que você está certo. /tmp está essencialmente obsoleto agora, temos /run . Se o seu programa está em condições de fazê-lo (o que requer que ele seja instalado como uma operação privilegiada), então hoje em dia você usaria um subdiretório de /run . Isso é por motivos de segurança.

Por exemplo o daemon de impressão do CUPS não é executado como root, mas geralmente é instalado a partir de um pacote do sistema operacional. O pacote instala /usr/lib/tmpfiles.d/cups.conf e systemd-tmpfiles cria um diretório que pode acessar. Como o diretório está em /run , o nome não pode ter sido mal-intencionado por um usuário não privilegiado, ao contrário de /tmp , que é gravável pelo mundo.

"Programas não privilegiados" que não podem usar /run diretamente

A verdadeira diferença é se o seu programa está sendo executado por um usuário arbitrário não privilegiado, sob seu próprio ID de usuário. Mas você ainda não quer usar /tmp , porque pode ser acessado por outros usuários sem privilégios. Você preferiria usar $XDG_RUNTIME_DIR . Normalmente, isso é implementado como /run/user/$(id -u) - então, também é um subdiretório de /run . A localização não é garantida; os programas devem sempre usar a variável de ambiente.

/tmp só seria útil para a cooperação ad-hoc entre diferentes usuários não privilegiados no sistema. Esses sistemas ad-hoc são vulneráveis a um usuário mal-intencionado que se recusa a cooperar e estragar as coisas para todos :). Um exemplo seria usuários não privilegiados que decidem executar uma versão do daemon talk , usando um soquete unix.

Informações originais de Lennart Poettering

Note que a lista de verificação de Poettering abaixo afirmou que /tmp seria útil para "arquivos pequenos", enquanto /run deveria ser usado apenas para "primitivos de comunicação". Eu não acho que essa distinção seja verdadeira também. O garoto-propaganda para /run é udev e tenho certeza que /run/udev inclui bancos de dados internos. Uma vez que você tenha um diretório /run , não creio que alguém queira seguir a distinção reivindicada e criar um outro diretório, para confundir /tmp . Então, na prática, usamos apenas /run nos dias de hoje.

Usage of world-writable shared namespaces [like /tmp] for communication purposes has always been problematic, since to establish communication you need stable names, but stable names open the doors for DoS attacks. This can be corrected partially, by establishing protected per-app directories for certain services during early boot (like we do for X11), but this only fixes the problem partially, since this only works correctly if every package installation is followed by a reboot.

...

Another Fedora feature (for Fedora 17) changed the semantics of /tmp for many system services to make them more secure, by isolating the /tmp namespaces of the various services

...

Because /tmp is no longer necessarily a shared namespace it is generally unsuitable as a location for communication primitives.

...

[/run] is guaranteed to be a tmpfs and is hence automatically flushed at boots. No automatic clean-up is done beyond that.

...

Here's a rough guide how we suggest you (a Linux application developer) pick the right directory to use:

  1. You need a place to put your socket (or other communication primitive) and your code runs privileged: use a subdirectory beneath /run. (Or beneath /var/run for extra compatibility.)
  2. You need a place to put your socket (or other communication primitive) and your code runs unprivileged: use a subdirectory beneath $XDG_RUNTIME_DIR.
  3. You need a place to put your larger downloads and downloads in progress and run unprivileged: use $XDG_DOWNLOAD_DIR.
  4. You need a place to put cache files which should be persistent and run unprivileged: use $XDG_CACHE_HOME.
  5. Nothing of the above applies and you need to place a small file that needs no persistency: use $TMPDIR with a fallback on /tmp. And use mkstemp(), and mkdtemp() and nothing homegrown.
  6. Otherwise use $TMPDIR with a fallback on /var/tmp. Also use mkstemp()/mkdtemp().

Note that these rules above are only suggested by us. These rules take into account everything we know about this topic and avoid problems with current and future distributions, as far as we can see them. Please consider updating your projects to follow these rules, and keep them in mind if you write new code.

One thing we'd like to stress is that /tmp and /var/tmp more often than not are actually not the right choice for your usecase. There are valid uses of these directories, but quite often another directory might actually be the better place. So, be careful, consider the other options, but if you do go for /tmp or /var/tmp then at least make sure to use mkstemp()/mkdtemp().

Nós meio que escapamos com o soquete /tmp legado usado pelo sistema X window, como descrito acima. Eu interpretei tmpfiles.d/x11.conf . Parece mais que depende de cooperação :). Presumo que o código tenha sido auditado, de tal forma que a negação de serviço é o pior que pode acontecer.

    
por 13.10.2016 / 18:21
21

Os diretórios /tmp e /usr/tmp (mais tarde /var/tmp ) costumavam ser o depósito para tudo e todos. O único mecanismo de proteção para arquivos nesses diretórios é o bit pegajoso que restringe a exclusão ou renomeação de arquivos para seus proprietários. Como assinalou marcelm em um comentário, em princípio nada impede que alguém crie arquivos com nomes que são usados por serviços (como nginx.pid ou sshd.pid ). (Na prática, os scripts de inicialização podem remover esses arquivos falsos primeiro.)

/run foi estabelecido para dados de tempo de execução não persistentes de serviços de longa duração, como bloqueios, sockets, arquivos pid e similares. Como não é gravável para o público, ele protege os dados de tempo de execução do serviço da bagunça em /tmp e os trabalhos que são limpos lá. De fato: Duas distribuições que eu executo (sem trocadilhos) têm permissões 755 em /run , enquanto /tmp e /var/tmp (e /dev/shm para essa matéria) têm permissões 1777.

    
por 13.10.2016 / 14:01
15

/tmp é o local para criação de arquivos e diretórios temporários. Não é útil armazenar "nomes conhecidos" (ou seja, nomes de que outro processo poderia estar ciente sem que você tenha que transmitir o nome a ele de alguma forma) porque ninguém tem propriedade sobre o namespace; qualquer um pode criar arquivos lá. Como tal, você geralmente o utiliza quando tem um utilitário que precisa de um arquivo (ou seja, não um pipe ou algo parecido) como entrada ou saída, em que qualquer nome (gerado aleatoriamente) funcionará contanto que você passe o nome.

Historicamente, algumas coisas (como X) violaram este princípio e colocaram nomes conhecidos (como .X11-unix ) em /tmp . Isto é claro com bugs e permite que qualquer usuário faça DoS o serviço que precisa fazer isso simplesmente correndo para criar um arquivo com o nome desejado primeiro. Essas coisas pertencem a /run (ou equivalentemente /var/run se você não se inscrever no revisionismo do Freedesktop.org). É claro que seria melhor corrigi-los para não usar nomes conhecidos em um espaço de nomes global, mas passar um nome de caminho.

    
por 14.10.2016 / 00:31
7

De acordo com o Padrão de hierarquia do sistema de arquivos,

  • /run é para dados variáveis de tempo de execução, ou seja, informações sobre o sistema em execução desde a reinicialização
  • /tmp é um local genérico para arquivos temporários.

Portanto, qualquer coisa relacionada ao status do daemon, usuários logados, dispositivos removíveis montados etc. entraria em /run , enquanto arquivos temporários criados por um programa entrariam em /tmp .

Edit: como apontado por @JdeBP no comentário abaixo,

The FHS allows for things like the conventional setup of cron jobs that regularly purge /tmp of "old" files; with no such mechanisms intended for /run. Hence the draconian limit on what programs can expect of the lifetime of anything put in /tmp. Whilst programs can expect files to live longer in /run on a continuously-up system, they are also expected to tidy up after themselves more there.

    
por 13.10.2016 / 14:01