bug-hurd
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

looking for the solution of rootless subhurd


From: Da Zheng
Subject: looking for the solution of rootless subhurd
Date: Sun, 23 Nov 2008 21:45:03 +0000
User-agent: Thunderbird 2.0.0.17 (Macintosh/20080914)

Hello everyone,

I am trying to make subhurd run without root's permission.
AFAIK, the reason that subhurd needs the root's permission is that the subhurd needs the master device port and privileged host port, and the current implementation gets the real ones from mach. It's relatively easy to handle the master device port and boot has already done part of the work (it gives the subhurd a pseudo master device port and acts as a device proxy itself). The device proxy can access some real devices with the help of other translators. As long as the user has the permission to access the device file, it should work fine.

However, the same method cannot apply to the privileged host port.
As I understand, the privileged host port is used to communicate with the kernel and manipulate the host. Again I can give the subhurd a pseudo one, create a host proxy, and implement the server side of RPC. The RPCs directly involved to the privileged host port are:
routine vm_set_default_memory_manager(
               host_priv       : host_priv_t;
       inout   default_manager : mach_port_make_send_t);
       hurd/boot/boot.c <<main>>
       hurd/libdiskfs/init-init.c <<diskfs_init_diskfs>>
       hurd/mach-defpager/main.c <<main>>
       hurd/serverboot/default_pager.c <<default_pager_initialize>>
       hurd/sutils/swapon.c <<swaponoff>>
       hurd/tmpfs/tmpfs.c <<main>>
       hurd/trans/proxy-defpager.c <<main>>
       hurd/utils/vmstat.c <<ensure_def_pager_info>>

routine host_adjust_time(
               host_priv       : host_priv_t;
       in      new_adjustment  : time_value_t;
       out     old_adjustment  : time_value_t);

routine host_get_boot_info(
               host_priv       : host_priv_t;
       out     boot_info       : kernel_boot_info_t);

routine host_reboot(
               host_priv       : host_priv_t;
               options         : int);
       hurd/init/init.c
       hurd/serverboot/bootstrap.c
       hurd/serverboot/panic.c
routine host_set_time(
               host_priv       : host_priv_t;
               new_time        : time_value_t);

routine host_processors(
               host_priv       : host_priv_t;
       out     processor_list  : processor_array_t);

routine host_processor_set_priv(
               host_priv       : host_priv_t;
               set_name        : processor_set_name_t;
       out     set             : processor_set_t);
       hurd/proc/main.c,
       hurd/proc/mgt.c

routine vm_wire(
               host_priv       : host_priv_t;
               task            : vm_task_t;
               address         : vm_address_t;
               size            : vm_size_t;
               access          : vm_prot_t);
       hurd/libshouldbeinlibc/wire.c
       hurd/serverboot/wiring.c

routine thread_wire(
               host_priv       : host_priv_t;
               thread          : thread_t;
               wired           : boolean_t);
       hurd/serverboot/wiring.c

I list all routines and the place where they are called in Hurd below them.
Note: several of them are not used by Hurd.
The problem here is host_processor_set_priv, which converts a processor set name port to a control port. proc gets the control port with host_processor_set_priv, but instead of calling an RPC to this port, it calls an RPC to its thread port and uses this port as a parameter, so the host proxy cannot get the RPC. The host proxy cannot return a real control port, either, because it doesn't has the root permission. The code in proc/main.c (shown below) will fail for sure:
 err = host_processor_set_priv (master_host_port, pset, &psetcntl);
 assert_perror (err);
 thread_max_priority (mach_thread_self (), psetcntl, 0);
 assert_perror (err);
 err = task_priority (mach_task_self (), 2, 1);
 assert_perror (err);

A simple solution might be to modify the code of proc since it is the only place having this problem. For a long run, it might not be a good idea. It might limit the ability of subhurd and I don't know if more similar code will be used in the future Hurd.

The other solution is to give pseudo task ports and thread ports to the subhurd, so boot can receive all RPCs from subhurd (which should go to the kernel). Now boot can get the full control of subhurd (it might give subhurd more features even though I don't know yet). The problem I mentioned above can be solved easily. However, this solution needs more work and makes the things more complicated. I wonder if it is worth the work. The more important question is how to give pseudo task ports and thread ports.
mach_thread_self () and mach_task_self () are system trap.
Maybe I can modify the implementation of mach_thread_self () and mach_task_self () in glibc and use an RPC to ask boot for the ports, but then every task has to know the port to boot. It needs much work and seems quite ugly.

I wonder if there is a better solution to get the pseudo task and thread port from boot, or even a better solution to solve the problem caused by host_processor_set_priv.

By the way, how are mach_thread_self () and mach_task_self () implemented in glibc (at least, how does glibc wrap these two system calls)?
I see the implementation of mach_task_self (), but it's quite weird.
In mach/mach_init.h, there is
extern mach_port_t __mach_task_self_;
#define __mach_task_self() (__mach_task_self_ + 0) /* Not an lvalue. */
#define mach_task_self()        (__mach_task_self ())
In mach/mach_init.c, there is
void
__mach_init (void)
{
 kern_return_t err;

 __mach_task_self_ = (__mach_task_self) ();
...
I am totally confused by the code. If I find the right code, then __mach_task_self_ is always 0.

Thank you very much.
Zheng Da




reply via email to

[Prev in Thread] Current Thread [Next in Thread]