I'm trying to use gate_desc *idt_table in a kernel module. The set_trap_gate() function defined in desc.h uses this pointer. In desc.h is also a definition : extern gate_desc idt_table[].
I tried different things:
use idt_table in my module without definition or affectation
affect idt_table with my (valid) idt_table address
I get either an id_table undefined warning during compilation or incomplete type for idt_table.
creating a new var named for instance gate_desc *it = (gate_desc *)#; And copy the set_trap_gate, set_gate, write_idt_entry, pack_gate functions from sched.h to my module file (renaming them, and using it instead of idt_table). This compiles fine but when inserting my module I get an unknown symbol in module (ret -1) error.
(there is no reference in my module to idt_table, and the functions I use from sched do use my variable).
I tried to see where in the files included by sched.h was defined idt_table, but couldn't find it!
Does someone know how I could use, the idt_table pointer from sched.h (affecting it with the corrct address) or create a new pointer?
Theoretically, you could implement a non-init-section set_trap_gate() via:
void set_trap_gate(int n, void *addr)
{
struct { uint16_t lim; struct desc_struct *idt_table; }
__attribute__((packed)) idt;
__asm__ ("sidt %0" : : "m"(idt) : "memory");
_set_gate(idt.idt_table + n, 15, 0, addr);
}
But that'd be CPU-local, i.e. it's not guaranteed to modify any other IDT but the one of the CPU it's running on. Also, it might fall foul of writeprotected memory.
What exactly is it you're trying to achieve ?
Related
I am trying to compile one driver in VS, but it shows -
Severity Code Description Project File Line Suppression State
Error LNK2019 unresolved external symbol __imp__PsGetProcessWow64Process#4 referenced in function _GetProcessModule#8 Garhal C:\Users\Raitis\source\repos\GarHal_CSGO\Garhal\memory.obj 1
Quickly enough, I found a place, where this PsGetProcessWow64Process is being used https://prnt.sc/uffavf
But it is defined, and it's even an official ntos.h function. Just pressing F12 on it finds it easily - https://prnt.sc/uffbjg
Screenshot from error list - https://prnt.sc/uffc6t
The problem is that this in undocumented functions and the linker is having a hard time finding where is the function to put a pointer to it in the generated binary, so first include ntifs.h before ntddk.h like this
#include <ntifs.h>
#include <ntddk.h>
it must be before ntddk or you will get weird errors
then add this line :
NTKERNELAPI PVOID PsGetProcessWow64Process(__in PEPROCESS Process);
which is the signature of the function and now you are ready to call that function
another way to get it is using function pointers and resolving it at run time
#include <ntddk.h>
typedef struct _PEB32 {
UCHAR InheritedAddressSpace;
UCHAR ReadImageFileExecOptions;
UCHAR BeingDebugged;
UCHAR Spare;
ULONG Mutant;
ULONG ImageBaseAddress;
ULONG/*PPEB_LDR_DATA32*/ Ldr;
} PEB32, *PPEB32;
typedef PPEB32 (NTAPI * pfn_PsGetProcessWow64Process) (PEPROCESS Process);
pfn_PsGetProcessWow64Process PsGetProcessWow64Process = NULL;
RtlInitUnicodeString (&usFunctionName, L"PsGetProcessWow64Process");
PsGetProcessWow64Process = (pfn_PsGetProcessWow64Process) (SIZE_T)MmGetSystemRoutineAddress (&usFunctionName);
pPEB32 = PsGetProcessWow64Process (pEProcess);
I have 3 files in my directory:
ex22.h, ex22.c. ex22_main.c
ex22.h:
#ifndef _ex22_h
#define _ex22_h
extern double* v;
...
#endif
ex22.c:
#include <stdio.h>
#include "ex22.h"
double* v;
/*a function that accepts a new_variable, changes a
static variable inside of it while keeping track of
what the static variable was before the change. The
purpose of the function is to update the static
variable and print what it was right before the
updating.*/
double update_variable(double new_variable)
{
static double variable = 1.0;
double old_variable = variable;
variable = new_variable;
v = &variable;
return old_variable;
}
...
ex22_main.c:
#include "ex22.h"
#include "dbg.h"
...
int main(void)
{
//test if it is possible
printf("Variable at first: %f", update_variable(2.0);
printf("Access 'variable' inside update_variable: %f", *v);
}
Compiller (ubuntu) gives me those error messages:
cc ex22_main.c -o ex22_main
/tmp/ccGLFiXP.o: In function `main':
...
ex22_main.c:(.text+0x1f4): undefined reference to `update_variable'
ex22_main.c:(.text+0x222): undefined reference to `r'
collect2: error: ld returned 1 exit status
<builtin>: recipe for target 'ex22_main' failed
make: *** [ex22_main] Error 1
Hope you understood what I'm trying to achieve. My goal is to access the static variable inside a function (which is not possible) by making a pointer to it. I'm just curious if it works that way?
EDIT:
There were some stupid bugs in my code but the idea of accessing a static variable inside a function by it's pointer is completely feasible.
Avoid my mistakes:
1) Make sure files are linked
2) Watch out for variable names
My goal is to access the static variable inside a function (which is not possible) by making a pointer to it. I'm just curious if it works that way?
Yes, it does. static has a different meaning for variables declared inside functions than for those declared at file scope, but but both varieties exist and have the same address for the entire lifetime of the program. A pointer to such a variable can be used to access its value anywhere in the program, without regard to whether the variable can be accessed via its declared identifier at the point of access-via-pointer.
Your compilation issue is unrelated. Your other answer explains the nature of that problem.
The compiler, or more precisely the linker, can't find the definitions of update_variable or r because you didn't compile and link ex22.c which contains those definitions.
You need to compile both files and link them together.
cc -o ex22_main ex22_main.c ex22.c
Linux Kernel 5.0.0-37
I'm writing a function to manage permissions to be provided as a function pointer to the struct inode_operations. Here is a simplified stub implementation:
#include <linux/cred.h>
int pfsw_permission(struct inode *ino, int op){
if(uid_eq(INIT_USER->uid, get_current_user()->uid)){
printk(KERN_INFO "Current user is root\n");
} else {
printk(KERN_INFO "Current user is not root\n");
}
if(op & (MAY_READ | MAY_WRITE)){
return 0;
}
return -EACCES;
}
when compiling a kernel module containing this function and trying to load it dmesg shows the following error:
Unknown symbol root_user (err -2)
This I think is due to INIT_USER macro coming from include/linux/sched/user.h which is defined as
extern struct user_struct root_user;
#define INIT_USER (&root_user)
QUESTION: Why is the symbol root_user declared, but not defined? How to use INIT_USER correctly?
root_user does not seem to be exported using EXPORT_SYMBOL by the linux kernel; therefore you cannot use it from a module.
Looking at its definition we can see that the uid value is set to GLOBAL_ROOT_UID. This is a macro defined in include/linux/uidgid.h and is basically just a type cast of 0 to kuid_t so you can use just that macro if all you need is the UID.
So ...
Why is the symbol root_user declared, but not defined?
The symbol is defined. It's not exported though so you cannot use it from a module.
How to use INIT_USER correctly?
"Not". You cannot use it.
The Problem
On a personal project of mine, I have a struct defined in a UART abstraction library (let's call it UART.c and UART.h)I made for an AVR.
In UART.h:
typedef struct ST_UARTRX_MESSAGECONTENTS{
uint8_t u_command[3]; //Command
uint32_t u32_value; //Parameter for Command
boolean b_newValue; //Is there new value written here
boolean b_Error; //Is there an error with this message
} ST_UARTRX_MESSAGECONTENTS;
volatile ST_UARTRX_MESSAGECONTENTS st_uartRX_MessageContents;
So basically it's a structure that holds a UART message, it has a "b_newValue" that's a flag for when a new message is received. A message is "received" when the AVR receives a new line "\n".
In the header file of another file (let's call "foo.h"): I include my "UART abstraction library" and put this in the header:
extern volatile ST_UARTRX_MESSAGECONTENTS st_uartRX_MessageContents;
But then in foo.c, I try to access the "b_newValue":
if(st_uartRX_MessageContents.b_newValue){
st_uartRX_MessageContents.b_newValue = TRUE;
fsm_state = ST_STOREMACRO;
}
But the "if" is never entered even if my debugger says the struct value is indeed true:
You can see I have breaked at the if statement. If I hit "Step", it just skips over it and doesn't enter!
Boolean typedef for reference:
typedef enum{FALSE, TRUE} boolean;
Some things I've tried
When I look at the compiled ASM code, I see that general purpose register R24 is used to load the b_newValue, but it loads 0x00, not 0x01 like I'd expect.
uartTX_sendArray(st_uartRX_MessageContents.u_command, sizeof st_uartRX_MessageContents.u_command);
delay_ms(2000);
if(st_uartRX_MessageContents.b_newValue){
st_uartRX_MessageContents.b_newValue = TRUE;
fsm_state = ST_STOREMACRO;
}
I used my "UART: send this array" function to send the ascii "command" from the same structure, and it works! I have no idea why my foo.c can see the "command" but not the "b_newValue".
I've been ripping my hair out for hours. Thanks for looking.
Judging by what you posted now, you have your struct object defined in the header file UART.h
volatile ST_UARTRX_MESSAGECONTENTS st_uartRX_MessageContents;
That's formally illegal (if you include UART.h into multiple translation units) and is generally not a good idea even if some compilers accept it as an extension. I would suggest you move the above definition into a UART.c file and place a non-defining declaration
extern volatile ST_UARTRX_MESSAGECONTENTS st_uartRX_MessageContents;
into UART.h.
I'm writing a device driver in MSVC. As part of design I want to have different modules but have the modules somewhat isolated from each other so that they are interchangeable in the future. My design has a structure with the following declaration
typedef struct tagMODULE_INTERFACE {
NTSTATUS (*initialize)(GLOBAL_DATA *pGD);
NTSTATUS (*shutdown)(void);
NTSTATUS (*sendResponse)(PVOID outBuf, ULONG outBufSz, PULONG outBufLen);
} MODULE_INTERFACE, *PMODULE_INTERFACE;
In the main .c file I have my main array of modules to load at install time. It is defined as such:
MODULE_INTERFACE modules[2] =
{
Module1,
{NULL, NULL, NULL}// terminal entry
};
In my module1.c file I expose the following:
CONST MODULE_INTERFACE Module1 = {initializeModule1, shutdownModule1, sendModule1Response};
In my module1.h file I have:
extern CONST MODULE_INTERFACE Module1;
The idea here is that I don't have to declare initializeModule1, shutdownModule1 and sendModule1Response functions outside of module1.c, but the main.c will have an array of function pointers to use to initialize, shutdown and callback whenever necessary.
My problem is that I'm getting a C2099 "initialize is not a constant" error for the Module1 entry in modules and I'm getting C2078 "too many initializers" for the {NULL, NULL, NULL} entry.
What am I missing here? I thought originally that if I ensured that module1.c compiled ahead of main.c it would solve the first problem, but it didn't.
Any help would be greatly appreciated.