LinuxQuestions.org
Review your favorite Linux distribution.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Linux Forums > Linux - General
User Name
Password
Linux - General This Linux forum is for general Linux questions and discussion.
If it is Linux Related and doesn't seem to fit in any other forum then this is the place.

Notices


Reply
  Search this Thread
Old 07-14-2016, 03:08 PM   #1
RickCheung
LQ Newbie
 
Registered: Oct 2012
Posts: 14

Rep: Reputation: Disabled
How does a system call restore the user level registers when it finishes executing?


In Linux (kernel 3.14.4), a process usually has two stacks - the user level stack and the kernel stack. When a system call is invoked in the process, the OS will first push the current registers into the kernel stack, and then switch to the kernel stack to execute the system call. When the system call finishes, the values of the registers that were previously pushed into the kernel stack will be poped out and restored to the corresponding registers, so that the user level process can continue executing. (correct me if I am wrong)

In the following code, the function main() invoked a system call, and printed out the value of the user level register RSP (pointing to the top of the stack) before and after the system call. Normally, rsp_beofer equals to rsp_after in this case.

I wanted to see whether a system call can change the user level RSP. Therefore, inside the system call, I first validated that the RSP of the user stack was on the kernel stack. Then I modified the value of RSP (decrease it by 0x10) on the kernel stack. I was expecting that rsp_before is 0x10 larger than rsp_after. However, it turned out rsp_before is still equal to rsp_after.

I am wondering why these two values are still equal even after I modifed the user level RSP in the system call? How does a system call restore the user level registers when it finishes executing?


------------code------------
int main(void){
#define __syscall_clobber "r11","rcx","memory"
#define __syscall "syscall"
long ret;

register unsigned long rsp_before asm("rsp");
printf("rsp_before = %p\n", (unsigned long *)rsp_before);

/*invoke the system call, in which the value of user level RSP on the kernel stack is decreased by 0x10*/
__asm__ volatile
(
__syscall
: "=a" (ret)
: "0" (316) : __syscall_clobber
);

register unsigned long rsp_after asm("rsp");
printf("rsp_after = %p\n", (unsigned long *)rsp_after);

}

/*syscall 316*/
asmlinkage long syscall_316(void)
{
/*get the bottom of current kernel stack*/
register unsigned long rbp asm("rbp");

/*the user level RBP is stored at '(unsigned long *)rbp + 15'*/
*((unsigned long *)rbp + 15) = *((unsigned long *)rbp + 15) - 0x10;

return 0;
}
 
Old 07-14-2016, 08:00 PM   #2
sundialsvcs
LQ Guru
 
Registered: Feb 2004
Location: SE Tennessee, USA
Distribution: Gentoo, LFS
Posts: 10,642
Blog Entries: 4

Rep: Reputation: 3933Reputation: 3933Reputation: 3933Reputation: 3933Reputation: 3933Reputation: 3933Reputation: 3933Reputation: 3933Reputation: 3933Reputation: 3933Reputation: 3933
Kindly remember that (no matter what the architecture), "user-land can never affect kernel-land!"

Likewise, "kernel-land behavior" cannot (or, rather, should not [elect to] ...) "affect user-land."

No matter what the user-side may attempt to do, "before the system call is made," it cannot possibly affect the kernel stack.

ln like manner, the kernel-side code should not (exercise its Sovereign Kernel Prerogatives™ to ...) meddle-with the user-land view of things.

And ... "no kernel code should presume that it is actually executing on "an x86," versus, say, "what used to be called 'a System/370 ...'"

The user-side code "commits an irrevocable act" by executing a system call. By doing so, "it hands-over all of the car-keys." It actually has no idea "what happens next," and in any case it has no influence over it. System-side code ought make no assumptions with regard to what user-side code has done: neither should it in any way trust(!) it.

Certainly, (IMHO ...) a grave concern, here, is that it would seem (to me) that "the kernel-side does trust the user." Not good. The kernel should probably always presume that the user is a L33T H4X0R ...

Last edited by sundialsvcs; 07-14-2016 at 08:06 PM.
 
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
Nice system call for non root user ramachandra reddy Linux - Kernel 2 02-09-2015 11:52 PM
ShellScrtips that run at Different System/User Level Events Hi_This_is_Dev Linux - Newbie 3 05-15-2009 06:53 AM
mksysb restore - Wrong OS level for restore pobman AIX 0 12-10-2008 09:32 PM
System call and registers Berhanie Programming 2 12-14-2006 06:30 PM
Half life level finishes loading but screen doesn't refresh! CPUFreak91 Linux - Games 9 08-05-2005 09:44 PM

LinuxQuestions.org > Forums > Linux Forums > Linux - General

All times are GMT -5. The time now is 10:27 PM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration