2006-09-12 12:05:48

by guest01

[permalink] [raw]
Subject: OT: calling kernel syscall manually

Hi

Sorry guys, this question is a little bit off topic, but maybe someone
has an answer, I am sure that there is a simple one. :-)

Ok, I have to find 3 possibilities to create a directory with 3 small c
programs:
1 -> using libc: mkdir(dir,mode)
2 -> using libcsyscall: syscall(__NR_mkdir, "mkdirLibcSyscall", 0777);
3 -> using kernel directly

Ok, the third one is a little bit tricky, at least for me. I found an
example for lseek, but I don't know how to convert that for mkdir. I
don't know the necessary arguments, ..

> #include <linux/unistd.h>
>
> _syscall5(int, _llseek, unsigned int, fd,
> unsigned long, offset_high, unsigned long, offset_low,
> long long *, result, unsigned int, origin)
>
> long long
> my_llseek(unsigned int fd, unsigned long long offset, unsigned int origin) {
> long long result;
> int retval;
>
> retval = _llseek (fd, offset >> 32, offset & 0xffffffff,
> &result, origin);
> return (retval == -1) ? -1 : result;
> }

Any help would be much appreciated. Thxs

regards
peda


2006-09-12 13:34:29

by David Woodhouse

[permalink] [raw]
Subject: Re: OT: calling kernel syscall manually

On Tue, 2006-09-12 at 14:05 +0200, guest01 wrote:
> Hi
>
> Sorry guys, this question is a little bit off topic, but maybe someone
> has an answer, I am sure that there is a simple one. :-)
>
> Ok, I have to find 3 possibilities to create a directory with 3 small c
> programs:
> 1 -> using libc: mkdir(dir,mode)
> 2 -> using libcsyscall: syscall(__NR_mkdir, "mkdirLibcSyscall", 0777);
> 3 -> using kernel directly
>
> Ok, the third one is a little bit tricky, at least for me. I found an
> example for lseek, but I don't know how to convert that for mkdir. I
> don't know the necessary arguments, ..

The third one has always been broken on i386 for PIC code and was
pointless anyway, since glibc provides this functionality. The kernel
method has been removed from userspace visibility all architectures, and
we plan to remove it entirely in 2.6.19 since it's not at all useful.

However, there was a patch which was sneaked to Linus in private which
reverted that cleanup on i386 and x86_64 and made them visible again --
but they'll be going away again on those two architectures shortly;
hopefully before 2.6.18.

Don't bother with it -- just use glibc's syscall().

--
dwmw2

2006-09-12 14:31:46

by guest01

[permalink] [raw]
Subject: Re: OT: calling kernel syscall manually

David Woodhouse wrote:
> The third one has always been broken on i386 for PIC code and was
> pointless anyway, since glibc provides this functionality. The kernel
> method has been removed from userspace visibility all architectures, and
> we plan to remove it entirely in 2.6.19 since it's not at all useful.
>
> However, there was a patch which was sneaked to Linus in private which
> reverted that cleanup on i386 and x86_64 and made them visible again --
> but they'll be going away again on those two architectures shortly;
> hopefully before 2.6.18.
>
> Don't bother with it -- just use glibc's syscall().
>

Thx for the fast reply. I wouldn't use the third method (3 -> using
kernel directly) in one of my projects, but I have to try each one of
the three methods for a small assignment (unfortunately, not every
assignment is very useful at a university :-))
So, I would be very grateful if you have some code snippets or further
information for me about method #3.

thx again
regards
Peda


2006-09-12 14:37:56

by David Woodhouse

[permalink] [raw]
Subject: Re: OT: calling kernel syscall manually

On Tue, 2006-09-12 at 16:31 +0200, guest01 wrote:
> Thx for the fast reply. I wouldn't use the third method (3 -> using
> kernel directly) in one of my projects, but I have to try each one of
> the three methods for a small assignment (unfortunately, not every
> assignment is very useful at a university :-))
> So, I would be very grateful if you have some code snippets or further
> information for me about method #3.

Method #3 no longer exists.

--
dwmw2

2006-09-12 20:25:10

by Phillip Susi

[permalink] [raw]
Subject: Re: OT: calling kernel syscall manually

What do you mean you have removed the ability to make system calls
directly? That makes no sense. Glibc has to be able to make system
calls so you can write your own code that does the same thing if you want.

For the OP: you might want to study the glibc sources to see how it
implements syscall, and mimic that. IIRC it involves making an int 80
call on i386.

David Woodhouse wrote:
> The third one has always been broken on i386 for PIC code and was
> pointless anyway, since glibc provides this functionality. The kernel
> method has been removed from userspace visibility all architectures, and
> we plan to remove it entirely in 2.6.19 since it's not at all useful.
>
> However, there was a patch which was sneaked to Linus in private which
> reverted that cleanup on i386 and x86_64 and made them visible again --
> but they'll be going away again on those two architectures shortly;
> hopefully before 2.6.18.
>
> Don't bother with it -- just use glibc's syscall().
>

2006-09-12 20:46:38

by Miguel Ojeda

[permalink] [raw]
Subject: Re: OT: calling kernel syscall manually

On 9/12/06, Phillip Susi <[email protected]> wrote:
> What do you mean you have removed the ability to make system calls
> directly? That makes no sense. Glibc has to be able to make system
> calls so you can write your own code that does the same thing if you want.
>

Well, they removed the EXPORT_SYMBOL_GPL(sys_call_table);

http://www.cs.helsinki.fi/linux/linux-kernel/2003-18/0173.html

You can still found syscall addresses with some "tricks".

2006-09-12 22:03:49

by Arnd Bergmann

[permalink] [raw]
Subject: Re: OT: calling kernel syscall manually

On Tuesday 12 September 2006 22:25, Phillip Susi wrote:
>
> What do you mean you have removed the ability to make system calls
> directly? ?That makes no sense. ?Glibc has to be able to make system
> calls so you can write your own code that does the same thing if you want.

the header file <asm/unistd.h> that used to provide the necessary _syscallX()
macros doesn't do that any more. You can still use your own copy of the
macros though, like every libc does internally.

> For the OP: you might want to study the glibc sources to see how it
> implements syscall, and mimic that. ?IIRC it involves making an int 80
> call on i386.
>

char *pathname = "/tmp/dir";
int mode = 0644;
int result;
__asm__ volatile ("push %%ebx ; movl %2,%%ebx ; int $0x80 ; pop %%ebx"
: "=a" (result)
: "0" (__NR_mkdir),"ri" (pathname),"c" (mode)
: "memory");

Understanding that inline assembly in detail is beyond what most people
do at university, but interesting nonetheless.

Arnd <><

2006-09-12 22:44:24

by David Woodhouse

[permalink] [raw]
Subject: Re: OT: calling kernel syscall manually

On Tue, 2006-09-12 at 16:25 -0400, Phillip Susi wrote:
> What do you mean you have removed the ability to make system calls
> directly? That makes no sense. Glibc has to be able to make system
> calls so you can write your own code that does the same thing if you want.

No. If you do the inline assembly (or call the vDSO) yourself of course
it's still possible.

However, the _example_ that the OP gave of this 'third one' was in fact
using the old _syscallX() macros which used to be found in the kernel's
private header files. So I assumed that's what he meant, rather than
open-coding his own inline assembly.

--
dwmw2

2006-09-13 05:35:11

by Albert Cahalan

[permalink] [raw]
Subject: Re: OT: calling kernel syscall manually

David Woodhouse writes:
> On Tue, 2006-09-12 at 14:05 +0200, guest01 wrote:

>> 3 -> using kernel directly
>>
>> Ok, the third one is a little bit tricky, at least for me.
>> I found an example for lseek, but I don't know how to convert
>> that for mkdir. I don't know the necessary arguments, ..
>
> The third one has always been broken on i386 for PIC code

No, I was just using it today in PIC i386 code.
The %ebx register gets pushed, the needed value
gets moved into %ebx, the int 0x80 is done, and
the %ebx register gets popped. Only a few odd
calls like clone() need something different.

(not that this should be needed: gcc is broken
if it can't save/restore the needed registers)

> and was pointless anyway, since glibc provides this
> functionality. The kernel method has been removed from
> userspace visibility all architectures, and we plan to
> remove it entirely in 2.6.19 since it's not at all useful.

It's damn useful. Hint: Linux does not require glibc.

I could hack up my own assembly. I did that for clone(),
but I didn't enjoy that waste of my time.

2006-09-13 06:55:54

by David Woodhouse

[permalink] [raw]
Subject: Re: OT: calling kernel syscall manually

On Wed, 2006-09-13 at 01:35 -0400, Albert Cahalan wrote:
> > The third one has always been broken on i386 for PIC code
>
> No, I was just using it today in PIC i386 code.
> The %ebx register gets pushed, the needed value
> gets moved into %ebx, the int 0x80 is done, and
> the %ebx register gets popped. Only a few odd
> calls like clone() need something different.

That's a very recent change -- it was broken for years before that.

> > and was pointless anyway, since glibc provides this
> > functionality. The kernel method has been removed from
> > userspace visibility all architectures, and we plan to
> > remove it entirely in 2.6.19 since it's not at all useful.
>
> It's damn useful. Hint: Linux does not require glibc.

Are you being deliberately obtuse or is it just a natural talent?

Other C libraries also provide syscall() -- at least dietlibc and uClibc
do.

Kernel headers do not exist to provide a library of random crap for
userspace to use.

--
dwmw2

2006-09-13 15:52:59

by Albert Cahalan

[permalink] [raw]
Subject: Re: OT: calling kernel syscall manually

On 9/13/06, David Woodhouse <[email protected]> wrote:
> On Wed, 2006-09-13 at 01:35 -0400, Albert Cahalan wrote:
> > > The third one has always been broken on i386 for PIC code
> >
> > No, I was just using it today in PIC i386 code.
> > The %ebx register gets pushed, the needed value
> > gets moved into %ebx, the int 0x80 is done, and
> > the %ebx register gets popped. Only a few odd
> > calls like clone() need something different.
>
> That's a very recent change -- it was broken for years before that.

It's fixed now. Obviously people care. Probably the
only reason it wasn't fixed earlier is that PIC code
just isn't all that popular for i386 executables.

> > > and was pointless anyway, since glibc provides this
> > > functionality. The kernel method has been removed from
> > > userspace visibility all architectures, and we plan to
> > > remove it entirely in 2.6.19 since it's not at all useful.
> >
> > It's damn useful. Hint: Linux does not require glibc.
>
> Are you being deliberately obtuse or is it just a natural talent?
>
> Other C libraries also provide syscall() -- at least dietlibc and uClibc
> do.

OK, but I don't need to be using a C library. I could write
my own or do without.

> Kernel headers do not exist to provide a library of random crap for
> userspace to use.

Sure, but this is existing functionality. It also isn't random crap;
it's the kernel's system call interface.

2006-09-13 16:52:13

by guest01

[permalink] [raw]
Subject: Re: OT: calling kernel syscall manually

David Woodhouse wrote:
> However, the _example_ that the OP gave of this 'third one' was in fact
> using the old _syscallX() macros which used to be found in the kernel's
> private header files. So I assumed that's what he meant, rather than
> open-coding his own inline assembly.
>

Yes, indeed. I think we should use the _syscallX() macro, but
nevertheless I like the inline assembly example :-)

So these macros are no longer available in the latest kernel versions?
Ok, if that's true, I will use the example with the inline assembler
code and write a few lines, that these "macros" are no longer supported.

thxs


2006-09-13 17:53:23

by David Woodhouse

[permalink] [raw]
Subject: Re: OT: calling kernel syscall manually

On Wed, 2006-09-13 at 18:52 +0200, guest01 wrote:
> So these macros are no longer available in the latest kernel versions?
> Ok, if that's true, I will use the example with the inline assembler
> code and write a few lines, that these "macros" are no longer supported.

Yes, as part of the cleanups which accompanied the new 'make
headers_install' target for creating sanitised kernel headers, all of
the _syscallX() stuff was removed from user visibility.

Unfortunately, Linus subsequently applied a patch which was sent to him
privately without review on the mailing list, which reverted that fixup
and made _syscallX() visible in userspace again on a couple of
architectures. That regressions should hopefully be fixed again before
2.6.18 is finally released though -- and in fact we're probably going to
kill off _all_ use of _syscallX(), even in the kernel, before 2.6.19.

--
dwmw2