Re: EPERM for CTLFLAG_ANYBODY sysctl.
Re: EPERM for CTLFLAG_ANYBODY sysctl.
- Subject: Re: EPERM for CTLFLAG_ANYBODY sysctl.
- From: "Maxim Zhuravlev" <email@hidden>
- Date: Wed, 20 Aug 2008 17:40:56 +0400
> Hi, all.
>
> Could you give me a hint, why do I get an EPERM error from
> sysctlbyname() for a write attempt to a sysctl of a type:
>
> SYSCTL_PROC (
> _kern,
> OID_AUTO,
> my_name,
> CTLTYPE_OPAQUE | CTLFLAG_WR | CTLFLAG_ANYBODY | CTLFLAG_KERN,
> 0,
> 0,
> sysctl_handler, // my handler
> "S",
> ""
> );
>
> The sysctl is registered from within a kext.
>
> I get EPERM error for non-root processes, while it works fine for root
> processes.
> Shouldn't CTLFLAG_ANYBODY flag make it possible for non-root processes
> to write to the sysctl?
>
> Thanks in advance,
> - Maxim.
>
Here goes some sample code that illustrates:
<Kernel Extension Code>
#include <mach/mach_types.h>
#include <sys/sysctl.h>
static int sysctl_handler SYSCTL_HANDLER_ARGS;
SYSCTL_PROC (
_kern, // parent OID
OID_AUTO, // sysctl number,
OID_AUTO means we're only accessible by name
my_custom_sysctl, // our name
CTLTYPE_OPAQUE | CTLFLAG_WR | CTLFLAG_ANYBODY , // we're an
opaque data structure
0,
0,
sysctl_handler, // our handler
"S", // because that's
what CTLTYPE_OPAQUE does
"" // just a comment
);
static int sysctl_handler SYSCTL_HANDLER_ARGS
{
int ctlmsg;
int error = 0;
printf( "entered sysctl_handler" );
error = sysctl_handle_opaque( oidp, &ctlmsg, sizeof( int ), req);
if ( error || !req->newptr )
{
printf( "error while sysctl_handle_opaque" );
}
printf( "got %d", ctlmsg );
return error;
}
kern_return_t KextSysctlTest_start (kmod_info_t * ki, void * d) {
sysctl_register_oid( &sysctl__kern_my_custom_sysctl );
return KERN_SUCCESS;
}
kern_return_t KextSysctlTest_stop (kmod_info_t * ki, void * d) {
sysctl_unregister_oid( &sysctl__kern_my_custom_sysctl );
return KERN_SUCCESS;
}
<Userland Clien Code>
#include <sys/types.h>
#include <sys/sysctl.h>
#include <stdio.h>
#include <errno.h>
int main ( void )
{
int error = 0, val = 2;
printf ( "writing %d to kern.my_custom_sysctl", val );
if ( ( error = sysctlbyname( "kern.my_custom_sysctl", NULL, 0, &val, si$
printf ( "got an error \"%s\"", strerror(errno) );
}
<Output>
$./testsysctl
userland output:
writing 2 to kern.my_custom_sysctl
got an error "Operation not permitted"
kext output:
$ sudo ./testsysctl
userland output:
writing 2 to kern.my_custom_sysctl
kext output:
entered sysctl_handler
got 2
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Darwin-kernel mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden