lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Message-ID: <45AD0062.9030603@cosy.sbg.ac.at>
Date:	Tue, 16 Jan 2007 17:42:10 +0100
From:	Michael Noisternig <mnoist@...y.sbg.ac.at>
To:	Joel Becker <Joel.Becker@...cle.com>
Cc:	linux-kernel@...r.kernel.org
Subject: Re: configfs: return value for drop_item()/make_item()?

> 	I'm sorry if I missed your previous post.  I've never ignored a
> configfs post on purpose :-)

Well, thanks a lot for the reply! :)

>> Here's the issue... the configfs system can prevent a user from 
>> _creating_ sub-directories in a certain directory (by not supplying 
>> struct configfs_group_operations->make_item()/make_group()) but it 
>> cannot prevent him from _removing_ sub-directories because struct 
>> configfs_group_operations->drop_item() is void.
> 
> 	This is intentional.  The entire point of configfs is to have
> the lifetime controlled from userspace.  If the kernel can pin things
> however it likes, we lose that property.

I fully agree with the idea of configfs not being allowed to destroy 
user-created objects. OTOH, while configfs is described as a filesystem 
for user-created objects under user control, compared to sysfs as a 
filesystem for kernel-created objects under kernel control, configfs 
_does_ permit kernel-created objects in a limited way (by filling in 
struct config_group->default_groups), and these objects can only be 
destroyed again by the kernel, and not by the user.

As such I don't understand fully why one doesn't want to merge sysfs and 
configfs (let's call it sysconfs for now) in such a way that it allows 
_both_ user- and kernel-created objects, with user-objects only allowed 
to be destroyed by the user and kernel-objects only by the kernel.

I'll explain more shortly, and also the connection with...

>> Similarly, struct configfs_group_operations->make_item() does not permit 
>> to return an error code, and as such it is impossible to 'check' the 
>> type of sub-directory a user wants to create (with returning a 
>> meaningful error code). This had already, unsuccessfully, been brought 
>> up before on 2006-08-29 by J. Berg (see 
>> http://marc.theaimsgroup.com/?l=linux-kernel&m=115692319227688&w=2).

One problem with configfs is that there is too little control over how 
many other objects a particular object may contain. IOW, an object may 
either contain
   - n sub-objects (n entries in ->default_groups), or
   - n..inf sub-objects (n entries in ->default_groups, 
->make_item()/make_group() supplied)

Often however, what you want is that an object may contain 0 or 1 other 
objects. If ->make_item()/make_group() would allow returning a 
meaningful error code the kernel could deny creation of a 2nd object 
other than by pretending to be out of memory.

For another example, and directly related to above link, suppose having 
an object with a number of attributes, one of them being called 'type'. 
Dependent on the value of 'type' this object may contain a particular 
type of sub-object (with type-dependent attributes). E.g. 'type' may be 
empty | 'a' | 'b' | 'ab', then dependent on this there should be 0 or 1 
directories called 'a', and 0 or 1 directories called 'b'. Doing it this 
way means that while the user decides what sub-directory/-ies the object 
has, he does not create them (directly) - it is the kernel which creates 
the object, and as such it is also the kernel only which is permitted to 
destroy the object again - by the user writing a different value to the 
'type' attribute (or clearing it). sysconfs could solve this.

Above problem could be solved in a different manner within the realms of 
configfs by not having a 'type' attribute, but the other way around 
defining the (implicit) type of the object by the user creating certain 
sub-directories ('a' and 'b'). I.e. if the user creates directory 'a' 
the object is of type a, if the user also creates 'b' then the object is 
of type ab. However, the user should not be permitted to create other 
objects than 'a' and 'b' - thus ->make_item()/make_group() should permit 
returning a meaningful error code.

> 	I don't quite see how this link relates, but perhaps I'm not
> understanding your entire question.  Currently, ->make_item() doesn't
> allow an error code because that would involve the ERR_PTR() construct.
> While that construct is quite useful, I'm always wary of adding
> complexity.  Thus, the tradeoff would have to be worth it.

I was thinking about
   ssize_t make_item(struct config_group *group, const char *name, 
struct config_item **new_item)
with return value 0 meaning no-error.

>> Please give some arguments why you think 
>> configfs_group_operations->drop_item() should remain void.
> 
> 	Very simply, the lifetime must be in the control of userspace.
> That's precisely the point of configfs.  If you'd like the kernel to
> control the lifetime, I suspect sysfs will be more to your liking.
> configfs is not meant to replace sysfs, merely to coexist for things
> that benefit from the configfs model and not the sysfs model.
> 	(More on the model and your problem near the bottom)

Well, I understand and agree to the philosophy... but I still don't know 
how to solve my problem elegantly... more below...

> 
>> (1)
>> Say the user creates one object, let's say as objects/myobj1/. This 
>> object is dependent on some (shared) parameters which the user created 
>> under params/myparams1/. Now while myobj1/ is 'active', I don't want to 
>> let the user remove myparams1/. I can prevent this by making the user 
>> create a symlink(2) in the objects/myobj1/ directory to myparams1/, i.e. 
>> objects/myobj1/params/ -> ../../params/myparams1/, to denote its use. 
>> Now - if I have read the documentation correctly - the user cannot 
>> remove myparams1/ without removing the params/ link first. So fine, so good.
> 
> 	This will certainly work.
> 
>> (2)
>> Next the user may create several objects which may be dependent on 
>> several params objects. Now I can solve this by creating a default group 
>> for each object, i.e. on myobj1 creation there is objects/myobj1/params/ 
>> automatically. In that directory the user may create symlink(2)s to 
>> several params/*/ dirs. Fine again.
>>
>> (3)
>> Now what I want is the list of params an object uses to be an ordered 
>> list. I cannot do this because there is no intrinsic order in a 
>> filesystem. I can get the order by instead having an attribute called 
>> param_list which contains the ordered list of all params to use, e.g.
> 
> 	Why does it need to be ordered?  Also, why can't the symlinks
> have a naming convention of order?  Sure, someone hacking at it can
> break that, but your tool that really does the work can create
> objects/myobj1/params/param1 -> myparams2.  So the listing does have
> meaning.  Just one possibility.

It must be ordered because it's a priority list.

I was thinking about having symlinks in a directory and deriving the 
order by the symlinks' filenames, too. I dismissed it originally for two 
reasons. First, I didn't see how to keep the order when some link gets 
deleted, e.g. there's 1,2,3 and then link 2 gets deleted. Now, thinking 
about it again, I can simply keep a ordered linked list internally, and 
therefrom remove the node for link 2. But it's still not perfect, 
because how do I insert a link between filenames 1 and 2? Ok, I have to 
delete all symlinks first and then rebuild them, and in the end it's 
like rewriting a params_list attribute file... except that it's not 
atomic. Second, a simple params_list file seems a lot more easy to 
handle from the user perspective... simply open the file with an editor, 
add or delete an entry, save it, close it. I don't know which method is 
better, the one described here with a params/ subdirectory containing 
symlinks with their order derived from their filenames, or method 2) 
from below with simply having a params_list file where params entries 
get renamed to <params removed> but are still valid until the user 
rewrites the params_list file.

>> 2)
>> Keep a reference on each configfs object (e.g. params) in use, so when 
>> the user removes it from configfs it is still present in memory. This, 
>> however, requires to rename each according entry in every affected 
>> param_list to <params removed> or similar... not a very user-friendly 
>> way to deal with the situation.
> 
> 	There are two ways to reference the params.  One is to let the
> userspace program ask for the reference via symlink.  The other is in
> your driver.  This has the property you describe above, that you have
> to keep track of it after the user has asked for it to go away.

Yes, these are exactly the two possible methods I see and describe above.

> 	This property is on purpose.  When a user asks for something to
> go away, it needs to disappear from configfs before the rmdir(2)
> returns.  It's gone, and it is no longer accessible from userspace.  The
> lifetiming of userspace access is clear, cut, and dried.
> 	However, some objects need some time to die.  So the driver has
> its own reference, and it schedules any cleanup and death later.  But
> that death and cleanup should happen as soon as possible, because
> userspace has asked for it.

Yes, I agree with the methodology, it's exactly how a filesystem is 
expected to handle such situtation. OTOH, the behavior for configfs 
files referenced by symlinks is already different.

> 	Let's break for a minute.  Let me try to restate all of this.
> You have an interrelationship between a few configfs objects.  When a
> [referrer -> reference] relationship is put together, you need to prevent
> the reference from going away.  You've proposed a couple of methods that
> boil down to "when the reference object knows it is being referred to,
> it prevents itself from going away".
> 	Therein lies the rub.  configfs works by putting all of that in
> userspace.  Lifetime decisions can only occur in userspace.  This allows
> us a very clean lifetime from the userspace perspective.  It also means
> that if we want to lock an object down, it has to happen in userspace.
> 	So, the object cannot "prevent itself from going away".  The
> kernel side just can't do this.  Userspace, however, can.  You've
> discussed the most common way configfs allows userspace to do this, the
> symlink.  I believe your only problem was that of naming.  There's no
> reason you can't populate a param_list file at the same time you respond
> to ->allow_link().  Or, you could have userspace name the links in a
> manner providing ordering.  These solve this problem without breaking
> the configfs contract.

See above. I still don't know what would be an optimal solution.

> 	Think about your requirements again.  Do you absolutely require
> that some part of your kernel driver make a lifetime decision?  If so,
> configfs isn't going to fit.  Can the lifetime decision be moved to
> userspace?  If so, configfs should work just fine as-is, and you'll gain
> the clean lifetime and simple manipulation that configfs provides.  I
> hope it's the latter :-)

configfs should be a perfect fit for my purposes, as it's the user (and 
the user only) who creates and destroys the objects. The problem lies 
elsewhere. :/

OTOH, I don't see why configfs and sysfs cannot (should not) be merged 
as described above for sysconfs.

I'll give an example once more:
I have a directory called 'statistics' in my module's main dir in the 
configfs tree. This directory will contain several attributes for 
statistical purposes. Normally you would place this object into sysfs 
because it's an object created by the kernel (->default_groups). 
However, I certainly don't want to rip apart the statistics dir from the 
rest of the module parameters. What this shows in my eyes is that (1) 
configfs _does_ create kernel objects, and (2) sysconfs might make sense.

> Joel

Thanks again!
   Michael
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ