I'm trying to setup my own NVRAM variable (nv+rt+bs) using WinAPI (SetFirmwareEnvironmentVariable). It fails with my variable and successfully completed with BootOrder. What do I do wrong? Is it possible to setup my own variable using WinAPI?
I'm trying to setup my variable using this code
void setMyNVRAM()
{
// here I setup SE_SYSTEM_ENVIRONMENT_NAME privilege
uint16_t value = 0x5aa5;
if (!SetFirmwareEnvironmentVariable(L"MY_VARIABLE",
L"{12345678-1234-1234-1234-123456789012}", &value, sizeof (value)))
{
std::cout << "error while settin up MY_VARIABLE. Error code: "
<< GetLastError() << std::endl;
}
else
{
std::cout << "success" << std::endl;
}
}
SetFirmwareEnvironmentVariable returns 0 and GetLastError() returns 5 (access denied). I also tried to write into BootOrder variable and it was successfully completed.
According to the instructions on the MSDN.
To write a firmware environment variable, the user account that the
app is running under must have the SE_SYSTEM_ENVIRONMENT_NAME
privilege. A Universal Windows app must be run from an administrator
account and follow the requirements outlined in Access UEFI firmware
variables from a Universal Windows App.
Customizing user privileges for an account in Windows
A similar discussion: How i can set firmware environment variable in UEFI driver
Related
NFSv3 protocol specifies that SETATTR can set file/dir mode and owner at the same time (as well as few other things). And yet Linux implementation of nfsd behaves in a quite strange way:
/* Revoke setuid/setgid on chown */
if (!S_ISDIR(inode->i_mode) &&
((iap->ia_valid & ATTR_UID) || (iap->ia_valid & ATTR_GID))) {
iap->ia_valid |= ATTR_KILL_PRIV;
if (iap->ia_valid & ATTR_MODE) {
/* we're setting mode too, just clear the s*id bits */
iap->ia_mode &= ~S_ISUID;
if (iap->ia_mode & S_IXGRP)
iap->ia_mode &= ~S_ISGID;
} else {
/* set ATTR_KILL_* bits and let VFS handle it */
iap->ia_valid |= (ATTR_KILL_SUID | ATTR_KILL_SGID);
}
}
What is the reason for this? I spent a lot of time tracking it down in some old app (that for some reason could not copy a file via NFS without losing suid bit). Is it a bug? It happens even if new owner is the same.
Disabling SUID is some sort of protection against untrusted NFS servers: If administrator of your local machine doesn't trust the NFS server, it cannot afford to execute files from the server with root privileges. See also article NFS, no_root_squash and SUID - Basic NFS Security.
It is a bug in Linux implementation of NFS server. See NFS specs.
I'm finally able to get the device path ("/dev/rdisk1") - called devname here - after a search but POSIX open() fails with -1. Is this a permission issue? The camera is mounted and can be read normally via /Volumes but I need to access via /dev to control the camera via USB tether.
/* Found PENTAX DIGITAL_CAMERA */
snprintf(pslr.devname, sizeof(pslr.devname), "%s", devpath);
pslr.devname[sizeof(pslr.devname)-1] = '\0';
printf("pslr.devname %s\n", pslr.devname);
pslr.fd = open(pslr.devname, O_RDWR);
if (pslr.fd == -1) {
return NULL;
}
PS: after the discussion below I changed the permissions with sudo chmod command and then tried open but it still fails. I must be missing a step.
I checked with apple support and they say I cannot use posix functions to control a USB device in OS X.
I am trying to mount a source directory from nfs server to a destination directory in embedded board having linux. The following command works perfectly as expected in shell prompt in the board.
mount -t nfs -o nolock 10.126.62.45:/vol/home/avinoba/Sky /mnt
What is the equivalent system call to be used in program for the command above?
I tried the below call but the mount failed with "Invalid Argument"
if(mount("10.126.62.45:/vol/home/avinoba/Sky","/mnt","nfs",MS_MGC_VAL,"nolock") == -1)
{
printf("ERROR: mount failed: %s \n",strerror(errno));
}
Please suggest what is the solution for it.
Thanks
I'm quite surprised here knowing that how this is not covered by any man page regarding NFS mounts. Diving into the kernel code, in the function nfs_validate_text_mount_data, the function nfs_parse_mount_options is responsible for parsing the multiple comma separated options passed as the fifth argument in the mount system call.
struct sockaddr *sap = (struct sockaddr *)&args->nfs_server.address;
if (nfs_parse_mount_options((char *)options, args) == 0)
return -EINVAL;
if (!nfs_verify_server_address(sap))
goto out_no_address;
In the above code block, the last if statement checks whether the nfs server address and socket family is defined to valid values. If they are not updated within nfs_parse_mount_options, mount would end up returning invalid parameter.
If the implementation of nfs_parse_mount_options is walked through, it can be seen that, only for the case Opt_addr, the nfs server address and the socket family is updated by parsing the options argument.
case Opt_addr:
string = match_strdup(args);
if (string == NULL)
goto out_nomem;
mnt->nfs_server.addrlen =
rpc_pton(mnt->net, string, strlen(string),
(struct sockaddr *)
&mnt->nfs_server.address,
sizeof(mnt->nfs_server.address));
kfree(string);
if (mnt->nfs_server.addrlen == 0)
goto out_invalid_address;
break;
The case Opt_addr corresponds to the option "addr=nfs server ip". So for the system call to work, defining this option is a must. As far as I have searched, this is completely missing from all the man pages which describes nfs mounts.
So now considering the problem statement, please try by changing to the below code
if(mount(":/vol/home/avinoba/Sky","/mnt","nfs",0,"nolock,addr=10.126.62.45") == -1)
{
printf("ERROR: mount failed: %s \n",strerror(errno));
}
Also note that when the addr option is put in the argument, the ip address in front of the nfs server path becomes optional. However the ':' is must,as this acts as the delimiter to parse the nfs server path.
MS_MGC_VAL should be in the top 16 bits if needed, not the bottom. If your kernel version is > 2.4, you don't need it at all.
It solved by the following call for me now.
if(system("mount -t nfs -o nolock 10.126.62.45:/vol/home/avinoba/Sky /mnt")==-1);
{
printf("ERROR: mount failed \n");
}
But still searching for the answer with mount() call as it accepts 'filesystemtype' argument as "nfs".
I have a problem with my Linux daemon program. It starts with root privileges, does some configuration, then permanently drops privileges by switching to some user and group and continues working. The switch to the non-privileged user is done like this:
void switch_to_user_group(std::string const& username, std::string const& groupname)
{
// Switch to user/group
gid_t gid = getgid();
if (!groupname.empty())
{
gid = get_group_id(groupname);
if (0 != setgid(gid))
{
std::cout << "Failed to switch to group " << gid << std::endl;
std::abort();
}
}
if (!username.empty())
{
uid_t uid = get_user_id(username);
if (initgroups(username.c_str(), gid) != 0)
{
std::cout << "initgroups failed" << std::endl;
std::abort();
}
if (0 != setuid(uid))
{
std::cout << "Failed to switch to user " << uid << std::endl;
std::abort();
}
}
}
The switch performs correctly, I can see the process in ps and top running under my user. The problem is that I can't attach to this process from gdb, even after it has dropped the privileges. The output is:
Attaching to process 15716
Could not attach to process. If your uid matches the uid of the target
process, check the setting of /proc/sys/kernel/yama/ptrace_scope, or try
again as the root user. For more details, see /etc/sysctl.d/10-ptrace.conf
ptrace: Operation not permitted.
I'm running gdb under the same user the process switched to, and I am able to attach to other processes that were initially started under under that user. I tried this on Kubuntu 13.10 (YAMA is disabled), Debian 6 and 7 with the same result.
So my questions are:
Why can't ptrace attach to a process that has the same effective and real UID as gdb?
Is it possible to drop privileges of my program in a way so that I can attach to it from the unprivileged gdb? How?
Thanks.
I found the solution on my own.
There is a 'dumpable' flag in the kernel for every process. When the process performs setuid or setgid (at least, in my case, when the process drops privileges) this flag gets cleared and normal users can't attach to this process with a debugger, and the process crashes also do not produce a crash dump. This is done for security reasons to protect any sensitive data obtained with elevated privileges that may be in the process memory.
To solve the problem the process can explicitly allow debugging by setting the 'dumpable' flag to 1.
prctl(PR_SET_DUMPABLE, 1);
This has to be done after the setgid/setuid calls.
I've got an application running as a Windows service that wants to read a file specified by a relative path. Since the service is running under C:\Windows\system32 (on Server 2003 and Windows 7), I figure it should be reading the file from there. However, the file read always fails.
I put together some simple test code to try to open a file for reading, using an absolute path. While the service succeeds for files such as C:\Temp\foo.txt, it always fails for files like C:\Windows\foo.txt and C:\Windows\system32\foo.txt . GetLastError() returns 2.
Am I running into an access issue? I couldn't find authoritative documentation on this. Is there any workaround?
Update:
The file test code is generic and straightforward:
std::ofstream out;
//...
std::string fileName("C:\\Windows\\system32\\Foo.txt");
hFile = CreateFile(fileName.c_str(), GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (hFile == INVALID_HANDLE_VALUE) {
out << "Could not create file handle! (" << GetLastError() << ")" << std::endl;
}
else {
out << "Successfully opened file!" << std::endl;
CloseHandle(hFile);
}
Try running the windows service from Local System account. By default the service may be running from "Network Service" account.
To change the settings, Open Windows Service Manager (Run-> services.msc) and double-click your service. On property window select 2nd Tab "Log On" and change it to run with Local System account.
Error code 2 is ERROR_FILE_NOT_FOUND so it's likelier that the path you give simply does not exist or the file does not exist in that path. Without the relevant flags from CreateFile it's hard to give you a better answer.
But generally - under default conditions - a service would be allowed to read in that folder.
One more thing came to mind. How do you obtain the path (C:\Windows in your case)? The proper means are to use the API (e.g. GetWindowsDirectory) for this and not hardcode it.