7

While studying for the RHCE, I came across a situation where stdin redirection does not work in bash:

# file /tmp/users.txt
/tmp/users.txt: cannot open `/tmp/users.txt' (No such file or directory)  
# semanage login -l > /tmp/users.txt
# file /tmp/users.txt
/tmp/users.txt: empty

However, this works:

# file /tmp/users.txt
/tmp/users.txt: cannot open `/tmp/users.txt' (No such file or directory)
# semanage login -l >> /tmp/users.txt
# file /tmp/users.txt
/tmp/users.txt: ASCII text

Why is this the case?

1st Update:

Permissions:

# ls -ld /tmp
drwxrwxrwt. 8 root root 4096 Jul 17 15:27 /tmp

ACLs (not an ACL mount but just in case):

# getfacl /tmp
getfacl: Removing leading '/' from absolute path names
# file: tmp
# owner: root
# group: root
# flags: --t
user::rwx
group::rwx
other::rwx

And I'm performing all commands as root (hence the hash prompt).

2nd Update

Per Caleb, full permissions listing of /tmp:

# ls -al /tmp
total 40
drwxrwxrwt.  8 root    root    4096 Jul 17 15:37 .
dr-xr-xr-x. 26 root    root    4096 Jul 17 15:07 ..
drwx------.  2 melmel  melmel  4096 Jul 16 21:08 .esd-500
drwxrwxrwt.  2 root    root    4096 Jul 17 15:07 .ICE-unix
drwx------.  2 gdm     gdm     4096 Jul 17 15:08 orbit-gdm
drwx------.  2 gdm     gdm     4096 Jul 17 15:07 pulse-5E9i88IGxaNh
drwx------.  2 melmel  melmel  4096 Jul 16 21:08 pulse-329qCo13Xk
-rw-------.  1 root    root       0 Jul 16 14:32 tmpXd9THg
-rw-------.  1 root    root       0 Jul 16 12:55 tmpie0O98
-rw-------.  1 root    root       0 Jul 16 20:23 tmpr10LrK
-r--r--r--.  1 root    root      11 Jul 17 15:07 .X0-lock
drwxrwxrwt.  2 root    root    4096 Jul 17 15:07 .X11-unix
-rw-r--r--.  1 root    root     865 Jul 16 20:20 yum.conf.security
-rw-------.  1 root    root       0 Jul 10 14:57 yum.log

3rd Update:

Per Hello71:

# mount | grep /tmp
# mount | grep -w '/'
/dev/mapper/vg_svr-tap-lv_root on / type ext4 (rw)

Answers to Gilles' questions:

Is this something you read about in a book, or did you reach this situation on a real machine?

Noticed this while performing a lab in a book on a real machine.

Is SELinux in use?

# sestatus 
SELinux status:                 enabled
SELinuxfs mount:                /selinux
Current mode:                   enforcing
Mode from config file:          enforcing
Policy version:                 24
Policy from config file:        targeted

Some Linux-on-Linux virtualisation?

Yes. KVM/QEMU guest.

I second Hello71's request, except please grep /tmp /proc/mounts

Nothing matches.

Also env | grep '^LD_' please.

Nothing matches.

Oh, and can we rule out active attacks

Yes we can. I'm the only one that has access to this guest.

  • Can you give us the output of ls -al for /tmp and /tmp/users.txt? – Caleb Jul 17 '11 at 19:24
  • Just added the file command before and after the IO redirects. Is that sufficient? – Belmin Fernandez Jul 17 '11 at 19:30
  • Please give us the full permissions view of the directory. – Caleb Jul 17 '11 at 19:33
  • Adding that now. I am confused as to how that would be relevant. Can you explain please? – Belmin Fernandez Jul 17 '11 at 19:35
  • mount | grep /tmp? – Hello71 Jul 17 '11 at 21:34
  • Try executing this from another shell: strace -p pid_of_shell Then in the first shell do the redirections and check what strace prints. For me the only difference is the O_TRUNC vs O_APPEND open mode. This way you can see if the shell actually calls write with the string you typed. If it does not open the file and does not write the text then your shell is buggy. If all open and write calls are OK then I don't know. – stribika Jul 17 '11 at 22:43
  • “While studying for the RHCE”: Is this something you read about in a book, or did you reach this situation on a real machine? Is SELinux in use? Some Linux-on-Linux virtualisation? I second Hello71's request, except please grep /tmp /proc/mounts, and then stribika's request of an strace trace to see what's really going on. Also env | grep '^LD_' please. Oh, and can we rule out active attacks (i.e. a person or program changing things in /tmp while you're doing these experiments)? – Gilles 'SO- stop being evil' Jul 17 '11 at 23:05
  • @Hello71 and @Gilles: Answered your questions above (this question's text is getting lengthy, my apologies). I will get to stribika's trace later today. – Belmin Fernandez Jul 18 '11 at 00:28
  • xxd /tmp/users.txt - what's in it? I'm gonna guess for some reason one gives a single LF. – Aaron D. Marasco Jul 18 '11 at 00:53
  • What if you execute redirection twice in a row? Just curiosity, because my understanding is, the file was created after all, just without any content. – greenoldman Jul 18 '11 at 05:40
  • I asked a similar question (SELinux + I/O Redirection), wish Riccardo Murri's answer help you too: http://unix.stackexchange.com/questions/14586/which-process-program-create-write-the-file-which-i-o-is-redirected-to – LiuYan 刘研 Jul 18 '11 at 07:36
  • You might want to check out this: http://unix.stackexchange.com/questions/25372/turn-off-buffering-in-pipe – M. Rubio-Roy Oct 13 '14 at 15:17

1 Answers1

2

It is probably bug in SELinux policy with regards to semanage binary (which has its own context semanage_t) and /tmp directory, which has its own context too - tmp_t.

I was able to reproduce almost same results on my CentOS 5.6.

# file /tmp/users.txt 
/tmp/users.txt: ERROR: cannot open `/tmp/users.txt' (No such file or directory)
# semanage login -l  >  /tmp/users.txt
# file /tmp/users.txt 
/tmp/users.txt: empty
# semanage login -l  >>  /tmp/users.txt
# file /tmp/users.txt 
/tmp/users.txt: empty

When I tried to use file in different directory I got normal results

# file /root/users.txt
/root/users.txt: ERROR: cannot open `/root/users.txt' (No such file or directory)
# semanage login -l  >  /root/users.txt
# file /root/users.txt
/root/users.txt: ASCII text

Difference between /tmp and /root is their contexts

# ls -Zd /root/
drwxr-x---  root root root:object_r:user_home_dir_t    /root/
# ls -Zd /tmp/
drwxrwxrwt  root root system_u:object_r:tmp_t          /tmp/

And finally, after trying to redirect into file in /tmp I have got following errors in /var/log/audit/audit.log

type=AVC msg=audit(1310971817.808:163242): avc:  denied  { write } for  pid=10782 comm="semanage" path="/tmp/users.txt" dev=dm
-0 ino=37093377 scontext=user_u:system_r:semanage_t:s0 tcontext=user_u:object_r:tmp_t:s0 tclass=file
type=AVC msg=audit(1310971838.888:163255): avc:  denied  { append } for  pid=11372 comm="semanage" path="/tmp/users.txt" dev=d
m-0 ino=37093377 scontext=user_u:system_r:semanage_t:s0 tcontext=user_u:object_r:tmp_t:s0 tclass=file

Interesting note: redirecting semanage output to pipe works OK

#semanage login -l  | tee /tmp/users.txt > /tmp/users1.txt
# file /tmp/users.txt 
/tmp/users.txt: ASCII text
# file /tmp/users1.txt 
/tmp/users1.txt: ASCII text
AlexD
  • 1,173
  • 2
    That doesn't explain why append works, but truncate doesn't. If the writes are being denied, then append should still leave the file empty. – psusi Jul 18 '11 at 15:57
  • On my system append doesn't work too. It could be explained by difference in SELinux policies between my CentOS and original system. – AlexD Jul 18 '11 at 16:06