Hi, I have not addressed this issue. Doing so would require defining new hooks, so we could treat each request as a transaction, perhaps splitting each current hook into a hook_query() and hook_finalize() function. Now I guess we would need hook_query() to return a serial number to send to hook_finalize(), and each LSM would have to keep around temporary storage for tentative state updates. I think that, given the current design of LSM, the side-effects are something we're simply going to have to live with, and keep in mind when writing LSMs. Are there reasons why/cases where that might be unworkable? -serge On Wed, 2005-01-05 at 15:21 -0800, Seth Arnold wrote: > On Fri, Dec 03, 2004 at 12:04:02PM -0600, Serge Hallyn wrote: > > Attached is a cleaned up version of stacker. > > Serge, I'm curious about a design point -- it appears that you've got > some loops here that will query each module in turn for an answer, > and a configurable flag to drop out as soon as a module rejects an access. > > However, I don't see any call-backs to modules that have granted access > (and likely updated internal control structures) to notify them that > their decision has been rescinded by a further module, should a module > further in the chain reject the access. > > I looked only for the specific case of turning quotas on and off, and > I didn't find any post hooks to allow modules to realign their internal > state based on success or failure of the quota hooks. I expect that many > of the hooks are similar to the quota hooks. > > Have I missed this functionality? Or have your initial results determined > that it is a rare module which needs to update internal state if its > "grant" decision is rescinded by another module's "deny" decision? > > Thanks Serge > > > +#define RETURN_ERROR_IF_ANY_ERROR(BASE_FUNC,FUNC_WITH_ARGS) do { \ > > + int final_result = 0; \ > > + struct module_entry *m; \ > > + rcu_read_lock(); \ > > + list_for_each_entry_rcu(m, &stacked_modules, lsm_list) { \ > > + int result = 0, stop = 0; \ > > + atomic_inc(&m->use); \ > > + rcu_read_unlock(); \ > > + if (m->module_operations.BASE_FUNC) \ > > + result = m->module_operations.FUNC_WITH_ARGS; \ > > + if (result && !final_result) { \ > > + final_result = result; \ > > + if (short_circuit_restrictive) \ > > + stop = 1; \ > > + } \ > > + rcu_read_lock(); \ > > + if (unlikely(atomic_dec_and_test(&m->use))) \ > > + stacker_free_module(m); \ > > + if (stop) \ > > + break; \ > > + } \ > > + rcu_read_unlock(); \ > > + return final_result; \ > > +} while (0) > > + > > +/* Call all modules in stacked_modules' routine */ > > +#define CALL_ALL(BASE_FUNC,FUNC_WITH_ARGS) do { \ > > + struct module_entry *m; \ > > + rcu_read_lock(); \ > > + list_for_each_entry_rcu(m, &stacked_modules, lsm_list) { \ > > + atomic_inc(&m->use); \ > > + rcu_read_unlock(); \ > > + if (m->module_operations.BASE_FUNC) \ > > + m->module_operations.FUNC_WITH_ARGS; \ > > + rcu_read_lock(); \ > > + if (unlikely(atomic_dec_and_test(&m->use))) \ > > + stacker_free_module(m); \ > > + } \ > > + rcu_read_unlock(); \ > > +} while (0) > -- Serge Hallyn <serue@private>
This archive was generated by hypermail 2.1.3 : Thu Jan 06 2005 - 07:58:14 PST