@ -520,6 +520,42 @@ struct seq_operations proc_projid_seq_operations = {
. show = projid_m_show ,
} ;
static bool mappings_overlap ( struct uid_gid_map * new_map , struct uid_gid_extent * extent )
{
u32 upper_first , lower_first , upper_last , lower_last ;
unsigned idx ;
upper_first = extent - > first ;
lower_first = extent - > lower_first ;
upper_last = upper_first + extent - > count - 1 ;
lower_last = lower_first + extent - > count - 1 ;
for ( idx = 0 ; idx < new_map - > nr_extents ; idx + + ) {
u32 prev_upper_first , prev_lower_first ;
u32 prev_upper_last , prev_lower_last ;
struct uid_gid_extent * prev ;
prev = & new_map - > extent [ idx ] ;
prev_upper_first = prev - > first ;
prev_lower_first = prev - > lower_first ;
prev_upper_last = prev_upper_first + prev - > count - 1 ;
prev_lower_last = prev_lower_first + prev - > count - 1 ;
/* Does the upper range intersect a previous extent? */
if ( ( prev_upper_first < = upper_last ) & &
( prev_upper_last > = upper_first ) )
return true ;
/* Does the lower range intersect a previous extent? */
if ( ( prev_lower_first < = lower_last ) & &
( prev_lower_last > = lower_first ) )
return true ;
}
return false ;
}
static DEFINE_MUTEX ( id_map_mutex ) ;
static ssize_t map_write ( struct file * file , const char __user * buf ,
@ -532,7 +568,7 @@ static ssize_t map_write(struct file *file, const char __user *buf,
struct user_namespace * ns = seq - > private ;
struct uid_gid_map new_map ;
unsigned idx ;
struct uid_gid_extent * extent , * last = NULL ;
struct uid_gid_extent * extent = NULL ;
unsigned long page = 0 ;
char * kbuf , * pos , * next_line ;
ssize_t ret = - EINVAL ;
@ -635,14 +671,11 @@ static ssize_t map_write(struct file *file, const char __user *buf,
if ( ( extent - > lower_first + extent - > count ) < = extent - > lower_first )
goto out ;
/* For now only accept extents that are strictly in order */
if ( last & &
( ( ( last - > first + last - > count ) > extent - > first ) | |
( ( last - > lower_first + last - > count ) > extent - > lower_first ) ) )
/* Do the ranges in extent overlap any previous extents? */
if ( mappings_overlap ( & new_map , extent ) )
goto out ;
new_map . nr_extents + + ;
last = extent ;
/* Fail if the file contains too many extents */
if ( ( new_map . nr_extents = = UID_GID_MAP_MAX_EXTENTS ) & &