smbd panic at find_oplock_types().

Hemanth Thummala hemanth.thummala at gmail.com
Fri Sep 5 17:21:11 MDT 2014


Hi,

Finally I am able to recreate this smb panic with the help of smbtorture
test. This issue actually related to alternate data streams. In one of our
customer core dumps, we could see the file is having alternate data stream.

Here are the steps to recreate the panic:

1) create some file say oplock.txt.
2) create a stream on the file. ex: oplock.txt:stream1
3) Open file oplock.txt with BATCH_OPLOCK. do not close the handle
4) Open the stream file(oplock.txt:stream1) with or without oplock. Do not
close the handle here as well.
5) Open the base file (oplock.txt) again. You will see smb panic.

Just to remind we are using samba 3.6.12+ stack.

I have reproduced this issue on a freenas server as well which is running
samba 3.6.12 stack. But did not see much changes in Master code specific to
this area. We should be hitting the same issue.

Log snippet during panic on freenas:

  parse_share_modes: owrt: Fri Sep  5 14:53:12 2014 PDT, cwrt: Wed Dec 31
16:00:00 1969 PST, ntok: 0, num_share_modes: 2
[2014/09/05 15:01:38.881370, 10] locking/locking.c:725(parse_share_modes)
  parse_share_modes: share_mode_entry[0]:  pid = 5178, share_access = 0x7,
private_options = 0x0, access_mask = 0x120089, mid = 0x4, type= 0x2, gen_id
= 1836070363, uid = 0, flags = 0, file
_id 1e7aff2c:3616f:0, name_hash = 0x2ab3c7
[2014/09/05 15:01:38.881384, 10] locking/locking.c:725(parse_share_modes)
  parse_share_modes: share_mode_entry[1]:  pid = 5178, share_access = 0x7,
private_options = 0x0, access_mask = 0x0, mid = 0x0, type= 0x0, gen_id =
1836070364, uid = 0, flags = 0, file_id 1
e7aff2c:3616f:0, name_hash = 0x2ab3c7
[2014/09/05 15:01:38.881394,  0] lib/util.c:1117(smb_panic)
  PANIC (pid 5178): Bad no oplock entry.


I think this is what its happening..

When we successfully open base file step#3, we register a shared mode lock
with BATCH_OPLOCK on base file. When we try to open the stream file in
step#4, we are doing an internal open on base file with access mask as
zero, oplock as zero(NO_OPLOCK) and req as NULL in create_file_unixpath().

In create_file_unixpath()
....
/* Open the base file. */
status = create_file_unixpath(conn, *NULL*, smb_fname_base,* 0*,
      FILE_SHARE_READ
      | FILE_SHARE_WRITE
      | FILE_SHARE_DELETE,
      base_create_disposition,
      0, 0, 0, 0, *0*, NULL, NULL,
      &base_fsp, NULL);
TALLOC_FREE(smb_fname_base);
...

But we avoid breaking existing batch oplock as we treat this as internal
open.  In open_file_ntcreate()..
/* First pass - send break only on batch oplocks. */
if ((req != NULL) && ===> we skip if req is NULL.
delay_for_batch_oplocks(fsp,
req->mid,
oplock_request,
batch_entry)) {
schedule_defer_open(lck, request_time, req);
TALLOC_FREE(lck);
return NT_STATUS_SHARING_VIOLATION;
}

But this entry is also getting added to share mode lock list for the base
file. Now we have a BATCH_OPLOCK and NO_OPLOCK on base file oplock.txt.
Next open request on base file is causing to traverse the list and leading
to panic situation.


I have observed that we are actually setting the flag "INTERNAL_OPEN_ONLY"
in create_file_unixpath when we see the req as NULL.
...
if (req == NULL) {
oplock_request |= INTERNAL_OPEN_ONLY;
}
...

But in open_file_ntcreate(), we are unconditionally clearing this
INTERNAL_OPEN_ONLY flag.

...
/* Ensure no SAMBA_PRIVATE bits can be set. */
fsp->oplock_type = (oplock_request & ~SAMBA_PRIVATE_OPLOCK_MASK);
....

Due to this, we never treated this shared lock entry as internal.

In find_oplock_types() we have the checks..

...
if ((oplock_request & INTERNAL_OPEN_ONLY) ||
is_stat_open(fsp->access_mask)) {
return;
}
....
if (lck->share_modes[i].op_type == NO_OPLOCK &&
is_stat_open(lck->share_modes[i].access_mask)) {
/* We ignore stat opens in the table - they
   always have NO_OPLOCK and never get or
   cause breaks. JRA. */
continue;
}
...

This particular shared lock is skipping all these checks. It was neither
having INTERNAL_OPEN_FLAG nor a stat open(since access mask is zero).

I want to know..
a) If its intentional to clear the SAMBA_PRIVATE_OPLOCK_MASK before adding
the lock to share mode list.
b) Why are we not using access mask as
(SYNCHRONIZE_ACCESS|FILE_READ_ATTRIBUTES|
FILE_WRITE_ATTRIBUTES) which will mark the open as stat_open and will allow
to skip this share lock check. Thereby avoids panic.

Will file a bug for the same and put more details.

Thanks,
Hemanth.



On Tue, Aug 5, 2014 at 3:35 PM, Richard Sharpe <realrichardsharpe at gmail.com>
wrote:

> On Tue, Aug 5, 2014 at 3:31 PM, Hemanth Thummala
> <hemanth.thummala at gmail.com> wrote:
> > Richard,
> >
> > This issue is not related to streams. I have verified that file in use
> not
> > having any (alternate) streams on it. And I have tried the rename tests
> as
> > well. Tried opening the file from one client and renamed at different
> place
> > and as expected this has failed with sharing violation error.
>
> I am not saying that it is related to streams. I am simply mentioning
> streams because most of the cases I saw there were related to the
> aliasing of a stream to its parent file. Thus, the aliasing of files
> is a problem.
>
> Combine that with the fact that the file_id in your version of Samba,
> when I last worked on it, was no longer an inode # (and FSID) but a
> hash of the path, and there are potential issues with aliasing. It
> would most likely occur in a case where the client renamed a file but
> held it open.
>
> > Thanks,
> > Hemanth.
> >
> >
> > On Tue, Aug 5, 2014 at 12:38 PM, Richard Sharpe
> > <realrichardsharpe at gmail.com> wrote:
> >>
> >> On Tue, Aug 5, 2014 at 12:17 PM, Volker Lendecke
> >> <Volker.Lendecke at sernet.de> wrote:
> >> > On Tue, Aug 05, 2014 at 11:22:19AM -0700, Hemanth Thummala wrote:
> >> >> Volker,
> >> >> These are user files not internal/temp files. Yeah stat open checks
> for
> >> >> non-zero access mask. But I have seen at one place where we send zero
> >> >> access mask along NO_OPLOCK flag.
> >> >>
> >> >> In create_file_unixpath():
> >> >> ...
> >> >> /* Open the base file. */
> >> >> status = create_file_unixpath(conn, NULL, smb_fname_base, 0==> Access
> >> >> mask,
> >> >>       FILE_SHARE_READ
> >> >>       | FILE_SHARE_WRITE
> >> >>       | FILE_SHARE_DELETE,
> >> >>       base_create_disposition,
> >> >>       0, 0, 0==> oplock, 0, 0, NULL, NULL,
> >> >>       &base_fsp, NULL);
> >> >> TALLOC_FREE(smb_fname_base);
> >> >> ...
> >> >>
> >> >> But this will happen only when the request comes for stream files.
> But
> >> >> I
> >> >> feel we should mark access mask non-zero so that we can filter these
> >> >> shared
> >> >> mode locks with is_stat_open().
> >> >> In my case, file doesn't have any streams. So I am ruling this
> >> >> possibility
> >> >> out. But thought of showing that we have a case where we are using
> zero
> >> >> access mask for stat/internal opens.
> >> >
> >> > The problem is -- access_mask==0 should have broken the
> >> > oplock. I don't really see how this could not happen.
> >>
> >> As I recall, one of the changes was to use a different file_id than
> >> the normal one Samba uses, based on a hash of the path (more details
> >> elided). Is it possible that in this case the code has aliased two
> >> files together, because my memory of dealing with this bug says that
> >> it was always related to files being aliased. In the ADS case, streams
> >> were being aliased to their parent file and causing the problem.
> >>
> >> --
> >> Regards,
> >> Richard Sharpe
> >> (何以解憂?唯有杜康。--曹操)
> >
> >
>
>
>
> --
> Regards,
> Richard Sharpe
> (何以解憂?唯有杜康。--曹操)
>


More information about the samba-technical mailing list