0

I created a read-only system on Raspberry Pi with Debian Buster for an embedded application. The apache2 server is running on it with a configuration web page for the application that I need. I need to remount the filesystem in read-write mode for editing a system file and I added a toolbox button on a php page that call a shell function.

This is the code for particular button:

<p><label>Remount Read-Write</label>
<button type="submit" name="rw">Remount</button>
</p>
<p><label>Remount Read-Only</label>
<button type="submit" name="ro">Remount</button>
</p>
<?php
    if(isset($_POST['rw'])){
        $cmd='sudo /home/pi/mount.sh --rw';
        shell_exec($cmd);
    }
    else if(isset($_POST['ro'])){
        $cmd='sudo /home/pi/mount.sh --ro';
        shell_exec($cmd);
    }
?>

Inside the shell script, there is a line of code for mounting the root path in rw mode with the option '--rw', in particular the command is:

/bin/mount -o remount,rw /

and the same with with '--ro' but with ro option.

I also added a suoders file in /etc/sudoers.d with this line:

www-data ALL=(ALL) NOPASSWD: /home/pi/mount.sh

The problem is that the command is executed without errors but the file system is not remounted. If I do the command via shell like this:

p@localhost# sudo mount -o remount,rw /

the php shell_exec starts to work and I can mount and remount by php page.

I cannot understand why the php page starts to work only after I do the remount via shell.

Edit

This is the script that is called:

#!/bin/bash
# Remount filesystem
# Options:
#           --rw:       remount read-write filesystem
#           --ro:       remount read-only filesystem

if [ "$#" == 1 ]; then
  if [ $1 == "--rw" ]; then
    sudo /bin/mount -o remount,rw /
    echo -e "Filesystem remounted in read-write mode"
  elif [ $1 == "--ro" ]; then
    sudo /bin/mount -o remount,ro /
    echo -e "Filesystem remounted in read-only mode"
  elif [ $1 == "--help" ] || [ $1 == "-h" ]; then
    echo -e "Remount Filesystem tool"
    echo "use remount.sh [OPTION]"
    echo ""
    echo -e "--rw         \tremount read-write filesystem"
    echo -e "--ro         \tremount read-only Filesystem"
    echo -e "--help (-h)  \tprint help"
  else
    echo "use -h or --help to see options"
  fi
else
    echo "use -h or --help to see options"
fi

SOLVED

I found the solution for the issue.

The main problem was due to a systemcl option on apache2.service. By default the service have PrivateTemp=true option. Changed in PrivateTemp=false solved the problem.

As I understood, PrivateTemp is set to true for creating a file system namespace that is not shared. By default apache2 create a separated namespace for security acces to temporary files.

Here a couple of links that I looked at for solving the problem:

(U)Mounting through "exec" with "sudo". The user is a "sudoer" with NOPASSWD

https://www.freedesktop.org/software/systemd/man/systemd.exec.html#PrivateTmp=

Pierre François
  • 4,733
  • 1
  • 14
  • 30
  • Please, take a look at https://stackoverflow.com/questions/8532304/execute-root-commands-via-php to see if this solves your problem. – Pierre François Mar 27 '20 at 11:35
  • I tried the wrapper but same result. The execution via web page does not remount before I use the shell with manually remount. After that, the buttons on php start to work and remount filesystem throug the wrapper. – Fabio Zerbetto Mar 27 '20 at 14:24
  • Can you edit your question in order to show the relevant lines of the shell script to remount the root filesystem? – Pierre François Mar 29 '20 at 13:01
  • I edited the post with the entire bash script that i call via PHP – Fabio Zerbetto Mar 29 '20 at 13:49

1 Answers1

0

There is an error in the assignments of your PHP code above. Assignments in PHP are not like in BASH.

Change cmd= into $cmd= on two places.

If you don't do so, you will pass an empty string to the function shell_exec.

So try:

<p><label>Remount Read-Write</label>
<button type="submit" name="rw">Remount</button>
</p>
<p><label>Remount Read-Only</label>
<button type="submit" name="ro">Remount</button>
</p>
<?php
    if(isset($_POST['rw'])){
        $cmd='sudo /home/pi/mount.sh --rw';
        shell_exec($cmd);
    }
    else if(isset($_POST['ro'])){
        $cmd='sudo /home/pi/mount.sh --ro';
        shell_exec($cmd);
    }
?>
Pierre François
  • 4,733
  • 1
  • 14
  • 30
  • Sorry for mistake, in my code is all ok with $cmd. I did an error by typing in the comment here. The php page is executed with no errors, remount via buttons work only after I write on shell # sudo mount -o remount,rw / Than buttons start to execute remounts. Seem that there is something that is trigged via shell command, but i don't know. – Fabio Zerbetto Mar 29 '20 at 12:21
  • Do you know how often you need to trigger this behaviour again with the shell? After each reboot? – Pierre François Mar 29 '20 at 12:26
  • Only one time, Pierre after each reboot. – Fabio Zerbetto Mar 29 '20 at 12:52
  • Is it possible that apache2 is running in an environment isolated by chroot? Could it be that remounting the system from the shell removes this protection? I am puzzled... – Pierre François Mar 29 '20 at 16:19
  • Thanks to your last comment, Pierre, I resolved the issue. apache2 is not running on a chrootted environment but this input helped me to find the solution. It was systemctl problem, that apache2 service create new not shared file system namespace. I wrote the solution on original post. Thankyou for your help. – Fabio Zerbetto Mar 30 '20 at 15:14