Skip to content

Commit 6473a55

Browse files
author
Steve French
committed
[CIFS] Fix missing permission check on setattr when noperm mount option is
disabled. Also set mode, uid, gid better on mkdir and create for the case when Unix Extensions is not enabled and setuids is enabled. This is necessary to fix the hole in which chown could be allowed for non-root users in some cases if root mounted, and also to display the mode and uid properly in some cases. Signed-off-by: Steve French <[email protected]>
1 parent 3abb927 commit 6473a55

File tree

5 files changed

+60
-13
lines changed

5 files changed

+60
-13
lines changed

fs/cifs/CHANGES

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ stress on writes). Modify cifs Kconfig options to expose CONFIG_CIFS_STATS2
66
Fix SFU style symlinks and mknod needed for servers which do not support the
77
CIFS Unix Extensions. Fix setfacl/getfacl on bigendian. Timeout negative
88
dentries so files that the client sees as deleted but that later get created
9-
on the server will be recognized.
9+
on the server will be recognized. Add client side permission check on setattr.
1010

1111
Version 1.38
1212
------------

fs/cifs/README

Lines changed: 24 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -278,7 +278,9 @@ A partial list of the supported mount options follows:
278278
(such as Windows), permissions can also be checked at the
279279
client, and a crude form of client side permission checking
280280
can be enabled by specifying file_mode and dir_mode on
281-
the client
281+
the client. Note that the mount.cifs helper must be
282+
at version 1.10 or higher to support specifying the uid
283+
(or gid) in non-numberic form.
282284
gid If CIFS Unix extensions are not supported by the server
283285
this overrides the default gid for inodes.
284286
file_mode If CIFS Unix extensions are not supported by the server
@@ -345,7 +347,10 @@ A partial list of the supported mount options follows:
345347
client system. It is typically only needed when the server
346348
supports the CIFS Unix Extensions but the UIDs/GIDs on the
347349
client and server system do not match closely enough to allow
348-
access by the user doing the mount.
350+
access by the user doing the mount, but it may be useful with
351+
non CIFS Unix Extension mounts for cases in which the default
352+
mode is specified on the mount but is not to be enforced on the
353+
client (e.g. perhaps when MultiUserMount is enabled)
349354
Note that this does not affect the normal ACL check on the
350355
target machine done by the server software (of the server
351356
ACL against the user name provided at mount time).
@@ -368,15 +373,21 @@ A partial list of the supported mount options follows:
368373
setuids If the CIFS Unix extensions are negotiated with the server
369374
the client will attempt to set the effective uid and gid of
370375
the local process on newly created files, directories, and
371-
devices (create, mkdir, mknod).
376+
devices (create, mkdir, mknod). If the CIFS Unix Extensions
377+
are not negotiated, for newly created files and directories
378+
instead of using the default uid and gid specified on the
379+
the mount, cache the new file's uid and gid locally which means
380+
that the uid for the file can change when the inode is
381+
reloaded (or the user remounts the share).
372382
nosetuids The client will not attempt to set the uid and gid on
373383
on newly created files, directories, and devices (create,
374384
mkdir, mknod) which will result in the server setting the
375385
uid and gid to the default (usually the server uid of the
376386
user who mounted the share). Letting the server (rather than
377-
the client) set the uid and gid is the default. This
378-
parameter has no effect if the CIFS Unix Extensions are not
379-
negotiated.
387+
the client) set the uid and gid is the default. If the CIFS
388+
Unix Extensions are not negotiated then the uid and gid for
389+
new files will appear to be the uid (gid) of the mounter or the
390+
uid (gid) parameter specified on the mount.
380391
netbiosname When mounting to servers via port 139, specifies the RFC1001
381392
source name to use to represent the client netbios machine
382393
name when doing the RFC1001 netbios session initialize.
@@ -418,6 +429,13 @@ A partial list of the supported mount options follows:
418429
byte range locks).
419430
remount remount the share (often used to change from ro to rw mounts
420431
or vice versa)
432+
sfu When the CIFS Unix Extensions are not negotiated, attempt to
433+
create device files and fifos in a format compatible with
434+
Services for Unix (SFU). In addition retrieve bits 10-12
435+
of the mode via the SETFILEBITS extended attribute (as
436+
SFU does). In the future the bottom 9 bits of the mode
437+
mode also will be emulated using queries of the security
438+
descriptor (ACL).
421439

422440
The mount.cifs mount helper also accepts a few mount options before -o
423441
including:

fs/cifs/TODO

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
version 1.37 October 9, 2005
1+
Version 1.39 November 30, 2005
22

33
A Partial List of Missing Features
44
==================================
@@ -58,7 +58,7 @@ o) Improve performance of readpages by sending more than one read
5858
at a time when 8 pages or more are requested. In conjuntion
5959
add support for async_cifs_readpages.
6060

61-
p) Add support for storing symlink and fifo info to Windows servers
61+
p) Add support for storing symlink info to Windows servers
6262
in the Extended Attribute format their SFU clients would recognize.
6363

6464
q) Finish fcntl D_NOTIFY support so kde and gnome file list windows

fs/cifs/dir.c

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -228,8 +228,15 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode,
228228
else {
229229
rc = cifs_get_inode_info(&newinode, full_path,
230230
buf, inode->i_sb,xid);
231-
if(newinode)
231+
if(newinode) {
232232
newinode->i_mode = mode;
233+
if((oplock & CIFS_CREATE_ACTION) &&
234+
(cifs_sb->mnt_cifs_flags &
235+
CIFS_MOUNT_SET_UID)) {
236+
newinode->i_uid = current->fsuid;
237+
newinode->i_gid = current->fsgid;
238+
}
239+
}
233240
}
234241

235242
if (rc != 0) {

fs/cifs/inode.c

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -710,7 +710,7 @@ int cifs_mkdir(struct inode *inode, struct dentry *direntry, int mode)
710710
char *full_path = NULL;
711711
struct inode *newinode = NULL;
712712

713-
cFYI(1, ("In cifs_mkdir, mode = 0x%x inode = 0x%p ", mode, inode));
713+
cFYI(1, ("In cifs_mkdir, mode = 0x%x inode = 0x%p", mode, inode));
714714

715715
xid = GetXid();
716716

@@ -768,7 +768,16 @@ int cifs_mkdir(struct inode *inode, struct dentry *direntry, int mode)
768768
/* BB to be implemented via Windows secrty descriptors
769769
eg CIFSSMBWinSetPerms(xid, pTcon, full_path, mode,
770770
-1, -1, local_nls); */
771-
}
771+
if(direntry->d_inode) {
772+
direntry->d_inode->i_mode = mode;
773+
if(cifs_sb->mnt_cifs_flags &
774+
CIFS_MOUNT_SET_UID) {
775+
direntry->d_inode->i_uid =
776+
current->fsuid;
777+
direntry->d_inode->i_gid =
778+
current->fsgid;
779+
}
780+
}
772781
}
773782
kfree(full_path);
774783
FreeXid(xid);
@@ -1111,9 +1120,20 @@ int cifs_setattr(struct dentry *direntry, struct iattr *attrs)
11111120

11121121
cFYI(1, ("In cifs_setattr, name = %s attrs->iavalid 0x%x ",
11131122
direntry->d_name.name, attrs->ia_valid));
1123+
11141124
cifs_sb = CIFS_SB(direntry->d_inode->i_sb);
11151125
pTcon = cifs_sb->tcon;
11161126

1127+
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_PERM == 0) {
1128+
/* check if we have permission to change attrs */
1129+
rc = inode_change_ok(direntry->d_inode, attrs);
1130+
if(rc < 0) {
1131+
FreeXid(xid);
1132+
return rc;
1133+
} else
1134+
rc = 0;
1135+
}
1136+
11171137
down(&direntry->d_sb->s_vfs_rename_sem);
11181138
full_path = build_path_from_dentry(direntry);
11191139
up(&direntry->d_sb->s_vfs_rename_sem);
@@ -1153,7 +1173,9 @@ int cifs_setattr(struct dentry *direntry, struct iattr *attrs)
11531173
1 /* 45 seconds */);
11541174
cFYI(1,("Wrt seteof rc %d", rc));
11551175
}
1156-
}
1176+
} else
1177+
rc = -EINVAL;
1178+
11571179
if (rc != 0) {
11581180
/* Set file size by pathname rather than by handle
11591181
either because no valid, writeable file handle for

0 commit comments

Comments
 (0)