#1050217 Better coexistence with libpam-tmpdir

Package:
tmpreaper
Source:
tmpreaper
Description:
cleans up files in directories based on their age
Submitter:
Andras Korn
Date:
2025-03-16 16:09:02 UTC
Severity:
normal
#1050217#5
Date:
2023-08-22 08:15:24 UTC
From:
To:
Hi,

having libpam-tmpdir installed results in PAM creating a /tmp/user/<numeric-user-id-here> directory for every user when they start a session, setting TMP and TMPDIR to this directory.

Long-running processes such as web applications started e.g. via sudo -u someuser may end up with their TMP set to /tmp/user/<id-of-someuser>, which is desirable because it makes /tmp attacks against them harder.

However, if they don't use their individual tmp directories frequently, tmpreaper with its default settings may delete them, breaking the application.

I suggest that the default configuration be changed thusly:

TMPREAPER_PROTECT_EXTRA='/tmp/user/[0-9]*'
TMPREAPER_DIRS='/tmp/. /tmp/user/*/.'

This would (I hope) cause the per-user tmp directories themselves to be left alone but their contents cleaned up.

Thanks

András

#1050217#10
Date:
2025-03-15 12:25:10 UTC
From:
To:
TMPREAPER_DIRS is the list of directories to search for old files, so
only the TMPREAPER_PROTECT_EXTRA list is what you want.


Thanks,
Paul

#1050217#15
Date:
2025-03-15 13:08:09 UTC
From:
To:
Even if /tmp/user (or a particular subdir under /tmp/user) is a mountpoint?

And won't the PROTECT_EXTRA also apply to the contents of /tmp/user/[0-9]*/?

If yes and no respectively, then I'm of courseOK with just setting TMPREAPER_PROTECT_EXTRA.

András

#1050217#20
Date:
2025-03-15 13:28:00 UTC
From:
To:
tmpreaper stays on the filesystem(s) the TMPREAPER_DIRS are on.
So if /tmp/user is a separate filesystem, you don't need to protect it
anyway as tmpreaper won't go there, unless you do specify /tmp/user/*/*
but I thought the point of this bug report was _not_ to delete stuff
under /tmp/user/* . If you do also want to remove files under /tmp/user/
that don't start with a digit, then sure, then it also needs to be added
to TMPREAPER_DIRS. Please let me know what the exact intention is.

I'm not sure what you mean with this. If you explicitly add
/tmp/user/[0-9]*/ to TMPREAPER_PROTECT_EXTRA then those of course will
be protected.

BTW I'll probably add --protect /tmp/user/[0-9]*  to the cron.daily
script instead of changing tmpreaper.conf .


Paul

#1050217#25
Date:
2025-03-15 13:56:20 UTC
From:
To:
The intention is to have tmpreaper descend /tmp/user/^[0-9]+$/ and delete old files in there in the same way files under /tmp itself are deleted, BUT not to delete the /tmp/user/^[0-9]*$ directories themselves even if they are "old"; whether /tmp/user or any particular /tmp/user/^[0-9]+$/ is a mountpoint or not.

The problem this solves is that if a long-running process is started with TMP=/tmp/user/4242 and it tries to create its first tempfile months after it was started, its individual tmp directory will have been reaped by tmpreaper, causing the tempfile creation to fail.

(Yes, I used regexes instead of proper glob patterns.)

András

#1050217#30
Date:
2025-03-15 14:11:45 UTC
From:
To:
OK, thanks for clarifying.

Hmm the problem is that tmpreaper only does glob.
The additional problem with supplying /tmp/user/*/. per default with
TMPREAPER_DIRS is that if those files don't exist, tmpreaper will give
an error as it can't chdir to that.

I think that I will leave this as a local configuration change when
needed.

In light of this, does adding /tmp/user/[0-9]* to
TMPREAPER_PROTECT_EXTRA anyway make sense?


Paul

#1050217#35
Date:
2025-03-16 16:05:44 UTC
From:
To:
On Sat, Mar 15, 2025 at 03:11:45PM +0100, Paul Slootman wrote:

Hi,

This is what I use locally:

# TMPREAPER_DIRS must exist, otherwise the cronjob aborts with an error
install -d -o root -g root -m 711 /tmp/user
install -d -o root -g root -m 700 /tmp/user/0

TMPREAPER_PROTECT_EXTRA=''
TMPREAPER_DIRS='/tmp/.'
set +f  # /etc/cron.daily/tmpreaper sets "-f", which prevents wildcard expansion
for i in /tmp/user/[0-9]*; do
	TMPREAPER_DIRS="$TMPREAPER_DIRS $i/."
	TMPREAPER_PROTECT_EXTRA="$TMPREAPER_PROTECT_EXTRA $i"
done
TMPREAPER_DELAY='256'
TMPREAPER_ADDITIONALOPTIONS=''

[ -r /etc/tmpreaper.local.conf ] && . /etc/tmpreaper.local.conf
set -f

(The tmpreaper.local.conf bit is there because I distribute the main file
using ansible and may want local overrides here and there.)

It's fugly, but works well enough for my particular use case. I haven't
thought much about further implications.

It's obviously racy (one of the per-user dirs could be deleted by something
else while tmpreaper works, so that one of the TMPREAPER_DIRS would not
exist), but since this will just cause an abort and presumably succeed on
the next run, it doesn't seem so bad. It would be better if tmpreaper could
be told to treat certain TMPREAPER_DIRS as optional.

András