[PATCH]: NetSessEnum - Removing a loop around locking tdb traversal
Christof Schmitt
cs at samba.org
Fri Jan 10 11:13:47 MST 2014
On Thu, Jan 09, 2014 at 01:39:26PM -0800, Jeremy Allison wrote:
> On Wed, Jan 08, 2014 at 10:00:58AM -0700, Christof Schmitt wrote:
> > On Wed, Jan 08, 2014 at 12:38:15PM +0530, Shekhar Amlekar wrote:
> > > Hi,
> > >
> > > Please find patches that removes a loop around locking tdb traversal in
> > > NetSessEnum() call. I've also removed the getpwnam() call and used the uid
> > > inside the sessionid structure. Request your review.
> >
> > Reviewed-by: Christof Schmitt <cs at samba.org>
> >
> > Can we get a second review?
>
> NAK on this one. I'm going to explain exactly
> why, hopefully not to make Shekhar feel bad,
> but to try and explain why this stuff can be
> very tricky :-).
>
> I started looking closely when I noticed in
> the introduced function count_sess_files_fn()
> the following code:
>
> static void count_sess_files_fn(const struct share_mode_entry *e,
> const char *sharepath, const char *fname,
> void *data)
> {
> struct sess_file_info *info = data;
> uint32_t rh = info->resume_handle;
> int i;
>
> for (i=0; i < info->num_entries; i++) {
>
> 'i' is being declared as an int, but info->num_entries
> is a uint32_t. Harmless enough but should be tidied up
> so I fixed it an moved on. But it raised a red flag
> enough that I started to look very carefully at how
> 'i' was being used in that function.
>
> Then we have:
>
> struct sessionid *sess = &info->session_list[rh + i];
>
> Hmmm. i is being added to 'rh' = info->resume_handler.
> Where does that come from ?
>
> Tracking back we find..
>
> static void net_count_files_for_all_sess(struct srvsvc_NetSessCtr1 *ctr1,
> struct sessionid *session_list,
> uint32_t resume_handle,
> uint32_t num_entries)
> {
> struct sess_file_info s_file_info;
>
> s_file_info.ctr = ctr1;
> s_file_info.session_list = session_list;
> s_file_info.resume_handle = resume_handle;
>
> and the caller:
>
> /* count open files on all sessions in single tdb traversal */
> net_count_files_for_all_sess(ctr1, session_list,
> resume_handle_p ? *resume_handle_p : 0,
> num_entries);
>
> But *resume_handle_p is a *client* passed value.
> And info->session_list[] is a *server* allocated
> array (via *total_entries = list_sessions(p->mem_ctx, &session_list);).
>
> Oops. There are no range checks on the passed in
> value..
>
> So the fix up for this is that at the very least
> *resume_handle_p+i must be checked for range between
> 0 and < *total_entries before being safe to use.
>
> I will fix this patchset up and re-post a corrected
> version for your review.
>
> But it does show how tricky dealing with RPC values
> from the client can be in a server :-).
Thanks for finding that and explaining the problem, i missed it in my
review. I will wait for the corrected patchset.
Christof
More information about the samba-technical
mailing list