Fixes kernel bug #10451http://bugzilla.kernel.org/show_bug.cgi?id=10451
Certain NAS appliances do not set the operating system or network operating system
fields in the session setup response on the wire. cifs was oopsing on the unexpected
zero length response fields (when trying to null terminate a zero length field).
This fixes the oops.
Acked-by: Jeff Layton <jlayton@redhat.com>
CC: stable <stable@kernel.org>
Signed-off-by: Steve French <sfrench@us.ibm.com>
When a search is pending of a parent directory, and a child directory
within it is removed, we need to reset the parent directory's time
so that we don't reuse the (now stale) search results.
Thanks to Gunter Kukkukk for reporting this:
> got the following failure notification on irc #samba:
>
> A user was updating from subversion 1.4 to 1.5, where the
> repository is located on a samba share (independent of
> unix extensions = Yes or No).
> svn 1.4 did work, 1.5 does not.
>
> The user did a lot of stracing of subversion - and wrote a
> testapplet to simulate the failing behaviour.
> I've converted the C++ source to C and added some error cases.
>
> When using "./testdir" on a local file system, "result2"
> is always (nil) as expected - cifs vfs behaves different here!
>
> ./testdir /mnt/cifs/mounted/share
>
> returns a (failing) valid pointer.
Acked-by: Dave Kleikamp <shaggy@us.ibm.com>
Acked-by: Jeff Layton <jlayton@redhat.com>
Signed-off-by: Steve French <sfrench@us.ibm.com>
The paths in a DFS request are supposed to only have a single preceding
backslash, but we are sending them with a double backslash. This is
exposing a bug in Windows where it also sends a path in the response
that has a double backslash.
The existing code that builds the mount option string however expects a
double backslash prefix in a couple of places when it tries to use the
path returned by build_path_from_dentry. Fix compose_mount_options to
expect properly formed DFS paths (single backslash at front).
Also clean up error handling in that function. There was a possible
NULL pointer dereference and situations where a partially built option
string would be returned.
Tested against Samba 3.0.28-ish server and Samba 3.3 and Win2k8.
CC: Stable <stable@kernel.org>
Signed-off-by: Jeff Layton <jlayton@redhat.com>
Signed-off-by: Steve French <sfrench@us.ibm.com>
Windows allows you to deny access to the top of a share, but permit access to
a directory lower in the path. With the prefixpath feature of cifs
(ie mounting \\server\share\directory\subdirectory\etc.) this should have
worked if the user specified a prefixpath which put the root of the mount
at a directory to which he had access, but we still were doing a lookup
on the root of the share (null path) when we should have been doing it on
the prefixpath subdirectory.
This fixes Samba bug # 5925
Acked-by: Jeff Layton <jlayton@redhat.com>
Signed-off-by: Steve French <sfrench@us.ibm.com>
Some applications/subsystems require mandatory byte range locks
(as is used for Windows/DOS/OS2 etc). Sending advisory (posix style)
byte range lock requests (instead of mandatory byte range locks) can
lead to problems for these applications (which expect that other
clients be prevented from writing to portions of the file which
they have locked and are updating). This mount option allows
mounting cifs with the new mount option "forcemand" (or
"forcemandatorylock") in order to have the cifs client use mandatory
byte range locks (ie SMB/CIFS/Windows/NTFS style locks) rather than
posix byte range lock requests, even if the server would support
posix byte range lock requests. This has no effect if the server
does not support the CIFS Unix Extensions (since posix style locks
require support for the CIFS Unix Extensions), but for mounts
to Samba servers this can be helpful for Wine and applications
that require mandatory byte range locks.
Acked-by: Jeff Layton <jlayton@redhat.com>
CC: Alexander Bokovoy <ab@samba.org>
Signed-off-by: Steve French <sfrench@us.ibm.com>
This was recently changed to check for need_reconnect, but should
actually be a check for a tidStatus of CifsExiting.
Signed-off-by: Jeff Layton <jlayton@redhat.com>
Signed-off-by: Steve French <sfrench@us.ibm.com>
CIFS in some heavy stress conditions cifs could get EAGAIN
repeatedly in smb_send2 which led to repeated retries and eventually
failure of large writes which could lead to data corruption.
There are three changes that were suggested by various network
developers:
1) convert cifs from non-blocking to blocking tcp sendmsg
(we left in the retry on failure)
2) change cifs to not set sendbuf and rcvbuf size for the socket
(let tcp autotune the buffer sizes since that works much better
in the TCP stack now)
3) if we have a partial frame sent in smb_send2, mark the tcp
session as invalid (close the socket and reconnect) so we do
not corrupt the remaining part of the SMB with the beginning
of the next SMB.
This does not appear to hurt performance measurably and has
been run in various scenarios, but it definately removes
a corruption that we were seeing in some high stress
test cases.
Acked-by: Shirish Pargaonkar <shirishp@us.ibm.com>
Signed-off-by: Steve French <sfrench@us.ibm.com>
fcntl(F_SETLEASE) currently is not exported by cifs (nor by local file
systems) so cifs grants leases based on how other local processes have
opened the file not by whether the file is cacheable (oplocked). This
adds the check to make sure that the file is cacheable on the client
before checking whether we can grant the lease locally
(generic_setlease). It also adds a mount option for cifs (locallease)
if the user wants to override this and try to grant leases even
if the server did not grant oplock.
Signed-off-by: Steve French <sfrench@us.ibm.com>
The cifs_rename_pending_delete process involves multiple steps. If it
fails and we're going to return error, we don't want to leave things in
a half-finished state. Add code to the function to undo changes if
a call fails.
Signed-off-by: Jeff Layton <jlayton@redhat.com>
Signed-off-by: Steve French <sfrench@us.ibm.com>
Otherwise, we're leaking the payload memory.
CC: Stable Kernel <stable@vger.kernel.org>
Acked-by: David Howells <dhowells@redhat.com>
Signed-off-by: Jeff Layton <jlayton@redhat.com>
Signed-off-by: Steve French <sfrench@us.ibm.com>
Currently, we don't check the version in the SPNEGO upcall response
even though one is provided. Jeff and Q have made the corresponding
change to the Samba client (cifs.upcall).
Acked-by: Jeff Layton <jlayton@redhat.com>
Signed-off-by: Steve French <sfrench@us.ibm.com>
Final piece for handling DFS in unix_query_path_info, constructing a
fake inode for the junction directory which the submount will cover.
Acked-by: Igor Mammedov <niallain@gmail.com>
Signed-off-by: Steve French <sfrench@us.ibm.com>
When CIFSFindNext gets back an -EBADF from a call, it sets the return
code of the function to 0 and eventually exits. Doing this makes the
cleanup at the end of the function skip freeing the SMB buffer, so
we need to make sure we free the buffer explicitly when doing this.
If we don't you end up with errors like this when unplugging the cifs
kernel module:
slab error in kmem_cache_destroy(): cache `cifs_request': Can't free all objects
[<c046bdbf>] kmem_cache_destroy+0x61/0xf3
[<e0f03045>] cifs_destroy_request_bufs+0x14/0x28 [cifs]
[<e0f2016e>] exit_cifs+0x1e/0x80 [cifs]
[<c043aeae>] sys_delete_module+0x192/0x1b8
[<c04451fd>] audit_syscall_entry+0x14b/0x17d
[<c0405413>] syscall_call+0x7/0xb
=======================
Signed-off-by: Jeff Layton <jlayton@redhat.com>
Currently, when we get a prefixpath as part of mount, the kernel only
changes the first character to be a '/' or '\' depending on whether
posix extensions are enabled. This is problematic as it expects
mount.cifs to pass in the correct delimiter in the rest of the
prefixpath. But, mount.cifs may not know *what* the correct delimiter
is. It's a chicken and egg problem.
Note that mount.cifs should not do conversion of the
prefixpath - if we want posix behavior then '\' is legal in a path
(and we have had bugs in the distant path to prove to me that
customers sometimes have apps that require '\'). The kernel code
assumes that the path passed in is posix (and current code will handle
the first path component fine but was broken for Windows mounts
for "deep" prefixpaths unless the user specified a prefixpath with '\'
deep in it. So e.g. with current kernel code:
1) mount to //server/share/dir1 will work to all server types
2) mount to //server/share/dir1/subdir1 will work to Samba
3) mount to //server/share/dir1\\subdir1 will work to Windows
But case two would fail to Windows without the fix.
With the kernel cifs module fix case two now works.
First analyzed by Jeff Layton and Simo Sorce
CC: Jeff Layton <jlayton@redhat.com>
CC: Simo Sorce <simo@samba.org>
Signed-off-by: Steve French <sfrench@us.ibm.com>
Requires cifsacl mount flag to be on and CIFS_EXPERIMENTAL enabled
CC: Shirish Pargaonkar <shirishp@us.ibm.com>
Signed-off-by: Steve French <sfrench@us.ibm.com>
When cifs_mount finds an existing SMB session that it can use for a new
mount, it does not check to see whether that session is in need of being
reconnected. An easy way to reproduce:
1) mount //server/share1
2) watch /proc/fs/cifs/DebugData for the share to go DISCONNECTED
3) mount //server/share2 with same creds as in step 1.
The second mount will fail because CIFSTCon returned -EAGAIN. If you do
an operation in share1 and then reattempt the mount it will work (since
the session is reestablished).
The following patch fixes this by having cifs_mount check the status
of the session when it picks an existing session and calling
cifs_setup_session on it again if it's in need of reconnection.
Thanks to Wojciech Pilorz for the initial bug report.
Signed-off-by: Jeff Layton <jlayton@tupile.poochiereds.net>
Signed-off-by: Steve French <sfrench@us.ibm.com>
Fix RedHat bug 329431
The idea here is separate "conscious" from "unconscious" flushes.
Conscious flushes are those due to a fsync() or close(). Unconscious
ones are flushes that occur as a side effect of some other operation or
due to memory pressure.
Currently, when an error occurs during an unconscious flush (ENOSPC or
EIO), we toss out the page and don't preserve that error to report to
the user when a conscious flush occurs. If after the unconscious flush,
there are no more dirty pages for the inode, the conscious flush will
simply return success even though there were previous errors when writing
out pages. This can lead to data corruption.
The easiest way to reproduce this is to mount up a CIFS share that's
very close to being full or where the user is very close to quota. mv
a file to the share that's slightly larger than the quota allows. The
writes will all succeed (since they go to pagecache). The mv will do a
setattr to set the new file's attributes. This calls
filemap_write_and_wait,
which will return an error since all of the pages can't be written out.
Then later, when the flush and release ops occur, there are no more
dirty pages in pagecache for the file and those operations return 0. mv
then assumes that the file was written out correctly and deletes the
original.
CIFS already has a write_behind_rc variable where it stores the results
from earlier flushes, but that value is only reported in cifs_close.
Since the VFS ignores the return value from the release operation, this
isn't helpful. We should be reporting this error during the flush
operation.
This patch does the following:
1) changes cifs_fsync to use filemap_write_and_wait and cifs_flush and also
sync to check its return code. If it returns successful, they then check
the value of write_behind_rc to see if an earlier flush had reported any
errors. If so, they return that error and clear write_behind_rc.
2) sets write_behind_rc in a few other places where pages are written
out as a side effect of other operations and the code waits on them.
3) changes cifs_setattr to only call filemap_write_and_wait for
ATTR_SIZE changes.
4) makes cifs_writepages accurately distinguish between EIO and ENOSPC
errors when writing out pages.
Some simple testing indicates that the patch works as expected and that
it fixes the reproduceable known problem.
Acked-by: Dave Kleikamp <shaggy@austin.rr.com>
Signed-off-by: Jeff Layton <jlayton@redhat.com>
Signed-off-by: Steve French <sfrench@us.ibm.com>
Have CIFS_SessSetup call cifs_get_spnego_key when Kerberos is
negotiated. Use the info in the key payload to build a session
setup request packet. Also clean up how the request buffer in
the function is freed on error.
With appropriate user space helper (in samba/source/client). Kerberos
support (secure session establishment can be done now via Kerberos,
previously users would have to use NTLMv2 instead for more secure
session setup).
Signed-off-by: Jeff Layton <jlayton@redhat.com>
Signed-off-by: Steve French <sfrench@us.ibm.com>
When a share is mounted using no username, cifs_mount sets
volume_info.username as a NULL pointer, and the sesInfo userName as an
empty string. The volume_info.username is passed to a couple of other
functions to see if there is an existing unc or tcp connection that can
be used. These functions assume that the username will be a valid
string that can be passed to strncmp. If the pointer is NULL, then the
kernel will oops if there's an existing session to which the string
can be compared.
This patch changes cifs_mount to set volume_info.username to an empty
string in this situation, which prevents the oops and should make it
so that the comparison to other null auth sessions match.
Signed-off-by: Jeff Layton <jlayton@redhat.com>
Signed-off-by: Steve French <sfrench@us.ibm.com>
Kernel bugzilla bug #9228
If mount helper (mount.cifs) missing, mounts with form like
//10.11.12.13/c$ would not work (only mounts with slash e.g.
//10.11.12.13\\c$ would work) due to problem with slash supposed
to be converted to backslash by the mount helper (which is not
there).
If we fail on converting an IPv4 address in in4_pton then
try to canonicalize the first slash (ie between sharename
and host ip address) if necessary. If we have to retry
to check for IPv6 address the slash is already converted
if necessary.
Signed-off-by: Steve French <sfrench@us.ibm.com>
Part 9 of ACL patch series. getting mode from ACL now works in
some cases (and requires CIFS_EXPERIMENTAL config option).
Signed-off-by: Shirish Pargaonkar <shirishp@us.ibm.com>
Signed-off-by: Steve French <sfrench@us.ibm.com>
When kernel_recvmsg returns -EAGAIN or -ERESTARTSYS, then
cifs_demultiplex_thread sleeps for a bit and then tries the read again.
When it does this, it's not zeroing out the length and that throws off
the value of total_read. Fix it to zero out the length.
Can cause memory corruption:
If kernel_recvmsg returns an error and total_read is a large enough
value, then we'll end up going through the loop again. total_read will
be a bogus value, as will (pdu_length-total_read). When this happens we
end up calling kernel_recvmsg with a bogus value (possibly larger than
the current iov_len).
At that point, memcpy_toiovec can overrun iov. It will start walking
up the stack, casting other things that are there to struct iovecs
(since it assumes that it's been passed an array of them). Any pointer
on the stack at an address above the kvec is a candidate for corruption
here.
Many thanks to Ulrich Obergfell for pointing this out.
Signed-off-by: Jeff Layton <jlayton@redhat.com>
Signed-off-by: Steve French <sfrench@us.ibm.com>
We were allocating request buffers twice in the statfs
path when mounted to very old (Windows 9x) servers.
Signed-off-by: Steve French <sfrench@us.ibm.com>
On a mount without posix extensions enabled, when an unlock request is
made, the client can release more than is intended. To reproduce, on a
CIFS mount without posix extensions enabled:
1) open file
2) do fcntl lock: start=0 len=1
3) do fcntl lock: start=2 len=1
4) do fcntl unlock: start=0 len=1
...on the unlock call the client sends an unlock request to the server
for both locks. The problem is a bad test in cifs_lock.
Signed-off-by: Jeff Layton <jlayton@redhat.com>
Signed-off-by: Steve French <sfrench@us.ibm.com>
Caused by unneeded reopen during reconnect while spinlock held.
Fixes kernel bugzilla bug #7903
Thanks to Lin Feng Shen for testing this, and Amit Arora for
some nice problem determination to narrow this down.
Acked-by: Dave Kleikamp <shaggy@us.ibm.com>
Signed-off-by: Steve French <sfrench@us.ibm.com>
In the cleanup phase of the dbench test, we were noticing sharing
violation followed by failed directory removals when dbench
did not close the test files before the cleanup phase started.
Using the new POSIX unlink, which Samba has supported for a few
months, avoids this.
Signed-off-by: Steve French <sfrench@us.ibm.com>
nfsd is passing null nameidata (probably the only one doing that)
on call to create - cifs was missing one check for this.
Note that running nfsd over a cifs mount requires specifying fsid on
the nfs exports entry and requires mounting cifs with serverino mount
option.
Signed-off-by: Steve French <sfrench@us.ibm.com>
Currently, if mount with a signing-enabled sec= option (e.g.
sec=ntlmi), the kernel does a warning printk if the server doesn't
support signing, and then proceeds without signatures.
This is probably OK for people that think to look at the ring buffer,
but seems wrong to me. If someone explicitly requests signing, we
should error out if that request can't be satisfied. They can then
reattempt the mount without signing if that's ok.
Signed-off-by: Jeff Layton <jlayton@redhat.com>
Signed-off-by: Steve French <sfrench@us.ibm.com>
We had a customer report that attempting to make CIFS mount with a null
username (i.e. doing an anonymous mount) doesn't work. Looking through the
code, it looks like CIFS expects a NULL username from userspace in order
to trigger an anonymous mount. The mount.cifs code doesn't seem to ever
pass a null username to the kernel, however.
It looks also like the kernel can take a sec=none option, but it only seems
to look at it if the username is already NULL. This seems redundant and
effectively makes sec=none useless.
The following patch makes sec=none force an anonymous mount.
Signed-off-by: Steve French <sfrench@us.ibm.com>
When CIFS Unix Extensions are negotiated we get the Unix uid and gid
owners of the file from the server (on the Unix Query Path Info
levels), but if the server's uids don't match the client uid's users
were having to disable the Unix Extensions (which turned off features
they still wanted). The changeset patch allows users to override uid
and/or gid for file/directory owner with a default uid and/or gid
specified at mount (as is often done when mounting from Linux cifs
client to Windows server). This changeset also displays the uid
and gid used by default in /proc/mounts (if applicable).
Also cleans up code by adding some of the missing spaces after
"if" keywords per-kernel style guidelines (as suggested by Randy Dunlap
when he reviewed the patch).
Signed-off-by: Steve French <sfrench@us.ibm.com>
IPv6 support was started a few years ago in the cifs client, but lacked a
kernel helper function for parsing the ascii form of the ipv6 address. Now
that that is added (and now IPv6 is the default that some OS use now) it
was fairly easy to finish the cifs ipv6 support. This requires that
CIFS_EXPERIMENTAL be enabled and (at least until the mount.cifs module is
modified to use a new ipv6 friendly call instead of gethostbyname) and the
ipv6 address be passed on the mount as "ip=" mount option.
Thanks
Signed-off-by: Steve French <sfrench@us.ibm.com>
Remove read only dos attribute on chmod when adding any write permission (ie on any of
user/group/other (not all of user/group/other ie 0222) when
mounted to windows.
Suggested by: Urs Fleisch
Signed-off-by: Urs Fleisch <urs.fleisch@gmail.com>
Signed-off-by: Steve French <sfrench@us.ibm.com>
When a file had a dos attribute of 0x1 (readonly - but dos attribute
of archive was not set) - doing chmod 0777 or equivalent would
try to set a dos attribute of 0 (which some servers ignore)
rather than ATTR_NORMAL (0x20) which most servers accept.
Does not affect servers which support the CIFS Unix Extensions.
Acked-by: Prasad Potluri <pvp@us.ibm.com>
Acked-by: Shirish Pargaonkar <shirishp@us.ibm.com>
Signed-off-by: Steve French <sfrench@us.ibm.com>
Could cause hangs on smp systems in i_size_read on a cifs inode
whose size has been previously simultaneously updated from
different processes.
Thanks to Brian Wang for some great testing/debugging on this
hard problem.
Fixes kernel bugzilla #7903
CC: Shirish Pargoankar <shirishp@us.ibm.com>
CC: Shaggy <shaggy@us.ibm.com>
Signed-off-by: Steve French <sfrench@us.ibm.com>