Re: user_memcpy()

"François Revol" <[email protected]>
Newsgroups gmane.os.openbeos.kernel.devel
Message-ID <6328981302-BeMail@patrick>
> "François Revol" <[email protected]> wrote:
> > > François Revol made me recognize a design flaw in our 
> > > user_memcpy()
> > > /
> > > user_strlcpy() API: you have to check the validity of the user 
> > > address yourself, ie. you have to make sure it's in user space.
> > > But we don't have a function for this, just the (kernel private) 
> > > macro IS_USER_ADDRESS().
> > Actually there is more to that...
> [...]
> > So you end up having is_valid_range(), which noone called anyway 
> > (also 
> > because it wasn't in a public header), and to which you didn't know 
> > which flag to give anyway:
> 
> Doing is_valid_range() correctly is quite a bit overhead, and if 
> possible I would like to get away without doing that :-)
> I think we could introduce something like:
> 	bool called_from_kernel(void);

Whatever the name.

> The VFS could set a flag in the current thread structure. For Haiku, 
> we 

Yes that was my idea.

> could also easily change the driver API (which we do anyway for new-
> style drivers), but a common solution would be preferable, I guess.

We already have the new driver model in as we need it for the IDE 
replacement driver.

> > #define B_READ_AREA 1
> > #define B_WRITE_AREA 2 */
> > #define B_USER_READ_AREA    0x00000004  /* user can read */
> > #define B_USER_WRITE_AREA    0x00000008  /* user can write */
> 
> Isn't it the other way around?
> B_READ_AREA already expresses "user can read". What's missing is a 
> B_KERNEL_READ_AREA (meaning: only kernel can read if used alone).
> 

Nono.. actually it's not the same values... the real constants are:
inc/vm.h:#define PROT_KRD       0x00000001      /* kernel read */
inc/vm.h:#define PROT_KWR       0x00000002      /* kernel write */
inc/vm.h:#define        PROT_URD        0x00000004      /* user read */
inc/vm.h:#define        PROT_UWR        0x00000008      /* user write *
/
inc/vm.h:#define        PROT_ALL        (PROT_KRD | PROT_KWR | PROT_URD 
| PROT_UWR)

> > /* why isn't that in KernelExport ??? */
> > extern bool is_valid_range(void *start, size_t len, uint32 prot);
> 
> Probably out of stupidity - it's a bit too much for an oversight.

Yeah probably.

> I don't think it should be always root, even if it could simply 
> switch 
> its access rights if needed (which would only be safe, though, if 
> these 
> rights could be specified by thread).

But they aren't. uid/gid is set for a whole team.
of course getuid() and friends could use called_from_kernel()...
But that would hide the real uid, so if someone really wants it...

> > See:
> > http://lxr.linux.no/source/include/asm-i386/uaccess.h
> 
> I don't really like this, though - the called_from_kernel() is a bit 
> more flexible.

Indeed.
And it hides the implementation, so drivers wo'nt be affected by a 
change.

> 
> > Now, the elf loader in BeOS certainly doesn't care about those 
> > sections, and the exception handler doesn't either. Probably Haiku 
> > has/
> 
> What does this have to do with the ELF loader, anyway?

Because in linux the return address for exception in *_*_user() are 
stored in those .eh_frame section, so the elf loader needs to parse 
them and store the addresses somewhere.

> 
> > work if we boot a new kernel that has say a new 1:3 vm split, or 
> > maybe 
> > a reverse split as it would make it easier for WINE.
> 
> We already did that for Haiku, btw.

Fine.

> > While Haiku's could be something closer to the linux one:
> > status_t copy_to_user(void *to, void *from, size_t len)
> > {
> > 	if (to < current->addr_limit)
> >         return EFAULT;
> >     // set up exception handler for memcpy
> >     return memcpy(to, from, len);
> > }
> > (but there is still the question of copying to an address in user 
> > space 
> > that is valid, but read only...)
> 
> That would still be catched by the Haiku version, at least (ie. it 
> would safely fail).
> BTW to be consistent to strlcpy_to_user() and user_memset(), I think 
> I 
> would like memcpy_to_user() more than copy_to_user().

I guess so.

> 
> > Anyway I'd propose 2 simple calls we could hardcode as macros for 
> > R5:
> > 
> > #if defined(COMPILE_FOR_R5) && !defined(B_ZETA_VERSION_VENTURE)
> > #define check_for_user() false
> > #define check_for_user_addr() false
> > #define check_for_user_fd() true
> > #else
> > // check for valid user addresses 
> > extern bool check_for_user_addr(void);
> > // check for valid user permissions (for fds and such)
> > extern bool check_for_user_fd(void);
> > #endif
> 
> Why FD?

cause it depends on if the call is made on the user fds or the kernel 
ones.

> Anyway, I think we should have those two:
> bool called_from_kernel(void);
> bool is_user_address(void);

I'd go for those... hmm is_ usually means it applies to a passed 
argument.
do_check_user_address maybe ?

> 
> (or also called_from_user() instead)

That one would just be !called_from_kernel(), which is conceptually 
different than the address stuff. (it's basically or R5 because though 
we must supposed we are called from user we must not check for user 
addresses).

> > I think I can stick something in Zeta R1, but the time window is 
> > shrinking, so it would be nice to reach a consensus there...
> 
> Would be nice, yes, although I we will definitely introduce a new 
> driver architecture, anyway, so maybe the pressure to be compatible 
> is 
> not that high (even if we both could benefit from it).
> 

One more ?
Remember it's yT's prerogative to increment B_CUR_DRIVER_API_VERSION 
now :D


François.




-------------------------------------------------------
This SF.Net email is sponsored by: NEC IT Guy Games.
Get your fingers limbered up and give it your best shot. 4 great events, 4
opportunities to win big! Highest score wins.NEC IT Guy Games. Play to
win an NEC 61 plasma display. Visit http://www.necitguy.com/?r
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.