EEVblog Electronics Community Forum

Computing => Embedded Computing => Topic started by: luiHS on June 08, 2021, 05:15:58 pm

Title: Raspbery, Open and read my txt file stored in /boot from C.
Post by: luiHS on June 08, 2021, 05:15:58 pm
 
Hello.
Is there an easy way to open and read a text file stored in Raspeberry's /boot, from a C program?

I need to have a text file in /boot for my C program to read, and based on a parameter run some routines or others.

The problem is that creating the text file in /boot does not allow me to change the owner from root to pi, nor does it allow me to read the file from my C program.
Title: Re: Raspbery, Open and read my txt file stored in /boot from C.
Post by: guenthert on June 08, 2021, 05:59:42 pm

Hello.
Is there an easy way to open and read a text file stored in Raspeberry's /boot, from a C program?

I need to have a text file in /boot for my C program to read, and based on a parameter run some routines or others.

The problem is that creating the text file in /boot does not allow me to change the owner from root to pi, nor does it allow me to read the file from my C program.
    For a file to be read in *nix it needs to be readable by the user (euid) of the process attempting the read.  The owner of the file is relevant only in as much file permissions apply.  Make the file readable by everyone ("others" or "all") e.g. by executing `chmod a+r /boot/file_of_interest.txt` with superuser privileges (e.g. by prefixing aforementioned command with `sudo `).
Title: Re: Raspbery, Open and read my txt file stored in /boot from C.
Post by: dave j on June 08, 2021, 06:29:26 pm
/boot is the mount point for the boot partition, which is formatted as FAT32. It needs to be FAT32 because that is the only filesystem that the Pi's boot mechanism supports. FAT filesystems don't support Unix style permissions so everything on the partition is assumed to have the permissions given to the mount point.

You won't be able to write a file to the partition unless you're root but you should be able to read as any user. (I've just tried creating a text file in /boot as root and reading it as user pi on one of my Pis and it worked.)
Title: Re: Raspbery, Open and read my txt file stored in /boot from C.
Post by: janoc on June 08, 2021, 08:36:26 pm
The problem is that creating the text file in /boot does not allow me to change the owner from root to pi, nor does it allow me to read the file from my C program.

You need to mount the VFAT partition with correct options. Open the /etc/fstab file in an editor and check the line:

Code: [Select]
/dev/mmcXXX /boot  vfat  defaults 0 2
What you need to do is to change that line to something like:

Code: [Select]
/dev/mmcXXX /boot  vfat  defaults,umask=000 0 2
Then save it and reboot.

That will allow anyone to open and write files on that partition. And no, you can't change owner of an individual file, FAT doesn't have a concept of file owners. You can only remap the files to appear with a different owner, e.g. using the uid and gid options in /etc/fstab.

E.g. the following will make all files on that filesystem appear as being owned by the user with the UID 1000 (which should be the user 'pi' on Raspbian).
Code: [Select]
/dev/mmcXXX /boot  vfat  defaults,uid=1000 0 2
You can find the user IDs in /etc/passwd or by typing:
Code: [Select]
id username (replace "username" with the user you want to check)


Title: Re: Raspbery, Open and read my txt file stored in /boot from C.
Post by: guenthert on June 08, 2021, 09:49:19 pm
   For just reading the file as non-privileged user the mount options don't need to be changed (and allowing non-privileged users to modify files under /boot is, er, not generally advisable).  Defaults for VFAT imply that files are created 0755, i.e. readable by all (among other things).  So, what exactly is the problem?
Title: Re: Raspbery, Open and read my txt file stored in /boot from C.
Post by: janoc on June 10, 2021, 08:56:58 am
   For just reading the file as non-privileged user the mount options don't need to be changed (and allowing non-privileged users to modify files under /boot is, er, not generally advisable).  Defaults for VFAT imply that files are created 0755, i.e. readable by all (among other things).  So, what exactly is the problem?

That's true and a good advice.

That said - we don't know what OS is he running. Raspbian mounts /boot with "defaults" in fstab but that may or may not be the case for others.

Also, if he said he has permission problems with the files /boot and is unable to read them, there certainly is some issue with mounting options (as there are no per-file permissions on vfat), no? Maybe he changed them, maybe the OS has different options for /boot by default, who knows. So I gave him the things to check.

Title: Re: Raspbery, Open and read my txt file stored in /boot from C.
Post by: Nominal Animal on June 11, 2021, 05:22:05 am
If you really-really need to, it is quite possible to create a privileged helper program that can be run via fork()+exec(), using an Unix domain stream socket pair to pass back the data.

Why a socket and not a normal pipe (so it could be run via popen())?

Because if you really need to do this, then you also need to add security checks.  If the parent process creates an Unix domain stream socket pair connecting the standard output of the privileged helper and itself, the privileged helper can verify the parent process identity using getsockopt(STDOUT_FILENO, SOL_SOCKET, SO_PEERCRED,  &creds, &credslen) with struct ucred  creds; socklen_t credslen = sizeof creds;.  If it returns zero and credslen == sizeof creds, the parent process ID is creds.pid (which obviously should match getppid()), and the user and group the parent process is running as in creds.uid and creds.pid.  Furthermore, the privileged helper can then verify which binary the parent process is running by calling readlink() on /proc/PID/exe.

A common attack in such mechanisms (they're used often with web services; see e.g. Apache SUExec etc.) is to entice the parent process to execute another (untrusted, hacked) binary just after it has forked and executed the helper and the helper has verified the parent.  These can be avoided by having the parent create the socket pair with SOCK_CLOEXEC flags (which the forked child process must undo for its own end before exec'ing the child process), and write a single-byte message after it has closed the end it gave the child process.  The helper waits for the message before verifying the parent process.  This way, the socket pair connection cannot leak outside the parent process without the child detecting it, unless someone manages to inject code into the parent process that deliberately leaks that socket pair connection.

This model is not itself secure, unless the parent process binary is immutable for all non-root users (i.e., installed as root, as binaries typically are, with only execute access to other users and groups).  If both the parent binary and the privileged helper binary are only writable by root, then this pattern is quite robust; code injection vulnerabilities can still break it, though – but those can break absolutely any process anyway.  Because a socket pair is used, the communication cannot be observed by any other processes running on the machine.  Because the privileged child process will only check the parent process identity after the parent process has secured its side of the connection, the connection cannot leak outside the parent process without the child process detecting it happened; there is no race window.

Code-wise, it's just a couple of hundred lines of codes that takes a couple of days to write (well, one day to write, the next day to verify and check with fresh eyes).
As a pattern, it is reliable within the parameters outlined above.  But it isn't something you throw at a problem because the proper solutions are less effort; that attitude just leads to pwned machines.  (As an example, if someone tells you to run chmod 0777 /var/www/html, that's like telling people to leave their doors unlocked because burglaries are just a conspiracy theory and do not happen in real life, and anyway keeping the doors unlocked might save you a fraction of a second getting out if your house caught on fire.)
Title: Re: Raspbery, Open and read my txt file stored in /boot from C.
Post by: DiTBho on June 11, 2021, 08:36:42 am
A common attack in such mechanisms

Hey? this is how I hacked my old PaperWhite ebook reader to load a decent browser because the one provided by Amazon is still "experimental".

Don't tell these tricks to people or someone in Amazon who reads this forum will work out something to block the exploit  :-X

(kidding, but it's a true story  ;D )
Title: Re: Raspbery, Open and read my txt file stored in /boot from C.
Post by: Nominal Animal on June 11, 2021, 09:37:12 am
Don't tell these tricks to people or someone in Amazon who reads this forum will work out something to block the exploit  :-X
Don't worry, people do not generally listen to me, even if I show them the proof of the pudding is in the eating.  :P

BTW, the reason I prefer to write UIs in Python: that lets any knowledgeable user to tweak their tool better without setting up a development environment, but at the same time, let me put all the sensitive/hard stuff in a C library that should not be accidentally modified.  Win-win, methinks.  If the user tweaks the UI so they can do stuff I did not imagine, well, more power to them; hopefully they'll let others know how to do it too.  If they want, they can replace the C library as well, but depending on the license I chose for that part, they may or may not have access to the sources to modify the existing one, and may have to just write a replacement one.

In other words, it does not make sense to lock everything down, even if there are business reasons why it might be desirable.  Would Rigol DS1054Z be so popular if it was less hackable?  No, I don't think so.

Me, I do not use security or security methods to constrain end users: only to protect end users and their data/work from attackers and exploiters.