Vitaliy Margolen wrote:
After checking object's SD against token we fail some tests. What it seems to me is that some one tried to "optimize" this part in windows and instead created a security problem.
If you already have a valid handle to the object, then it isn't really a security problem to have another one with the same access rights.
@@ -450,25 +453,34 @@ obj_handle_t duplicate_handle( struct pr unsigned int access, unsigned int attr, unsigned int options ) { obj_handle_t res; + struct handle_entry *entry; + unsigned int src_access, dst_access; struct object *obj = get_handle_obj( src, src_handle, 0, NULL );
if (!obj) return 0; - if (options & DUP_HANDLE_SAME_ACCESS) + if ((entry = get_handle( src, src_handle ))) + src_access = entry->access; + else /* pseudo-handle, give it full access */ { - struct handle_entry *entry = get_handle( src, src_handle ); - if (entry) - access = entry->access; - else /* pseudo-handle, give it full access */ - { - access = obj->ops->map_access( obj, GENERIC_ALL ); - clear_error(); - } + src_access = obj->ops->map_access( obj, GENERIC_ALL ); + clear_error(); } - access &= ~RESERVED_ALL; + src_access &= ~RESERVED_ALL; + + if (options & DUP_HANDLE_SAME_ACCESS) + dst_access = src_access; + else + dst_access = obj->ops->map_access( obj, access ) & ~RESERVED_ALL; + + /* asking for more or the same/less access rights */ + access = ~src_access & dst_access ? dst_access : 0; + if (options & DUP_HANDLE_MAKE_GLOBAL) res = alloc_global_handle( obj, access ); else res = alloc_handle( dst, obj, access, attr ); + if (res) get_handle( dst, res )->access = dst_access; +
It would seem better to add an extra parameter to alloc_handle and alloc_global_handle to tell them to not check access rather than adding this hack. It should use less processor time and it should make patch 2 not necessary. -- Rob Shearman