open /dev/mem - Operation not permitted - c

I am working on ubuntu.
I am trying to open /dev/mem and i am getting permission denied
int32_t open_memdev()
{
int32_t fd;
fd = open("/dev/mem", O_RDONLY);
if (fd < 0) {
printf("Failed to open /dev/mem : %s\n", strerror(errno));
return-EINVAL;
}
return fd;
}
This code always prints "Failed to open /dev/mem : Operation not permitted"
I have searched for this on SO
access-permissions-of-dev-mem
accessing-mmaped-dev-mem
These q's seem to discuss the issue of not being able to access above 1 MB, but my problem is that i am unable to open even once.
Addtitional details if they help:
1) I checked my configuration that CONFIG_STRICT_DEVMEM is enabled.
2) ls -l /dev/mem
crw-r----- 1 root kmem 1, 1 2014-03-13 13:57 /dev/mem
Please let me know if additional information is required.

You cannot read /dev/mem if you are not root.
There is no reason for an ordinary application to access /dev/mem, i.e. the physical RAM, since applications are running in virtual memory !
If you change the permission of /dev/mem to enable that (you should not), you will open a huge security hole in your system. Only trusted root processes should access /dev/mem. See mem(4)
(you could use setuid techniques if so wanted, or run your program with sudo)
If you need to access virtual memory in the address space of some other process, consider proc(5) e.g. /proc/1234/mem for process of pid 1234.

Related

Entering sudo password through c

I asked this question before but no-one gave a straight answer. I wanted to know how I can enter the sudo password through c code. I'm trying to write a script to be able to execute sudo bash and enter the password required. Also I know the risks of hardcoding passwords but I don't mind in this instance.
No. Doing it that way is an antipattern.
There are several alternatives to choose from, depending on the situation:
Use gksudo (if DISPLAY environment variable is set) for a graphical prompt.
Install the scripts to be executed in /usr/share/yourapp/scripts/ or /usr/lib/yourapp/scripts/, and the proper sudo configuration that allows running them with sudo without supplying a password in /etc/sudoers.d/yourapp (or /etc/sudoers in systems without /etc/sudoers.d/)
At the beginning of your program, check if geteuid() == 0. If not, re-execute self using gksudo/sudo, to obtain root privileges.
For normal operations, your program should use only the privileges of the real user who executed the program. To be able to raise the privileges later, the root privileges are "saved". So, initially, your program will drop the privileges using e.g.
uid_t uid = getuid();
gid_t gid = getgid();
if (setresgid(gid, gid, 0) == -1 ||
setresuid(uid, uid, 0) == -1) {
/* Failed: no root privileges! */
}
To re-elevate privileges, you use
if (setresgid(gid, 0, 0) == -1 ||
setresuid(uid, 0, 0) == -1) {
/* Failed: no root privileges! */
}
which changes only the effective identity to root (as setuid binaries do), or
if (setresgid(0, 0, 0) == -1 ||
setresuid(0, 0, 0) == -1) {
/* Failed: no root privileges! */
}
which changes both real and effective identity to root.
Often, the privileges are elevated for only forking a privileged child slave, after which the main program drops the privileges completely using
if (setresgid(gid, gid, gid) == -1 ||
setresuid(uid, uid, uid) == -1) {
/* Failed. */
}
keeping just a socket pair or pipes between the parent and the child; the child can then fork and execute new processes. (If an Unix domain socket is used, the parent can even send new descriptors to be used for the new processes' standard streams via ancillary messages.)
Use filesystem capabilities to give your program the capabilities it needs, without elevating all its privileges.
For example, sudo setcap CAP_NET_BIND_SERVICE=pe /usr/bin/yourapp gives /usr/bin/yourapp the CAP_NET_BIND_SERVICE capability (permitted and effective; not inherited), which allows your program to bind to any unused TCP/IP and UDP/IP ports, including 1-1024. See man 7 capabilities for detailed descriptions of the capabilities.
Use a trusted helper binary (program) to act as sudo for you. If you install this at e.g. /usr/lib/yourapp/execute, you can add the sudo configuration necessary to allow executing it without supplying a password. Alternatively, you can make it setuid root, or give it the necessary capabilities via filesystem capabilities.
To avoid other programs from exploiting this helper, you must ensure it is only executed by your program. One way to ensure that is to have your program create an Unix domain socket pair, leaving one end open in your program, and the other end for the helper in e.g. descriptor 3. Before doing anything, the helper checks that there is nothing to receive yet (to avoid "pipe stuffing" attacks), and writes a single byte to the parent. The parent responds with a single byte, but with its credentials in an ancillary message. The credentials contain the process ID of the parent. (Do not simply use getppid(), because that allows certain attacks; this socket approach verifies the parent is still alive when we do the check.) Finally, use readlink() to read the /proc/PID/exe pseudo-symlink, where PID is the parent process ID from the credentials ancillary message. At this point, the helper should send a byte, and receive a byte with the credentials again as an ancillary message, to ensure the parent process is still the same.
The verification process is complex, but necessary, to avoid making it easy to exploit root privileges by misusing the helper. For another approach to do exactly this, look into Apache suEXEC, the helper used by Apache to execute CGI programs with specific user privileges.
Let's say you are totally uninterested in doing things in a sensible way, and insist on using passwords. Fine; all I ask is that you don't publish such code, or at least warn your users that it is completely unsafe.
This is not just a crude hack: it is a suicidal one, similar to putting the password to your web site in your e-mail signature, because you only mail to friends who should have admin access to your site in the first place. So, footgun, with a hair trigger, no safety, and armed with buckshot coated in tetrodotoxin. With a nice label with big, child-readable letters saying "Please play with me! I'm safe!", stored in the kids bedroom.
The simplest thing to do is to execute sudo with the -S flag, which causes it to read the password from the standard input. For example, example.c:
#define _POSIX_C_SOURCE 200809L
#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <string.h>
#include <stdio.h>
#include <errno.h>
int main(void)
{
FILE *cmd;
int status;
cmd = popen("/usr/bin/sudo -S id -un 2>/dev/null", "w");
if (!cmd) {
fprintf(stderr, "Cannot run sudo: %s.\n", strerror(errno));
return EXIT_FAILURE;
}
fprintf(cmd, "Password\n");
fflush(cmd);
status = pclose(cmd);
if (WIFEXITED(status)) {
if (WEXITSTATUS(status) == EXIT_SUCCESS)
fprintf(stderr, "No errors.\n");
else
fprintf(stderr, "Command failed with exit status %d.\n", WEXITSTATUS(status));
} else
if (WIFSIGNALED(status))
fprintf(stderr, "Command killed by signal %d.\n", WTERMSIG(status));
else
fprintf(stderr, "Command failed.\n");
return EXIT_SUCCESS;
}
The command pipe is opened in write mode, so that we can write the password to it. The 2>/dev/null redirection hides the password prompt.
If the password is correct, the above will output what id -un outputs when run as root (i.e.: root) to standard output, and No errors. to standard error.
If the password is incorrect, sudo will retry a couple of times (so nothing will happen for a few seconds), then the program will report Command failed with exit status 1. to standard error, because that's what sudo does when the password is incorrect.

Shared memory - shm_open causing permission denied

I am writing a program that uses POSIX shared memory and have an error that I am unsure how to fix. I looked for similar questions but could not find any relevant to this specific problem.
Two files are involved - server.c, which contains the code run by the program, and shm.c, which contains functions that provide abstraction for handling the shared memory. This is an assignment, so I cannot deviate very far from the current structure.
Below is the relevant code from each file:
server.c
int shmFd;
shmFd = createSHM(SHNAME);
shm.c
int createSHM(char * shname)
{
int fileDesc;
fileDesc = shm_open(shname, O_CREAT | O_RDWR, 0);
if(fileDesc == -1)
{
perror("Error: Could not create shared memory space");
}
return fileDesc;
}
shm.h
#define SHNAME "/shmserver"
When I attempt to run the built program in the terminal, the following error appears:
Error: Could not create shared memory space: Permission denied
Any help would be much appreciated.
The line
fileDesc = shm_open(shname, O_CREAT | O_RDWR, 0);
gives no-one any access rights to the shared memory object. Once you create a shared memory object with no access rights, only the root user will be able to open it.
Instead, use (for example)
fileDesc = shm_open(shname, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR | S_IXUSR);
(You could allow other users to access the shared memory, obviously. But you need, at a minimum, to allow yourself to access it; otherwise, you won't be able to open it once you've created it.)
Perhaps worth noting that your error message is incorrect, so you might be misleading yourself (and others). The call to shm_open does not fail when it is creating the shared memory object. What fails is opening an already created shared memory object without all permissions for the user.

My open() command is not creating a new file

I am supposed to write a program that creates new files using the open() command, which, everything I read says that it's supposed to do if a file doesn't already exist.
My code is like this:
char startroom[] = "laruee.rooms/startroom.txt";
//...
int file_descriptor;
//...
file_descriptor = open(startroom, O_WRONLY | O_CREAT );
{
fprintf(stderr, "Could not open %s\n", startroom);
perror("in main");
exit(1);
}
However, despite everything I've googled about this command indicating that the file should get created if it doesn't already exist, the file is not getting created. (And also from everything I googled, it appears that I am the only programmer in the universe having this problem.)
What gives?
Your question could be operating-system (and even file-system) specific. I guess you are running on Linux on some usual file-system like Ext4 or BTRFS.
Read open(2) & path_resolution(7). There are several reasons why an open could fail (and we cannot guess which is relevant for your computer).
It might happen that your code is not running in the conditions you want it to (working directory, user id...)
Then, improve your code as:
char startroom[] = "laruee.rooms/startroom.txt";
//...
int file_descriptor = open(startroom, O_WRONLY | O_CREAT );
if (file_descriptor < 0) {
fprintf(stderr, "Could not open %s : %s\n",
startroom, strerror(errno));
char wdbuf[256];
if (getcwd(wdbuf, sizeof(wdbuf))
fprintf(stderr, "in %s\n", wdbuf);
exit(EXIT_FAILURE);
}
When using perror or strerror on errno you don't want any function which might change errno to be called after the failing syscall. On Linux with glibc the fprintf(3) function knows about %m ....
BTW, you could also strace(1) your program
Perhaps look also in your /var/log/syslog or /var/log/messages. Be sure your disk is not full (use df -h and df -i). If you have disk quotas, be sure to not overflow them. Be sure that your program is running in the directory you want it to and that current directory contains a laruee.rooms/ sub-directory; you might get it with getcwd(2) like I did above.
Particularly for server-like programs, you might want to use syslog(3).
You should read Advanced Linux Programming
BTW your open is not a command (that would be xdg-open) but a system call or at least a POSIX function

Check if a file is being written using Win32 API or C/C++. I do not have write access myself

Inside a Windows C/C++ programm, I need to process a text file. So I just need to open the file for reading. However, I do not want to do that while the file is still being written to by another process. I also know that this other process will eventually close the file and never write to it agin.
Looking at similar questions on stackoverflow, the typical answer is "try and open the file for writing - if that fails then try again later").
Now in this case, my process does not have write access to the file at all. So checking if the file can be opened for writing is not an option . It will always fail irrespective of any other process having write access or not.
As Hans Passant and Igor Tandetnik said you just need to pass the appropriate sharing flag to CreateFile. As the MSDN documentation for CreateFile says:
FILE_SHARE_WRITE 0x00000002
Enables subsequent open operations on a file or device to request write access.
Otherwise, other processes cannot open the file or device if they request write access.
If this flag is not specified, but the file or device has been opened for write access
or has a file mapping with write access, the function fails.
You'll want to use code like the following:
HANDLE handle = CreateFile(name, GENERIC_READ, FILE_SHARE_READ, NULL,
OPEN_EXISTING, 0, NULL);
if (handle == INVALID_HANDLE_VALUE) {
DWORD errcode = GetLastError();
if (errcode == ERROR_SHARING_VIOLATION) {
printf("%s: sharing violation\n", name);
} else {
printf("%s: CreateFile failed, error code = %lu\n", name, errcode);
}
} else {
printf("%s: CreateFile succeeded\n", name);
}
This code in unable to tell if the ERROR_SHARING_VIOLATION occurred because the other process has the file open for writing or because the another process didn't use FILE_SHARE_READ when opening the file. In the later case any attempt to read from the file will fail with a sharing violation. The FILE_SHARE_READ flag is passed to prevent sharing violations in the case when the file already been opened and FILE_SHARE_READ was used. You could also add FILE_SHARE_DELETE but I assume you'd consider that the same as write access.

device file open failed in linux system

I am working in omap4 based system. It has 4 UART port so kernel makes:
/dev/ttyO0
/dev/ttyO1
/dev/ttyO2
/dev/ttyO3
When I open from user space:
fd = open("/dev/ttyO1",O_RDONLY)
it succesfully open and i can peform read and write with that.
But when I open:
fd = open("/dev/ttyO3",O_RDONLY)
Its failed.
I am able to see /dev/ttyO3 node in my system still why i am not able to open it? Any idea?
i have given permission to that node and now i can open that node
chmod 0606 /dev/ttyO3

Resources