Permission denied as root

Hi

I cannot write to a file that I don't own as root with ksh

# cat /etc/redhat-release
Red Hat Enterprise Linux release 9.3 (Plow)
# ksh --version
  version         sh (AT&T Research) 93u+m/1.0.0-beta.1 2021-05-10
# date>>foo
# chown nobody foo
# date>>foo
ksh: foo: cannot create [Permission denied]
# id
uid=0(root) gid=0(root) groups=0(root)
#

Bash works.

Thanks
Laurent

@laurentschneider , Welcome

have you logged in as root or su'd/sudo'd to it ?
please, show id prior to ksh, do same for permissions (ls -al foo etc) before and after the chown command, owner+permissions of the directory

the 'Bash works' ? - show that as well ( and states prior and post commands - as per ksh ) and the bash version

to quote Lemmy But just 'cos you got the power
That don't mean you got the right
(or 'write' in this case)

:thinking:

tks

1 Like

Is your ksh binary okay?

ls -l /bin/ksh

should show permissions
-rwxr-xr-x

Check its integrity with your package manager.

rpm -qf /bin/ksh
rpm --verify ...

Hi
Nothing special

$ ls -l /bin/ksh
lrwxrwxrwx 1 root root 21 Feb  7 12:47 /bin/ksh -> /etc/alternatives/ksh
$ ls -la /etc/alternatives/ksh
lrwxrwxrwx 1 root root 14 Feb  7 12:47 /etc/alternatives/ksh -> /usr/bin/ksh93
$ ls -la /usr/bin/ksh93
-rwxr-xr-x 1 root root 1448088 Jun 29  2023 /usr/bin/ksh93
$ rpm -qf /bin/ksh
ksh-1.0.0~beta.1-3.el9.x86_64

Thanks
Laurent

Hi
I login with my personal user than issue
sudo su -

# bash -c 'rm -f foo; :>foo; chown nobody foo; ls -la foo; date>foo; cat foo'
-rw-r----- 1 nobody root 0 Feb 12 21:53 foo
Mon Feb 12 09:53:48 PM CET 2024

# ksh -c 'rm -f foo; :>foo; chown nobody foo; ls -la foo; date>foo; cat foo'
-rw-r----- 1 nobody root 0 Feb 12 21:53 foo
ksh: foo: cannot create [Permission denied]
1 Like

Next few shots (might as well be blind).

What is your root's default shell?
Does it have ksh command aliased in any way?
Did you also try invoking /bin/ksh instead of just ksh?

hmmm, works for me as is (linux mint 20.x).

I ran the following - added a few more details.

printf "pwd:%s user:%s umask:%s\n" "$PWD" "$USER" "$(umask)"

sudo su -

ls -al ..|grep -E 'root$'

bash -c '$0 --version; printf "\npwd:%s user:%s umask:%s\n" "$PWD" "$USER" "$(umask)"; rm -vf foo; :>foo; ls -al foo; chown nobody foo; ls -la foo; date>foo; ls -al foo; cat foo'

ksh -c '$0 --version; printf "\npwd:%s user:%s umask:%s\n" "$PWD" "$USER" "$(umask)"; rm -vf foo; :>foo; ls -al foo; chown nobody foo; ls -la foo; date>foo; ls -al foo; cat foo'

Very useful ! It does not bug in /root, I was in /tmp. Thank you very much for the command :smiley:

Let's try this

# mkdir /root/tmp
# cd /root/tmp
# touch foo
# chown nobody foo
# chmod 555 .
# ksh -c "date>foo"
# chmod 7777 .
# ksh -c "date>foo"
ksh: foo: cannot create [Permission denied]
# chmod 1777 .
# ksh -c "date>foo"
ksh: foo: cannot create [Permission denied]
# chmod 1775 .
# ksh -c "date>foo"
#

very strange

also strange, the ksh version !!!

# ksh --version
  version         sh (AT&T Research) 93u+m/1.0.0-beta.1 2021-05-10

It is RHEL9. I just asked my sysadmin for explanation why using beta software

Thanks

Good point, a beta version.
I have seen an earlier AT&T ksh update on SUSE Linux where they managed to break it.
SUSE's fix was a roll back; later they moved to mksh that has not much in common with ksh (but the name).
Also there was a ksh-2000 project - a total fail.
The latest stable version is ksh93u+

Maybe this time they broke the euid == ruid check?
Display all the current UIDs:

ps -o pid,euid,ruid,suid,egid,rgid,sgid,cmd -p $$

The behavior changes if you invoke ksh with -p option.

Unsure...

# ksh -p -c 'ps -o pid,euid,ruid,suid,egid,rgid,sgid,cmd -p $$'
    PID  EUID  RUID  SUID  EGID  RGID  SGID CMD
 970350     0     0     0     0     0     0 ps -o pid,euid,ruid,suid,egid,rgid,sgid,cmd -p 970350
# bash -p -c 'ps -o pid,euid,ruid,suid,egid,rgid,sgid,cmd -p $$'
    PID  EUID  RUID  SUID  EGID  RGID  SGID CMD
 970360     0     0     0     0     0     0 ps -o pid,euid,ruid,suid,egid,rgid,sgid,cmd -p 970360

I also tried ksh-1.0.6-1.el9.x86_64 and also mksh but it does bug as well

could be related to the sticky bit on /tmp (+/ group membership(s))
in /tmp - the sticky bit (normally !) prevents the change - as only owner/group have write permission and 'nobody' is not a member of root.
however under root/tmp .... root still has permission to change the file as they own

ls -al .. | grep -E '(root|tmp)$'
drwx------  21 root root       4096 Feb 13 09:08 root
drwxrwxrwt  33 root root       4096 Feb 13 09:09 tmp
root@Z800:~# pwd 
/root
root@Z800:~# touch t; touch /tmp/t; ls -al t ; ls -al /tmp/t
-rw-r--r-- 1 root root 0 Feb 13 09:09 t
-rw-r--r-- 1 root root 0 Feb 13 09:09 /tmp/t
root@Z800:~# chown nobody t; chown nobody /tmp/t; ls -al t ; ls -al /tmp/t
-rw-r--r-- 1 nobody root 0 Feb 13 09:09 t
-rw-r--r-- 1 nobody root 0 Feb 13 09:09 /tmp/t
root@Z800:~# date >> t; ls -al t; date>> /tmp/t; ls -al /tmp/t
-rw-r--r-- 1 nobody root 29 Feb 13 09:11 t
-bash: /tmp/t: Permission denied
-rw-r--r-- 1 nobody root 0 Feb 13 09:09 /tmp/t

whereas doing same on macos darwin, - it works without barfing

1 Like

Thank you for reproducing my issue. Let's avoid /tmp and ksh
Best regards
Laurent

Thanks a lot, now I found the behavior change between RHEL8 and RHEL9, it is all about protected_regular

# ksh
# echo 0 > /proc/sys/fs/protected_regular
# :>/tmp/foo
# echo 1 > /proc/sys/fs/protected_regular
# :>/tmp/foo
ksh: /tmp/foo: cannot create [Permission denied]

is the workaround

2 Likes

thks, was not familiar with this, related excerpts from kernel documentation below .

https://docs.kernel.org/admin-guide/sysctl/fs.html?highlight=protected_regular#protected-regular

This protection is similar to protected_fifos, but it avoids writes to an attacker-controlled regular file, where a program expected to create one.

When set to "0", writing to regular files is unrestricted.

When set to "1" don't allow O_CREAT open on regular files that we don't own in world writable sticky directories, unless they are owned by the owner of the directory.

When set to "2" it also applies to group writable sticky directories.

2 Likes

The traditional behavior is that a +t bit ("sticky bit") on a directory prevents from deletion i.e. unlink() of another owner's file, even if the other directory permissions are rwxrwxrwx, like /tmp
But root (uid 0) is not restricted, can delete everything in /tmp

Now this
/proc/sys/fs/protected_regular = 1
feature extends it to open() and even restricts root!

says:

That even root can't edit files anymore seems to be a side-effect.

I call this a severe violation of Unix compatibility if not a bug!
I would set it to 0 (off) via the sysctl facilty. Then it's on only during the early boot phase.

2 Likes