Where is code refers to /proc/PID/maps? - linux-kernel

I what to observe kernel code to print /proc/PID/maps but can't find this. Could anybody tell me where this code is located

The procfs code can be found in fs/proc/ subdirectory. If you open fs/proc/base.c, you can find two very similar arrays - tgid_base_stuff and tid_base_stuff. They both register file operations functions for files inside of /proc/PID/ and /proc/PID/TID/ respectivly. So you're more interested in the first one. Find the one that registers "maps" file, it looks like this:
REG("maps", S_IRUGO, proc_pid_maps_operations),
So the structure describing file operations on this file is called proc_pid_maps_operations. This function is defined in two places - fs/proc/task_mmu.c and fs/proc/task_nommu.c. Which one is actually used depends on your kernel configuration but it's most likely the first one.
Inside of task_mmu.c, you can find the structure definition:
const struct file_operations proc_pid_maps_operations =
{
.open = pid_maps_open,
.read = seq_read,
.llseek = seq_lseek,
.release = proc_map_release,
};
So when /proc/PID/maps is opened, the kernel will use pid_maps_open function, which registers another set of operations:
static const struct seq_operations proc_pid_maps_op = {
.start = m_start,
.next = m_next,
.stop = m_stop,
.show = show_pid_map
};
So you're interested in show_pid_map function, which only calls show_map function which in turn calls show_map_vma (all in the same file).

It's the show_pid_map() function in fs/proc/task_mmu.c (provided your system uses an MMU, which is the case of most non-embedded systems).
In general, the code for files under /proc/ can be cause under fs/procfs.

Related

storing a function that was retrieved from FunctionCallbackInfo

I'm pretty much trying to make a AddInputEvent but, after a month, can't find a way to turn a local "function from FunctionCallbackInfo"(i'll just call this argf) in to a Persistent Function so that garbage collection doesn't erase the pointers.
Most stakeoverflow threads and example code I can find just say to Cast argf with a Local Function; then to throw that in to a Persistent New. This results in a error: cannot convert 'v8::Local<v8::Function>' to 'v8::Function*'
here is the code, not completely sure why I can't convert it
class inputevnt_feld{
public:
char* call_on;
v8::Persistent<v8::Function> func;
};
int entvcount = -1;
vector<inputevnt_feld> event_calls; //this is pretty much a array of events that we can call later
// in js looks like this "AddInputEvent("string", function);"
void AddInputEvent( const v8::FunctionCallbackInfo<v8::Value>& args ) {
v8::HandleScope handle_scope(args.GetIsolate());
//gotta make sure that we ain't letting in some trojan horse that has nothing in it
if (args[1]->IsFunction() && args[0]->IsString()) {
inputevnt_feld newt;
//converts js string to char array
v8::String::Utf8Value str(args.GetIsolate(), args[0]);
const char* cstr = ToCString(str);
newt.call_on = (char*)cstr;
//here is where the problem is with function casting
v8::Local<v8::Function> callback = v8::Local<v8::Function>::Cast(args[1]);
newt.func = v8::Persistent<v8::Function>::New(args.GetIsolate(), callback);
//push the new stuff in to even array
event_calls.push_back(newt);
//getting vector array size is too much for my smol brain
//so I'ma just do this myself
entvcount++;
//cout << event_calls[entvcount].call_on << endl; //debug
}
}
Most stakeoverflow threads and example code I can find just say to Cast argf with a Local Function; then to throw that in to a Persistent New
Yes, that's correct. If you know how to read it, the C++ type system is your friend for figuring out the details.
If you look at the definition of v8::PersistentBase<T>::New, you'll see that it takes a T* (for its template type T). If you look at the v8::Local<T> class, you'll see that a way to get a T* from it is to use its operator*. That leads to:
v8::Local<v8::Function> callback = ...Cast(args[1]);
... = v8::Persistent<v8::Function>::New(..., *callback);
Alternatively, you can use the Persistent constructor directly, and pass it the Local without dereferencing it first:
v8::Local<v8::Function> callback = ...Cast(args[1]);
... = v8::Persistent<v8::Function>(..., callback);
Both options are entirely equivalent. Personally I'd prefer the latter as it takes slightly fewer characters to spell out, but that's really the only difference.
(Your current code as posted does something else: it ignores the result of the cast and passes the original args[1] directly to Persistent::New -- that's not going to work.)

How to get the timestamp of when a disk is made offline from diskmgmt or other ways in windows?

I want to know the time when a disk is made offline by user. Is there a way to know this through WMI classes or other ways?
If you cannot find a way to do it through the Win32 API/WMI or other, I do know of an alternate way which you could look into as a last-resort.
What about using NtQueryVolumeInformationFile with the FileFsVolumeInformation class? You can do this to retrieve the data about the volume and then access the data through the FILE_FS_VOLUME_INFORMATION structure. This includes the creation time.
At the end of the post, I've left some resource links for you to read more on understanding this so you can finish it off the way you'd like to implement it; I do need to quickly address something important though, which is that the documentation will lead you to
an enum definition for the _FSINFOCLASS, but just by copy-pasting it from MSDN, it probably won't work. You need to set the first entry of the enum definition to 1 manually, otherwise it will mess up and NtQueryVolumeInformationFile will return an error status of STATUS_INVALID_INFO_CLASS (because the first entry will be identified as 0 and not 1 and then all the entries following it will be -1 to what they should be unless you manually set the = 1).
Here is the edited version which should work.
typedef enum _FSINFOCLASS {
FileFsVolumeInformation = 1,
FileFsLabelInformation,
FileFsSizeInformation,
FileFsDeviceInformation,
FileFsAttributeInformation,
FileFsControlInformation,
FileFsFullSizeInformation,
FileFsObjectIdInformation,
FileFsDriverPathInformation,
FileFsVolumeFlagsInformation,
FileFsSectorSizeInformation,
FileFsDataCopyInformation,
FileFsMetadataSizeInformation,
FileFsMaximumInformation
} FS_INFORMATION_CLASS, *PFS_INFORMATION_CLASS;
Once you've opened a handle to the disk, you can call NtQueryVolumeInformationFile like this:
NTSTATUS NtStatus = 0;
HANDLE FileHandle = NULL;
IO_STATUS_BLOCK IoStatusBlock = { 0 };
FILE_FS_VOLUME_INFORMATION FsVolumeInformation = { 0 };
...
Open the handle to the disk here, and then check that you have a valid handle.
...
NtStatus = NtQueryVolumeInformationFile(FileHandle,
&IoStatusBlock,
&FsVolumeInformation,
sizeof(FILE_FS_VOLUME_INFORMATION),
FileFsVolumeInformation);
...
If NtStatus represents an NTSTATUS error code for success (e.g. STATUS_SUCCESS) then you can access the VolumeCreationTime (LARGE_INTEGER) field of the FILE_FS_VOLUME_INFORMATION structure with the FsVolumeInformation variable.
Your final task at this point will be using the LARGE_INTEGER field named VolumeCreationTime to gather proper time/date information. There are two links included at the end of the post which are focused on that topic, they should help you sort it out.
See the following for more information.
https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/content/ntifs/nf-ntifs-ntqueryvolumeinformationfile
https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/content/wdm/ne-wdm-_fsinfoclass
https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/content/ntddk/ns-ntddk-_file_fs_volume_information
https://msdn.microsoft.com/en-us/library/windows/desktop/ms724280.aspx
https://blogs.msdn.microsoft.com/joshpoley/2007/12/19/datetime-formats-and-conversions/

Linux character-device protection

I would like to protect my character device,from application operations.
I would like that only specific application can do operation on the device.
How can I do it?
Thanks
This may not be correct answer(Because I didn't test it). But I believe this will work.
I hope, you have idea about current field in task_struct which will give you the current PID of the process. Please refer this thread. how does current->pid work for linux?
so instead of pid, you can use comm field of task_struct.
http://lxr.free-electrons.com/source/include/linux/sched.h#L1180.
Keep an array of allowed application names in your driver. check comm field against allowed list during /dev/<yourchardriver> open() operation.
sample file operations structure.
struct file_operations fops = { /* these are the file operations provided by our driver */
.owner = THIS_MODULE, /*prevents unloading when operations are in use*/
.open = device_open, /*to open the device*/
.write = device_write, /*to write to the device*/
.read = device_read, /*to read the device*/
.release = device_close, /*to close the device*/
.llseek = device_lseek
};
when you call open("/dev/sampledrv") in user space, device_open() will be called in your driver. so these validation can be done here.

How to convert between shared_ptr<FILE> to FILE* in C++?

I am trying to use a FILE pointer multiple times through out my application
for this I though I create a function and pass the pointer through that. Basically I have this bit of code
FILE* fp;
_wfopen_s (&fp, L"ftest.txt", L"r");
_setmode (_fileno(fp), _O_U8TEXT);
wifstream file(fp);
which is repeated and now instead I want to have something like this:
wifstream file(SetFilePointer(L"ftest.txt",L"r"));
....
wofstream output(SetFilePointer(L"flist.txt",L"w"));
and for the function :
FILE* SetFilePointer(const wchar_t* filePath, const wchar_t * openMode)
{
shared_ptr<FILE> fp = make_shared<FILE>();
_wfopen_s (fp.get(), L"ftest.txt", L"r");
_setmode (_fileno(fp.get()), _O_U8TEXT);
return fp.get();
}
this doesn't simply work. I tried using &*fp instead of fp.get() but still no luck.
You aren't supposed to create FILE instances with new and destroy them with delete, like make_shared does. Instead, FILEs are created with fopen (or in this case, _wfopen_s) and destroyed with fclose. These functions do the allocating and deallocating internally using some unspecified means.
Note that _wfopen_s does not take a pointer but a pointer to pointer - it changes the pointer you gave it to point to the new FILE object it allocates. You cannot get the address of the pointer contained in shared_ptr to form a pointer-to-pointer to it, and this is a very good thing - it would horribly break the ownership semantics of shared_ptr and lead to memory leaks or worse.
However, you can use shared_ptr to manage arbitrary "handle"-like types, as it can take a custom deleter object or function:
FILE* tmp;
shared_ptr<FILE> fp;
if(_wfopen_s(&tmp, L"ftest.txt", L"r") == 0) {
// Note that we use the shared_ptr constructor, not make_shared
fp = shared_ptr<FILE>(tmp, std::fclose);
} else {
// Remember to handle errors somehow!
}
Please do take a look at the link #KerrekSB gave, it covers this same idea with more detail.

A particular C programming style problem?

I have heard a lot about the importance of programming style. In my opinion, indention is easy to deal with. But other things frustrated me a lot. Considering a particular example to demonstrate the use of inet_makeaddr.
/* demonstrate the use of host address functions */
#include <stdio.h>
#include <arpa/inet.h>
#include <netinet/in.h>
int
main(void)
{
/* inet_makeaddr demo */
uint32_t neta = 0x0a3e5500;
uint32_t hosta = 0x0c;
struct in_addr alla = inet_makeaddr(neta, hosta);
printf("makeaddr of net: %08x and host: %08x = %08x\n",
neta, hosta, alla);
return 0;
}
Somebody may want to write as follows:
uint32_t neta;
uint32_t hosta;
struct in_addr alla;
neta = 0x0a3e5500;
hosta = 0x0c;
alla = inet_makeaddr(neta, hosta);
Then others may always initialize the variable when defined:
uint32_t neta = 0;
uint32_t hosta = 0;
struct in_addr alla = {0};
neta = 0x0a3e5500;
hosta = 0x0c;
alla = inet_makeaddr(neta, hosta);
Is any one of these better than the other ones, or it is just a personal taste?
I think the first of the three examples is the best: the second example one has uninitialized variables, and the third example has variables initialized to a meaningless (zero) value. I prefer to initialize variables (with a meaningful value) as soon as I define them (so that I don't have uninitialized variables). See also Should Local Variable Initialisation Be Mandatory?
I like to initialize values when defining. At least you know you won't have any "silly" NULL reference errors.
The bottom one has the small advantage that even if you change the code so that the initialization is no longer performed, you'll never have garbage in the variables, but only zeros. The top one has the same advantage though. My own preference in C is for functions to be extremely short, so that you never have to worry about those kinds of things, so I use the top form or the second form. But if your functions are long-winded, initializing everything to zero might be the way to go.
Personally I define the variables close to the function call if they are interesting for the function call. If it is an uninteresting variable I usually define it it in the declaration.
It is usually always better to initialise variables in any language. Somehow it's just oen of those little things that make your life easier, just like leaving a trailing comma.
Although if you are going to initialise your variables it's probably best to do it with a value that means something to your algorithm, otherwise you're not solving anything, just changing the way everything behaves when you create a bug.

Resources