Linux - Reading File from Sudo - "Permission Denied" - c++

When performing a recursive directory scan of the drive to generate a hash for each file by running the program executable under sudo, I'm discovering 1,000s of files are throwing "Permission Denied" errors.
My Question: Is this by design, why is sudo unable to read the files? Is what I'm doing even possible because files might be encrypted or currently in use during the time of the scan?
When I compile to Mac OSX and perform the same scan under sudo, I don't have this issue, just Linux.
Distro: 3.19.0-25-generic #26~14.04.1-Ubuntu SMP Fri Jul 24 21:16:20 UTC 2015 x86_64 x86_64 x86_64 GNU/Linux
An example of files with permission denied:
Can't open file: "/sys/class/gpio/unexport"
MSG: "Permission denied"
Can't open file: "/sys/class/gpio/export"
MSG: "Permission denied"
Sample of permission settings:
/sys/class/gpio$ ls -al
total 0
drwxr-xr-x 2 root root 0 Oct 5 04:51 .
drwxr-xr-x 57 root root 0 Oct 4 11:25 ..
--w------- 1 root root 4096 Oct 5 04:51 export
--w------- 1 root root 4096 Oct 5 04:51 unexport
MD5 Function where file reads fail:
QByteArray MD5(QString sPath)
{
QByteArray resultMD5 = NULL;
QFile* file = new QFile(sPath);
if(file->open(QIODevice::ReadOnly))
{
QCryptographicHash* pHashMD5 = NULL;
resultMD5 = pHashMD5->hash(file->readAll(),QCryptographicHash::Md5);
file->close();
//Clean up pointer
delete pHashMD5;
delete file;
}
else
{
qDebug() << "Can't open file: " << sPath;
qDebug() << "MSG: " << file->errorString();
file->close();
delete file;
}
return resultMD5;
}

What is under /sys are not really files. It's an interface into the kernel.
With regard to the examples you have mentioned, see here for an explanation of what they do.
Given their function, it makes no sense to consider that such "files" could be read.

Related

spdlog for C++; what(): Failed opening file ~/logs/log.txt for writing: No such file or directory

I am using spdlog to do some simple logging on a c++ program on a beaglebone, debian 10. I set up a rotating logger:
auto logger = spdlog::rotating_logger_mt("runtime_log", "~/logs/log.txt", max_size, max_files);
and this returns the error
terminate called after throwing an instance of spdlog::spdlog_ex'
what(): Failed opening file ~/logs/log.txt for writing: No such file or directory
Aborted
I have already ensured that the directory exists and have tried chmod -R 776 ~/logs/
so:
drwxrwxrw- 2 user group 4096 Oct 28 09:03 logs
-rwxrwxrw- 1 user group 0 Oct 28 09:03 runtime.log
When given the path logs/log.txt, it works. This puts the logfile in ~/project/build/logs
I have also tried giving the full path /home/user/logs/log.txt. And that works fine.
Why would my program and spdlog not be able to access the directory at the path ~/logs/log.txt?
~ is special character in Bash shell, shorthand for home directory. The C++ program doesn't know about the ~. Usual way to get home directory would be to use std::getenv function like:
const char* home_dir = std::getenv("HOME");
auto log_path = std::string{home_dir} + "/logs/log.txt";
I suggest you also to make use of <filesystem> header as it has functions to check the existence of files and directories.

Can't download a file via os.system('scp (...)') whithin a python script launched via a init script

I'm trying to download a remote file using the scp command called by os.system() in a Python script (scp.py) started as a service by a procd init script.
This script is running on OpenWrt 15.05.1 (which uses BusyBox to implement the shell environment). SCP itself is handled by dropbear SSH (https://matt.ucc.asn.au/dropbear/dropbear.html)
The code is quite simple :
import os
import logging
logging.basicConfig(level=logging.DEBUG, filename='/usr/local/www/log/scp_test.log', filemode = 'w')
rc = os.system('scp -i /root/.ssh/id_rsa root#vps500141.ovh.net:/root/simon/test /tmp/hello')
error_code, signal = rc >> 8, rc & 0xFF
logging.debug('error_code -> {}'.format(error_code))
logging.debug('signal -> {}'.format(signal))
When launched in the terminal using the command "python scp.py", the program's behave well. The download is successful and produces the following output :
root#S096C08:/usr/local/bin# python scp.py
test 100% 24 0.0KB/s 00:00
root#S096C08:/usr/local/bin# cat /usr/local/www/log/scp_test.log
DEBUG:root:error_code -> 0
DEBUG:root:signal -> 0
But this program fails to download anything when launched as a service using the command /etc/init.d/scp_test start
root#S096C08:/usr/local/bin# /etc/init.d/scp_test start
root#S096C08:/usr/local/bin# cat /usr/local/www/log/scp_test.log
DEBUG:root:error_code -> 1
DEBUG:root:signal -> 0
Furthermore, a quick investigation of the syslogs using the logread command shows this :
Wed May 15 10:24:58 2019 daemon.err python[3156]: Host 'vps500141.ovh.net' is not in the trusted hosts file.
Wed May 15 10:24:58 2019 daemon.err python[3156]: (ssh-rsa fingerprint md5 41:aa:2b:57:48:be:01:81:48:a3:d0:ac:b6:56:16:34)
Wed May 15 10:24:58 2019 daemon.err python[3156]: Do you want to continue connecting? (y/n)
Wed May 15 10:24:58 2019 daemon.err python[3156]: /usr/bin/dbclient: Connection to root#vps500141.ovh.net:22 exited: Didn't validate host key
vps500141.ovh.net already have an entry in /root/.ssh/known_hosts so this is quite surprising that it is not found when the script is running.
I've also tried to add the "-o StrictHostKeyChecking=no" option to the scp command but it doesn't seems to work either.
NB : this is the content of the init script /etc/init.d/scp_test
#!/bin/sh /etc/rc.common
# Copyright (C) 2015 CZ.NIC z.s.p.o. (http://www.nic.cz/)
START=99
STOP=0
USE_PROCD=1
SCRIPT="/usr/local/bin/scp.py"
start_service() {
procd_open_instance
procd_set_param user root
procd_set_param command python "$SCRIPT"
procd_set_param stderr 1
procd_close_instance
}
Problem resolved after moving /root/.ssh/known_hosts to /.ssh/known_hosts

ERROR: ld.so: object '/opt/xyz/mylib.so' from LD_PRELOAD cannot be preloaded: ignored

After upgrading a software from 32 to 64-bit, a pre-compiled binary starts to fail with the error:
[root#localhost /root]# LD_PRELOAD=/opt/xyz/lib/mylib.so mycommand /inputfile.txt /outputfile.txt
ERROR: ld.so: object '/opt/xyz/lib/mylib.so' from LD_PRELOAD cannot be preloaded: ignored.
mycommand: error while loading shared libraries: mylib.so: cannot open shared object file: No such file or directory
mycommand is a precompiled binary that sits in /usr/bin/mycommand. It requires the library as LD_PRELOAD.
Obviously I made sure that the file /opt/xyz/lib/mylib.so does exist:
[root#localhost lib]# ls -alh
total 512K
drwxr-xr-x 2 root root 4.0K Mar 1 15:40 .
drwxr-xr-x 10 root root 4.0K Feb 24 10:54 ..
-rwxr-xr-x 1 root root 218K Oct 28 22:41 mylib64.so
lrwxrwxrwx 1 root root 14 Mar 1 15:40 mylib.so -> mylib64.so
Is there any more debugging information I can extract other that this error?
It seems like not relevant if I simply delete the mylib.so or not, the error stays the same. It's kind of hard to say if it can't preload the library or if it can't find the library.
Is there any other environment variables or libraries that are required for LD_PRELOAD to work?
It seems to me essential to acquire a version of the source code of the mycommand binary and re-compile it. However to do that I think it would be probably useful to see why it actually fails right now.
LD_PRELOAD will not work on symlinks. You will need to set the path to the actual location of the library. For example:
LD_PRELOAD=/opt/xyz/lib/mylib64.so
I agree that a more specific error message would've been useful.

Audio capturing using ALSA library - snd_pcm_open => No such file or directory

I'm trying to implement audio capturing on a SoC using ALSA library.
I've a precompiled libasound.so.2.0.0 a asoundlib.h together with other headers.
now I have
int returnCode;
snd_pcm_t *pcm_Handle;
char *pcm_device_name = "hw:0,0";
returnCode = snd_pcm_open(&pcm_Handle, pcm_device_name, SND_PCM_STREAM_CAPTURE, 0);
which returns snd_strerror(returnCode) of No such file or directory
Does this indicate that the capturing device isn't properly installed (e.g. drivers or something)?
How can I find out what's wrong/missing?
Can I list whether ANY alsa accessible sound device is installed?
UPDATE:
I found out how to scan for devices by: Finding available sound cards on Linux programmatically
snd_card_next finds a single cardNum : 0 but I still fail on snd_ctl_open(&cardHandle, "hw:0", 0) and snd_pcm_open(&pcm_Handle, "hw:0,0", SND_PCM_STREAM_CAPTURE, 0) with No such file or directory. Is that an indication for that the sound device isn't properly installed?
UPDATE::
I found some more information on http://www.tldp.org/HOWTO/Alsa-sound-4.html
"4.6 Preparing the devices There is a script in the driver-directory
that will install the ALSA-sound-devices in your /dev directory. Type
./snddevices from the driver-directory. There should be a /dev/snd
subdirectory now (test if it is there. If you are not familiar with
even the "ls" command, please consider reading other HOWTO's first.
You should have some basic Linux knowledge to install these drivers).
Now you're ready to insert the driver, so please turn over to the next
paragraph."
I remember that I've run a snddevices script that was provided with the SoC alsa version, but I wasnt sure whether it was successful or whether it just didn't show the errors. But the link says I'll have to install drivers afterwards? Unfortunately I can't test before tomorrow.
UPDATE:
From CL. and http://www.tldp.org/HOWTO/Alsa-sound-6.html I tested the following:
dev/snd/ has the following entries:
crw-rw---- 1 root audio 116, 0 Mar 11 04:44 controlC0
crw-rw---- 1 root audio 116, 24 Mar 11 04:44 pcmC0D0c
crw-rw---- 1 root audio 116, 16 Mar 11 04:44 pcmC0D0p
crw-rw---- 1 root audio 116, 25 Mar 11 04:44 pcmC0D1c
crw-rw---- 1 root audio 116, 26 Mar 11 04:44 pcmC0D2c
crw-rw---- 1 root audio 116, 27 Mar 11 04:44 pcmC0D3c
crw-rw---- 1 root audio 116, 28 Mar 11 04:44 pcmC0D4c
where cat controlC0 cat pcmC0D0c and cat pcmC0D1c return cat: read error: File descriptor in bad state while the others return like cat: can't open 'pcmC0D2c': No such device
While cat /proc/asound/cards gives
0 [VPL_AUDIO ]: VPL AUDIO - VPL Audio TW2866 Driver
VPL Audio Codec Driver, TW2866.
1 [Mozart_SSM2603 ]: I2S - I2S driver
I2S driver
Here is some more information. Since I'n not any experienced with audio, I don't know whether they are important or to help...
cat /proc/asound/pcm
00-00: tw2866#0 : VPL Audio TW2866 Driver : capture 1
00-01: tw2866#1 : VPL Audio TW2866 Driver : playback 1 : capture 1
01-00: I2S AIC23 PCM : I2S driver : playback 1 : capture 1
Your problem is that the alsa-lib package is not installed correctly (and it looks as if there is no package for your hardware).
To find out which files you need, get the alsa-lib source package, compile it, and install it into a temporary directory with
make install DESTDIR=/tmp/test
Then look into /tmp/test/; the compiled library file itself (libasound.so*) cannot be used if you didn't use the correct cross compiler, but the other files are text files suitable for any architecture.
I had different version of the snddevices script. I had to use the right script int he right directory to get snd_pcm_open to work. I had to copy the script to the driver directory of the SoC.
I copied the .conf file to the same directory as in the reference implementation.
The bad file descriptor error message seems to be present if no capturing device is running. The capturing still doesn't work as of now.

How to read HD serial in Linux without root privileges?

I am building a C/C++ program which needs to read the HD serial. I am aware that if I run these commands:
hdparm -i /dev/sda | grep -i serial
/sbin/udevadm info --query=property --name=sda | grep "ID_SERIAL"
I can get it, the first requires root permissions but the second doesn't.
However, my application cannot access external programs, and it cannot require root privileges, so is there a C/C++ linux library that has a function that returns the HD serial? Or is there any other way that does not require running a program?
By just listing /dev/disk/by-id/ directory, you get IDs of all block devices on your system. The output is not exactly the same as with the commands, but it is close enough.
For this, you do not need root privileges.
On my PC :
$ /sbin/udevadm info --query=property --name=sda | grep "ID_SERIAL"
ID_SERIAL=WDC_WD5000AAKX-60U6AA0_WD-WCC2EHJ93860
ID_SERIAL_SHORT=WD-WCC2EHJ93860
and
$ ll /dev/disk/by-id/ | grep sda
lrwxrwxrwx 1 root root 9 Nov 11 07:47 ata-WDC_WD5000AAKX-60U6AA0_WD-WCC2EHJ93860 -> ../../sda
lrwxrwxrwx 1 root root 10 Nov 11 07:47 ata-WDC_WD5000AAKX-60U6AA0_WD-WCC2EHJ93860-part1 -> ../../sda1
lrwxrwxrwx 1 root root 10 Nov 11 07:47 ata-WDC_WD5000AAKX-60U6AA0_WD-WCC2EHJ93860-part2 -> ../../sda2
lrwxrwxrwx 1 root root 10 Nov 11 07:47 ata-WDC_WD5000AAKX-60U6AA0_WD-WCC2EHJ93860-part3 -> ../../sda3
You can use ioctls to access hard drive information, just as hdparm does. The HDIO_GET_IDENTITY ioctl should be sufficient for your needs. It returns a structure which (IIRC) includes the serial number; googling around should help you find the structure definition.