mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-29 11:11:45 -04:00
[XFS] Fix merge failures
Merge git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6 Conflicts: fs/xfs/linux-2.6/xfs_cred.h fs/xfs/linux-2.6/xfs_globals.h fs/xfs/linux-2.6/xfs_ioctl.c fs/xfs/xfs_vnodeops.h Signed-off-by: Lachlan McIlroy <[email protected]>
This commit is contained in:
commit
0a8c5395f9
2880 changed files with 143837 additions and 81099 deletions
|
|
@ -120,7 +120,7 @@ struct p9_fid *v9fs_fid_lookup(struct dentry *dentry)
|
|||
switch (access) {
|
||||
case V9FS_ACCESS_SINGLE:
|
||||
case V9FS_ACCESS_USER:
|
||||
uid = current->fsuid;
|
||||
uid = current_fsuid();
|
||||
any = 0;
|
||||
break;
|
||||
|
||||
|
|
|
|||
|
|
@ -215,8 +215,8 @@ struct inode *v9fs_get_inode(struct super_block *sb, int mode)
|
|||
inode = new_inode(sb);
|
||||
if (inode) {
|
||||
inode->i_mode = mode;
|
||||
inode->i_uid = current->fsuid;
|
||||
inode->i_gid = current->fsgid;
|
||||
inode->i_uid = current_fsuid();
|
||||
inode->i_gid = current_fsgid();
|
||||
inode->i_blocks = 0;
|
||||
inode->i_rdev = 0;
|
||||
inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
|
||||
|
|
|
|||
|
|
@ -113,8 +113,8 @@ static int v9fs_get_sb(struct file_system_type *fs_type, int flags,
|
|||
struct v9fs_session_info *v9ses = NULL;
|
||||
struct p9_wstat *st = NULL;
|
||||
int mode = S_IRWXUGO | S_ISVTX;
|
||||
uid_t uid = current->fsuid;
|
||||
gid_t gid = current->fsgid;
|
||||
uid_t uid = current_fsuid();
|
||||
gid_t gid = current_fsgid();
|
||||
struct p9_fid *fid;
|
||||
int retval = 0;
|
||||
|
||||
|
|
|
|||
|
|
@ -293,8 +293,8 @@ affs_new_inode(struct inode *dir)
|
|||
mark_buffer_dirty_inode(bh, inode);
|
||||
affs_brelse(bh);
|
||||
|
||||
inode->i_uid = current->fsuid;
|
||||
inode->i_gid = current->fsgid;
|
||||
inode->i_uid = current_fsuid();
|
||||
inode->i_gid = current_fsgid();
|
||||
inode->i_ino = block;
|
||||
inode->i_nlink = 1;
|
||||
inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME_SEC;
|
||||
|
|
|
|||
|
|
@ -163,8 +163,8 @@ parse_options(char *options, uid_t *uid, gid_t *gid, int *mode, int *reserved, s
|
|||
|
||||
/* Fill in defaults */
|
||||
|
||||
*uid = current->uid;
|
||||
*gid = current->gid;
|
||||
*uid = current_uid();
|
||||
*gid = current_gid();
|
||||
*reserved = 2;
|
||||
*root = -1;
|
||||
*blocksize = -1;
|
||||
|
|
|
|||
|
|
@ -646,7 +646,7 @@ static int afs_proc_cell_vlservers_show(struct seq_file *m, void *v)
|
|||
}
|
||||
|
||||
/* display one cell per line on subsequent lines */
|
||||
seq_printf(m, "%u.%u.%u.%u\n", NIPQUAD(addr->s_addr));
|
||||
seq_printf(m, "%pI4\n", &addr->s_addr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -737,7 +737,7 @@ static int afs_proc_cell_servers_show(struct seq_file *m, void *v)
|
|||
}
|
||||
|
||||
/* display one cell per line on subsequent lines */
|
||||
sprintf(ipaddr, "%u.%u.%u.%u", NIPQUAD(server->addr));
|
||||
sprintf(ipaddr, "%pI4", &server->addr);
|
||||
seq_printf(m, "%3d %-15.15s %5d\n",
|
||||
atomic_read(&server->usage), ipaddr, server->fs_state);
|
||||
|
||||
|
|
|
|||
|
|
@ -105,7 +105,7 @@ struct afs_server *afs_lookup_server(struct afs_cell *cell,
|
|||
{
|
||||
struct afs_server *server, *candidate;
|
||||
|
||||
_enter("%p,"NIPQUAD_FMT, cell, NIPQUAD(addr->s_addr));
|
||||
_enter("%p,%pI4", cell, &addr->s_addr);
|
||||
|
||||
/* quick scan of the list to see if we already have the server */
|
||||
read_lock(&cell->servers_lock);
|
||||
|
|
@ -168,9 +168,8 @@ found_server:
|
|||
server_in_two_cells:
|
||||
write_unlock(&cell->servers_lock);
|
||||
kfree(candidate);
|
||||
printk(KERN_NOTICE "kAFS:"
|
||||
" Server "NIPQUAD_FMT" appears to be in two cells\n",
|
||||
NIPQUAD(*addr));
|
||||
printk(KERN_NOTICE "kAFS: Server %pI4 appears to be in two cells\n",
|
||||
addr);
|
||||
_leave(" = -EEXIST");
|
||||
return ERR_PTR(-EEXIST);
|
||||
}
|
||||
|
|
@ -184,7 +183,7 @@ struct afs_server *afs_find_server(const struct in_addr *_addr)
|
|||
struct rb_node *p;
|
||||
struct in_addr addr = *_addr;
|
||||
|
||||
_enter(NIPQUAD_FMT, NIPQUAD(addr.s_addr));
|
||||
_enter("%pI4", &addr.s_addr);
|
||||
|
||||
read_lock(&afs_servers_lock);
|
||||
|
||||
|
|
|
|||
|
|
@ -154,8 +154,8 @@ static struct inode *anon_inode_mkinode(void)
|
|||
*/
|
||||
inode->i_state = I_DIRTY;
|
||||
inode->i_mode = S_IRUSR | S_IWUSR;
|
||||
inode->i_uid = current->fsuid;
|
||||
inode->i_gid = current->fsgid;
|
||||
inode->i_uid = current_fsuid();
|
||||
inode->i_gid = current_fsgid();
|
||||
inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
|
||||
return inode;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,13 +29,13 @@ int inode_change_ok(struct inode *inode, struct iattr *attr)
|
|||
|
||||
/* Make sure a caller can chown. */
|
||||
if ((ia_valid & ATTR_UID) &&
|
||||
(current->fsuid != inode->i_uid ||
|
||||
(current_fsuid() != inode->i_uid ||
|
||||
attr->ia_uid != inode->i_uid) && !capable(CAP_CHOWN))
|
||||
goto error;
|
||||
|
||||
/* Make sure caller can chgrp. */
|
||||
if ((ia_valid & ATTR_GID) &&
|
||||
(current->fsuid != inode->i_uid ||
|
||||
(current_fsuid() != inode->i_uid ||
|
||||
(!in_group_p(attr->ia_gid) && attr->ia_gid != inode->i_gid)) &&
|
||||
!capable(CAP_CHOWN))
|
||||
goto error;
|
||||
|
|
|
|||
|
|
@ -76,8 +76,8 @@ static int parse_options(char *options, int *pipefd, uid_t *uid, gid_t *gid,
|
|||
substring_t args[MAX_OPT_ARGS];
|
||||
int option;
|
||||
|
||||
*uid = current->uid;
|
||||
*gid = current->gid;
|
||||
*uid = current_uid();
|
||||
*gid = current_gid();
|
||||
*pgrp = task_pgrp_nr(current);
|
||||
|
||||
*minproto = *maxproto = AUTOFS_PROTO_VERSION;
|
||||
|
|
|
|||
|
|
@ -308,7 +308,8 @@ static int autofs_dev_ioctl_open_mountpoint(const char *path, dev_t devid)
|
|||
goto out;
|
||||
}
|
||||
|
||||
filp = dentry_open(nd.path.dentry, nd.path.mnt, O_RDONLY);
|
||||
filp = dentry_open(nd.path.dentry, nd.path.mnt, O_RDONLY,
|
||||
current_cred());
|
||||
if (IS_ERR(filp)) {
|
||||
err = PTR_ERR(filp);
|
||||
goto out;
|
||||
|
|
|
|||
|
|
@ -235,8 +235,8 @@ static int parse_options(char *options, int *pipefd, uid_t *uid, gid_t *gid,
|
|||
substring_t args[MAX_OPT_ARGS];
|
||||
int option;
|
||||
|
||||
*uid = current->uid;
|
||||
*gid = current->gid;
|
||||
*uid = current_uid();
|
||||
*gid = current_gid();
|
||||
*pgrp = task_pgrp_nr(current);
|
||||
|
||||
*minproto = AUTOFS_MIN_PROTO_VERSION;
|
||||
|
|
|
|||
|
|
@ -391,8 +391,8 @@ int autofs4_wait(struct autofs_sb_info *sbi, struct dentry *dentry,
|
|||
memcpy(&wq->name, &qstr, sizeof(struct qstr));
|
||||
wq->dev = autofs4_get_dev(sbi);
|
||||
wq->ino = autofs4_get_ino(sbi);
|
||||
wq->uid = current->uid;
|
||||
wq->gid = current->gid;
|
||||
wq->uid = current_uid();
|
||||
wq->gid = current_gid();
|
||||
wq->pid = current->pid;
|
||||
wq->tgid = current->tgid;
|
||||
wq->status = -EINTR; /* Status return if interrupted */
|
||||
|
|
|
|||
|
|
@ -106,8 +106,8 @@ static int bfs_create(struct inode *dir, struct dentry *dentry, int mode,
|
|||
}
|
||||
set_bit(ino, info->si_imap);
|
||||
info->si_freei--;
|
||||
inode->i_uid = current->fsuid;
|
||||
inode->i_gid = (dir->i_mode & S_ISGID) ? dir->i_gid : current->fsgid;
|
||||
inode->i_uid = current_fsuid();
|
||||
inode->i_gid = (dir->i_mode & S_ISGID) ? dir->i_gid : current_fsgid();
|
||||
inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME_SEC;
|
||||
inode->i_blocks = 0;
|
||||
inode->i_op = &bfs_file_inops;
|
||||
|
|
|
|||
|
|
@ -320,7 +320,7 @@ static int load_aout_binary(struct linux_binprm * bprm, struct pt_regs * regs)
|
|||
current->mm->free_area_cache = current->mm->mmap_base;
|
||||
current->mm->cached_hole_size = 0;
|
||||
|
||||
compute_creds(bprm);
|
||||
install_exec_creds(bprm);
|
||||
current->flags &= ~PF_FORKNOEXEC;
|
||||
#ifdef __sparc__
|
||||
if (N_MAGIC(ex) == NMAGIC) {
|
||||
|
|
|
|||
|
|
@ -157,7 +157,7 @@ create_elf_tables(struct linux_binprm *bprm, struct elfhdr *exec,
|
|||
int items;
|
||||
elf_addr_t *elf_info;
|
||||
int ei_index = 0;
|
||||
struct task_struct *tsk = current;
|
||||
const struct cred *cred = current_cred();
|
||||
struct vm_area_struct *vma;
|
||||
|
||||
/*
|
||||
|
|
@ -223,10 +223,10 @@ create_elf_tables(struct linux_binprm *bprm, struct elfhdr *exec,
|
|||
NEW_AUX_ENT(AT_BASE, interp_load_addr);
|
||||
NEW_AUX_ENT(AT_FLAGS, 0);
|
||||
NEW_AUX_ENT(AT_ENTRY, exec->e_entry);
|
||||
NEW_AUX_ENT(AT_UID, tsk->uid);
|
||||
NEW_AUX_ENT(AT_EUID, tsk->euid);
|
||||
NEW_AUX_ENT(AT_GID, tsk->gid);
|
||||
NEW_AUX_ENT(AT_EGID, tsk->egid);
|
||||
NEW_AUX_ENT(AT_UID, cred->uid);
|
||||
NEW_AUX_ENT(AT_EUID, cred->euid);
|
||||
NEW_AUX_ENT(AT_GID, cred->gid);
|
||||
NEW_AUX_ENT(AT_EGID, cred->egid);
|
||||
NEW_AUX_ENT(AT_SECURE, security_bprm_secureexec(bprm));
|
||||
NEW_AUX_ENT(AT_EXECFN, bprm->exec);
|
||||
if (k_platform) {
|
||||
|
|
@ -949,14 +949,14 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs)
|
|||
set_binfmt(&elf_format);
|
||||
|
||||
#ifdef ARCH_HAS_SETUP_ADDITIONAL_PAGES
|
||||
retval = arch_setup_additional_pages(bprm, executable_stack);
|
||||
retval = arch_setup_additional_pages(bprm, !!elf_interpreter);
|
||||
if (retval < 0) {
|
||||
send_sig(SIGKILL, current, 0);
|
||||
goto out;
|
||||
}
|
||||
#endif /* ARCH_HAS_SETUP_ADDITIONAL_PAGES */
|
||||
|
||||
compute_creds(bprm);
|
||||
install_exec_creds(bprm);
|
||||
current->flags &= ~PF_FORKNOEXEC;
|
||||
retval = create_elf_tables(bprm, &loc->elf_ex,
|
||||
load_addr, interp_load_addr);
|
||||
|
|
@ -1361,6 +1361,7 @@ static void fill_prstatus(struct elf_prstatus *prstatus,
|
|||
static int fill_psinfo(struct elf_prpsinfo *psinfo, struct task_struct *p,
|
||||
struct mm_struct *mm)
|
||||
{
|
||||
const struct cred *cred;
|
||||
unsigned int i, len;
|
||||
|
||||
/* first copy the parameters from user space */
|
||||
|
|
@ -1388,8 +1389,11 @@ static int fill_psinfo(struct elf_prpsinfo *psinfo, struct task_struct *p,
|
|||
psinfo->pr_zomb = psinfo->pr_sname == 'Z';
|
||||
psinfo->pr_nice = task_nice(p);
|
||||
psinfo->pr_flag = p->flags;
|
||||
SET_UID(psinfo->pr_uid, p->uid);
|
||||
SET_GID(psinfo->pr_gid, p->gid);
|
||||
rcu_read_lock();
|
||||
cred = __task_cred(p);
|
||||
SET_UID(psinfo->pr_uid, cred->uid);
|
||||
SET_GID(psinfo->pr_gid, cred->gid);
|
||||
rcu_read_unlock();
|
||||
strncpy(psinfo->pr_fname, p->comm, sizeof(psinfo->pr_fname));
|
||||
|
||||
return 0;
|
||||
|
|
|
|||
|
|
@ -404,7 +404,7 @@ static int load_elf_fdpic_binary(struct linux_binprm *bprm,
|
|||
current->mm->start_stack = current->mm->start_brk + stack_size;
|
||||
#endif
|
||||
|
||||
compute_creds(bprm);
|
||||
install_exec_creds(bprm);
|
||||
current->flags &= ~PF_FORKNOEXEC;
|
||||
if (create_elf_fdpic_tables(bprm, current->mm,
|
||||
&exec_params, &interp_params) < 0)
|
||||
|
|
@ -475,6 +475,7 @@ static int create_elf_fdpic_tables(struct linux_binprm *bprm,
|
|||
struct elf_fdpic_params *exec_params,
|
||||
struct elf_fdpic_params *interp_params)
|
||||
{
|
||||
const struct cred *cred = current_cred();
|
||||
unsigned long sp, csp, nitems;
|
||||
elf_caddr_t __user *argv, *envp;
|
||||
size_t platform_len = 0, len;
|
||||
|
|
@ -623,10 +624,10 @@ static int create_elf_fdpic_tables(struct linux_binprm *bprm,
|
|||
NEW_AUX_ENT(AT_BASE, interp_params->elfhdr_addr);
|
||||
NEW_AUX_ENT(AT_FLAGS, 0);
|
||||
NEW_AUX_ENT(AT_ENTRY, exec_params->entry_addr);
|
||||
NEW_AUX_ENT(AT_UID, (elf_addr_t) current->uid);
|
||||
NEW_AUX_ENT(AT_EUID, (elf_addr_t) current->euid);
|
||||
NEW_AUX_ENT(AT_GID, (elf_addr_t) current->gid);
|
||||
NEW_AUX_ENT(AT_EGID, (elf_addr_t) current->egid);
|
||||
NEW_AUX_ENT(AT_UID, (elf_addr_t) cred->uid);
|
||||
NEW_AUX_ENT(AT_EUID, (elf_addr_t) cred->euid);
|
||||
NEW_AUX_ENT(AT_GID, (elf_addr_t) cred->gid);
|
||||
NEW_AUX_ENT(AT_EGID, (elf_addr_t) cred->egid);
|
||||
NEW_AUX_ENT(AT_SECURE, security_bprm_secureexec(bprm));
|
||||
NEW_AUX_ENT(AT_EXECFN, bprm->exec);
|
||||
|
||||
|
|
@ -1413,6 +1414,7 @@ static void fill_prstatus(struct elf_prstatus *prstatus,
|
|||
static int fill_psinfo(struct elf_prpsinfo *psinfo, struct task_struct *p,
|
||||
struct mm_struct *mm)
|
||||
{
|
||||
const struct cred *cred;
|
||||
unsigned int i, len;
|
||||
|
||||
/* first copy the parameters from user space */
|
||||
|
|
@ -1440,8 +1442,11 @@ static int fill_psinfo(struct elf_prpsinfo *psinfo, struct task_struct *p,
|
|||
psinfo->pr_zomb = psinfo->pr_sname == 'Z';
|
||||
psinfo->pr_nice = task_nice(p);
|
||||
psinfo->pr_flag = p->flags;
|
||||
SET_UID(psinfo->pr_uid, p->uid);
|
||||
SET_GID(psinfo->pr_gid, p->gid);
|
||||
rcu_read_lock();
|
||||
cred = __task_cred(p);
|
||||
SET_UID(psinfo->pr_uid, cred->uid);
|
||||
SET_GID(psinfo->pr_gid, cred->gid);
|
||||
rcu_read_unlock();
|
||||
strncpy(psinfo->pr_fname, p->comm, sizeof(psinfo->pr_fname));
|
||||
|
||||
return 0;
|
||||
|
|
|
|||
|
|
@ -880,7 +880,7 @@ static int load_flat_binary(struct linux_binprm * bprm, struct pt_regs * regs)
|
|||
(libinfo.lib_list[j].loaded)?
|
||||
libinfo.lib_list[j].start_data:UNLOADED_LIB;
|
||||
|
||||
compute_creds(bprm);
|
||||
install_exec_creds(bprm);
|
||||
current->flags &= ~PF_FORKNOEXEC;
|
||||
|
||||
set_binfmt(&flat_format);
|
||||
|
|
|
|||
|
|
@ -255,7 +255,7 @@ load_som_binary(struct linux_binprm * bprm, struct pt_regs * regs)
|
|||
kfree(hpuxhdr);
|
||||
|
||||
set_binfmt(&som_format);
|
||||
compute_creds(bprm);
|
||||
install_exec_creds(bprm);
|
||||
setup_arg_pages(bprm, STACK_TOP, EXSTACK_DEFAULT);
|
||||
|
||||
create_som_tables(bprm);
|
||||
|
|
|
|||
5
fs/bio.c
5
fs/bio.c
|
|
@ -26,8 +26,11 @@
|
|||
#include <linux/mempool.h>
|
||||
#include <linux/workqueue.h>
|
||||
#include <linux/blktrace_api.h>
|
||||
#include <trace/block.h>
|
||||
#include <scsi/sg.h> /* for struct sg_iovec */
|
||||
|
||||
DEFINE_TRACE(block_split);
|
||||
|
||||
static struct kmem_cache *bio_slab __read_mostly;
|
||||
|
||||
static mempool_t *bio_split_pool __read_mostly;
|
||||
|
|
@ -1263,7 +1266,7 @@ struct bio_pair *bio_split(struct bio *bi, int first_sectors)
|
|||
if (!bp)
|
||||
return bp;
|
||||
|
||||
blk_add_trace_pdu_int(bdev_get_queue(bi->bi_bdev), BLK_TA_SPLIT, bi,
|
||||
trace_block_split(bdev_get_queue(bi->bi_bdev), bi,
|
||||
bi->bi_sector + first_sectors);
|
||||
|
||||
BUG_ON(bi->bi_vcnt != 1);
|
||||
|
|
|
|||
|
|
@ -36,7 +36,9 @@ Miklos Szeredi
|
|||
Kazeon team for various fixes especially for 2.4 version.
|
||||
Asser Ferno (Change Notify support)
|
||||
Shaggy (Dave Kleikamp) for inumerable small fs suggestions and some good cleanup
|
||||
Gunter Kukkukk (testing and suggestions for support of old servers)
|
||||
Igor Mammedov (DFS support)
|
||||
Jeff Layton (many, many fixes, as well as great work on the cifs Kerberos code)
|
||||
|
||||
Test case and Bug Report contributors
|
||||
-------------------------------------
|
||||
|
|
|
|||
|
|
@ -1,3 +1,12 @@
|
|||
Version 1.56
|
||||
------------
|
||||
Add "forcemandatorylock" mount option to allow user to use mandatory
|
||||
rather than posix (advisory) byte range locks, even though server would
|
||||
support posix byte range locks. Fix query of root inode when prefixpath
|
||||
specified and user does not have access to query information about the
|
||||
top of the share. Fix problem in 2.6.28 resolving DFS paths to
|
||||
Samba servers (worked to Windows).
|
||||
|
||||
Version 1.55
|
||||
------------
|
||||
Various fixes to make delete of open files behavior more predictable
|
||||
|
|
|
|||
|
|
@ -463,9 +463,19 @@ A partial list of the supported mount options follows:
|
|||
with cifs style mandatory byte range locks (and most
|
||||
cifs servers do not yet support requesting advisory
|
||||
byte range locks).
|
||||
forcemandatorylock Even if the server supports posix (advisory) byte range
|
||||
locking, send only mandatory lock requests. For some
|
||||
(presumably rare) applications, originally coded for
|
||||
DOS/Windows, which require Windows style mandatory byte range
|
||||
locking, they may be able to take advantage of this option,
|
||||
forcing the cifs client to only send mandatory locks
|
||||
even if the cifs server would support posix advisory locks.
|
||||
"forcemand" is accepted as a shorter form of this mount
|
||||
option.
|
||||
nodfs Disable DFS (global name space support) even if the
|
||||
server claims to support it. This can help work around
|
||||
a problem with parsing of DFS paths with Samba 3.0.24 server.
|
||||
a problem with parsing of DFS paths with Samba server
|
||||
versions 3.0.24 and 3.0.25.
|
||||
remount remount the share (often used to change from ro to rw mounts
|
||||
or vice versa)
|
||||
cifsacl Report mode bits (e.g. on stat) based on the Windows ACL for
|
||||
|
|
|
|||
|
|
@ -122,7 +122,7 @@ static char *compose_mount_options(const char *sb_mountdata,
|
|||
char **devname)
|
||||
{
|
||||
int rc;
|
||||
char *mountdata;
|
||||
char *mountdata = NULL;
|
||||
int md_len;
|
||||
char *tkn_e;
|
||||
char *srvIP = NULL;
|
||||
|
|
@ -136,10 +136,9 @@ static char *compose_mount_options(const char *sb_mountdata,
|
|||
*devname = cifs_get_share_name(ref->node_name);
|
||||
rc = dns_resolve_server_name_to_ip(*devname, &srvIP);
|
||||
if (rc != 0) {
|
||||
cERROR(1, ("%s: Failed to resolve server part of %s to IP",
|
||||
__func__, *devname));
|
||||
mountdata = ERR_PTR(rc);
|
||||
goto compose_mount_options_out;
|
||||
cERROR(1, ("%s: Failed to resolve server part of %s to IP: %d",
|
||||
__func__, *devname, rc));;
|
||||
goto compose_mount_options_err;
|
||||
}
|
||||
/* md_len = strlen(...) + 12 for 'sep+prefixpath='
|
||||
* assuming that we have 'unc=' and 'ip=' in
|
||||
|
|
@ -149,8 +148,8 @@ static char *compose_mount_options(const char *sb_mountdata,
|
|||
strlen(ref->node_name) + 12;
|
||||
mountdata = kzalloc(md_len+1, GFP_KERNEL);
|
||||
if (mountdata == NULL) {
|
||||
mountdata = ERR_PTR(-ENOMEM);
|
||||
goto compose_mount_options_out;
|
||||
rc = -ENOMEM;
|
||||
goto compose_mount_options_err;
|
||||
}
|
||||
|
||||
/* copy all options except of unc,ip,prefixpath */
|
||||
|
|
@ -197,18 +196,32 @@ static char *compose_mount_options(const char *sb_mountdata,
|
|||
|
||||
/* find & copy prefixpath */
|
||||
tkn_e = strchr(ref->node_name + 2, '\\');
|
||||
if (tkn_e == NULL) /* invalid unc, missing share name*/
|
||||
goto compose_mount_options_out;
|
||||
if (tkn_e == NULL) {
|
||||
/* invalid unc, missing share name*/
|
||||
rc = -EINVAL;
|
||||
goto compose_mount_options_err;
|
||||
}
|
||||
|
||||
/*
|
||||
* this function gives us a path with a double backslash prefix. We
|
||||
* require a single backslash for DFS. Temporarily increment fullpath
|
||||
* to put it in the proper form and decrement before freeing it.
|
||||
*/
|
||||
fullpath = build_path_from_dentry(dentry);
|
||||
if (!fullpath) {
|
||||
rc = -ENOMEM;
|
||||
goto compose_mount_options_err;
|
||||
}
|
||||
++fullpath;
|
||||
tkn_e = strchr(tkn_e + 1, '\\');
|
||||
if (tkn_e || strlen(fullpath) - (ref->path_consumed)) {
|
||||
if (tkn_e || (strlen(fullpath) - ref->path_consumed)) {
|
||||
strncat(mountdata, &sep, 1);
|
||||
strcat(mountdata, "prefixpath=");
|
||||
if (tkn_e)
|
||||
strcat(mountdata, tkn_e + 1);
|
||||
strcat(mountdata, fullpath + (ref->path_consumed));
|
||||
strcat(mountdata, fullpath + ref->path_consumed);
|
||||
}
|
||||
--fullpath;
|
||||
kfree(fullpath);
|
||||
|
||||
/*cFYI(1,("%s: parent mountdata: %s", __func__,sb_mountdata));*/
|
||||
|
|
@ -217,6 +230,11 @@ static char *compose_mount_options(const char *sb_mountdata,
|
|||
compose_mount_options_out:
|
||||
kfree(srvIP);
|
||||
return mountdata;
|
||||
|
||||
compose_mount_options_err:
|
||||
kfree(mountdata);
|
||||
mountdata = ERR_PTR(rc);
|
||||
goto compose_mount_options_out;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -309,13 +327,19 @@ cifs_dfs_follow_mountpoint(struct dentry *dentry, struct nameidata *nd)
|
|||
goto out_err;
|
||||
}
|
||||
|
||||
/*
|
||||
* The MSDFS spec states that paths in DFS referral requests and
|
||||
* responses must be prefixed by a single '\' character instead of
|
||||
* the double backslashes usually used in the UNC. This function
|
||||
* gives us the latter, so we must adjust the result.
|
||||
*/
|
||||
full_path = build_path_from_dentry(dentry);
|
||||
if (full_path == NULL) {
|
||||
rc = -ENOMEM;
|
||||
goto out_err;
|
||||
}
|
||||
|
||||
rc = get_dfs_path(xid, ses , full_path, cifs_sb->local_nls,
|
||||
rc = get_dfs_path(xid, ses , full_path + 1, cifs_sb->local_nls,
|
||||
&num_referrals, &referrals,
|
||||
cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
|
||||
|
||||
|
|
|
|||
|
|
@ -19,8 +19,8 @@
|
|||
#define _CIFS_FS_SB_H
|
||||
|
||||
#define CIFS_MOUNT_NO_PERM 1 /* do not do client vfs_perm check */
|
||||
#define CIFS_MOUNT_SET_UID 2 /* set current->euid in create etc. */
|
||||
#define CIFS_MOUNT_SERVER_INUM 4 /* inode numbers from uniqueid from server */
|
||||
#define CIFS_MOUNT_SET_UID 2 /* set current's euid in create etc. */
|
||||
#define CIFS_MOUNT_SERVER_INUM 4 /* inode numbers from uniqueid from server */
|
||||
#define CIFS_MOUNT_DIRECT_IO 8 /* do not write nor read through page cache */
|
||||
#define CIFS_MOUNT_NO_XATTR 0x10 /* if set - disable xattr support */
|
||||
#define CIFS_MOUNT_MAP_SPECIAL_CHR 0x20 /* remap illegal chars in filenames */
|
||||
|
|
@ -30,7 +30,8 @@
|
|||
#define CIFS_MOUNT_CIFS_ACL 0x200 /* send ACL requests to non-POSIX srv */
|
||||
#define CIFS_MOUNT_OVERR_UID 0x400 /* override uid returned from server */
|
||||
#define CIFS_MOUNT_OVERR_GID 0x800 /* override gid returned from server */
|
||||
#define CIFS_MOUNT_DYNPERM 0x1000 /* allow in-memory only mode setting */
|
||||
#define CIFS_MOUNT_DYNPERM 0x1000 /* allow in-memory only mode setting */
|
||||
#define CIFS_MOUNT_NOPOSIXBRL 0x2000 /* mandatory not posix byte range lock */
|
||||
|
||||
struct cifs_sb_info {
|
||||
struct cifsTconInfo *tcon; /* primary mount */
|
||||
|
|
|
|||
|
|
@ -121,11 +121,9 @@ cifs_get_spnego_key(struct cifsSesInfo *sesInfo)
|
|||
|
||||
/* add the server address */
|
||||
if (server->addr.sockAddr.sin_family == AF_INET)
|
||||
sprintf(dp, "ip4=" NIPQUAD_FMT,
|
||||
NIPQUAD(server->addr.sockAddr.sin_addr));
|
||||
sprintf(dp, "ip4=%pI4", &server->addr.sockAddr.sin_addr);
|
||||
else if (server->addr.sockAddr.sin_family == AF_INET6)
|
||||
sprintf(dp, "ip6=" NIP6_SEQFMT,
|
||||
NIP6(server->addr.sockAddr6.sin6_addr));
|
||||
sprintf(dp, "ip6=%pi6", &server->addr.sockAddr6.sin6_addr);
|
||||
else
|
||||
goto out;
|
||||
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@
|
|||
|
||||
extern void mdfour(unsigned char *out, unsigned char *in, int n);
|
||||
extern void E_md4hash(const unsigned char *passwd, unsigned char *p16);
|
||||
extern void SMBencrypt(unsigned char *passwd, unsigned char *c8,
|
||||
extern void SMBencrypt(unsigned char *passwd, const unsigned char *c8,
|
||||
unsigned char *p24);
|
||||
|
||||
static int cifs_calculate_signature(const struct smb_hdr *cifs_pdu,
|
||||
|
|
@ -280,25 +280,22 @@ int CalcNTLMv2_partial_mac_key(struct cifsSesInfo *ses,
|
|||
}
|
||||
|
||||
#ifdef CONFIG_CIFS_WEAK_PW_HASH
|
||||
void calc_lanman_hash(struct cifsSesInfo *ses, char *lnm_session_key)
|
||||
void calc_lanman_hash(const char *password, const char *cryptkey, bool encrypt,
|
||||
char *lnm_session_key)
|
||||
{
|
||||
int i;
|
||||
char password_with_pad[CIFS_ENCPWD_SIZE];
|
||||
|
||||
if (ses->server == NULL)
|
||||
return;
|
||||
|
||||
memset(password_with_pad, 0, CIFS_ENCPWD_SIZE);
|
||||
if (ses->password)
|
||||
strncpy(password_with_pad, ses->password, CIFS_ENCPWD_SIZE);
|
||||
if (password)
|
||||
strncpy(password_with_pad, password, CIFS_ENCPWD_SIZE);
|
||||
|
||||
if ((ses->server->secMode & SECMODE_PW_ENCRYPT) == 0)
|
||||
if (extended_security & CIFSSEC_MAY_PLNTXT) {
|
||||
memset(lnm_session_key, 0, CIFS_SESS_KEY_SIZE);
|
||||
memcpy(lnm_session_key, password_with_pad,
|
||||
CIFS_ENCPWD_SIZE);
|
||||
return;
|
||||
}
|
||||
if (!encrypt && extended_security & CIFSSEC_MAY_PLNTXT) {
|
||||
memset(lnm_session_key, 0, CIFS_SESS_KEY_SIZE);
|
||||
memcpy(lnm_session_key, password_with_pad,
|
||||
CIFS_ENCPWD_SIZE);
|
||||
return;
|
||||
}
|
||||
|
||||
/* calculate old style session key */
|
||||
/* calling toupper is less broken than repeatedly
|
||||
|
|
@ -314,7 +311,8 @@ void calc_lanman_hash(struct cifsSesInfo *ses, char *lnm_session_key)
|
|||
for (i = 0; i < CIFS_ENCPWD_SIZE; i++)
|
||||
password_with_pad[i] = toupper(password_with_pad[i]);
|
||||
|
||||
SMBencrypt(password_with_pad, ses->server->cryptKey, lnm_session_key);
|
||||
SMBencrypt(password_with_pad, cryptkey, lnm_session_key);
|
||||
|
||||
/* clear password before we return/free memory */
|
||||
memset(password_with_pad, 0, CIFS_ENCPWD_SIZE);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,7 +26,8 @@
|
|||
extern void mdfour(unsigned char *out, unsigned char *in, int n);
|
||||
/* smbdes.c */
|
||||
extern void E_P16(unsigned char *p14, unsigned char *p16);
|
||||
extern void E_P24(unsigned char *p21, unsigned char *c8, unsigned char *p24);
|
||||
extern void E_P24(unsigned char *p21, const unsigned char *c8,
|
||||
unsigned char *p24);
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -66,7 +66,9 @@ unsigned int sign_CIFS_PDUs = 1;
|
|||
extern struct task_struct *oplockThread; /* remove sparse warning */
|
||||
struct task_struct *oplockThread = NULL;
|
||||
/* extern struct task_struct * dnotifyThread; remove sparse warning */
|
||||
#ifdef CONFIG_CIFS_EXPERIMENTAL
|
||||
static struct task_struct *dnotifyThread = NULL;
|
||||
#endif
|
||||
static const struct super_operations cifs_super_ops;
|
||||
unsigned int CIFSMaxBufSize = CIFS_MAX_MSGSIZE;
|
||||
module_param(CIFSMaxBufSize, int, 0);
|
||||
|
|
@ -337,39 +339,58 @@ static int
|
|||
cifs_show_options(struct seq_file *s, struct vfsmount *m)
|
||||
{
|
||||
struct cifs_sb_info *cifs_sb;
|
||||
struct cifsTconInfo *tcon;
|
||||
struct TCP_Server_Info *server;
|
||||
|
||||
cifs_sb = CIFS_SB(m->mnt_sb);
|
||||
|
||||
if (cifs_sb) {
|
||||
if (cifs_sb->tcon) {
|
||||
/* BB add prepath to mount options displayed */
|
||||
tcon = cifs_sb->tcon;
|
||||
if (tcon) {
|
||||
seq_printf(s, ",unc=%s", cifs_sb->tcon->treeName);
|
||||
if (cifs_sb->tcon->ses) {
|
||||
if (cifs_sb->tcon->ses->userName)
|
||||
if (tcon->ses) {
|
||||
if (tcon->ses->userName)
|
||||
seq_printf(s, ",username=%s",
|
||||
cifs_sb->tcon->ses->userName);
|
||||
if (cifs_sb->tcon->ses->domainName)
|
||||
tcon->ses->userName);
|
||||
if (tcon->ses->domainName)
|
||||
seq_printf(s, ",domain=%s",
|
||||
cifs_sb->tcon->ses->domainName);
|
||||
tcon->ses->domainName);
|
||||
server = tcon->ses->server;
|
||||
if (server) {
|
||||
seq_printf(s, ",addr=");
|
||||
switch (server->addr.sockAddr6.
|
||||
sin6_family) {
|
||||
case AF_INET6:
|
||||
seq_printf(s, "%pI6",
|
||||
&server->addr.sockAddr6.sin6_addr);
|
||||
break;
|
||||
case AF_INET:
|
||||
seq_printf(s, "%pI4",
|
||||
&server->addr.sockAddr.sin_addr.s_addr);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_UID) ||
|
||||
!(cifs_sb->tcon->unix_ext))
|
||||
!(tcon->unix_ext))
|
||||
seq_printf(s, ",uid=%d", cifs_sb->mnt_uid);
|
||||
if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_GID) ||
|
||||
!(cifs_sb->tcon->unix_ext))
|
||||
!(tcon->unix_ext))
|
||||
seq_printf(s, ",gid=%d", cifs_sb->mnt_gid);
|
||||
if (!cifs_sb->tcon->unix_ext) {
|
||||
if (!tcon->unix_ext) {
|
||||
seq_printf(s, ",file_mode=0%o,dir_mode=0%o",
|
||||
cifs_sb->mnt_file_mode,
|
||||
cifs_sb->mnt_dir_mode);
|
||||
}
|
||||
if (cifs_sb->tcon->seal)
|
||||
if (tcon->seal)
|
||||
seq_printf(s, ",seal");
|
||||
if (cifs_sb->tcon->nocase)
|
||||
if (tcon->nocase)
|
||||
seq_printf(s, ",nocase");
|
||||
if (cifs_sb->tcon->retry)
|
||||
if (tcon->retry)
|
||||
seq_printf(s, ",hard");
|
||||
}
|
||||
if (cifs_sb->prepath)
|
||||
seq_printf(s, ",prepath=%s", cifs_sb->prepath);
|
||||
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS)
|
||||
seq_printf(s, ",posixpaths");
|
||||
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID)
|
||||
|
|
@ -417,9 +438,8 @@ int cifs_xquota_set(struct super_block *sb, int quota_type, qid_t qid,
|
|||
xid = GetXid();
|
||||
if (pTcon) {
|
||||
cFYI(1, ("set type: 0x%x id: %d", quota_type, qid));
|
||||
} else {
|
||||
} else
|
||||
rc = -EIO;
|
||||
}
|
||||
|
||||
FreeXid(xid);
|
||||
return rc;
|
||||
|
|
@ -441,9 +461,8 @@ int cifs_xquota_get(struct super_block *sb, int quota_type, qid_t qid,
|
|||
xid = GetXid();
|
||||
if (pTcon) {
|
||||
cFYI(1, ("set type: 0x%x id: %d", quota_type, qid));
|
||||
} else {
|
||||
} else
|
||||
rc = -EIO;
|
||||
}
|
||||
|
||||
FreeXid(xid);
|
||||
return rc;
|
||||
|
|
@ -464,9 +483,8 @@ int cifs_xstate_set(struct super_block *sb, unsigned int flags, int operation)
|
|||
xid = GetXid();
|
||||
if (pTcon) {
|
||||
cFYI(1, ("flags: 0x%x operation: 0x%x", flags, operation));
|
||||
} else {
|
||||
} else
|
||||
rc = -EIO;
|
||||
}
|
||||
|
||||
FreeXid(xid);
|
||||
return rc;
|
||||
|
|
@ -479,17 +497,16 @@ int cifs_xstate_get(struct super_block *sb, struct fs_quota_stat *qstats)
|
|||
struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
|
||||
struct cifsTconInfo *pTcon;
|
||||
|
||||
if (cifs_sb) {
|
||||
if (cifs_sb)
|
||||
pTcon = cifs_sb->tcon;
|
||||
} else {
|
||||
else
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
xid = GetXid();
|
||||
if (pTcon) {
|
||||
cFYI(1, ("pqstats %p", qstats));
|
||||
} else {
|
||||
} else
|
||||
rc = -EIO;
|
||||
}
|
||||
|
||||
FreeXid(xid);
|
||||
return rc;
|
||||
|
|
@ -1029,6 +1046,7 @@ static int cifs_oplock_thread(void *dummyarg)
|
|||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_CIFS_EXPERIMENTAL
|
||||
static int cifs_dnotify_thread(void *dummyarg)
|
||||
{
|
||||
struct list_head *tmp;
|
||||
|
|
@ -1054,6 +1072,7 @@ static int cifs_dnotify_thread(void *dummyarg)
|
|||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int __init
|
||||
init_cifs(void)
|
||||
|
|
@ -1131,16 +1150,20 @@ init_cifs(void)
|
|||
goto out_unregister_dfs_key_type;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_CIFS_EXPERIMENTAL
|
||||
dnotifyThread = kthread_run(cifs_dnotify_thread, NULL, "cifsdnotifyd");
|
||||
if (IS_ERR(dnotifyThread)) {
|
||||
rc = PTR_ERR(dnotifyThread);
|
||||
cERROR(1, ("error %d create dnotify thread", rc));
|
||||
goto out_stop_oplock_thread;
|
||||
}
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
|
||||
#ifdef CONFIG_CIFS_EXPERIMENTAL
|
||||
out_stop_oplock_thread:
|
||||
#endif
|
||||
kthread_stop(oplockThread);
|
||||
out_unregister_dfs_key_type:
|
||||
#ifdef CONFIG_CIFS_DFS_UPCALL
|
||||
|
|
@ -1179,8 +1202,10 @@ exit_cifs(void)
|
|||
cifs_destroy_inodecache();
|
||||
cifs_destroy_mids();
|
||||
cifs_destroy_request_bufs();
|
||||
kthread_stop(oplockThread);
|
||||
#ifdef CONFIG_CIFS_EXPERIMENTAL
|
||||
kthread_stop(dnotifyThread);
|
||||
#endif
|
||||
kthread_stop(oplockThread);
|
||||
}
|
||||
|
||||
MODULE_AUTHOR("Steve French <[email protected]>");
|
||||
|
|
|
|||
|
|
@ -101,5 +101,5 @@ extern long cifs_ioctl(struct file *filep, unsigned int cmd, unsigned long arg);
|
|||
extern const struct export_operations cifs_export_ops;
|
||||
#endif /* EXPERIMENTAL */
|
||||
|
||||
#define CIFS_VERSION "1.55"
|
||||
#define CIFS_VERSION "1.56"
|
||||
#endif /* _CIFSFS_H */
|
||||
|
|
|
|||
|
|
@ -47,7 +47,11 @@
|
|||
*/
|
||||
#define CIFS_MAX_REQ 50
|
||||
|
||||
#define SERVER_NAME_LENGTH 15
|
||||
#define RFC1001_NAME_LEN 15
|
||||
#define RFC1001_NAME_LEN_WITH_NULL (RFC1001_NAME_LEN + 1)
|
||||
|
||||
/* currently length of NIP6_FMT */
|
||||
#define SERVER_NAME_LENGTH 40
|
||||
#define SERVER_NAME_LEN_WITH_NULL (SERVER_NAME_LENGTH + 1)
|
||||
|
||||
/* used to define string lengths for reversing unicode strings */
|
||||
|
|
@ -125,8 +129,7 @@ struct TCP_Server_Info {
|
|||
struct list_head smb_ses_list;
|
||||
int srv_count; /* reference counter */
|
||||
/* 15 character server name + 0x20 16th byte indicating type = srv */
|
||||
char server_RFC1001_name[SERVER_NAME_LEN_WITH_NULL];
|
||||
char unicode_server_Name[SERVER_NAME_LEN_WITH_NULL * 2];
|
||||
char server_RFC1001_name[RFC1001_NAME_LEN_WITH_NULL];
|
||||
char *hostname; /* hostname portion of UNC string */
|
||||
struct socket *ssocket;
|
||||
union {
|
||||
|
|
@ -151,7 +154,7 @@ struct TCP_Server_Info {
|
|||
atomic_t num_waiters; /* blocked waiting to get in sendrecv */
|
||||
#endif
|
||||
enum statusEnum tcpStatus; /* what we think the status is */
|
||||
struct semaphore tcpSem;
|
||||
struct mutex srv_mutex;
|
||||
struct task_struct *tsk;
|
||||
char server_GUID[16];
|
||||
char secMode;
|
||||
|
|
@ -171,7 +174,7 @@ struct TCP_Server_Info {
|
|||
__u16 CurrentMid; /* multiplex id - rotating counter */
|
||||
char cryptKey[CIFS_CRYPTO_KEY_SIZE];
|
||||
/* 16th byte of RFC1001 workstation name is always null */
|
||||
char workstation_RFC1001_name[SERVER_NAME_LEN_WITH_NULL];
|
||||
char workstation_RFC1001_name[RFC1001_NAME_LEN_WITH_NULL];
|
||||
__u32 sequence_number; /* needed for CIFS PDU signature */
|
||||
struct mac_key mac_signing_key;
|
||||
char ntlmv2_hash[16];
|
||||
|
|
@ -239,6 +242,7 @@ struct cifsTconInfo {
|
|||
struct cifsSesInfo *ses; /* pointer to session associated with */
|
||||
char treeName[MAX_TREE_SIZE + 1]; /* UNC name of resource in ASCII */
|
||||
char *nativeFileSystem;
|
||||
char *password; /* for share-level security */
|
||||
__u16 tid; /* The 2 byte tree id */
|
||||
__u16 Flags; /* optional support bits */
|
||||
enum statusEnum tidStatus;
|
||||
|
|
@ -422,7 +426,6 @@ struct mid_q_entry {
|
|||
unsigned long when_sent; /* time when smb send finished */
|
||||
unsigned long when_received; /* when demux complete (taken off wire) */
|
||||
#endif
|
||||
struct cifsSesInfo *ses; /* smb was sent to this server */
|
||||
struct task_struct *tsk; /* task waiting for response */
|
||||
struct smb_hdr *resp_buf; /* response buffer */
|
||||
int midState; /* wish this were enum but can not pass to wait_event */
|
||||
|
|
|
|||
|
|
@ -1922,7 +1922,7 @@ typedef struct smb_com_transaction2_get_dfs_refer_req {
|
|||
/* DFS server target type */
|
||||
#define DFS_TYPE_LINK 0x0000 /* also for sysvol targets */
|
||||
#define DFS_TYPE_ROOT 0x0001
|
||||
|
||||
|
||||
/* Referral Entry Flags */
|
||||
#define DFS_NAME_LIST_REF 0x0200
|
||||
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@ extern int smb_send(struct socket *, struct smb_hdr *,
|
|||
unsigned int /* length */ , struct sockaddr *, bool);
|
||||
extern unsigned int _GetXid(void);
|
||||
extern void _FreeXid(unsigned int);
|
||||
#define GetXid() (int)_GetXid(); cFYI(1,("CIFS VFS: in %s as Xid: %d with uid: %d",__func__, xid,current->fsuid));
|
||||
#define GetXid() (int)_GetXid(); cFYI(1,("CIFS VFS: in %s as Xid: %d with uid: %d",__func__, xid,current_fsuid()));
|
||||
#define FreeXid(curr_xid) {_FreeXid(curr_xid); cFYI(1,("CIFS VFS: leaving %s (xid = %d) rc = %d",__func__,curr_xid,(int)rc));}
|
||||
extern char *build_path_from_dentry(struct dentry *);
|
||||
extern char *build_wildcard_path_from_dentry(struct dentry *direntry);
|
||||
|
|
@ -330,7 +330,8 @@ extern void CalcNTLMv2_response(const struct cifsSesInfo *, char *);
|
|||
extern void setup_ntlmv2_rsp(struct cifsSesInfo *, char *,
|
||||
const struct nls_table *);
|
||||
#ifdef CONFIG_CIFS_WEAK_PW_HASH
|
||||
extern void calc_lanman_hash(struct cifsSesInfo *ses, char *lnm_session_key);
|
||||
extern void calc_lanman_hash(const char *password, const char *cryptkey,
|
||||
bool encrypt, char *lnm_session_key);
|
||||
#endif /* CIFS_WEAK_PW_HASH */
|
||||
extern int CIFSSMBCopy(int xid,
|
||||
struct cifsTconInfo *source_tcon,
|
||||
|
|
|
|||
|
|
@ -1382,13 +1382,13 @@ openRetry:
|
|||
if (cpu_to_le32(FILE_CREATE) == pSMBr->CreateAction)
|
||||
*pOplock |= CIFS_CREATE_ACTION;
|
||||
if (pfile_info) {
|
||||
memcpy((char *)pfile_info, (char *)&pSMBr->CreationTime,
|
||||
36 /* CreationTime to Attributes */);
|
||||
/* the file_info buf is endian converted by caller */
|
||||
pfile_info->AllocationSize = pSMBr->AllocationSize;
|
||||
pfile_info->EndOfFile = pSMBr->EndOfFile;
|
||||
pfile_info->NumberOfLinks = cpu_to_le32(1);
|
||||
pfile_info->DeletePending = 0;
|
||||
memcpy((char *)pfile_info, (char *)&pSMBr->CreationTime,
|
||||
36 /* CreationTime to Attributes */);
|
||||
/* the file_info buf is endian converted by caller */
|
||||
pfile_info->AllocationSize = pSMBr->AllocationSize;
|
||||
pfile_info->EndOfFile = pSMBr->EndOfFile;
|
||||
pfile_info->NumberOfLinks = cpu_to_le32(1);
|
||||
pfile_info->DeletePending = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1414,8 +1414,13 @@ CIFSSMBRead(const int xid, struct cifsTconInfo *tcon, const int netfid,
|
|||
cFYI(1, ("Reading %d bytes on fid %d", count, netfid));
|
||||
if (tcon->ses->capabilities & CAP_LARGE_FILES)
|
||||
wct = 12;
|
||||
else
|
||||
else {
|
||||
wct = 10; /* old style read */
|
||||
if ((lseek >> 32) > 0) {
|
||||
/* can not handle this big offset for old */
|
||||
return -EIO;
|
||||
}
|
||||
}
|
||||
|
||||
*nbytes = 0;
|
||||
rc = small_smb_init(SMB_COM_READ_ANDX, wct, tcon, (void **) &pSMB);
|
||||
|
|
@ -1431,8 +1436,6 @@ CIFSSMBRead(const int xid, struct cifsTconInfo *tcon, const int netfid,
|
|||
pSMB->OffsetLow = cpu_to_le32(lseek & 0xFFFFFFFF);
|
||||
if (wct == 12)
|
||||
pSMB->OffsetHigh = cpu_to_le32(lseek >> 32);
|
||||
else if ((lseek >> 32) > 0) /* can not handle this big offset for old */
|
||||
return -EIO;
|
||||
|
||||
pSMB->Remaining = 0;
|
||||
pSMB->MaxCount = cpu_to_le16(count & 0xFFFF);
|
||||
|
|
@ -1519,8 +1522,13 @@ CIFSSMBWrite(const int xid, struct cifsTconInfo *tcon,
|
|||
|
||||
if (tcon->ses->capabilities & CAP_LARGE_FILES)
|
||||
wct = 14;
|
||||
else
|
||||
else {
|
||||
wct = 12;
|
||||
if ((offset >> 32) > 0) {
|
||||
/* can not handle big offset for old srv */
|
||||
return -EIO;
|
||||
}
|
||||
}
|
||||
|
||||
rc = smb_init(SMB_COM_WRITE_ANDX, wct, tcon, (void **) &pSMB,
|
||||
(void **) &pSMBr);
|
||||
|
|
@ -1535,8 +1543,6 @@ CIFSSMBWrite(const int xid, struct cifsTconInfo *tcon,
|
|||
pSMB->OffsetLow = cpu_to_le32(offset & 0xFFFFFFFF);
|
||||
if (wct == 14)
|
||||
pSMB->OffsetHigh = cpu_to_le32(offset >> 32);
|
||||
else if ((offset >> 32) > 0) /* can not handle big offset for old srv */
|
||||
return -EIO;
|
||||
|
||||
pSMB->Reserved = 0xFFFFFFFF;
|
||||
pSMB->WriteMode = 0;
|
||||
|
|
@ -1558,7 +1564,7 @@ CIFSSMBWrite(const int xid, struct cifsTconInfo *tcon,
|
|||
pSMB->DataOffset =
|
||||
cpu_to_le16(offsetof(struct smb_com_write_req, Data) - 4);
|
||||
if (buf)
|
||||
memcpy(pSMB->Data, buf, bytes_sent);
|
||||
memcpy(pSMB->Data, buf, bytes_sent);
|
||||
else if (ubuf) {
|
||||
if (copy_from_user(pSMB->Data, ubuf, bytes_sent)) {
|
||||
cifs_buf_release(pSMB);
|
||||
|
|
@ -1621,10 +1627,15 @@ CIFSSMBWrite2(const int xid, struct cifsTconInfo *tcon,
|
|||
|
||||
cFYI(1, ("write2 at %lld %d bytes", (long long)offset, count));
|
||||
|
||||
if (tcon->ses->capabilities & CAP_LARGE_FILES)
|
||||
if (tcon->ses->capabilities & CAP_LARGE_FILES) {
|
||||
wct = 14;
|
||||
else
|
||||
} else {
|
||||
wct = 12;
|
||||
if ((offset >> 32) > 0) {
|
||||
/* can not handle big offset for old srv */
|
||||
return -EIO;
|
||||
}
|
||||
}
|
||||
rc = small_smb_init(SMB_COM_WRITE_ANDX, wct, tcon, (void **) &pSMB);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
|
@ -1637,8 +1648,6 @@ CIFSSMBWrite2(const int xid, struct cifsTconInfo *tcon,
|
|||
pSMB->OffsetLow = cpu_to_le32(offset & 0xFFFFFFFF);
|
||||
if (wct == 14)
|
||||
pSMB->OffsetHigh = cpu_to_le32(offset >> 32);
|
||||
else if ((offset >> 32) > 0) /* can not handle big offset for old srv */
|
||||
return -EIO;
|
||||
pSMB->Reserved = 0xFFFFFFFF;
|
||||
pSMB->WriteMode = 0;
|
||||
pSMB->Remaining = 0;
|
||||
|
|
@ -1862,10 +1871,6 @@ CIFSSMBPosixLock(const int xid, struct cifsTconInfo *tcon,
|
|||
rc = -EIO; /* bad smb */
|
||||
goto plk_err_exit;
|
||||
}
|
||||
if (pLockData == NULL) {
|
||||
rc = -EINVAL;
|
||||
goto plk_err_exit;
|
||||
}
|
||||
data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
|
||||
data_count = le16_to_cpu(pSMBr->t2.DataCount);
|
||||
if (data_count < sizeof(struct cifs_posix_lock)) {
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -235,11 +235,11 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode,
|
|||
};
|
||||
|
||||
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) {
|
||||
args.uid = (__u64) current->fsuid;
|
||||
args.uid = (__u64) current_fsuid();
|
||||
if (inode->i_mode & S_ISGID)
|
||||
args.gid = (__u64) inode->i_gid;
|
||||
else
|
||||
args.gid = (__u64) current->fsgid;
|
||||
args.gid = (__u64) current_fsgid();
|
||||
} else {
|
||||
args.uid = NO_CHANGE_64;
|
||||
args.gid = NO_CHANGE_64;
|
||||
|
|
@ -271,13 +271,13 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode,
|
|||
if ((oplock & CIFS_CREATE_ACTION) &&
|
||||
(cifs_sb->mnt_cifs_flags &
|
||||
CIFS_MOUNT_SET_UID)) {
|
||||
newinode->i_uid = current->fsuid;
|
||||
newinode->i_uid = current_fsuid();
|
||||
if (inode->i_mode & S_ISGID)
|
||||
newinode->i_gid =
|
||||
inode->i_gid;
|
||||
else
|
||||
newinode->i_gid =
|
||||
current->fsgid;
|
||||
current_fsgid();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -375,8 +375,8 @@ int cifs_mknod(struct inode *inode, struct dentry *direntry, int mode,
|
|||
.device = device_number,
|
||||
};
|
||||
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) {
|
||||
args.uid = (__u64) current->fsuid;
|
||||
args.gid = (__u64) current->fsgid;
|
||||
args.uid = (__u64) current_fsuid();
|
||||
args.gid = (__u64) current_fsgid();
|
||||
} else {
|
||||
args.uid = NO_CHANGE_64;
|
||||
args.gid = NO_CHANGE_64;
|
||||
|
|
@ -483,7 +483,7 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry,
|
|||
|
||||
xid = GetXid();
|
||||
|
||||
cFYI(1, (" parent inode = 0x%p name is: %s and dentry = 0x%p",
|
||||
cFYI(1, ("parent inode = 0x%p name is: %s and dentry = 0x%p",
|
||||
parent_dir_inode, direntry->d_name.name, direntry));
|
||||
|
||||
/* check whether path exists */
|
||||
|
|
@ -515,12 +515,11 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry,
|
|||
}
|
||||
|
||||
if (direntry->d_inode != NULL) {
|
||||
cFYI(1, (" non-NULL inode in lookup"));
|
||||
cFYI(1, ("non-NULL inode in lookup"));
|
||||
} else {
|
||||
cFYI(1, (" NULL inode in lookup"));
|
||||
cFYI(1, ("NULL inode in lookup"));
|
||||
}
|
||||
cFYI(1,
|
||||
(" Full path: %s inode = 0x%p", full_path, direntry->d_inode));
|
||||
cFYI(1, ("Full path: %s inode = 0x%p", full_path, direntry->d_inode));
|
||||
|
||||
if (pTcon->unix_ext)
|
||||
rc = cifs_get_inode_info_unix(&newInode, full_path,
|
||||
|
|
|
|||
|
|
@ -644,10 +644,10 @@ int cifs_lock(struct file *file, int cmd, struct file_lock *pfLock)
|
|||
__u64 length;
|
||||
bool wait_flag = false;
|
||||
struct cifs_sb_info *cifs_sb;
|
||||
struct cifsTconInfo *pTcon;
|
||||
struct cifsTconInfo *tcon;
|
||||
__u16 netfid;
|
||||
__u8 lockType = LOCKING_ANDX_LARGE_FILES;
|
||||
bool posix_locking;
|
||||
bool posix_locking = 0;
|
||||
|
||||
length = 1 + pfLock->fl_end - pfLock->fl_start;
|
||||
rc = -EACCES;
|
||||
|
|
@ -698,7 +698,7 @@ int cifs_lock(struct file *file, int cmd, struct file_lock *pfLock)
|
|||
cFYI(1, ("Unknown type of lock"));
|
||||
|
||||
cifs_sb = CIFS_SB(file->f_path.dentry->d_sb);
|
||||
pTcon = cifs_sb->tcon;
|
||||
tcon = cifs_sb->tcon;
|
||||
|
||||
if (file->private_data == NULL) {
|
||||
FreeXid(xid);
|
||||
|
|
@ -706,9 +706,10 @@ int cifs_lock(struct file *file, int cmd, struct file_lock *pfLock)
|
|||
}
|
||||
netfid = ((struct cifsFileInfo *)file->private_data)->netfid;
|
||||
|
||||
posix_locking = (cifs_sb->tcon->ses->capabilities & CAP_UNIX) &&
|
||||
(CIFS_UNIX_FCNTL_CAP & le64_to_cpu(cifs_sb->tcon->fsUnixInfo.Capability));
|
||||
|
||||
if ((tcon->ses->capabilities & CAP_UNIX) &&
|
||||
(CIFS_UNIX_FCNTL_CAP & le64_to_cpu(tcon->fsUnixInfo.Capability)) &&
|
||||
((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NOPOSIXBRL) == 0))
|
||||
posix_locking = 1;
|
||||
/* BB add code here to normalize offset and length to
|
||||
account for negative length which we can not accept over the
|
||||
wire */
|
||||
|
|
@ -719,7 +720,7 @@ int cifs_lock(struct file *file, int cmd, struct file_lock *pfLock)
|
|||
posix_lock_type = CIFS_RDLCK;
|
||||
else
|
||||
posix_lock_type = CIFS_WRLCK;
|
||||
rc = CIFSSMBPosixLock(xid, pTcon, netfid, 1 /* get */,
|
||||
rc = CIFSSMBPosixLock(xid, tcon, netfid, 1 /* get */,
|
||||
length, pfLock,
|
||||
posix_lock_type, wait_flag);
|
||||
FreeXid(xid);
|
||||
|
|
@ -727,10 +728,10 @@ int cifs_lock(struct file *file, int cmd, struct file_lock *pfLock)
|
|||
}
|
||||
|
||||
/* BB we could chain these into one lock request BB */
|
||||
rc = CIFSSMBLock(xid, pTcon, netfid, length, pfLock->fl_start,
|
||||
rc = CIFSSMBLock(xid, tcon, netfid, length, pfLock->fl_start,
|
||||
0, 1, lockType, 0 /* wait flag */ );
|
||||
if (rc == 0) {
|
||||
rc = CIFSSMBLock(xid, pTcon, netfid, length,
|
||||
rc = CIFSSMBLock(xid, tcon, netfid, length,
|
||||
pfLock->fl_start, 1 /* numUnlock */ ,
|
||||
0 /* numLock */ , lockType,
|
||||
0 /* wait flag */ );
|
||||
|
|
@ -767,7 +768,7 @@ int cifs_lock(struct file *file, int cmd, struct file_lock *pfLock)
|
|||
if (numUnlock == 1)
|
||||
posix_lock_type = CIFS_UNLCK;
|
||||
|
||||
rc = CIFSSMBPosixLock(xid, pTcon, netfid, 0 /* set */,
|
||||
rc = CIFSSMBPosixLock(xid, tcon, netfid, 0 /* set */,
|
||||
length, pfLock,
|
||||
posix_lock_type, wait_flag);
|
||||
} else {
|
||||
|
|
@ -775,7 +776,7 @@ int cifs_lock(struct file *file, int cmd, struct file_lock *pfLock)
|
|||
(struct cifsFileInfo *)file->private_data;
|
||||
|
||||
if (numLock) {
|
||||
rc = CIFSSMBLock(xid, pTcon, netfid, length,
|
||||
rc = CIFSSMBLock(xid, tcon, netfid, length,
|
||||
pfLock->fl_start,
|
||||
0, numLock, lockType, wait_flag);
|
||||
|
||||
|
|
@ -796,7 +797,7 @@ int cifs_lock(struct file *file, int cmd, struct file_lock *pfLock)
|
|||
if (pfLock->fl_start <= li->offset &&
|
||||
(pfLock->fl_start + length) >=
|
||||
(li->offset + li->length)) {
|
||||
stored_rc = CIFSSMBLock(xid, pTcon,
|
||||
stored_rc = CIFSSMBLock(xid, tcon,
|
||||
netfid,
|
||||
li->length, li->offset,
|
||||
1, 0, li->type, false);
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* fs/cifs/inode.c
|
||||
*
|
||||
* Copyright (C) International Business Machines Corp., 2002,2007
|
||||
* Copyright (C) International Business Machines Corp., 2002,2008
|
||||
* Author(s): Steve French (sfrench@us.ibm.com)
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or modify
|
||||
|
|
@ -621,6 +621,47 @@ static const struct inode_operations cifs_ipc_inode_ops = {
|
|||
.lookup = cifs_lookup,
|
||||
};
|
||||
|
||||
static char *build_path_to_root(struct cifs_sb_info *cifs_sb)
|
||||
{
|
||||
int pplen = cifs_sb->prepathlen;
|
||||
int dfsplen;
|
||||
char *full_path = NULL;
|
||||
|
||||
/* if no prefix path, simply set path to the root of share to "" */
|
||||
if (pplen == 0) {
|
||||
full_path = kmalloc(1, GFP_KERNEL);
|
||||
if (full_path)
|
||||
full_path[0] = 0;
|
||||
return full_path;
|
||||
}
|
||||
|
||||
if (cifs_sb->tcon && (cifs_sb->tcon->Flags & SMB_SHARE_IS_IN_DFS))
|
||||
dfsplen = strnlen(cifs_sb->tcon->treeName, MAX_TREE_SIZE + 1);
|
||||
else
|
||||
dfsplen = 0;
|
||||
|
||||
full_path = kmalloc(dfsplen + pplen + 1, GFP_KERNEL);
|
||||
if (full_path == NULL)
|
||||
return full_path;
|
||||
|
||||
if (dfsplen) {
|
||||
strncpy(full_path, cifs_sb->tcon->treeName, dfsplen);
|
||||
/* switch slash direction in prepath depending on whether
|
||||
* windows or posix style path names
|
||||
*/
|
||||
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS) {
|
||||
int i;
|
||||
for (i = 0; i < dfsplen; i++) {
|
||||
if (full_path[i] == '\\')
|
||||
full_path[i] = '/';
|
||||
}
|
||||
}
|
||||
}
|
||||
strncpy(full_path + dfsplen, cifs_sb->prepath, pplen);
|
||||
full_path[dfsplen + pplen] = 0; /* add trailing null */
|
||||
return full_path;
|
||||
}
|
||||
|
||||
/* gets root inode */
|
||||
struct inode *cifs_iget(struct super_block *sb, unsigned long ino)
|
||||
{
|
||||
|
|
@ -628,6 +669,7 @@ struct inode *cifs_iget(struct super_block *sb, unsigned long ino)
|
|||
struct cifs_sb_info *cifs_sb;
|
||||
struct inode *inode;
|
||||
long rc;
|
||||
char *full_path;
|
||||
|
||||
inode = iget_locked(sb, ino);
|
||||
if (!inode)
|
||||
|
|
@ -636,13 +678,17 @@ struct inode *cifs_iget(struct super_block *sb, unsigned long ino)
|
|||
return inode;
|
||||
|
||||
cifs_sb = CIFS_SB(inode->i_sb);
|
||||
xid = GetXid();
|
||||
full_path = build_path_to_root(cifs_sb);
|
||||
if (full_path == NULL)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
xid = GetXid();
|
||||
if (cifs_sb->tcon->unix_ext)
|
||||
rc = cifs_get_inode_info_unix(&inode, "", inode->i_sb, xid);
|
||||
rc = cifs_get_inode_info_unix(&inode, full_path, inode->i_sb,
|
||||
xid);
|
||||
else
|
||||
rc = cifs_get_inode_info(&inode, "", NULL, inode->i_sb, xid,
|
||||
NULL);
|
||||
rc = cifs_get_inode_info(&inode, full_path, NULL, inode->i_sb,
|
||||
xid, NULL);
|
||||
if (rc && cifs_sb->tcon->ipc) {
|
||||
cFYI(1, ("ipc connection - fake read inode"));
|
||||
inode->i_mode |= S_IFDIR;
|
||||
|
|
@ -652,6 +698,7 @@ struct inode *cifs_iget(struct super_block *sb, unsigned long ino)
|
|||
inode->i_uid = cifs_sb->mnt_uid;
|
||||
inode->i_gid = cifs_sb->mnt_gid;
|
||||
} else if (rc) {
|
||||
kfree(full_path);
|
||||
_FreeXid(xid);
|
||||
iget_failed(inode);
|
||||
return ERR_PTR(rc);
|
||||
|
|
@ -659,6 +706,7 @@ struct inode *cifs_iget(struct super_block *sb, unsigned long ino)
|
|||
|
||||
unlock_new_inode(inode);
|
||||
|
||||
kfree(full_path);
|
||||
/* can not call macro FreeXid here since in a void func
|
||||
* TODO: This is no longer true
|
||||
*/
|
||||
|
|
@ -1143,11 +1191,11 @@ mkdir_get_info:
|
|||
.device = 0,
|
||||
};
|
||||
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) {
|
||||
args.uid = (__u64)current->fsuid;
|
||||
args.uid = (__u64)current_fsuid();
|
||||
if (inode->i_mode & S_ISGID)
|
||||
args.gid = (__u64)inode->i_gid;
|
||||
else
|
||||
args.gid = (__u64)current->fsgid;
|
||||
args.gid = (__u64)current_fsgid();
|
||||
} else {
|
||||
args.uid = NO_CHANGE_64;
|
||||
args.gid = NO_CHANGE_64;
|
||||
|
|
@ -1184,13 +1232,13 @@ mkdir_get_info:
|
|||
if (cifs_sb->mnt_cifs_flags &
|
||||
CIFS_MOUNT_SET_UID) {
|
||||
direntry->d_inode->i_uid =
|
||||
current->fsuid;
|
||||
current_fsuid();
|
||||
if (inode->i_mode & S_ISGID)
|
||||
direntry->d_inode->i_gid =
|
||||
inode->i_gid;
|
||||
else
|
||||
direntry->d_inode->i_gid =
|
||||
current->fsgid;
|
||||
current_fsgid();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -65,7 +65,7 @@ long cifs_ioctl(struct file *filep, unsigned int command, unsigned long arg)
|
|||
switch (command) {
|
||||
case CIFS_IOC_CHECKUMOUNT:
|
||||
cFYI(1, ("User unmount attempted"));
|
||||
if (cifs_sb->mnt_uid == current->uid)
|
||||
if (cifs_sb->mnt_uid == current_uid())
|
||||
rc = 0;
|
||||
else {
|
||||
rc = -EACCES;
|
||||
|
|
|
|||
|
|
@ -97,7 +97,10 @@ sesInfoFree(struct cifsSesInfo *buf_to_free)
|
|||
kfree(buf_to_free->serverOS);
|
||||
kfree(buf_to_free->serverDomain);
|
||||
kfree(buf_to_free->serverNOS);
|
||||
kfree(buf_to_free->password);
|
||||
if (buf_to_free->password) {
|
||||
memset(buf_to_free->password, 0, strlen(buf_to_free->password));
|
||||
kfree(buf_to_free->password);
|
||||
}
|
||||
kfree(buf_to_free->domainName);
|
||||
kfree(buf_to_free);
|
||||
}
|
||||
|
|
@ -129,6 +132,10 @@ tconInfoFree(struct cifsTconInfo *buf_to_free)
|
|||
}
|
||||
atomic_dec(&tconInfoAllocCount);
|
||||
kfree(buf_to_free->nativeFileSystem);
|
||||
if (buf_to_free->password) {
|
||||
memset(buf_to_free->password, 0, strlen(buf_to_free->password));
|
||||
kfree(buf_to_free->password);
|
||||
}
|
||||
kfree(buf_to_free);
|
||||
}
|
||||
|
||||
|
|
@ -338,13 +345,13 @@ header_assemble(struct smb_hdr *buffer, char smb_command /* command */ ,
|
|||
/* BB Add support for establishing new tCon and SMB Session */
|
||||
/* with userid/password pairs found on the smb session */
|
||||
/* for other target tcp/ip addresses BB */
|
||||
if (current->fsuid != treeCon->ses->linux_uid) {
|
||||
if (current_fsuid() != treeCon->ses->linux_uid) {
|
||||
cFYI(1, ("Multiuser mode and UID "
|
||||
"did not match tcon uid"));
|
||||
read_lock(&cifs_tcp_ses_lock);
|
||||
list_for_each(temp_item, &treeCon->ses->server->smb_ses_list) {
|
||||
ses = list_entry(temp_item, struct cifsSesInfo, smb_ses_list);
|
||||
if (ses->linux_uid == current->fsuid) {
|
||||
if (ses->linux_uid == current_fsuid()) {
|
||||
if (ses->server == treeCon->ses->server) {
|
||||
cFYI(1, ("found matching uid substitute right smb_uid"));
|
||||
buffer->Uid = ses->Suid;
|
||||
|
|
|
|||
|
|
@ -417,7 +417,10 @@ CIFS_SessSetup(unsigned int xid, struct cifsSesInfo *ses, int first_time,
|
|||
/* BB calculate hash with password */
|
||||
/* and copy into bcc */
|
||||
|
||||
calc_lanman_hash(ses, lnm_session_key);
|
||||
calc_lanman_hash(ses->password, ses->server->cryptKey,
|
||||
ses->server->secMode & SECMODE_PW_ENCRYPT ?
|
||||
true : false, lnm_session_key);
|
||||
|
||||
ses->flags |= CIFS_SES_LANMAN;
|
||||
memcpy(bcc_ptr, (char *)lnm_session_key, CIFS_SESS_KEY_SIZE);
|
||||
bcc_ptr += CIFS_SESS_KEY_SIZE;
|
||||
|
|
|
|||
|
|
@ -318,7 +318,8 @@ str_to_key(unsigned char *str, unsigned char *key)
|
|||
}
|
||||
|
||||
static void
|
||||
smbhash(unsigned char *out, unsigned char *in, unsigned char *key, int forw)
|
||||
smbhash(unsigned char *out, const unsigned char *in, unsigned char *key,
|
||||
int forw)
|
||||
{
|
||||
int i;
|
||||
char *outb; /* outb[64] */
|
||||
|
|
@ -363,7 +364,7 @@ E_P16(unsigned char *p14, unsigned char *p16)
|
|||
}
|
||||
|
||||
void
|
||||
E_P24(unsigned char *p21, unsigned char *c8, unsigned char *p24)
|
||||
E_P24(unsigned char *p21, const unsigned char *c8, unsigned char *p24)
|
||||
{
|
||||
smbhash(p24, c8, p21, 1);
|
||||
smbhash(p24 + 8, c8, p21 + 7, 1);
|
||||
|
|
|
|||
|
|
@ -49,9 +49,10 @@
|
|||
|
||||
/*The following definitions come from libsmb/smbencrypt.c */
|
||||
|
||||
void SMBencrypt(unsigned char *passwd, unsigned char *c8, unsigned char *p24);
|
||||
void SMBencrypt(unsigned char *passwd, const unsigned char *c8,
|
||||
unsigned char *p24);
|
||||
void E_md4hash(const unsigned char *passwd, unsigned char *p16);
|
||||
static void SMBOWFencrypt(unsigned char passwd[16], unsigned char *c8,
|
||||
static void SMBOWFencrypt(unsigned char passwd[16], const unsigned char *c8,
|
||||
unsigned char p24[24]);
|
||||
void SMBNTencrypt(unsigned char *passwd, unsigned char *c8, unsigned char *p24);
|
||||
|
||||
|
|
@ -61,7 +62,7 @@ void SMBNTencrypt(unsigned char *passwd, unsigned char *c8, unsigned char *p24);
|
|||
encrypted password into p24 */
|
||||
/* Note that password must be uppercased and null terminated */
|
||||
void
|
||||
SMBencrypt(unsigned char *passwd, unsigned char *c8, unsigned char *p24)
|
||||
SMBencrypt(unsigned char *passwd, const unsigned char *c8, unsigned char *p24)
|
||||
{
|
||||
unsigned char p14[15], p21[21];
|
||||
|
||||
|
|
@ -212,7 +213,7 @@ ntv2_owf_gen(const unsigned char owf[16], const char *user_n,
|
|||
|
||||
/* Does the des encryption from the NT or LM MD4 hash. */
|
||||
static void
|
||||
SMBOWFencrypt(unsigned char passwd[16], unsigned char *c8,
|
||||
SMBOWFencrypt(unsigned char passwd[16], const unsigned char *c8,
|
||||
unsigned char p24[24])
|
||||
{
|
||||
unsigned char p21[21];
|
||||
|
|
|
|||
|
|
@ -37,15 +37,11 @@ extern mempool_t *cifs_mid_poolp;
|
|||
extern struct kmem_cache *cifs_oplock_cachep;
|
||||
|
||||
static struct mid_q_entry *
|
||||
AllocMidQEntry(const struct smb_hdr *smb_buffer, struct cifsSesInfo *ses)
|
||||
AllocMidQEntry(const struct smb_hdr *smb_buffer, struct TCP_Server_Info *server)
|
||||
{
|
||||
struct mid_q_entry *temp;
|
||||
|
||||
if (ses == NULL) {
|
||||
cERROR(1, ("Null session passed in to AllocMidQEntry"));
|
||||
return NULL;
|
||||
}
|
||||
if (ses->server == NULL) {
|
||||
if (server == NULL) {
|
||||
cERROR(1, ("Null TCP session in AllocMidQEntry"));
|
||||
return NULL;
|
||||
}
|
||||
|
|
@ -62,12 +58,11 @@ AllocMidQEntry(const struct smb_hdr *smb_buffer, struct cifsSesInfo *ses)
|
|||
/* do_gettimeofday(&temp->when_sent);*/ /* easier to use jiffies */
|
||||
/* when mid allocated can be before when sent */
|
||||
temp->when_alloc = jiffies;
|
||||
temp->ses = ses;
|
||||
temp->tsk = current;
|
||||
}
|
||||
|
||||
spin_lock(&GlobalMid_Lock);
|
||||
list_add_tail(&temp->qhead, &ses->server->pending_mid_q);
|
||||
list_add_tail(&temp->qhead, &server->pending_mid_q);
|
||||
atomic_inc(&midCount);
|
||||
temp->midState = MID_REQUEST_ALLOCATED;
|
||||
spin_unlock(&GlobalMid_Lock);
|
||||
|
|
@ -349,37 +344,38 @@ static int wait_for_free_request(struct cifsSesInfo *ses, const int long_op)
|
|||
if (long_op == CIFS_ASYNC_OP) {
|
||||
/* oplock breaks must not be held up */
|
||||
atomic_inc(&ses->server->inFlight);
|
||||
} else {
|
||||
spin_lock(&GlobalMid_Lock);
|
||||
while (1) {
|
||||
if (atomic_read(&ses->server->inFlight) >=
|
||||
cifs_max_pending){
|
||||
spin_unlock(&GlobalMid_Lock);
|
||||
#ifdef CONFIG_CIFS_STATS2
|
||||
atomic_inc(&ses->server->num_waiters);
|
||||
#endif
|
||||
wait_event(ses->server->request_q,
|
||||
atomic_read(&ses->server->inFlight)
|
||||
< cifs_max_pending);
|
||||
#ifdef CONFIG_CIFS_STATS2
|
||||
atomic_dec(&ses->server->num_waiters);
|
||||
#endif
|
||||
spin_lock(&GlobalMid_Lock);
|
||||
} else {
|
||||
if (ses->server->tcpStatus == CifsExiting) {
|
||||
spin_unlock(&GlobalMid_Lock);
|
||||
return -ENOENT;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* can not count locking commands against total
|
||||
as they are allowed to block on server */
|
||||
|
||||
/* update # of requests on the wire to server */
|
||||
if (long_op != CIFS_BLOCKING_OP)
|
||||
atomic_inc(&ses->server->inFlight);
|
||||
spin_lock(&GlobalMid_Lock);
|
||||
while (1) {
|
||||
if (atomic_read(&ses->server->inFlight) >=
|
||||
cifs_max_pending){
|
||||
spin_unlock(&GlobalMid_Lock);
|
||||
#ifdef CONFIG_CIFS_STATS2
|
||||
atomic_inc(&ses->server->num_waiters);
|
||||
#endif
|
||||
wait_event(ses->server->request_q,
|
||||
atomic_read(&ses->server->inFlight)
|
||||
< cifs_max_pending);
|
||||
#ifdef CONFIG_CIFS_STATS2
|
||||
atomic_dec(&ses->server->num_waiters);
|
||||
#endif
|
||||
spin_lock(&GlobalMid_Lock);
|
||||
} else {
|
||||
if (ses->server->tcpStatus == CifsExiting) {
|
||||
spin_unlock(&GlobalMid_Lock);
|
||||
break;
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
/* can not count locking commands against total
|
||||
as they are allowed to block on server */
|
||||
|
||||
/* update # of requests on the wire to server */
|
||||
if (long_op != CIFS_BLOCKING_OP)
|
||||
atomic_inc(&ses->server->inFlight);
|
||||
spin_unlock(&GlobalMid_Lock);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
|
|
@ -390,17 +386,21 @@ static int allocate_mid(struct cifsSesInfo *ses, struct smb_hdr *in_buf,
|
|||
{
|
||||
if (ses->server->tcpStatus == CifsExiting) {
|
||||
return -ENOENT;
|
||||
} else if (ses->server->tcpStatus == CifsNeedReconnect) {
|
||||
}
|
||||
|
||||
if (ses->server->tcpStatus == CifsNeedReconnect) {
|
||||
cFYI(1, ("tcp session dead - return to caller to retry"));
|
||||
return -EAGAIN;
|
||||
} else if (ses->status != CifsGood) {
|
||||
}
|
||||
|
||||
if (ses->status != CifsGood) {
|
||||
/* check if SMB session is bad because we are setting it up */
|
||||
if ((in_buf->Command != SMB_COM_SESSION_SETUP_ANDX) &&
|
||||
(in_buf->Command != SMB_COM_NEGOTIATE))
|
||||
return -EAGAIN;
|
||||
/* else ok - we are setting up session */
|
||||
}
|
||||
*ppmidQ = AllocMidQEntry(in_buf, ses);
|
||||
*ppmidQ = AllocMidQEntry(in_buf, ses->server);
|
||||
if (*ppmidQ == NULL)
|
||||
return -ENOMEM;
|
||||
return 0;
|
||||
|
|
@ -415,11 +415,8 @@ static int wait_for_response(struct cifsSesInfo *ses,
|
|||
|
||||
for (;;) {
|
||||
curr_timeout = timeout + jiffies;
|
||||
wait_event(ses->server->response_q,
|
||||
(!(midQ->midState == MID_REQUEST_SUBMITTED)) ||
|
||||
time_after(jiffies, curr_timeout) ||
|
||||
((ses->server->tcpStatus != CifsGood) &&
|
||||
(ses->server->tcpStatus != CifsNew)));
|
||||
wait_event_timeout(ses->server->response_q,
|
||||
midQ->midState != MID_REQUEST_SUBMITTED, timeout);
|
||||
|
||||
if (time_after(jiffies, curr_timeout) &&
|
||||
(midQ->midState == MID_REQUEST_SUBMITTED) &&
|
||||
|
|
@ -521,11 +518,11 @@ SendReceive2(const unsigned int xid, struct cifsSesInfo *ses,
|
|||
and avoid races inside tcp sendmsg code that could cause corruption
|
||||
of smb data */
|
||||
|
||||
down(&ses->server->tcpSem);
|
||||
mutex_lock(&ses->server->srv_mutex);
|
||||
|
||||
rc = allocate_mid(ses, in_buf, &midQ);
|
||||
if (rc) {
|
||||
up(&ses->server->tcpSem);
|
||||
mutex_unlock(&ses->server->srv_mutex);
|
||||
cifs_small_buf_release(in_buf);
|
||||
/* Update # of requests on wire to server */
|
||||
atomic_dec(&ses->server->inFlight);
|
||||
|
|
@ -533,6 +530,11 @@ SendReceive2(const unsigned int xid, struct cifsSesInfo *ses,
|
|||
return rc;
|
||||
}
|
||||
rc = cifs_sign_smb2(iov, n_vec, ses->server, &midQ->sequence_number);
|
||||
if (rc) {
|
||||
mutex_unlock(&ses->server->srv_mutex);
|
||||
cifs_small_buf_release(in_buf);
|
||||
goto out;
|
||||
}
|
||||
|
||||
midQ->midState = MID_REQUEST_SUBMITTED;
|
||||
#ifdef CONFIG_CIFS_STATS2
|
||||
|
|
@ -546,7 +548,7 @@ SendReceive2(const unsigned int xid, struct cifsSesInfo *ses,
|
|||
midQ->when_sent = jiffies;
|
||||
#endif
|
||||
|
||||
up(&ses->server->tcpSem);
|
||||
mutex_unlock(&ses->server->srv_mutex);
|
||||
cifs_small_buf_release(in_buf);
|
||||
|
||||
if (rc < 0)
|
||||
|
|
@ -581,10 +583,8 @@ SendReceive2(const unsigned int xid, struct cifsSesInfo *ses,
|
|||
wait_for_response(ses, midQ, timeout, 10 * HZ);
|
||||
|
||||
spin_lock(&GlobalMid_Lock);
|
||||
if (midQ->resp_buf) {
|
||||
spin_unlock(&GlobalMid_Lock);
|
||||
receive_len = midQ->resp_buf->smb_buf_length;
|
||||
} else {
|
||||
|
||||
if (midQ->resp_buf == NULL) {
|
||||
cERROR(1, ("No response to cmd %d mid %d",
|
||||
midQ->command, midQ->mid));
|
||||
if (midQ->midState == MID_REQUEST_SUBMITTED) {
|
||||
|
|
@ -612,53 +612,59 @@ SendReceive2(const unsigned int xid, struct cifsSesInfo *ses,
|
|||
return rc;
|
||||
}
|
||||
|
||||
spin_unlock(&GlobalMid_Lock);
|
||||
receive_len = midQ->resp_buf->smb_buf_length;
|
||||
|
||||
if (receive_len > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE) {
|
||||
cERROR(1, ("Frame too large received. Length: %d Xid: %d",
|
||||
receive_len, xid));
|
||||
rc = -EIO;
|
||||
} else { /* rcvd frame is ok */
|
||||
if (midQ->resp_buf &&
|
||||
(midQ->midState == MID_RESPONSE_RECEIVED)) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
iov[0].iov_base = (char *)midQ->resp_buf;
|
||||
if (midQ->largeBuf)
|
||||
*pRespBufType = CIFS_LARGE_BUFFER;
|
||||
else
|
||||
*pRespBufType = CIFS_SMALL_BUFFER;
|
||||
iov[0].iov_len = receive_len + 4;
|
||||
/* rcvd frame is ok */
|
||||
|
||||
dump_smb(midQ->resp_buf, 80);
|
||||
/* convert the length into a more usable form */
|
||||
if ((receive_len > 24) &&
|
||||
(ses->server->secMode & (SECMODE_SIGN_REQUIRED |
|
||||
SECMODE_SIGN_ENABLED))) {
|
||||
rc = cifs_verify_signature(midQ->resp_buf,
|
||||
if (midQ->resp_buf &&
|
||||
(midQ->midState == MID_RESPONSE_RECEIVED)) {
|
||||
|
||||
iov[0].iov_base = (char *)midQ->resp_buf;
|
||||
if (midQ->largeBuf)
|
||||
*pRespBufType = CIFS_LARGE_BUFFER;
|
||||
else
|
||||
*pRespBufType = CIFS_SMALL_BUFFER;
|
||||
iov[0].iov_len = receive_len + 4;
|
||||
|
||||
dump_smb(midQ->resp_buf, 80);
|
||||
/* convert the length into a more usable form */
|
||||
if ((receive_len > 24) &&
|
||||
(ses->server->secMode & (SECMODE_SIGN_REQUIRED |
|
||||
SECMODE_SIGN_ENABLED))) {
|
||||
rc = cifs_verify_signature(midQ->resp_buf,
|
||||
&ses->server->mac_signing_key,
|
||||
midQ->sequence_number+1);
|
||||
if (rc) {
|
||||
cERROR(1, ("Unexpected SMB signature"));
|
||||
/* BB FIXME add code to kill session */
|
||||
}
|
||||
if (rc) {
|
||||
cERROR(1, ("Unexpected SMB signature"));
|
||||
/* BB FIXME add code to kill session */
|
||||
}
|
||||
|
||||
/* BB special case reconnect tid and uid here? */
|
||||
rc = map_smb_to_linux_error(midQ->resp_buf,
|
||||
flags & CIFS_LOG_ERROR);
|
||||
|
||||
/* convert ByteCount if necessary */
|
||||
if (receive_len >= sizeof(struct smb_hdr) - 4
|
||||
/* do not count RFC1001 header */ +
|
||||
(2 * midQ->resp_buf->WordCount) + 2 /* bcc */ )
|
||||
BCC(midQ->resp_buf) =
|
||||
le16_to_cpu(BCC_LE(midQ->resp_buf));
|
||||
if ((flags & CIFS_NO_RESP) == 0)
|
||||
midQ->resp_buf = NULL; /* mark it so buf will
|
||||
not be freed by
|
||||
DeleteMidQEntry */
|
||||
} else {
|
||||
rc = -EIO;
|
||||
cFYI(1, ("Bad MID state?"));
|
||||
}
|
||||
|
||||
/* BB special case reconnect tid and uid here? */
|
||||
rc = map_smb_to_linux_error(midQ->resp_buf,
|
||||
flags & CIFS_LOG_ERROR);
|
||||
|
||||
/* convert ByteCount if necessary */
|
||||
if (receive_len >= sizeof(struct smb_hdr) - 4
|
||||
/* do not count RFC1001 header */ +
|
||||
(2 * midQ->resp_buf->WordCount) + 2 /* bcc */ )
|
||||
BCC(midQ->resp_buf) =
|
||||
le16_to_cpu(BCC_LE(midQ->resp_buf));
|
||||
if ((flags & CIFS_NO_RESP) == 0)
|
||||
midQ->resp_buf = NULL; /* mark it so buf will
|
||||
not be freed by
|
||||
DeleteMidQEntry */
|
||||
} else {
|
||||
rc = -EIO;
|
||||
cFYI(1, ("Bad MID state?"));
|
||||
}
|
||||
|
||||
out:
|
||||
|
|
@ -695,6 +701,12 @@ SendReceive(const unsigned int xid, struct cifsSesInfo *ses,
|
|||
to the same server. We may make this configurable later or
|
||||
use ses->maxReq */
|
||||
|
||||
if (in_buf->smb_buf_length > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE - 4) {
|
||||
cERROR(1, ("Illegal length, greater than maximum frame, %d",
|
||||
in_buf->smb_buf_length));
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
rc = wait_for_free_request(ses, long_op);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
|
@ -703,29 +715,22 @@ SendReceive(const unsigned int xid, struct cifsSesInfo *ses,
|
|||
and avoid races inside tcp sendmsg code that could cause corruption
|
||||
of smb data */
|
||||
|
||||
down(&ses->server->tcpSem);
|
||||
mutex_lock(&ses->server->srv_mutex);
|
||||
|
||||
rc = allocate_mid(ses, in_buf, &midQ);
|
||||
if (rc) {
|
||||
up(&ses->server->tcpSem);
|
||||
mutex_unlock(&ses->server->srv_mutex);
|
||||
/* Update # of requests on wire to server */
|
||||
atomic_dec(&ses->server->inFlight);
|
||||
wake_up(&ses->server->request_q);
|
||||
return rc;
|
||||
}
|
||||
|
||||
if (in_buf->smb_buf_length > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE - 4) {
|
||||
cERROR(1, ("Illegal length, greater than maximum frame, %d",
|
||||
in_buf->smb_buf_length));
|
||||
DeleteMidQEntry(midQ);
|
||||
up(&ses->server->tcpSem);
|
||||
/* Update # of requests on wire to server */
|
||||
atomic_dec(&ses->server->inFlight);
|
||||
wake_up(&ses->server->request_q);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
rc = cifs_sign_smb(in_buf, ses->server, &midQ->sequence_number);
|
||||
if (rc) {
|
||||
mutex_unlock(&ses->server->srv_mutex);
|
||||
goto out;
|
||||
}
|
||||
|
||||
midQ->midState = MID_REQUEST_SUBMITTED;
|
||||
#ifdef CONFIG_CIFS_STATS2
|
||||
|
|
@ -738,7 +743,7 @@ SendReceive(const unsigned int xid, struct cifsSesInfo *ses,
|
|||
atomic_dec(&ses->server->inSend);
|
||||
midQ->when_sent = jiffies;
|
||||
#endif
|
||||
up(&ses->server->tcpSem);
|
||||
mutex_unlock(&ses->server->srv_mutex);
|
||||
|
||||
if (rc < 0)
|
||||
goto out;
|
||||
|
|
@ -772,10 +777,7 @@ SendReceive(const unsigned int xid, struct cifsSesInfo *ses,
|
|||
wait_for_response(ses, midQ, timeout, 10 * HZ);
|
||||
|
||||
spin_lock(&GlobalMid_Lock);
|
||||
if (midQ->resp_buf) {
|
||||
spin_unlock(&GlobalMid_Lock);
|
||||
receive_len = midQ->resp_buf->smb_buf_length;
|
||||
} else {
|
||||
if (midQ->resp_buf == NULL) {
|
||||
cERROR(1, ("No response for cmd %d mid %d",
|
||||
midQ->command, midQ->mid));
|
||||
if (midQ->midState == MID_REQUEST_SUBMITTED) {
|
||||
|
|
@ -803,47 +805,52 @@ SendReceive(const unsigned int xid, struct cifsSesInfo *ses,
|
|||
return rc;
|
||||
}
|
||||
|
||||
spin_unlock(&GlobalMid_Lock);
|
||||
receive_len = midQ->resp_buf->smb_buf_length;
|
||||
|
||||
if (receive_len > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE) {
|
||||
cERROR(1, ("Frame too large received. Length: %d Xid: %d",
|
||||
receive_len, xid));
|
||||
rc = -EIO;
|
||||
} else { /* rcvd frame is ok */
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (midQ->resp_buf && out_buf
|
||||
&& (midQ->midState == MID_RESPONSE_RECEIVED)) {
|
||||
out_buf->smb_buf_length = receive_len;
|
||||
memcpy((char *)out_buf + 4,
|
||||
(char *)midQ->resp_buf + 4,
|
||||
receive_len);
|
||||
/* rcvd frame is ok */
|
||||
|
||||
dump_smb(out_buf, 92);
|
||||
/* convert the length into a more usable form */
|
||||
if ((receive_len > 24) &&
|
||||
(ses->server->secMode & (SECMODE_SIGN_REQUIRED |
|
||||
SECMODE_SIGN_ENABLED))) {
|
||||
rc = cifs_verify_signature(out_buf,
|
||||
if (midQ->resp_buf && out_buf
|
||||
&& (midQ->midState == MID_RESPONSE_RECEIVED)) {
|
||||
out_buf->smb_buf_length = receive_len;
|
||||
memcpy((char *)out_buf + 4,
|
||||
(char *)midQ->resp_buf + 4,
|
||||
receive_len);
|
||||
|
||||
dump_smb(out_buf, 92);
|
||||
/* convert the length into a more usable form */
|
||||
if ((receive_len > 24) &&
|
||||
(ses->server->secMode & (SECMODE_SIGN_REQUIRED |
|
||||
SECMODE_SIGN_ENABLED))) {
|
||||
rc = cifs_verify_signature(out_buf,
|
||||
&ses->server->mac_signing_key,
|
||||
midQ->sequence_number+1);
|
||||
if (rc) {
|
||||
cERROR(1, ("Unexpected SMB signature"));
|
||||
/* BB FIXME add code to kill session */
|
||||
}
|
||||
if (rc) {
|
||||
cERROR(1, ("Unexpected SMB signature"));
|
||||
/* BB FIXME add code to kill session */
|
||||
}
|
||||
|
||||
*pbytes_returned = out_buf->smb_buf_length;
|
||||
|
||||
/* BB special case reconnect tid and uid here? */
|
||||
rc = map_smb_to_linux_error(out_buf, 0 /* no log */ );
|
||||
|
||||
/* convert ByteCount if necessary */
|
||||
if (receive_len >= sizeof(struct smb_hdr) - 4
|
||||
/* do not count RFC1001 header */ +
|
||||
(2 * out_buf->WordCount) + 2 /* bcc */ )
|
||||
BCC(out_buf) = le16_to_cpu(BCC_LE(out_buf));
|
||||
} else {
|
||||
rc = -EIO;
|
||||
cERROR(1, ("Bad MID state?"));
|
||||
}
|
||||
|
||||
*pbytes_returned = out_buf->smb_buf_length;
|
||||
|
||||
/* BB special case reconnect tid and uid here? */
|
||||
rc = map_smb_to_linux_error(out_buf, 0 /* no log */ );
|
||||
|
||||
/* convert ByteCount if necessary */
|
||||
if (receive_len >= sizeof(struct smb_hdr) - 4
|
||||
/* do not count RFC1001 header */ +
|
||||
(2 * out_buf->WordCount) + 2 /* bcc */ )
|
||||
BCC(out_buf) = le16_to_cpu(BCC_LE(out_buf));
|
||||
} else {
|
||||
rc = -EIO;
|
||||
cERROR(1, ("Bad MID state?"));
|
||||
}
|
||||
|
||||
out:
|
||||
|
|
@ -866,16 +873,16 @@ send_nt_cancel(struct cifsTconInfo *tcon, struct smb_hdr *in_buf,
|
|||
|
||||
header_assemble(in_buf, SMB_COM_NT_CANCEL, tcon, 0);
|
||||
in_buf->Mid = mid;
|
||||
down(&ses->server->tcpSem);
|
||||
mutex_lock(&ses->server->srv_mutex);
|
||||
rc = cifs_sign_smb(in_buf, ses->server, &midQ->sequence_number);
|
||||
if (rc) {
|
||||
up(&ses->server->tcpSem);
|
||||
mutex_unlock(&ses->server->srv_mutex);
|
||||
return rc;
|
||||
}
|
||||
rc = smb_send(ses->server->ssocket, in_buf, in_buf->smb_buf_length,
|
||||
(struct sockaddr *) &(ses->server->addr.sockAddr),
|
||||
ses->server->noblocksnd);
|
||||
up(&ses->server->tcpSem);
|
||||
mutex_unlock(&ses->server->srv_mutex);
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
|
@ -933,6 +940,12 @@ SendReceiveBlockingLock(const unsigned int xid, struct cifsTconInfo *tcon,
|
|||
to the same server. We may make this configurable later or
|
||||
use ses->maxReq */
|
||||
|
||||
if (in_buf->smb_buf_length > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE - 4) {
|
||||
cERROR(1, ("Illegal length, greater than maximum frame, %d",
|
||||
in_buf->smb_buf_length));
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
rc = wait_for_free_request(ses, CIFS_BLOCKING_OP);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
|
@ -941,23 +954,20 @@ SendReceiveBlockingLock(const unsigned int xid, struct cifsTconInfo *tcon,
|
|||
and avoid races inside tcp sendmsg code that could cause corruption
|
||||
of smb data */
|
||||
|
||||
down(&ses->server->tcpSem);
|
||||
mutex_lock(&ses->server->srv_mutex);
|
||||
|
||||
rc = allocate_mid(ses, in_buf, &midQ);
|
||||
if (rc) {
|
||||
up(&ses->server->tcpSem);
|
||||
mutex_unlock(&ses->server->srv_mutex);
|
||||
return rc;
|
||||
}
|
||||
|
||||
if (in_buf->smb_buf_length > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE - 4) {
|
||||
up(&ses->server->tcpSem);
|
||||
cERROR(1, ("Illegal length, greater than maximum frame, %d",
|
||||
in_buf->smb_buf_length));
|
||||
DeleteMidQEntry(midQ);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
rc = cifs_sign_smb(in_buf, ses->server, &midQ->sequence_number);
|
||||
if (rc) {
|
||||
DeleteMidQEntry(midQ);
|
||||
mutex_unlock(&ses->server->srv_mutex);
|
||||
return rc;
|
||||
}
|
||||
|
||||
midQ->midState = MID_REQUEST_SUBMITTED;
|
||||
#ifdef CONFIG_CIFS_STATS2
|
||||
|
|
@ -970,7 +980,7 @@ SendReceiveBlockingLock(const unsigned int xid, struct cifsTconInfo *tcon,
|
|||
atomic_dec(&ses->server->inSend);
|
||||
midQ->when_sent = jiffies;
|
||||
#endif
|
||||
up(&ses->server->tcpSem);
|
||||
mutex_unlock(&ses->server->srv_mutex);
|
||||
|
||||
if (rc < 0) {
|
||||
DeleteMidQEntry(midQ);
|
||||
|
|
@ -1052,44 +1062,48 @@ SendReceiveBlockingLock(const unsigned int xid, struct cifsTconInfo *tcon,
|
|||
cERROR(1, ("Frame too large received. Length: %d Xid: %d",
|
||||
receive_len, xid));
|
||||
rc = -EIO;
|
||||
} else { /* rcvd frame is ok */
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (midQ->resp_buf && out_buf
|
||||
&& (midQ->midState == MID_RESPONSE_RECEIVED)) {
|
||||
out_buf->smb_buf_length = receive_len;
|
||||
memcpy((char *)out_buf + 4,
|
||||
(char *)midQ->resp_buf + 4,
|
||||
receive_len);
|
||||
/* rcvd frame is ok */
|
||||
|
||||
dump_smb(out_buf, 92);
|
||||
/* convert the length into a more usable form */
|
||||
if ((receive_len > 24) &&
|
||||
(ses->server->secMode & (SECMODE_SIGN_REQUIRED |
|
||||
SECMODE_SIGN_ENABLED))) {
|
||||
rc = cifs_verify_signature(out_buf,
|
||||
&ses->server->mac_signing_key,
|
||||
midQ->sequence_number+1);
|
||||
if (rc) {
|
||||
cERROR(1, ("Unexpected SMB signature"));
|
||||
/* BB FIXME add code to kill session */
|
||||
}
|
||||
}
|
||||
if ((out_buf == NULL) || (midQ->midState != MID_RESPONSE_RECEIVED)) {
|
||||
rc = -EIO;
|
||||
cERROR(1, ("Bad MID state?"));
|
||||
goto out;
|
||||
}
|
||||
|
||||
*pbytes_returned = out_buf->smb_buf_length;
|
||||
out_buf->smb_buf_length = receive_len;
|
||||
memcpy((char *)out_buf + 4,
|
||||
(char *)midQ->resp_buf + 4,
|
||||
receive_len);
|
||||
|
||||
/* BB special case reconnect tid and uid here? */
|
||||
rc = map_smb_to_linux_error(out_buf, 0 /* no log */ );
|
||||
|
||||
/* convert ByteCount if necessary */
|
||||
if (receive_len >= sizeof(struct smb_hdr) - 4
|
||||
/* do not count RFC1001 header */ +
|
||||
(2 * out_buf->WordCount) + 2 /* bcc */ )
|
||||
BCC(out_buf) = le16_to_cpu(BCC_LE(out_buf));
|
||||
} else {
|
||||
rc = -EIO;
|
||||
cERROR(1, ("Bad MID state?"));
|
||||
dump_smb(out_buf, 92);
|
||||
/* convert the length into a more usable form */
|
||||
if ((receive_len > 24) &&
|
||||
(ses->server->secMode & (SECMODE_SIGN_REQUIRED |
|
||||
SECMODE_SIGN_ENABLED))) {
|
||||
rc = cifs_verify_signature(out_buf,
|
||||
&ses->server->mac_signing_key,
|
||||
midQ->sequence_number+1);
|
||||
if (rc) {
|
||||
cERROR(1, ("Unexpected SMB signature"));
|
||||
/* BB FIXME add code to kill session */
|
||||
}
|
||||
}
|
||||
|
||||
*pbytes_returned = out_buf->smb_buf_length;
|
||||
|
||||
/* BB special case reconnect tid and uid here? */
|
||||
rc = map_smb_to_linux_error(out_buf, 0 /* no log */ );
|
||||
|
||||
/* convert ByteCount if necessary */
|
||||
if (receive_len >= sizeof(struct smb_hdr) - 4
|
||||
/* do not count RFC1001 header */ +
|
||||
(2 * out_buf->WordCount) + 2 /* bcc */ )
|
||||
BCC(out_buf) = le16_to_cpu(BCC_LE(out_buf));
|
||||
|
||||
out:
|
||||
DeleteMidQEntry(midQ);
|
||||
if (rstart && rc == -EACCES)
|
||||
return -ERESTARTSYS;
|
||||
|
|
|
|||
|
|
@ -32,8 +32,8 @@ void coda_cache_enter(struct inode *inode, int mask)
|
|||
struct coda_inode_info *cii = ITOC(inode);
|
||||
|
||||
cii->c_cached_epoch = atomic_read(&permission_epoch);
|
||||
if (cii->c_uid != current->fsuid) {
|
||||
cii->c_uid = current->fsuid;
|
||||
if (cii->c_uid != current_fsuid()) {
|
||||
cii->c_uid = current_fsuid();
|
||||
cii->c_cached_perm = mask;
|
||||
} else
|
||||
cii->c_cached_perm |= mask;
|
||||
|
|
@ -60,7 +60,7 @@ int coda_cache_check(struct inode *inode, int mask)
|
|||
int hit;
|
||||
|
||||
hit = (mask & cii->c_cached_perm) == mask &&
|
||||
cii->c_uid == current->fsuid &&
|
||||
cii->c_uid == current_fsuid() &&
|
||||
cii->c_cached_epoch == atomic_read(&permission_epoch);
|
||||
|
||||
return hit;
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@
|
|||
#include <linux/file.h>
|
||||
#include <linux/fs.h>
|
||||
#include <linux/stat.h>
|
||||
#include <linux/cred.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/smp_lock.h>
|
||||
#include <linux/string.h>
|
||||
|
|
@ -174,7 +175,7 @@ int coda_release(struct inode *coda_inode, struct file *coda_file)
|
|||
BUG_ON(!cfi || cfi->cfi_magic != CODA_MAGIC);
|
||||
|
||||
err = venus_close(coda_inode->i_sb, coda_i2f(coda_inode),
|
||||
coda_flags, coda_file->f_uid);
|
||||
coda_flags, coda_file->f_cred->fsuid);
|
||||
|
||||
host_inode = cfi->cfi_container->f_path.dentry->d_inode;
|
||||
cii = ITOC(coda_inode);
|
||||
|
|
|
|||
|
|
@ -52,7 +52,7 @@ static void *alloc_upcall(int opcode, int size)
|
|||
inp->ih.opcode = opcode;
|
||||
inp->ih.pid = current->pid;
|
||||
inp->ih.pgid = task_pgrp_nr(current);
|
||||
inp->ih.uid = current->fsuid;
|
||||
inp->ih.uid = current_fsuid();
|
||||
|
||||
return (void*)inp;
|
||||
}
|
||||
|
|
|
|||
42
fs/compat.c
42
fs/compat.c
|
|
@ -1393,10 +1393,20 @@ int compat_do_execve(char * filename,
|
|||
if (!bprm)
|
||||
goto out_ret;
|
||||
|
||||
retval = mutex_lock_interruptible(¤t->cred_exec_mutex);
|
||||
if (retval < 0)
|
||||
goto out_free;
|
||||
|
||||
retval = -ENOMEM;
|
||||
bprm->cred = prepare_exec_creds();
|
||||
if (!bprm->cred)
|
||||
goto out_unlock;
|
||||
check_unsafe_exec(bprm);
|
||||
|
||||
file = open_exec(filename);
|
||||
retval = PTR_ERR(file);
|
||||
if (IS_ERR(file))
|
||||
goto out_kfree;
|
||||
goto out_unlock;
|
||||
|
||||
sched_exec();
|
||||
|
||||
|
|
@ -1410,14 +1420,10 @@ int compat_do_execve(char * filename,
|
|||
|
||||
bprm->argc = compat_count(argv, MAX_ARG_STRINGS);
|
||||
if ((retval = bprm->argc) < 0)
|
||||
goto out_mm;
|
||||
goto out;
|
||||
|
||||
bprm->envc = compat_count(envp, MAX_ARG_STRINGS);
|
||||
if ((retval = bprm->envc) < 0)
|
||||
goto out_mm;
|
||||
|
||||
retval = security_bprm_alloc(bprm);
|
||||
if (retval)
|
||||
goto out;
|
||||
|
||||
retval = prepare_binprm(bprm);
|
||||
|
|
@ -1438,19 +1444,16 @@ int compat_do_execve(char * filename,
|
|||
goto out;
|
||||
|
||||
retval = search_binary_handler(bprm, regs);
|
||||
if (retval >= 0) {
|
||||
/* execve success */
|
||||
security_bprm_free(bprm);
|
||||
acct_update_integrals(current);
|
||||
free_bprm(bprm);
|
||||
return retval;
|
||||
}
|
||||
if (retval < 0)
|
||||
goto out;
|
||||
|
||||
/* execve succeeded */
|
||||
mutex_unlock(¤t->cred_exec_mutex);
|
||||
acct_update_integrals(current);
|
||||
free_bprm(bprm);
|
||||
return retval;
|
||||
|
||||
out:
|
||||
if (bprm->security)
|
||||
security_bprm_free(bprm);
|
||||
|
||||
out_mm:
|
||||
if (bprm->mm)
|
||||
mmput(bprm->mm);
|
||||
|
||||
|
|
@ -1460,7 +1463,10 @@ out_file:
|
|||
fput(bprm->file);
|
||||
}
|
||||
|
||||
out_kfree:
|
||||
out_unlock:
|
||||
mutex_unlock(¤t->cred_exec_mutex);
|
||||
|
||||
out_free:
|
||||
free_bprm(bprm);
|
||||
|
||||
out_ret:
|
||||
|
|
|
|||
|
|
@ -222,8 +222,8 @@ int devpts_pty_new(struct inode *ptmx_inode, struct tty_struct *tty)
|
|||
return -ENOMEM;
|
||||
|
||||
inode->i_ino = number+2;
|
||||
inode->i_uid = config.setuid ? config.uid : current->fsuid;
|
||||
inode->i_gid = config.setgid ? config.gid : current->fsgid;
|
||||
inode->i_uid = config.setuid ? config.uid : current_fsuid();
|
||||
inode->i_gid = config.setgid ? config.gid : current_fsgid();
|
||||
inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
|
||||
init_special_inode(inode, S_IFCHR|config.mode, device);
|
||||
inode->i_private = tty;
|
||||
|
|
|
|||
|
|
@ -127,8 +127,8 @@ static void fill_data(struct dlm_lock_data *data, struct dlm_lkb *lkb)
|
|||
|
||||
void dlm_timeout_warn(struct dlm_lkb *lkb)
|
||||
{
|
||||
struct sk_buff *uninitialized_var(send_skb);
|
||||
struct dlm_lock_data *data;
|
||||
struct sk_buff *send_skb;
|
||||
size_t size;
|
||||
int rv;
|
||||
|
||||
|
|
|
|||
|
|
@ -874,7 +874,7 @@ static inline int need_print_warning(struct dquot *dquot)
|
|||
|
||||
switch (dquot->dq_type) {
|
||||
case USRQUOTA:
|
||||
return current->fsuid == dquot->dq_id;
|
||||
return current_fsuid() == dquot->dq_id;
|
||||
case GRPQUOTA:
|
||||
return in_group_p(dquot->dq_id);
|
||||
}
|
||||
|
|
@ -981,7 +981,7 @@ static void send_warning(const struct dquot *dquot, const char warntype)
|
|||
MINOR(dquot->dq_sb->s_dev));
|
||||
if (ret)
|
||||
goto attr_err_out;
|
||||
ret = nla_put_u64(skb, QUOTA_NL_A_CAUSED_ID, current->user->uid);
|
||||
ret = nla_put_u64(skb, QUOTA_NL_A_CAUSED_ID, current_uid());
|
||||
if (ret)
|
||||
goto attr_err_out;
|
||||
genlmsg_end(skb, msg_head);
|
||||
|
|
|
|||
|
|
@ -691,7 +691,8 @@ int ecryptfs_init_kthread(void);
|
|||
void ecryptfs_destroy_kthread(void);
|
||||
int ecryptfs_privileged_open(struct file **lower_file,
|
||||
struct dentry *lower_dentry,
|
||||
struct vfsmount *lower_mnt);
|
||||
struct vfsmount *lower_mnt,
|
||||
const struct cred *cred);
|
||||
int ecryptfs_init_persistent_file(struct dentry *ecryptfs_dentry);
|
||||
|
||||
#endif /* #ifndef ECRYPTFS_KERNEL_H */
|
||||
|
|
|
|||
|
|
@ -73,7 +73,7 @@ static int ecryptfs_threadfn(void *ignored)
|
|||
mntget(req->lower_mnt);
|
||||
(*req->lower_file) = dentry_open(
|
||||
req->lower_dentry, req->lower_mnt,
|
||||
(O_RDWR | O_LARGEFILE));
|
||||
(O_RDWR | O_LARGEFILE), current_cred());
|
||||
req->flags |= ECRYPTFS_REQ_PROCESSED;
|
||||
}
|
||||
wake_up(&req->wait);
|
||||
|
|
@ -132,7 +132,8 @@ void ecryptfs_destroy_kthread(void)
|
|||
*/
|
||||
int ecryptfs_privileged_open(struct file **lower_file,
|
||||
struct dentry *lower_dentry,
|
||||
struct vfsmount *lower_mnt)
|
||||
struct vfsmount *lower_mnt,
|
||||
const struct cred *cred)
|
||||
{
|
||||
struct ecryptfs_open_req *req;
|
||||
int rc = 0;
|
||||
|
|
@ -143,7 +144,7 @@ int ecryptfs_privileged_open(struct file **lower_file,
|
|||
dget(lower_dentry);
|
||||
mntget(lower_mnt);
|
||||
(*lower_file) = dentry_open(lower_dentry, lower_mnt,
|
||||
(O_RDWR | O_LARGEFILE));
|
||||
(O_RDWR | O_LARGEFILE), cred);
|
||||
if (!IS_ERR(*lower_file))
|
||||
goto out;
|
||||
req = kmem_cache_alloc(ecryptfs_open_req_cache, GFP_KERNEL);
|
||||
|
|
@ -184,7 +185,7 @@ int ecryptfs_privileged_open(struct file **lower_file,
|
|||
dget(lower_dentry);
|
||||
mntget(lower_mnt);
|
||||
(*lower_file) = dentry_open(lower_dentry, lower_mnt,
|
||||
(O_RDONLY | O_LARGEFILE));
|
||||
(O_RDONLY | O_LARGEFILE), cred);
|
||||
if (IS_ERR(*lower_file)) {
|
||||
rc = PTR_ERR(*req->lower_file);
|
||||
(*lower_file) = NULL;
|
||||
|
|
|
|||
|
|
@ -115,6 +115,7 @@ void __ecryptfs_printk(const char *fmt, ...)
|
|||
*/
|
||||
int ecryptfs_init_persistent_file(struct dentry *ecryptfs_dentry)
|
||||
{
|
||||
const struct cred *cred = current_cred();
|
||||
struct ecryptfs_inode_info *inode_info =
|
||||
ecryptfs_inode_to_private(ecryptfs_dentry->d_inode);
|
||||
int rc = 0;
|
||||
|
|
@ -127,7 +128,7 @@ int ecryptfs_init_persistent_file(struct dentry *ecryptfs_dentry)
|
|||
|
||||
lower_dentry = ecryptfs_dentry_to_lower(ecryptfs_dentry);
|
||||
rc = ecryptfs_privileged_open(&inode_info->lower_file,
|
||||
lower_dentry, lower_mnt);
|
||||
lower_dentry, lower_mnt, cred);
|
||||
if (rc || IS_ERR(inode_info->lower_file)) {
|
||||
printk(KERN_ERR "Error opening lower persistent file "
|
||||
"for lower_dentry [0x%p] and lower_mnt [0x%p]; "
|
||||
|
|
|
|||
|
|
@ -360,7 +360,8 @@ int ecryptfs_process_response(struct ecryptfs_message *msg, uid_t euid,
|
|||
struct ecryptfs_msg_ctx *msg_ctx;
|
||||
size_t msg_size;
|
||||
struct nsproxy *nsproxy;
|
||||
struct user_namespace *current_user_ns;
|
||||
struct user_namespace *tsk_user_ns;
|
||||
uid_t ctx_euid;
|
||||
int rc;
|
||||
|
||||
if (msg->index >= ecryptfs_message_buf_len) {
|
||||
|
|
@ -384,9 +385,9 @@ int ecryptfs_process_response(struct ecryptfs_message *msg, uid_t euid,
|
|||
mutex_unlock(&ecryptfs_daemon_hash_mux);
|
||||
goto wake_up;
|
||||
}
|
||||
current_user_ns = nsproxy->user_ns;
|
||||
rc = ecryptfs_find_daemon_by_euid(&daemon, msg_ctx->task->euid,
|
||||
current_user_ns);
|
||||
tsk_user_ns = __task_cred(msg_ctx->task)->user->user_ns;
|
||||
ctx_euid = task_euid(msg_ctx->task);
|
||||
rc = ecryptfs_find_daemon_by_euid(&daemon, ctx_euid, tsk_user_ns);
|
||||
rcu_read_unlock();
|
||||
mutex_unlock(&ecryptfs_daemon_hash_mux);
|
||||
if (rc) {
|
||||
|
|
@ -394,28 +395,28 @@ int ecryptfs_process_response(struct ecryptfs_message *msg, uid_t euid,
|
|||
printk(KERN_WARNING "%s: User [%d] received a "
|
||||
"message response from process [0x%p] but does "
|
||||
"not have a registered daemon\n", __func__,
|
||||
msg_ctx->task->euid, pid);
|
||||
ctx_euid, pid);
|
||||
goto wake_up;
|
||||
}
|
||||
if (msg_ctx->task->euid != euid) {
|
||||
if (ctx_euid != euid) {
|
||||
rc = -EBADMSG;
|
||||
printk(KERN_WARNING "%s: Received message from user "
|
||||
"[%d]; expected message from user [%d]\n", __func__,
|
||||
euid, msg_ctx->task->euid);
|
||||
euid, ctx_euid);
|
||||
goto unlock;
|
||||
}
|
||||
if (current_user_ns != user_ns) {
|
||||
if (tsk_user_ns != user_ns) {
|
||||
rc = -EBADMSG;
|
||||
printk(KERN_WARNING "%s: Received message from user_ns "
|
||||
"[0x%p]; expected message from user_ns [0x%p]\n",
|
||||
__func__, user_ns, nsproxy->user_ns);
|
||||
__func__, user_ns, tsk_user_ns);
|
||||
goto unlock;
|
||||
}
|
||||
if (daemon->pid != pid) {
|
||||
rc = -EBADMSG;
|
||||
printk(KERN_ERR "%s: User [%d] sent a message response "
|
||||
"from an unrecognized process [0x%p]\n",
|
||||
__func__, msg_ctx->task->euid, pid);
|
||||
__func__, ctx_euid, pid);
|
||||
goto unlock;
|
||||
}
|
||||
if (msg_ctx->state != ECRYPTFS_MSG_CTX_STATE_PENDING) {
|
||||
|
|
@ -464,14 +465,14 @@ ecryptfs_send_message_locked(char *data, int data_len, u8 msg_type,
|
|||
struct ecryptfs_msg_ctx **msg_ctx)
|
||||
{
|
||||
struct ecryptfs_daemon *daemon;
|
||||
uid_t euid = current_euid();
|
||||
int rc;
|
||||
|
||||
rc = ecryptfs_find_daemon_by_euid(&daemon, current->euid,
|
||||
current->nsproxy->user_ns);
|
||||
rc = ecryptfs_find_daemon_by_euid(&daemon, euid, current_user_ns());
|
||||
if (rc || !daemon) {
|
||||
rc = -ENOTCONN;
|
||||
printk(KERN_ERR "%s: User [%d] does not have a daemon "
|
||||
"registered\n", __func__, current->euid);
|
||||
"registered\n", __func__, euid);
|
||||
goto out;
|
||||
}
|
||||
mutex_lock(&ecryptfs_msg_ctx_lists_mux);
|
||||
|
|
|
|||
|
|
@ -42,12 +42,12 @@ ecryptfs_miscdev_poll(struct file *file, poll_table *pt)
|
|||
{
|
||||
struct ecryptfs_daemon *daemon;
|
||||
unsigned int mask = 0;
|
||||
uid_t euid = current_euid();
|
||||
int rc;
|
||||
|
||||
mutex_lock(&ecryptfs_daemon_hash_mux);
|
||||
/* TODO: Just use file->private_data? */
|
||||
rc = ecryptfs_find_daemon_by_euid(&daemon, current->euid,
|
||||
current->nsproxy->user_ns);
|
||||
rc = ecryptfs_find_daemon_by_euid(&daemon, euid, current_user_ns());
|
||||
BUG_ON(rc || !daemon);
|
||||
mutex_lock(&daemon->mux);
|
||||
mutex_unlock(&ecryptfs_daemon_hash_mux);
|
||||
|
|
@ -83,6 +83,7 @@ static int
|
|||
ecryptfs_miscdev_open(struct inode *inode, struct file *file)
|
||||
{
|
||||
struct ecryptfs_daemon *daemon = NULL;
|
||||
uid_t euid = current_euid();
|
||||
int rc;
|
||||
|
||||
mutex_lock(&ecryptfs_daemon_hash_mux);
|
||||
|
|
@ -93,11 +94,9 @@ ecryptfs_miscdev_open(struct inode *inode, struct file *file)
|
|||
"count; rc = [%d]\n", __func__, rc);
|
||||
goto out_unlock_daemon_list;
|
||||
}
|
||||
rc = ecryptfs_find_daemon_by_euid(&daemon, current->euid,
|
||||
current->nsproxy->user_ns);
|
||||
rc = ecryptfs_find_daemon_by_euid(&daemon, euid, current_user_ns());
|
||||
if (rc || !daemon) {
|
||||
rc = ecryptfs_spawn_daemon(&daemon, current->euid,
|
||||
current->nsproxy->user_ns,
|
||||
rc = ecryptfs_spawn_daemon(&daemon, euid, current_user_ns(),
|
||||
task_pid(current));
|
||||
if (rc) {
|
||||
printk(KERN_ERR "%s: Error attempting to spawn daemon; "
|
||||
|
|
@ -147,11 +146,11 @@ static int
|
|||
ecryptfs_miscdev_release(struct inode *inode, struct file *file)
|
||||
{
|
||||
struct ecryptfs_daemon *daemon = NULL;
|
||||
uid_t euid = current_euid();
|
||||
int rc;
|
||||
|
||||
mutex_lock(&ecryptfs_daemon_hash_mux);
|
||||
rc = ecryptfs_find_daemon_by_euid(&daemon, current->euid,
|
||||
current->nsproxy->user_ns);
|
||||
rc = ecryptfs_find_daemon_by_euid(&daemon, euid, current_user_ns());
|
||||
BUG_ON(rc || !daemon);
|
||||
mutex_lock(&daemon->mux);
|
||||
BUG_ON(daemon->pid != task_pid(current));
|
||||
|
|
@ -246,12 +245,12 @@ ecryptfs_miscdev_read(struct file *file, char __user *buf, size_t count,
|
|||
char packet_length[3];
|
||||
size_t i;
|
||||
size_t total_length;
|
||||
uid_t euid = current_euid();
|
||||
int rc;
|
||||
|
||||
mutex_lock(&ecryptfs_daemon_hash_mux);
|
||||
/* TODO: Just use file->private_data? */
|
||||
rc = ecryptfs_find_daemon_by_euid(&daemon, current->euid,
|
||||
current->nsproxy->user_ns);
|
||||
rc = ecryptfs_find_daemon_by_euid(&daemon, euid, current_user_ns());
|
||||
BUG_ON(rc || !daemon);
|
||||
mutex_lock(&daemon->mux);
|
||||
if (daemon->flags & ECRYPTFS_DAEMON_ZOMBIE) {
|
||||
|
|
@ -290,8 +289,8 @@ check_list:
|
|||
* message from the queue; try again */
|
||||
goto check_list;
|
||||
}
|
||||
BUG_ON(current->euid != daemon->euid);
|
||||
BUG_ON(current->nsproxy->user_ns != daemon->user_ns);
|
||||
BUG_ON(euid != daemon->euid);
|
||||
BUG_ON(current_user_ns() != daemon->user_ns);
|
||||
BUG_ON(task_pid(current) != daemon->pid);
|
||||
msg_ctx = list_first_entry(&daemon->msg_ctx_out_queue,
|
||||
struct ecryptfs_msg_ctx, daemon_out_list);
|
||||
|
|
@ -414,6 +413,7 @@ ecryptfs_miscdev_write(struct file *file, const char __user *buf,
|
|||
size_t packet_size, packet_size_length, i;
|
||||
ssize_t sz = 0;
|
||||
char *data;
|
||||
uid_t euid = current_euid();
|
||||
int rc;
|
||||
|
||||
if (count == 0)
|
||||
|
|
@ -463,8 +463,7 @@ ecryptfs_miscdev_write(struct file *file, const char __user *buf,
|
|||
goto out_free;
|
||||
}
|
||||
rc = ecryptfs_miscdev_response(&data[i], packet_size,
|
||||
current->euid,
|
||||
current->nsproxy->user_ns,
|
||||
euid, current_user_ns(),
|
||||
task_pid(current), seq);
|
||||
if (rc)
|
||||
printk(KERN_WARNING "%s: Failed to deliver miscdev "
|
||||
|
|
|
|||
183
fs/exec.c
183
fs/exec.c
|
|
@ -55,6 +55,7 @@
|
|||
#include <asm/uaccess.h>
|
||||
#include <asm/mmu_context.h>
|
||||
#include <asm/tlb.h>
|
||||
#include "internal.h"
|
||||
|
||||
#ifdef __alpha__
|
||||
/* for /sbin/loader handling in search_binary_handler() */
|
||||
|
|
@ -980,7 +981,7 @@ int flush_old_exec(struct linux_binprm * bprm)
|
|||
/* This is the point of no return */
|
||||
current->sas_ss_sp = current->sas_ss_size = 0;
|
||||
|
||||
if (current->euid == current->uid && current->egid == current->gid)
|
||||
if (current_euid() == current_uid() && current_egid() == current_gid())
|
||||
set_dumpable(current->mm, 1);
|
||||
else
|
||||
set_dumpable(current->mm, suid_dumpable);
|
||||
|
|
@ -1007,16 +1008,17 @@ int flush_old_exec(struct linux_binprm * bprm)
|
|||
*/
|
||||
current->mm->task_size = TASK_SIZE;
|
||||
|
||||
if (bprm->e_uid != current->euid || bprm->e_gid != current->egid) {
|
||||
suid_keys(current);
|
||||
set_dumpable(current->mm, suid_dumpable);
|
||||
/* install the new credentials */
|
||||
if (bprm->cred->uid != current_euid() ||
|
||||
bprm->cred->gid != current_egid()) {
|
||||
current->pdeath_signal = 0;
|
||||
} else if (file_permission(bprm->file, MAY_READ) ||
|
||||
(bprm->interp_flags & BINPRM_FLAGS_ENFORCE_NONDUMP)) {
|
||||
suid_keys(current);
|
||||
bprm->interp_flags & BINPRM_FLAGS_ENFORCE_NONDUMP) {
|
||||
set_dumpable(current->mm, suid_dumpable);
|
||||
}
|
||||
|
||||
current->personality &= ~bprm->per_clear;
|
||||
|
||||
/* An exec changes our domain. We are no longer part of the thread
|
||||
group */
|
||||
|
||||
|
|
@ -1033,13 +1035,50 @@ out:
|
|||
|
||||
EXPORT_SYMBOL(flush_old_exec);
|
||||
|
||||
/*
|
||||
* install the new credentials for this executable
|
||||
*/
|
||||
void install_exec_creds(struct linux_binprm *bprm)
|
||||
{
|
||||
security_bprm_committing_creds(bprm);
|
||||
|
||||
commit_creds(bprm->cred);
|
||||
bprm->cred = NULL;
|
||||
|
||||
/* cred_exec_mutex must be held at least to this point to prevent
|
||||
* ptrace_attach() from altering our determination of the task's
|
||||
* credentials; any time after this it may be unlocked */
|
||||
|
||||
security_bprm_committed_creds(bprm);
|
||||
}
|
||||
EXPORT_SYMBOL(install_exec_creds);
|
||||
|
||||
/*
|
||||
* determine how safe it is to execute the proposed program
|
||||
* - the caller must hold current->cred_exec_mutex to protect against
|
||||
* PTRACE_ATTACH
|
||||
*/
|
||||
void check_unsafe_exec(struct linux_binprm *bprm)
|
||||
{
|
||||
struct task_struct *p = current;
|
||||
|
||||
bprm->unsafe = tracehook_unsafe_exec(p);
|
||||
|
||||
if (atomic_read(&p->fs->count) > 1 ||
|
||||
atomic_read(&p->files->count) > 1 ||
|
||||
atomic_read(&p->sighand->count) > 1)
|
||||
bprm->unsafe |= LSM_UNSAFE_SHARE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Fill the binprm structure from the inode.
|
||||
* Check permissions, then read the first 128 (BINPRM_BUF_SIZE) bytes
|
||||
*
|
||||
* This may be called multiple times for binary chains (scripts for example).
|
||||
*/
|
||||
int prepare_binprm(struct linux_binprm *bprm)
|
||||
{
|
||||
int mode;
|
||||
umode_t mode;
|
||||
struct inode * inode = bprm->file->f_path.dentry->d_inode;
|
||||
int retval;
|
||||
|
||||
|
|
@ -1047,14 +1086,15 @@ int prepare_binprm(struct linux_binprm *bprm)
|
|||
if (bprm->file->f_op == NULL)
|
||||
return -EACCES;
|
||||
|
||||
bprm->e_uid = current->euid;
|
||||
bprm->e_gid = current->egid;
|
||||
/* clear any previous set[ug]id data from a previous binary */
|
||||
bprm->cred->euid = current_euid();
|
||||
bprm->cred->egid = current_egid();
|
||||
|
||||
if(!(bprm->file->f_path.mnt->mnt_flags & MNT_NOSUID)) {
|
||||
if (!(bprm->file->f_path.mnt->mnt_flags & MNT_NOSUID)) {
|
||||
/* Set-uid? */
|
||||
if (mode & S_ISUID) {
|
||||
current->personality &= ~PER_CLEAR_ON_SETID;
|
||||
bprm->e_uid = inode->i_uid;
|
||||
bprm->per_clear |= PER_CLEAR_ON_SETID;
|
||||
bprm->cred->euid = inode->i_uid;
|
||||
}
|
||||
|
||||
/* Set-gid? */
|
||||
|
|
@ -1064,52 +1104,23 @@ int prepare_binprm(struct linux_binprm *bprm)
|
|||
* executable.
|
||||
*/
|
||||
if ((mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP)) {
|
||||
current->personality &= ~PER_CLEAR_ON_SETID;
|
||||
bprm->e_gid = inode->i_gid;
|
||||
bprm->per_clear |= PER_CLEAR_ON_SETID;
|
||||
bprm->cred->egid = inode->i_gid;
|
||||
}
|
||||
}
|
||||
|
||||
/* fill in binprm security blob */
|
||||
retval = security_bprm_set(bprm);
|
||||
retval = security_bprm_set_creds(bprm);
|
||||
if (retval)
|
||||
return retval;
|
||||
bprm->cred_prepared = 1;
|
||||
|
||||
memset(bprm->buf,0,BINPRM_BUF_SIZE);
|
||||
return kernel_read(bprm->file,0,bprm->buf,BINPRM_BUF_SIZE);
|
||||
memset(bprm->buf, 0, BINPRM_BUF_SIZE);
|
||||
return kernel_read(bprm->file, 0, bprm->buf, BINPRM_BUF_SIZE);
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(prepare_binprm);
|
||||
|
||||
static int unsafe_exec(struct task_struct *p)
|
||||
{
|
||||
int unsafe = tracehook_unsafe_exec(p);
|
||||
|
||||
if (atomic_read(&p->fs->count) > 1 ||
|
||||
atomic_read(&p->files->count) > 1 ||
|
||||
atomic_read(&p->sighand->count) > 1)
|
||||
unsafe |= LSM_UNSAFE_SHARE;
|
||||
|
||||
return unsafe;
|
||||
}
|
||||
|
||||
void compute_creds(struct linux_binprm *bprm)
|
||||
{
|
||||
int unsafe;
|
||||
|
||||
if (bprm->e_uid != current->uid) {
|
||||
suid_keys(current);
|
||||
current->pdeath_signal = 0;
|
||||
}
|
||||
exec_keys(current);
|
||||
|
||||
task_lock(current);
|
||||
unsafe = unsafe_exec(current);
|
||||
security_bprm_apply_creds(bprm, unsafe);
|
||||
task_unlock(current);
|
||||
security_bprm_post_apply_creds(bprm);
|
||||
}
|
||||
EXPORT_SYMBOL(compute_creds);
|
||||
|
||||
/*
|
||||
* Arguments are '\0' separated strings found at the location bprm->p
|
||||
* points to; chop off the first by relocating brpm->p to right after
|
||||
|
|
@ -1270,6 +1281,8 @@ EXPORT_SYMBOL(search_binary_handler);
|
|||
void free_bprm(struct linux_binprm *bprm)
|
||||
{
|
||||
free_arg_pages(bprm);
|
||||
if (bprm->cred)
|
||||
abort_creds(bprm->cred);
|
||||
kfree(bprm);
|
||||
}
|
||||
|
||||
|
|
@ -1295,10 +1308,20 @@ int do_execve(char * filename,
|
|||
if (!bprm)
|
||||
goto out_files;
|
||||
|
||||
retval = mutex_lock_interruptible(¤t->cred_exec_mutex);
|
||||
if (retval < 0)
|
||||
goto out_free;
|
||||
|
||||
retval = -ENOMEM;
|
||||
bprm->cred = prepare_exec_creds();
|
||||
if (!bprm->cred)
|
||||
goto out_unlock;
|
||||
check_unsafe_exec(bprm);
|
||||
|
||||
file = open_exec(filename);
|
||||
retval = PTR_ERR(file);
|
||||
if (IS_ERR(file))
|
||||
goto out_kfree;
|
||||
goto out_unlock;
|
||||
|
||||
sched_exec();
|
||||
|
||||
|
|
@ -1312,14 +1335,10 @@ int do_execve(char * filename,
|
|||
|
||||
bprm->argc = count(argv, MAX_ARG_STRINGS);
|
||||
if ((retval = bprm->argc) < 0)
|
||||
goto out_mm;
|
||||
goto out;
|
||||
|
||||
bprm->envc = count(envp, MAX_ARG_STRINGS);
|
||||
if ((retval = bprm->envc) < 0)
|
||||
goto out_mm;
|
||||
|
||||
retval = security_bprm_alloc(bprm);
|
||||
if (retval)
|
||||
goto out;
|
||||
|
||||
retval = prepare_binprm(bprm);
|
||||
|
|
@ -1341,21 +1360,18 @@ int do_execve(char * filename,
|
|||
|
||||
current->flags &= ~PF_KTHREAD;
|
||||
retval = search_binary_handler(bprm,regs);
|
||||
if (retval >= 0) {
|
||||
/* execve success */
|
||||
security_bprm_free(bprm);
|
||||
acct_update_integrals(current);
|
||||
free_bprm(bprm);
|
||||
if (displaced)
|
||||
put_files_struct(displaced);
|
||||
return retval;
|
||||
}
|
||||
if (retval < 0)
|
||||
goto out;
|
||||
|
||||
/* execve succeeded */
|
||||
mutex_unlock(¤t->cred_exec_mutex);
|
||||
acct_update_integrals(current);
|
||||
free_bprm(bprm);
|
||||
if (displaced)
|
||||
put_files_struct(displaced);
|
||||
return retval;
|
||||
|
||||
out:
|
||||
if (bprm->security)
|
||||
security_bprm_free(bprm);
|
||||
|
||||
out_mm:
|
||||
if (bprm->mm)
|
||||
mmput (bprm->mm);
|
||||
|
||||
|
|
@ -1364,7 +1380,11 @@ out_file:
|
|||
allow_write_access(bprm->file);
|
||||
fput(bprm->file);
|
||||
}
|
||||
out_kfree:
|
||||
|
||||
out_unlock:
|
||||
mutex_unlock(¤t->cred_exec_mutex);
|
||||
|
||||
out_free:
|
||||
free_bprm(bprm);
|
||||
|
||||
out_files:
|
||||
|
|
@ -1396,6 +1416,7 @@ EXPORT_SYMBOL(set_binfmt);
|
|||
*/
|
||||
static int format_corename(char *corename, long signr)
|
||||
{
|
||||
const struct cred *cred = current_cred();
|
||||
const char *pat_ptr = core_pattern;
|
||||
int ispipe = (*pat_ptr == '|');
|
||||
char *out_ptr = corename;
|
||||
|
|
@ -1432,7 +1453,7 @@ static int format_corename(char *corename, long signr)
|
|||
/* uid */
|
||||
case 'u':
|
||||
rc = snprintf(out_ptr, out_end - out_ptr,
|
||||
"%d", current->uid);
|
||||
"%d", cred->uid);
|
||||
if (rc > out_end - out_ptr)
|
||||
goto out;
|
||||
out_ptr += rc;
|
||||
|
|
@ -1440,7 +1461,7 @@ static int format_corename(char *corename, long signr)
|
|||
/* gid */
|
||||
case 'g':
|
||||
rc = snprintf(out_ptr, out_end - out_ptr,
|
||||
"%d", current->gid);
|
||||
"%d", cred->gid);
|
||||
if (rc > out_end - out_ptr)
|
||||
goto out;
|
||||
out_ptr += rc;
|
||||
|
|
@ -1716,8 +1737,9 @@ int do_coredump(long signr, int exit_code, struct pt_regs * regs)
|
|||
struct linux_binfmt * binfmt;
|
||||
struct inode * inode;
|
||||
struct file * file;
|
||||
const struct cred *old_cred;
|
||||
struct cred *cred;
|
||||
int retval = 0;
|
||||
int fsuid = current->fsuid;
|
||||
int flag = 0;
|
||||
int ispipe = 0;
|
||||
unsigned long core_limit = current->signal->rlim[RLIMIT_CORE].rlim_cur;
|
||||
|
|
@ -1730,12 +1752,20 @@ int do_coredump(long signr, int exit_code, struct pt_regs * regs)
|
|||
binfmt = current->binfmt;
|
||||
if (!binfmt || !binfmt->core_dump)
|
||||
goto fail;
|
||||
|
||||
cred = prepare_creds();
|
||||
if (!cred) {
|
||||
retval = -ENOMEM;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
down_write(&mm->mmap_sem);
|
||||
/*
|
||||
* If another thread got here first, or we are not dumpable, bail out.
|
||||
*/
|
||||
if (mm->core_state || !get_dumpable(mm)) {
|
||||
up_write(&mm->mmap_sem);
|
||||
put_cred(cred);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
|
|
@ -1746,12 +1776,16 @@ int do_coredump(long signr, int exit_code, struct pt_regs * regs)
|
|||
*/
|
||||
if (get_dumpable(mm) == 2) { /* Setuid core dump mode */
|
||||
flag = O_EXCL; /* Stop rewrite attacks */
|
||||
current->fsuid = 0; /* Dump root private */
|
||||
cred->fsuid = 0; /* Dump root private */
|
||||
}
|
||||
|
||||
retval = coredump_wait(exit_code, &core_state);
|
||||
if (retval < 0)
|
||||
if (retval < 0) {
|
||||
put_cred(cred);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
old_cred = override_creds(cred);
|
||||
|
||||
/*
|
||||
* Clear any false indication of pending signals that might
|
||||
|
|
@ -1823,7 +1857,7 @@ int do_coredump(long signr, int exit_code, struct pt_regs * regs)
|
|||
* Dont allow local users get cute and trick others to coredump
|
||||
* into their pre-created files:
|
||||
*/
|
||||
if (inode->i_uid != current->fsuid)
|
||||
if (inode->i_uid != current_fsuid())
|
||||
goto close_fail;
|
||||
if (!file->f_op)
|
||||
goto close_fail;
|
||||
|
|
@ -1842,7 +1876,8 @@ fail_unlock:
|
|||
if (helper_argv)
|
||||
argv_free(helper_argv);
|
||||
|
||||
current->fsuid = fsuid;
|
||||
revert_creds(old_cred);
|
||||
put_cred(cred);
|
||||
coredump_finish(mm);
|
||||
fail:
|
||||
return retval;
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@
|
|||
#include <linux/module.h>
|
||||
#include <linux/mount.h>
|
||||
#include <linux/namei.h>
|
||||
#include <linux/sched.h>
|
||||
|
||||
#define dprintk(fmt, args...) do{}while(0)
|
||||
|
||||
|
|
@ -249,6 +250,7 @@ static int filldir_one(void * __buf, const char * name, int len,
|
|||
static int get_name(struct vfsmount *mnt, struct dentry *dentry,
|
||||
char *name, struct dentry *child)
|
||||
{
|
||||
const struct cred *cred = current_cred();
|
||||
struct inode *dir = dentry->d_inode;
|
||||
int error;
|
||||
struct file *file;
|
||||
|
|
@ -263,7 +265,7 @@ static int get_name(struct vfsmount *mnt, struct dentry *dentry,
|
|||
/*
|
||||
* Open the directory ...
|
||||
*/
|
||||
file = dentry_open(dget(dentry), mntget(mnt), O_RDONLY);
|
||||
file = dentry_open(dget(dentry), mntget(mnt), O_RDONLY, cred);
|
||||
error = PTR_ERR(file);
|
||||
if (IS_ERR(file))
|
||||
goto out;
|
||||
|
|
|
|||
|
|
@ -1193,7 +1193,7 @@ static int ext2_has_free_blocks(struct ext2_sb_info *sbi)
|
|||
free_blocks = percpu_counter_read_positive(&sbi->s_freeblocks_counter);
|
||||
root_blocks = le32_to_cpu(sbi->s_es->s_r_blocks_count);
|
||||
if (free_blocks < root_blocks + 1 && !capable(CAP_SYS_RESOURCE) &&
|
||||
sbi->s_resuid != current->fsuid &&
|
||||
sbi->s_resuid != current_fsuid() &&
|
||||
(sbi->s_resgid == 0 || !in_group_p (sbi->s_resgid))) {
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -550,7 +550,7 @@ got:
|
|||
|
||||
sb->s_dirt = 1;
|
||||
mark_buffer_dirty(bh2);
|
||||
inode->i_uid = current->fsuid;
|
||||
inode->i_uid = current_fsuid();
|
||||
if (test_opt (sb, GRPID))
|
||||
inode->i_gid = dir->i_gid;
|
||||
else if (dir->i_mode & S_ISGID) {
|
||||
|
|
@ -558,7 +558,7 @@ got:
|
|||
if (S_ISDIR(mode))
|
||||
mode |= S_ISGID;
|
||||
} else
|
||||
inode->i_gid = current->fsgid;
|
||||
inode->i_gid = current_fsgid();
|
||||
inode->i_mode = mode;
|
||||
|
||||
inode->i_ino = ino;
|
||||
|
|
|
|||
|
|
@ -1422,7 +1422,7 @@ static int ext3_has_free_blocks(struct ext3_sb_info *sbi)
|
|||
free_blocks = percpu_counter_read_positive(&sbi->s_freeblocks_counter);
|
||||
root_blocks = le32_to_cpu(sbi->s_es->s_r_blocks_count);
|
||||
if (free_blocks < root_blocks + 1 && !capable(CAP_SYS_RESOURCE) &&
|
||||
sbi->s_resuid != current->fsuid &&
|
||||
sbi->s_resuid != current_fsuid() &&
|
||||
(sbi->s_resgid == 0 || !in_group_p (sbi->s_resgid))) {
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -539,7 +539,7 @@ got:
|
|||
percpu_counter_inc(&sbi->s_dirs_counter);
|
||||
sb->s_dirt = 1;
|
||||
|
||||
inode->i_uid = current->fsuid;
|
||||
inode->i_uid = current_fsuid();
|
||||
if (test_opt (sb, GRPID))
|
||||
inode->i_gid = dir->i_gid;
|
||||
else if (dir->i_mode & S_ISGID) {
|
||||
|
|
@ -547,7 +547,7 @@ got:
|
|||
if (S_ISDIR(mode))
|
||||
mode |= S_ISGID;
|
||||
} else
|
||||
inode->i_gid = current->fsgid;
|
||||
inode->i_gid = current_fsgid();
|
||||
inode->i_mode = mode;
|
||||
|
||||
inode->i_ino = ino;
|
||||
|
|
|
|||
|
|
@ -624,7 +624,7 @@ int ext4_has_free_blocks(struct ext4_sb_info *sbi, s64 nblocks)
|
|||
return 1;
|
||||
|
||||
/* Hm, nope. Are (enough) root reserved blocks available? */
|
||||
if (sbi->s_resuid == current->fsuid ||
|
||||
if (sbi->s_resuid == current_fsuid() ||
|
||||
((sbi->s_resgid != 0) && in_group_p(sbi->s_resgid)) ||
|
||||
capable(CAP_SYS_RESOURCE)) {
|
||||
if (free_blocks >= (nblocks + dirty_blocks))
|
||||
|
|
|
|||
|
|
@ -787,7 +787,7 @@ got:
|
|||
spin_unlock(sb_bgl_lock(sbi, flex_group));
|
||||
}
|
||||
|
||||
inode->i_uid = current->fsuid;
|
||||
inode->i_uid = current_fsuid();
|
||||
if (test_opt(sb, GRPID))
|
||||
inode->i_gid = dir->i_gid;
|
||||
else if (dir->i_mode & S_ISGID) {
|
||||
|
|
@ -795,7 +795,7 @@ got:
|
|||
if (S_ISDIR(mode))
|
||||
mode |= S_ISGID;
|
||||
} else
|
||||
inode->i_gid = current->fsgid;
|
||||
inode->i_gid = current_fsgid();
|
||||
inode->i_mode = mode;
|
||||
|
||||
inode->i_ino = ino + group * EXT4_INODES_PER_GROUP(sb);
|
||||
|
|
|
|||
|
|
@ -304,7 +304,7 @@ static int fat_allow_set_time(struct msdos_sb_info *sbi, struct inode *inode)
|
|||
{
|
||||
mode_t allow_utime = sbi->options.allow_utime;
|
||||
|
||||
if (current->fsuid != inode->i_uid) {
|
||||
if (current_fsuid() != inode->i_uid) {
|
||||
if (in_group_p(inode->i_gid))
|
||||
allow_utime >>= 3;
|
||||
if (allow_utime & MAY_WRITE)
|
||||
|
|
|
|||
|
|
@ -926,8 +926,8 @@ static int parse_options(char *options, int is_vfat, int silent, int *debug,
|
|||
|
||||
opts->isvfat = is_vfat;
|
||||
|
||||
opts->fs_uid = current->uid;
|
||||
opts->fs_gid = current->gid;
|
||||
opts->fs_uid = current_uid();
|
||||
opts->fs_gid = current_gid();
|
||||
opts->fs_fmask = opts->fs_dmask = current->fs->umask;
|
||||
opts->allow_utime = -1;
|
||||
opts->codepage = fat_default_codepage;
|
||||
|
|
|
|||
18
fs/fcntl.c
18
fs/fcntl.c
|
|
@ -212,13 +212,14 @@ static void f_modown(struct file *filp, struct pid *pid, enum pid_type type,
|
|||
int __f_setown(struct file *filp, struct pid *pid, enum pid_type type,
|
||||
int force)
|
||||
{
|
||||
const struct cred *cred = current_cred();
|
||||
int err;
|
||||
|
||||
err = security_file_set_fowner(filp);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
f_modown(filp, pid, type, current->uid, current->euid, force);
|
||||
f_modown(filp, pid, type, cred->uid, cred->euid, force);
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(__f_setown);
|
||||
|
|
@ -407,10 +408,17 @@ static const long band_table[NSIGPOLL] = {
|
|||
static inline int sigio_perm(struct task_struct *p,
|
||||
struct fown_struct *fown, int sig)
|
||||
{
|
||||
return (((fown->euid == 0) ||
|
||||
(fown->euid == p->suid) || (fown->euid == p->uid) ||
|
||||
(fown->uid == p->suid) || (fown->uid == p->uid)) &&
|
||||
!security_file_send_sigiotask(p, fown, sig));
|
||||
const struct cred *cred;
|
||||
int ret;
|
||||
|
||||
rcu_read_lock();
|
||||
cred = __task_cred(p);
|
||||
ret = ((fown->euid == 0 ||
|
||||
fown->euid == cred->suid || fown->euid == cred->uid ||
|
||||
fown->uid == cred->suid || fown->uid == cred->uid) &&
|
||||
!security_file_send_sigiotask(p, fown, sig));
|
||||
rcu_read_unlock();
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void send_sigio_to_task(struct task_struct *p,
|
||||
|
|
|
|||
|
|
@ -36,7 +36,9 @@ static struct percpu_counter nr_files __cacheline_aligned_in_smp;
|
|||
|
||||
static inline void file_free_rcu(struct rcu_head *head)
|
||||
{
|
||||
struct file *f = container_of(head, struct file, f_u.fu_rcuhead);
|
||||
struct file *f = container_of(head, struct file, f_u.fu_rcuhead);
|
||||
|
||||
put_cred(f->f_cred);
|
||||
kmem_cache_free(filp_cachep, f);
|
||||
}
|
||||
|
||||
|
|
@ -94,7 +96,7 @@ int proc_nr_files(ctl_table *table, int write, struct file *filp,
|
|||
*/
|
||||
struct file *get_empty_filp(void)
|
||||
{
|
||||
struct task_struct *tsk;
|
||||
const struct cred *cred = current_cred();
|
||||
static int old_max;
|
||||
struct file * f;
|
||||
|
||||
|
|
@ -118,12 +120,10 @@ struct file *get_empty_filp(void)
|
|||
if (security_file_alloc(f))
|
||||
goto fail_sec;
|
||||
|
||||
tsk = current;
|
||||
INIT_LIST_HEAD(&f->f_u.fu_list);
|
||||
atomic_long_set(&f->f_count, 1);
|
||||
rwlock_init(&f->f_owner.lock);
|
||||
f->f_uid = tsk->fsuid;
|
||||
f->f_gid = tsk->fsgid;
|
||||
f->f_cred = get_cred(cred);
|
||||
eventpoll_init_file(f);
|
||||
/* f->f_version: 0 */
|
||||
return f;
|
||||
|
|
|
|||
|
|
@ -87,8 +87,8 @@ static void __fuse_put_request(struct fuse_req *req)
|
|||
|
||||
static void fuse_req_init_context(struct fuse_req *req)
|
||||
{
|
||||
req->in.h.uid = current->fsuid;
|
||||
req->in.h.gid = current->fsgid;
|
||||
req->in.h.uid = current_fsuid();
|
||||
req->in.h.gid = current_fsgid();
|
||||
req->in.h.pid = current->pid;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -869,18 +869,25 @@ int fuse_update_attributes(struct inode *inode, struct kstat *stat,
|
|||
*/
|
||||
int fuse_allow_task(struct fuse_conn *fc, struct task_struct *task)
|
||||
{
|
||||
const struct cred *cred;
|
||||
int ret;
|
||||
|
||||
if (fc->flags & FUSE_ALLOW_OTHER)
|
||||
return 1;
|
||||
|
||||
if (task->euid == fc->user_id &&
|
||||
task->suid == fc->user_id &&
|
||||
task->uid == fc->user_id &&
|
||||
task->egid == fc->group_id &&
|
||||
task->sgid == fc->group_id &&
|
||||
task->gid == fc->group_id)
|
||||
return 1;
|
||||
rcu_read_lock();
|
||||
ret = 0;
|
||||
cred = __task_cred(task);
|
||||
if (cred->euid == fc->user_id &&
|
||||
cred->suid == fc->user_id &&
|
||||
cred->uid == fc->user_id &&
|
||||
cred->egid == fc->group_id &&
|
||||
cred->sgid == fc->group_id &&
|
||||
cred->gid == fc->group_id)
|
||||
ret = 1;
|
||||
rcu_read_unlock();
|
||||
|
||||
return 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int fuse_access(struct inode *inode, int mask)
|
||||
|
|
|
|||
|
|
@ -705,18 +705,18 @@ static void munge_mode_uid_gid(struct gfs2_inode *dip, unsigned int *mode,
|
|||
(dip->i_inode.i_mode & S_ISUID) && dip->i_inode.i_uid) {
|
||||
if (S_ISDIR(*mode))
|
||||
*mode |= S_ISUID;
|
||||
else if (dip->i_inode.i_uid != current->fsuid)
|
||||
else if (dip->i_inode.i_uid != current_fsuid())
|
||||
*mode &= ~07111;
|
||||
*uid = dip->i_inode.i_uid;
|
||||
} else
|
||||
*uid = current->fsuid;
|
||||
*uid = current_fsuid();
|
||||
|
||||
if (dip->i_inode.i_mode & S_ISGID) {
|
||||
if (S_ISDIR(*mode))
|
||||
*mode |= S_ISGID;
|
||||
*gid = dip->i_inode.i_gid;
|
||||
} else
|
||||
*gid = current->fsgid;
|
||||
*gid = current_fsgid();
|
||||
}
|
||||
|
||||
static int alloc_dinode(struct gfs2_inode *dip, u64 *no_addr, u64 *generation)
|
||||
|
|
@ -1124,8 +1124,8 @@ int gfs2_unlink_ok(struct gfs2_inode *dip, const struct qstr *name,
|
|||
return -EPERM;
|
||||
|
||||
if ((dip->i_inode.i_mode & S_ISVTX) &&
|
||||
dip->i_inode.i_uid != current->fsuid &&
|
||||
ip->i_inode.i_uid != current->fsuid && !capable(CAP_FOWNER))
|
||||
dip->i_inode.i_uid != current_fsuid() &&
|
||||
ip->i_inode.i_uid != current_fsuid() && !capable(CAP_FOWNER))
|
||||
return -EPERM;
|
||||
|
||||
if (IS_APPEND(&dip->i_inode))
|
||||
|
|
|
|||
|
|
@ -155,8 +155,8 @@ struct inode *hfs_new_inode(struct inode *dir, struct qstr *name, int mode)
|
|||
hfs_cat_build_key(sb, (btree_key *)&HFS_I(inode)->cat_key, dir->i_ino, name);
|
||||
inode->i_ino = HFS_SB(sb)->next_id++;
|
||||
inode->i_mode = mode;
|
||||
inode->i_uid = current->fsuid;
|
||||
inode->i_gid = current->fsgid;
|
||||
inode->i_uid = current_fsuid();
|
||||
inode->i_gid = current_fsgid();
|
||||
inode->i_nlink = 1;
|
||||
inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME_SEC;
|
||||
HFS_I(inode)->flags = 0;
|
||||
|
|
|
|||
|
|
@ -210,8 +210,8 @@ static int parse_options(char *options, struct hfs_sb_info *hsb)
|
|||
int tmp, token;
|
||||
|
||||
/* initialize the sb with defaults */
|
||||
hsb->s_uid = current->uid;
|
||||
hsb->s_gid = current->gid;
|
||||
hsb->s_uid = current_uid();
|
||||
hsb->s_gid = current_gid();
|
||||
hsb->s_file_umask = 0133;
|
||||
hsb->s_dir_umask = 0022;
|
||||
hsb->s_type = hsb->s_creator = cpu_to_be32(0x3f3f3f3f); /* == '????' */
|
||||
|
|
|
|||
|
|
@ -296,8 +296,8 @@ struct inode *hfsplus_new_inode(struct super_block *sb, int mode)
|
|||
|
||||
inode->i_ino = HFSPLUS_SB(sb).next_cnid++;
|
||||
inode->i_mode = mode;
|
||||
inode->i_uid = current->fsuid;
|
||||
inode->i_gid = current->fsgid;
|
||||
inode->i_uid = current_fsuid();
|
||||
inode->i_gid = current_fsgid();
|
||||
inode->i_nlink = 1;
|
||||
inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME_SEC;
|
||||
INIT_LIST_HEAD(&HFSPLUS_I(inode).open_dir_list);
|
||||
|
|
|
|||
|
|
@ -49,8 +49,8 @@ void hfsplus_fill_defaults(struct hfsplus_sb_info *opts)
|
|||
opts->creator = HFSPLUS_DEF_CR_TYPE;
|
||||
opts->type = HFSPLUS_DEF_CR_TYPE;
|
||||
opts->umask = current->fs->umask;
|
||||
opts->uid = current->uid;
|
||||
opts->gid = current->gid;
|
||||
opts->uid = current_uid();
|
||||
opts->gid = current_gid();
|
||||
opts->part = -1;
|
||||
opts->session = -1;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -92,11 +92,11 @@ static int hpfs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
|
|||
inc_nlink(dir);
|
||||
insert_inode_hash(result);
|
||||
|
||||
if (result->i_uid != current->fsuid ||
|
||||
result->i_gid != current->fsgid ||
|
||||
if (result->i_uid != current_fsuid() ||
|
||||
result->i_gid != current_fsgid() ||
|
||||
result->i_mode != (mode | S_IFDIR)) {
|
||||
result->i_uid = current->fsuid;
|
||||
result->i_gid = current->fsgid;
|
||||
result->i_uid = current_fsuid();
|
||||
result->i_gid = current_fsgid();
|
||||
result->i_mode = mode | S_IFDIR;
|
||||
hpfs_write_inode_nolock(result);
|
||||
}
|
||||
|
|
@ -184,11 +184,11 @@ static int hpfs_create(struct inode *dir, struct dentry *dentry, int mode, struc
|
|||
|
||||
insert_inode_hash(result);
|
||||
|
||||
if (result->i_uid != current->fsuid ||
|
||||
result->i_gid != current->fsgid ||
|
||||
if (result->i_uid != current_fsuid() ||
|
||||
result->i_gid != current_fsgid() ||
|
||||
result->i_mode != (mode | S_IFREG)) {
|
||||
result->i_uid = current->fsuid;
|
||||
result->i_gid = current->fsgid;
|
||||
result->i_uid = current_fsuid();
|
||||
result->i_gid = current_fsgid();
|
||||
result->i_mode = mode | S_IFREG;
|
||||
hpfs_write_inode_nolock(result);
|
||||
}
|
||||
|
|
@ -247,8 +247,8 @@ static int hpfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t
|
|||
result->i_mtime.tv_nsec = 0;
|
||||
result->i_atime.tv_nsec = 0;
|
||||
hpfs_i(result)->i_ea_size = 0;
|
||||
result->i_uid = current->fsuid;
|
||||
result->i_gid = current->fsgid;
|
||||
result->i_uid = current_fsuid();
|
||||
result->i_gid = current_fsgid();
|
||||
result->i_nlink = 1;
|
||||
result->i_size = 0;
|
||||
result->i_blocks = 1;
|
||||
|
|
@ -325,8 +325,8 @@ static int hpfs_symlink(struct inode *dir, struct dentry *dentry, const char *sy
|
|||
result->i_atime.tv_nsec = 0;
|
||||
hpfs_i(result)->i_ea_size = 0;
|
||||
result->i_mode = S_IFLNK | 0777;
|
||||
result->i_uid = current->fsuid;
|
||||
result->i_gid = current->fsgid;
|
||||
result->i_uid = current_fsuid();
|
||||
result->i_gid = current_fsgid();
|
||||
result->i_blocks = 1;
|
||||
result->i_nlink = 1;
|
||||
result->i_size = strlen(symlink);
|
||||
|
|
|
|||
|
|
@ -475,8 +475,8 @@ static int hpfs_fill_super(struct super_block *s, void *options, int silent)
|
|||
|
||||
init_MUTEX(&sbi->hpfs_creation_de);
|
||||
|
||||
uid = current->uid;
|
||||
gid = current->gid;
|
||||
uid = current_uid();
|
||||
gid = current_gid();
|
||||
umask = current->fs->umask;
|
||||
lowercase = 0;
|
||||
conv = CONV_BINARY;
|
||||
|
|
|
|||
|
|
@ -426,6 +426,7 @@ static int file_mode(int fmode)
|
|||
|
||||
static int hppfs_open(struct inode *inode, struct file *file)
|
||||
{
|
||||
const struct cred *cred = file->f_cred;
|
||||
struct hppfs_private *data;
|
||||
struct vfsmount *proc_mnt;
|
||||
struct dentry *proc_dentry;
|
||||
|
|
@ -446,7 +447,7 @@ static int hppfs_open(struct inode *inode, struct file *file)
|
|||
|
||||
/* XXX This isn't closed anywhere */
|
||||
data->proc_file = dentry_open(dget(proc_dentry), mntget(proc_mnt),
|
||||
file_mode(file->f_mode));
|
||||
file_mode(file->f_mode), cred);
|
||||
err = PTR_ERR(data->proc_file);
|
||||
if (IS_ERR(data->proc_file))
|
||||
goto out_free1;
|
||||
|
|
@ -489,6 +490,7 @@ static int hppfs_open(struct inode *inode, struct file *file)
|
|||
|
||||
static int hppfs_dir_open(struct inode *inode, struct file *file)
|
||||
{
|
||||
const struct cred *cred = file->f_cred;
|
||||
struct hppfs_private *data;
|
||||
struct vfsmount *proc_mnt;
|
||||
struct dentry *proc_dentry;
|
||||
|
|
@ -502,7 +504,7 @@ static int hppfs_dir_open(struct inode *inode, struct file *file)
|
|||
proc_dentry = HPPFS_I(inode)->proc_dentry;
|
||||
proc_mnt = inode->i_sb->s_fs_info;
|
||||
data->proc_file = dentry_open(dget(proc_dentry), mntget(proc_mnt),
|
||||
file_mode(file->f_mode));
|
||||
file_mode(file->f_mode), cred);
|
||||
err = PTR_ERR(data->proc_file);
|
||||
if (IS_ERR(data->proc_file))
|
||||
goto out_free;
|
||||
|
|
|
|||
|
|
@ -551,9 +551,9 @@ static int hugetlbfs_mknod(struct inode *dir,
|
|||
if (S_ISDIR(mode))
|
||||
mode |= S_ISGID;
|
||||
} else {
|
||||
gid = current->fsgid;
|
||||
gid = current_fsgid();
|
||||
}
|
||||
inode = hugetlbfs_get_inode(dir->i_sb, current->fsuid, gid, mode, dev);
|
||||
inode = hugetlbfs_get_inode(dir->i_sb, current_fsuid(), gid, mode, dev);
|
||||
if (inode) {
|
||||
dir->i_ctime = dir->i_mtime = CURRENT_TIME;
|
||||
d_instantiate(dentry, inode);
|
||||
|
|
@ -586,9 +586,9 @@ static int hugetlbfs_symlink(struct inode *dir,
|
|||
if (dir->i_mode & S_ISGID)
|
||||
gid = dir->i_gid;
|
||||
else
|
||||
gid = current->fsgid;
|
||||
gid = current_fsgid();
|
||||
|
||||
inode = hugetlbfs_get_inode(dir->i_sb, current->fsuid,
|
||||
inode = hugetlbfs_get_inode(dir->i_sb, current_fsuid(),
|
||||
gid, S_IFLNK|S_IRWXUGO, 0);
|
||||
if (inode) {
|
||||
int l = strlen(symname)+1;
|
||||
|
|
@ -854,8 +854,8 @@ hugetlbfs_fill_super(struct super_block *sb, void *data, int silent)
|
|||
|
||||
config.nr_blocks = -1; /* No limit on size by default */
|
||||
config.nr_inodes = -1; /* No limit on number of inodes by default */
|
||||
config.uid = current->fsuid;
|
||||
config.gid = current->fsgid;
|
||||
config.uid = current_fsuid();
|
||||
config.gid = current_fsgid();
|
||||
config.mode = 0755;
|
||||
config.hstate = &default_hstate;
|
||||
ret = hugetlbfs_parse_options(data, &config);
|
||||
|
|
@ -951,6 +951,7 @@ struct file *hugetlb_file_setup(const char *name, size_t size)
|
|||
struct inode *inode;
|
||||
struct dentry *dentry, *root;
|
||||
struct qstr quick_string;
|
||||
struct user_struct *user = current_user();
|
||||
|
||||
if (!hugetlbfs_vfsmount)
|
||||
return ERR_PTR(-ENOENT);
|
||||
|
|
@ -958,7 +959,7 @@ struct file *hugetlb_file_setup(const char *name, size_t size)
|
|||
if (!can_do_hugetlb_shm())
|
||||
return ERR_PTR(-EPERM);
|
||||
|
||||
if (!user_shm_lock(size, current->user))
|
||||
if (!user_shm_lock(size, user))
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
root = hugetlbfs_vfsmount->mnt_root;
|
||||
|
|
@ -970,8 +971,8 @@ struct file *hugetlb_file_setup(const char *name, size_t size)
|
|||
goto out_shm_unlock;
|
||||
|
||||
error = -ENOSPC;
|
||||
inode = hugetlbfs_get_inode(root->d_sb, current->fsuid,
|
||||
current->fsgid, S_IFREG | S_IRWXUGO, 0);
|
||||
inode = hugetlbfs_get_inode(root->d_sb, current_fsuid(),
|
||||
current_fsgid(), S_IFREG | S_IRWXUGO, 0);
|
||||
if (!inode)
|
||||
goto out_dentry;
|
||||
|
||||
|
|
@ -998,7 +999,7 @@ out_inode:
|
|||
out_dentry:
|
||||
dput(dentry);
|
||||
out_shm_unlock:
|
||||
user_shm_unlock(size, current->user);
|
||||
user_shm_unlock(size, user);
|
||||
return ERR_PTR(error);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -601,7 +601,7 @@ asmlinkage long sys_inotify_init1(int flags)
|
|||
goto out_put_fd;
|
||||
}
|
||||
|
||||
user = get_uid(current->user);
|
||||
user = get_current_user();
|
||||
if (unlikely(atomic_read(&user->inotify_devs) >=
|
||||
inotify_max_user_instances)) {
|
||||
ret = -EMFILE;
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@
|
|||
*/
|
||||
|
||||
struct super_block;
|
||||
struct linux_binprm;
|
||||
|
||||
/*
|
||||
* block_dev.c
|
||||
|
|
@ -39,6 +40,11 @@ static inline int sb_is_blkdev_sb(struct super_block *sb)
|
|||
*/
|
||||
extern void __init chrdev_init(void);
|
||||
|
||||
/*
|
||||
* exec.c
|
||||
*/
|
||||
extern void check_unsafe_exec(struct linux_binprm *);
|
||||
|
||||
/*
|
||||
* namespace.c
|
||||
*/
|
||||
|
|
|
|||
18
fs/ioprio.c
18
fs/ioprio.c
|
|
@ -31,10 +31,16 @@ static int set_task_ioprio(struct task_struct *task, int ioprio)
|
|||
{
|
||||
int err;
|
||||
struct io_context *ioc;
|
||||
const struct cred *cred = current_cred(), *tcred;
|
||||
|
||||
if (task->uid != current->euid &&
|
||||
task->uid != current->uid && !capable(CAP_SYS_NICE))
|
||||
rcu_read_lock();
|
||||
tcred = __task_cred(task);
|
||||
if (tcred->uid != cred->euid &&
|
||||
tcred->uid != cred->uid && !capable(CAP_SYS_NICE)) {
|
||||
rcu_read_unlock();
|
||||
return -EPERM;
|
||||
}
|
||||
rcu_read_unlock();
|
||||
|
||||
err = security_task_setioprio(task, ioprio);
|
||||
if (err)
|
||||
|
|
@ -123,7 +129,7 @@ asmlinkage long sys_ioprio_set(int which, int who, int ioprio)
|
|||
break;
|
||||
case IOPRIO_WHO_USER:
|
||||
if (!who)
|
||||
user = current->user;
|
||||
user = current_user();
|
||||
else
|
||||
user = find_user(who);
|
||||
|
||||
|
|
@ -131,7 +137,7 @@ asmlinkage long sys_ioprio_set(int which, int who, int ioprio)
|
|||
break;
|
||||
|
||||
do_each_thread(g, p) {
|
||||
if (p->uid != who)
|
||||
if (__task_cred(p)->uid != who)
|
||||
continue;
|
||||
ret = set_task_ioprio(p, ioprio);
|
||||
if (ret)
|
||||
|
|
@ -216,7 +222,7 @@ asmlinkage long sys_ioprio_get(int which, int who)
|
|||
break;
|
||||
case IOPRIO_WHO_USER:
|
||||
if (!who)
|
||||
user = current->user;
|
||||
user = current_user();
|
||||
else
|
||||
user = find_user(who);
|
||||
|
||||
|
|
@ -224,7 +230,7 @@ asmlinkage long sys_ioprio_get(int which, int who)
|
|||
break;
|
||||
|
||||
do_each_thread(g, p) {
|
||||
if (p->uid != user->uid)
|
||||
if (__task_cred(p)->uid != user->uid)
|
||||
continue;
|
||||
tmpio = get_task_ioprio(p);
|
||||
if (tmpio < 0)
|
||||
|
|
|
|||
|
|
@ -93,13 +93,13 @@ struct inode *ialloc(struct inode *parent, umode_t mode)
|
|||
return ERR_PTR(rc);
|
||||
}
|
||||
|
||||
inode->i_uid = current->fsuid;
|
||||
inode->i_uid = current_fsuid();
|
||||
if (parent->i_mode & S_ISGID) {
|
||||
inode->i_gid = parent->i_gid;
|
||||
if (S_ISDIR(mode))
|
||||
mode |= S_ISGID;
|
||||
} else
|
||||
inode->i_gid = current->fsgid;
|
||||
inode->i_gid = current_fsgid();
|
||||
|
||||
/*
|
||||
* New inodes need to save sane values on disk when
|
||||
|
|
|
|||
|
|
@ -115,14 +115,14 @@ static void nlm_display_address(const struct sockaddr *sap,
|
|||
snprintf(buf, len, "unspecified");
|
||||
break;
|
||||
case AF_INET:
|
||||
snprintf(buf, len, NIPQUAD_FMT, NIPQUAD(sin->sin_addr.s_addr));
|
||||
snprintf(buf, len, "%pI4", &sin->sin_addr.s_addr);
|
||||
break;
|
||||
case AF_INET6:
|
||||
if (ipv6_addr_v4mapped(&sin6->sin6_addr))
|
||||
snprintf(buf, len, NIPQUAD_FMT,
|
||||
NIPQUAD(sin6->sin6_addr.s6_addr32[3]));
|
||||
snprintf(buf, len, "%pI4",
|
||||
&sin6->sin6_addr.s6_addr32[3]);
|
||||
else
|
||||
snprintf(buf, len, NIP6_FMT, NIP6(sin6->sin6_addr));
|
||||
snprintf(buf, len, "%pI6", &sin6->sin6_addr);
|
||||
break;
|
||||
default:
|
||||
snprintf(buf, len, "unsupported address family");
|
||||
|
|
|
|||
|
|
@ -179,7 +179,7 @@ static __be32 *xdr_encode_mon_name(__be32 *p, struct nsm_args *argp)
|
|||
|
||||
if (!nsm_use_hostnames) {
|
||||
snprintf(buffer, XDR_ADDRBUF_LEN,
|
||||
NIPQUAD_FMT, NIPQUAD(argp->addr));
|
||||
"%pI4", &argp->addr);
|
||||
name = buffer;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1349,7 +1349,7 @@ int generic_setlease(struct file *filp, long arg, struct file_lock **flp)
|
|||
struct inode *inode = dentry->d_inode;
|
||||
int error, rdlease_count = 0, wrlease_count = 0;
|
||||
|
||||
if ((current->fsuid != inode->i_uid) && !capable(CAP_LEASE))
|
||||
if ((current_fsuid() != inode->i_uid) && !capable(CAP_LEASE))
|
||||
return -EACCES;
|
||||
if (!S_ISREG(inode->i_mode))
|
||||
return -EINVAL;
|
||||
|
|
|
|||
|
|
@ -262,8 +262,8 @@ struct inode * minix_new_inode(const struct inode * dir, int * error)
|
|||
iput(inode);
|
||||
return NULL;
|
||||
}
|
||||
inode->i_uid = current->fsuid;
|
||||
inode->i_gid = (dir->i_mode & S_ISGID) ? dir->i_gid : current->fsgid;
|
||||
inode->i_uid = current_fsuid();
|
||||
inode->i_gid = (dir->i_mode & S_ISGID) ? dir->i_gid : current_fsgid();
|
||||
inode->i_ino = j;
|
||||
inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME_SEC;
|
||||
inode->i_blocks = 0;
|
||||
|
|
|
|||
10
fs/namei.c
10
fs/namei.c
|
|
@ -186,7 +186,7 @@ int generic_permission(struct inode *inode, int mask,
|
|||
|
||||
mask &= MAY_READ | MAY_WRITE | MAY_EXEC;
|
||||
|
||||
if (current->fsuid == inode->i_uid)
|
||||
if (current_fsuid() == inode->i_uid)
|
||||
mode >>= 6;
|
||||
else {
|
||||
if (IS_POSIXACL(inode) && (mode & S_IRWXG) && check_acl) {
|
||||
|
|
@ -441,7 +441,7 @@ static int exec_permission_lite(struct inode *inode)
|
|||
if (inode->i_op && inode->i_op->permission)
|
||||
return -EAGAIN;
|
||||
|
||||
if (current->fsuid == inode->i_uid)
|
||||
if (current_fsuid() == inode->i_uid)
|
||||
mode >>= 6;
|
||||
else if (in_group_p(inode->i_gid))
|
||||
mode >>= 3;
|
||||
|
|
@ -1334,11 +1334,13 @@ static int user_path_parent(int dfd, const char __user *path,
|
|||
*/
|
||||
static inline int check_sticky(struct inode *dir, struct inode *inode)
|
||||
{
|
||||
uid_t fsuid = current_fsuid();
|
||||
|
||||
if (!(dir->i_mode & S_ISVTX))
|
||||
return 0;
|
||||
if (inode->i_uid == current->fsuid)
|
||||
if (inode->i_uid == fsuid)
|
||||
return 0;
|
||||
if (dir->i_uid == current->fsuid)
|
||||
if (dir->i_uid == fsuid)
|
||||
return 0;
|
||||
return !capable(CAP_FOWNER);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1176,7 +1176,7 @@ static int mount_is_safe(struct path *path)
|
|||
if (S_ISLNK(path->dentry->d_inode->i_mode))
|
||||
return -EPERM;
|
||||
if (path->dentry->d_inode->i_mode & S_ISVTX) {
|
||||
if (current->uid != path->dentry->d_inode->i_uid)
|
||||
if (current_uid() != path->dentry->d_inode->i_uid)
|
||||
return -EPERM;
|
||||
}
|
||||
if (inode_permission(path->dentry->d_inode, MAY_WRITE))
|
||||
|
|
|
|||
|
|
@ -40,10 +40,10 @@ ncp_get_fs_info(struct ncp_server * server, struct file *file,
|
|||
struct inode *inode = file->f_path.dentry->d_inode;
|
||||
struct ncp_fs_info info;
|
||||
|
||||
if ((file_permission(file, MAY_WRITE) != 0)
|
||||
&& (current->uid != server->m.mounted_uid)) {
|
||||
if (file_permission(file, MAY_WRITE) != 0
|
||||
&& current_uid() != server->m.mounted_uid)
|
||||
return -EACCES;
|
||||
}
|
||||
|
||||
if (copy_from_user(&info, arg, sizeof(info)))
|
||||
return -EFAULT;
|
||||
|
||||
|
|
@ -70,10 +70,10 @@ ncp_get_fs_info_v2(struct ncp_server * server, struct file *file,
|
|||
struct inode *inode = file->f_path.dentry->d_inode;
|
||||
struct ncp_fs_info_v2 info2;
|
||||
|
||||
if ((file_permission(file, MAY_WRITE) != 0)
|
||||
&& (current->uid != server->m.mounted_uid)) {
|
||||
if (file_permission(file, MAY_WRITE) != 0
|
||||
&& current_uid() != server->m.mounted_uid)
|
||||
return -EACCES;
|
||||
}
|
||||
|
||||
if (copy_from_user(&info2, arg, sizeof(info2)))
|
||||
return -EFAULT;
|
||||
|
||||
|
|
@ -141,10 +141,10 @@ ncp_get_compat_fs_info_v2(struct ncp_server * server, struct file *file,
|
|||
struct inode *inode = file->f_path.dentry->d_inode;
|
||||
struct compat_ncp_fs_info_v2 info2;
|
||||
|
||||
if ((file_permission(file, MAY_WRITE) != 0)
|
||||
&& (current->uid != server->m.mounted_uid)) {
|
||||
if (file_permission(file, MAY_WRITE) != 0
|
||||
&& current_uid() != server->m.mounted_uid)
|
||||
return -EACCES;
|
||||
}
|
||||
|
||||
if (copy_from_user(&info2, arg, sizeof(info2)))
|
||||
return -EFAULT;
|
||||
|
||||
|
|
@ -270,16 +270,17 @@ static int __ncp_ioctl(struct inode *inode, struct file *filp,
|
|||
struct ncp_ioctl_request request;
|
||||
char* bouncebuffer;
|
||||
void __user *argp = (void __user *)arg;
|
||||
uid_t uid = current_uid();
|
||||
|
||||
switch (cmd) {
|
||||
#ifdef CONFIG_COMPAT
|
||||
case NCP_IOC_NCPREQUEST_32:
|
||||
#endif
|
||||
case NCP_IOC_NCPREQUEST:
|
||||
if ((file_permission(filp, MAY_WRITE) != 0)
|
||||
&& (current->uid != server->m.mounted_uid)) {
|
||||
if (file_permission(filp, MAY_WRITE) != 0
|
||||
&& uid != server->m.mounted_uid)
|
||||
return -EACCES;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_COMPAT
|
||||
if (cmd == NCP_IOC_NCPREQUEST_32) {
|
||||
struct compat_ncp_ioctl_request request32;
|
||||
|
|
@ -356,10 +357,10 @@ static int __ncp_ioctl(struct inode *inode, struct file *filp,
|
|||
case NCP_IOC_GETMOUNTUID16:
|
||||
case NCP_IOC_GETMOUNTUID32:
|
||||
case NCP_IOC_GETMOUNTUID64:
|
||||
if ((file_permission(filp, MAY_READ) != 0)
|
||||
&& (current->uid != server->m.mounted_uid)) {
|
||||
if (file_permission(filp, MAY_READ) != 0
|
||||
&& uid != server->m.mounted_uid)
|
||||
return -EACCES;
|
||||
}
|
||||
|
||||
if (cmd == NCP_IOC_GETMOUNTUID16) {
|
||||
u16 uid;
|
||||
SET_UID(uid, server->m.mounted_uid);
|
||||
|
|
@ -380,11 +381,10 @@ static int __ncp_ioctl(struct inode *inode, struct file *filp,
|
|||
{
|
||||
struct ncp_setroot_ioctl sr;
|
||||
|
||||
if ((file_permission(filp, MAY_READ) != 0)
|
||||
&& (current->uid != server->m.mounted_uid))
|
||||
{
|
||||
if (file_permission(filp, MAY_READ) != 0
|
||||
&& uid != server->m.mounted_uid)
|
||||
return -EACCES;
|
||||
}
|
||||
|
||||
if (server->m.mounted_vol[0]) {
|
||||
struct dentry* dentry = inode->i_sb->s_root;
|
||||
|
||||
|
|
@ -408,6 +408,7 @@ static int __ncp_ioctl(struct inode *inode, struct file *filp,
|
|||
return -EFAULT;
|
||||
return 0;
|
||||
}
|
||||
|
||||
case NCP_IOC_SETROOT:
|
||||
{
|
||||
struct ncp_setroot_ioctl sr;
|
||||
|
|
@ -455,11 +456,10 @@ static int __ncp_ioctl(struct inode *inode, struct file *filp,
|
|||
|
||||
#ifdef CONFIG_NCPFS_PACKET_SIGNING
|
||||
case NCP_IOC_SIGN_INIT:
|
||||
if ((file_permission(filp, MAY_WRITE) != 0)
|
||||
&& (current->uid != server->m.mounted_uid))
|
||||
{
|
||||
if (file_permission(filp, MAY_WRITE) != 0
|
||||
&& uid != server->m.mounted_uid)
|
||||
return -EACCES;
|
||||
}
|
||||
|
||||
if (argp) {
|
||||
if (server->sign_wanted)
|
||||
{
|
||||
|
|
@ -478,24 +478,22 @@ static int __ncp_ioctl(struct inode *inode, struct file *filp,
|
|||
return 0;
|
||||
|
||||
case NCP_IOC_SIGN_WANTED:
|
||||
if ((file_permission(filp, MAY_READ) != 0)
|
||||
&& (current->uid != server->m.mounted_uid))
|
||||
{
|
||||
if (file_permission(filp, MAY_READ) != 0
|
||||
&& uid != server->m.mounted_uid)
|
||||
return -EACCES;
|
||||
}
|
||||
|
||||
if (put_user(server->sign_wanted, (int __user *)argp))
|
||||
return -EFAULT;
|
||||
return 0;
|
||||
|
||||
case NCP_IOC_SET_SIGN_WANTED:
|
||||
{
|
||||
int newstate;
|
||||
|
||||
if ((file_permission(filp, MAY_WRITE) != 0)
|
||||
&& (current->uid != server->m.mounted_uid))
|
||||
{
|
||||
if (file_permission(filp, MAY_WRITE) != 0
|
||||
&& uid != server->m.mounted_uid)
|
||||
return -EACCES;
|
||||
}
|
||||
|
||||
/* get only low 8 bits... */
|
||||
if (get_user(newstate, (unsigned char __user *)argp))
|
||||
return -EFAULT;
|
||||
|
|
@ -512,11 +510,10 @@ static int __ncp_ioctl(struct inode *inode, struct file *filp,
|
|||
|
||||
#ifdef CONFIG_NCPFS_IOCTL_LOCKING
|
||||
case NCP_IOC_LOCKUNLOCK:
|
||||
if ((file_permission(filp, MAY_WRITE) != 0)
|
||||
&& (current->uid != server->m.mounted_uid))
|
||||
{
|
||||
if (file_permission(filp, MAY_WRITE) != 0
|
||||
&& uid != server->m.mounted_uid)
|
||||
return -EACCES;
|
||||
}
|
||||
|
||||
{
|
||||
struct ncp_lock_ioctl rqdata;
|
||||
|
||||
|
|
@ -585,9 +582,8 @@ outrel:
|
|||
|
||||
#ifdef CONFIG_COMPAT
|
||||
case NCP_IOC_GETOBJECTNAME_32:
|
||||
if (current->uid != server->m.mounted_uid) {
|
||||
if (uid != server->m.mounted_uid)
|
||||
return -EACCES;
|
||||
}
|
||||
{
|
||||
struct compat_ncp_objectname_ioctl user;
|
||||
size_t outl;
|
||||
|
|
@ -609,10 +605,10 @@ outrel:
|
|||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
case NCP_IOC_GETOBJECTNAME:
|
||||
if (current->uid != server->m.mounted_uid) {
|
||||
if (uid != server->m.mounted_uid)
|
||||
return -EACCES;
|
||||
}
|
||||
{
|
||||
struct ncp_objectname_ioctl user;
|
||||
size_t outl;
|
||||
|
|
@ -633,13 +629,13 @@ outrel:
|
|||
return -EFAULT;
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_COMPAT
|
||||
case NCP_IOC_SETOBJECTNAME_32:
|
||||
#endif
|
||||
case NCP_IOC_SETOBJECTNAME:
|
||||
if (current->uid != server->m.mounted_uid) {
|
||||
if (uid != server->m.mounted_uid)
|
||||
return -EACCES;
|
||||
}
|
||||
{
|
||||
struct ncp_objectname_ioctl user;
|
||||
void* newname;
|
||||
|
|
@ -691,13 +687,13 @@ outrel:
|
|||
kfree(oldname);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_COMPAT
|
||||
case NCP_IOC_GETPRIVATEDATA_32:
|
||||
#endif
|
||||
case NCP_IOC_GETPRIVATEDATA:
|
||||
if (current->uid != server->m.mounted_uid) {
|
||||
if (uid != server->m.mounted_uid)
|
||||
return -EACCES;
|
||||
}
|
||||
{
|
||||
struct ncp_privatedata_ioctl user;
|
||||
size_t outl;
|
||||
|
|
@ -736,13 +732,13 @@ outrel:
|
|||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_COMPAT
|
||||
case NCP_IOC_SETPRIVATEDATA_32:
|
||||
#endif
|
||||
case NCP_IOC_SETPRIVATEDATA:
|
||||
if (current->uid != server->m.mounted_uid) {
|
||||
if (uid != server->m.mounted_uid)
|
||||
return -EACCES;
|
||||
}
|
||||
{
|
||||
struct ncp_privatedata_ioctl user;
|
||||
void* new;
|
||||
|
|
@ -794,9 +790,10 @@ outrel:
|
|||
#endif /* CONFIG_NCPFS_NLS */
|
||||
|
||||
case NCP_IOC_SETDENTRYTTL:
|
||||
if ((file_permission(filp, MAY_WRITE) != 0) &&
|
||||
(current->uid != server->m.mounted_uid))
|
||||
if (file_permission(filp, MAY_WRITE) != 0 &&
|
||||
uid != server->m.mounted_uid)
|
||||
return -EACCES;
|
||||
|
||||
{
|
||||
u_int32_t user;
|
||||
|
||||
|
|
|
|||
|
|
@ -329,7 +329,7 @@ static int __init root_nfs_addr(void)
|
|||
}
|
||||
|
||||
snprintf(nfs_data.hostname, sizeof(nfs_data.hostname),
|
||||
"%u.%u.%u.%u", NIPQUAD(servaddr));
|
||||
"%pI4", &servaddr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -421,8 +421,8 @@ static int __init root_nfs_getport(int program, int version, int proto)
|
|||
{
|
||||
struct sockaddr_in sin;
|
||||
|
||||
printk(KERN_NOTICE "Looking up port of RPC %d/%d on %u.%u.%u.%u\n",
|
||||
program, version, NIPQUAD(servaddr));
|
||||
printk(KERN_NOTICE "Looking up port of RPC %d/%d on %pI4\n",
|
||||
program, version, &servaddr);
|
||||
set_sockaddr(&sin, servaddr, 0);
|
||||
return rpcb_getport_sync(&sin, program, version, proto);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -462,14 +462,12 @@ static void nfs_show_mountd_options(struct seq_file *m, struct nfs_server *nfss,
|
|||
switch (sap->sa_family) {
|
||||
case AF_INET: {
|
||||
struct sockaddr_in *sin = (struct sockaddr_in *)sap;
|
||||
seq_printf(m, ",mountaddr=" NIPQUAD_FMT,
|
||||
NIPQUAD(sin->sin_addr.s_addr));
|
||||
seq_printf(m, ",mountaddr=%pI4", &sin->sin_addr.s_addr);
|
||||
break;
|
||||
}
|
||||
case AF_INET6: {
|
||||
struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)sap;
|
||||
seq_printf(m, ",mountaddr=" NIP6_FMT,
|
||||
NIP6(sin6->sin6_addr));
|
||||
seq_printf(m, ",mountaddr=%pI6", &sin6->sin6_addr);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
|
|
|
|||
|
|
@ -10,6 +10,8 @@
|
|||
#include <linux/sunrpc/svc.h>
|
||||
#include <linux/nfsd/nfsd.h>
|
||||
#include <linux/nfsd/syscall.h>
|
||||
#include <linux/cred.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/linkage.h>
|
||||
#include <linux/namei.h>
|
||||
#include <linux/mount.h>
|
||||
|
|
@ -41,7 +43,8 @@ static struct file *do_open(char *name, int flags)
|
|||
error = may_open(&nd, MAY_WRITE, FMODE_WRITE);
|
||||
|
||||
if (!error)
|
||||
return dentry_open(nd.path.dentry, nd.path.mnt, flags);
|
||||
return dentry_open(nd.path.dentry, nd.path.mnt, flags,
|
||||
current_cred());
|
||||
|
||||
path_put(&nd.path);
|
||||
return ERR_PTR(error);
|
||||
|
|
|
|||
|
|
@ -27,53 +27,70 @@ int nfsexp_flags(struct svc_rqst *rqstp, struct svc_export *exp)
|
|||
|
||||
int nfsd_setuser(struct svc_rqst *rqstp, struct svc_export *exp)
|
||||
{
|
||||
struct svc_cred cred = rqstp->rq_cred;
|
||||
struct group_info *rqgi;
|
||||
struct group_info *gi;
|
||||
struct cred *new;
|
||||
int i;
|
||||
int flags = nfsexp_flags(rqstp, exp);
|
||||
int ret;
|
||||
|
||||
if (flags & NFSEXP_ALLSQUASH) {
|
||||
cred.cr_uid = exp->ex_anon_uid;
|
||||
cred.cr_gid = exp->ex_anon_gid;
|
||||
cred.cr_group_info = groups_alloc(0);
|
||||
} else if (flags & NFSEXP_ROOTSQUASH) {
|
||||
struct group_info *gi;
|
||||
if (!cred.cr_uid)
|
||||
cred.cr_uid = exp->ex_anon_uid;
|
||||
if (!cred.cr_gid)
|
||||
cred.cr_gid = exp->ex_anon_gid;
|
||||
gi = groups_alloc(cred.cr_group_info->ngroups);
|
||||
if (gi)
|
||||
for (i = 0; i < cred.cr_group_info->ngroups; i++) {
|
||||
if (!GROUP_AT(cred.cr_group_info, i))
|
||||
GROUP_AT(gi, i) = exp->ex_anon_gid;
|
||||
else
|
||||
GROUP_AT(gi, i) = GROUP_AT(cred.cr_group_info, i);
|
||||
}
|
||||
cred.cr_group_info = gi;
|
||||
} else
|
||||
get_group_info(cred.cr_group_info);
|
||||
|
||||
if (cred.cr_uid != (uid_t) -1)
|
||||
current->fsuid = cred.cr_uid;
|
||||
else
|
||||
current->fsuid = exp->ex_anon_uid;
|
||||
if (cred.cr_gid != (gid_t) -1)
|
||||
current->fsgid = cred.cr_gid;
|
||||
else
|
||||
current->fsgid = exp->ex_anon_gid;
|
||||
|
||||
if (!cred.cr_group_info)
|
||||
/* discard any old override before preparing the new set */
|
||||
revert_creds(get_cred(current->real_cred));
|
||||
new = prepare_creds();
|
||||
if (!new)
|
||||
return -ENOMEM;
|
||||
ret = set_current_groups(cred.cr_group_info);
|
||||
put_group_info(cred.cr_group_info);
|
||||
if ((cred.cr_uid)) {
|
||||
current->cap_effective =
|
||||
cap_drop_nfsd_set(current->cap_effective);
|
||||
|
||||
new->fsuid = rqstp->rq_cred.cr_uid;
|
||||
new->fsgid = rqstp->rq_cred.cr_gid;
|
||||
|
||||
rqgi = rqstp->rq_cred.cr_group_info;
|
||||
|
||||
if (flags & NFSEXP_ALLSQUASH) {
|
||||
new->fsuid = exp->ex_anon_uid;
|
||||
new->fsgid = exp->ex_anon_gid;
|
||||
gi = groups_alloc(0);
|
||||
} else if (flags & NFSEXP_ROOTSQUASH) {
|
||||
if (!new->fsuid)
|
||||
new->fsuid = exp->ex_anon_uid;
|
||||
if (!new->fsgid)
|
||||
new->fsgid = exp->ex_anon_gid;
|
||||
|
||||
gi = groups_alloc(rqgi->ngroups);
|
||||
if (!gi)
|
||||
goto oom;
|
||||
|
||||
for (i = 0; i < rqgi->ngroups; i++) {
|
||||
if (!GROUP_AT(rqgi, i))
|
||||
GROUP_AT(gi, i) = exp->ex_anon_gid;
|
||||
else
|
||||
GROUP_AT(gi, i) = GROUP_AT(rqgi, i);
|
||||
}
|
||||
} else {
|
||||
current->cap_effective =
|
||||
cap_raise_nfsd_set(current->cap_effective,
|
||||
current->cap_permitted);
|
||||
gi = get_group_info(rqgi);
|
||||
}
|
||||
|
||||
if (new->fsuid == (uid_t) -1)
|
||||
new->fsuid = exp->ex_anon_uid;
|
||||
if (new->fsgid == (gid_t) -1)
|
||||
new->fsgid = exp->ex_anon_gid;
|
||||
|
||||
ret = set_groups(new, gi);
|
||||
put_group_info(gi);
|
||||
if (!ret)
|
||||
goto error;
|
||||
|
||||
if (new->uid)
|
||||
new->cap_effective = cap_drop_nfsd_set(new->cap_effective);
|
||||
else
|
||||
new->cap_effective = cap_raise_nfsd_set(new->cap_effective,
|
||||
new->cap_permitted);
|
||||
put_cred(override_creds(new));
|
||||
return 0;
|
||||
|
||||
oom:
|
||||
ret = -ENOMEM;
|
||||
error:
|
||||
abort_creds(new);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -54,20 +54,26 @@
|
|||
static struct path rec_dir;
|
||||
static int rec_dir_init = 0;
|
||||
|
||||
static void
|
||||
nfs4_save_user(uid_t *saveuid, gid_t *savegid)
|
||||
static int
|
||||
nfs4_save_creds(const struct cred **original_creds)
|
||||
{
|
||||
*saveuid = current->fsuid;
|
||||
*savegid = current->fsgid;
|
||||
current->fsuid = 0;
|
||||
current->fsgid = 0;
|
||||
struct cred *new;
|
||||
|
||||
new = prepare_creds();
|
||||
if (!new)
|
||||
return -ENOMEM;
|
||||
|
||||
new->fsuid = 0;
|
||||
new->fsgid = 0;
|
||||
*original_creds = override_creds(new);
|
||||
put_cred(new);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
nfs4_reset_user(uid_t saveuid, gid_t savegid)
|
||||
nfs4_reset_creds(const struct cred *original)
|
||||
{
|
||||
current->fsuid = saveuid;
|
||||
current->fsgid = savegid;
|
||||
revert_creds(original);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -129,10 +135,9 @@ nfsd4_sync_rec_dir(void)
|
|||
int
|
||||
nfsd4_create_clid_dir(struct nfs4_client *clp)
|
||||
{
|
||||
const struct cred *original_cred;
|
||||
char *dname = clp->cl_recdir;
|
||||
struct dentry *dentry;
|
||||
uid_t uid;
|
||||
gid_t gid;
|
||||
int status;
|
||||
|
||||
dprintk("NFSD: nfsd4_create_clid_dir for \"%s\"\n", dname);
|
||||
|
|
@ -140,7 +145,9 @@ nfsd4_create_clid_dir(struct nfs4_client *clp)
|
|||
if (!rec_dir_init || clp->cl_firststate)
|
||||
return 0;
|
||||
|
||||
nfs4_save_user(&uid, &gid);
|
||||
status = nfs4_save_creds(&original_cred);
|
||||
if (status < 0)
|
||||
return status;
|
||||
|
||||
/* lock the parent */
|
||||
mutex_lock(&rec_dir.dentry->d_inode->i_mutex);
|
||||
|
|
@ -168,7 +175,7 @@ out_unlock:
|
|||
clp->cl_firststate = 1;
|
||||
nfsd4_sync_rec_dir();
|
||||
}
|
||||
nfs4_reset_user(uid, gid);
|
||||
nfs4_reset_creds(original_cred);
|
||||
dprintk("NFSD: nfsd4_create_clid_dir returns %d\n", status);
|
||||
return status;
|
||||
}
|
||||
|
|
@ -211,26 +218,29 @@ nfsd4_build_dentrylist(void *arg, const char *name, int namlen,
|
|||
static int
|
||||
nfsd4_list_rec_dir(struct dentry *dir, recdir_func *f)
|
||||
{
|
||||
const struct cred *original_cred;
|
||||
struct file *filp;
|
||||
struct dentry_list_arg dla = {
|
||||
.parent = dir,
|
||||
};
|
||||
struct list_head *dentries = &dla.dentries;
|
||||
struct dentry_list *child;
|
||||
uid_t uid;
|
||||
gid_t gid;
|
||||
int status;
|
||||
|
||||
if (!rec_dir_init)
|
||||
return 0;
|
||||
|
||||
nfs4_save_user(&uid, &gid);
|
||||
status = nfs4_save_creds(&original_cred);
|
||||
if (status < 0)
|
||||
return status;
|
||||
INIT_LIST_HEAD(dentries);
|
||||
|
||||
filp = dentry_open(dget(dir), mntget(rec_dir.mnt), O_RDONLY);
|
||||
filp = dentry_open(dget(dir), mntget(rec_dir.mnt), O_RDONLY,
|
||||
current_cred());
|
||||
status = PTR_ERR(filp);
|
||||
if (IS_ERR(filp))
|
||||
goto out;
|
||||
INIT_LIST_HEAD(dentries);
|
||||
status = vfs_readdir(filp, nfsd4_build_dentrylist, &dla);
|
||||
fput(filp);
|
||||
while (!list_empty(dentries)) {
|
||||
|
|
@ -249,7 +259,7 @@ out:
|
|||
dput(child->dentry);
|
||||
kfree(child);
|
||||
}
|
||||
nfs4_reset_user(uid, gid);
|
||||
nfs4_reset_creds(original_cred);
|
||||
return status;
|
||||
}
|
||||
|
||||
|
|
@ -311,8 +321,7 @@ out:
|
|||
void
|
||||
nfsd4_remove_clid_dir(struct nfs4_client *clp)
|
||||
{
|
||||
uid_t uid;
|
||||
gid_t gid;
|
||||
const struct cred *original_cred;
|
||||
int status;
|
||||
|
||||
if (!rec_dir_init || !clp->cl_firststate)
|
||||
|
|
@ -322,9 +331,13 @@ nfsd4_remove_clid_dir(struct nfs4_client *clp)
|
|||
if (status)
|
||||
goto out;
|
||||
clp->cl_firststate = 0;
|
||||
nfs4_save_user(&uid, &gid);
|
||||
|
||||
status = nfs4_save_creds(&original_cred);
|
||||
if (status < 0)
|
||||
goto out;
|
||||
|
||||
status = nfsd4_unlink_clid_dir(clp->cl_recdir, HEXDIR_LEN-1);
|
||||
nfs4_reset_user(uid, gid);
|
||||
nfs4_reset_creds(original_cred);
|
||||
if (status == 0)
|
||||
nfsd4_sync_rec_dir();
|
||||
mnt_drop_write(rec_dir.mnt);
|
||||
|
|
@ -401,16 +414,21 @@ nfsd4_recdir_load(void) {
|
|||
void
|
||||
nfsd4_init_recdir(char *rec_dirname)
|
||||
{
|
||||
uid_t uid = 0;
|
||||
gid_t gid = 0;
|
||||
int status;
|
||||
const struct cred *original_cred;
|
||||
int status;
|
||||
|
||||
printk("NFSD: Using %s as the NFSv4 state recovery directory\n",
|
||||
rec_dirname);
|
||||
|
||||
BUG_ON(rec_dir_init);
|
||||
|
||||
nfs4_save_user(&uid, &gid);
|
||||
status = nfs4_save_creds(&original_cred);
|
||||
if (status < 0) {
|
||||
printk("NFSD: Unable to change credentials to find recovery"
|
||||
" directory: error %d\n",
|
||||
status);
|
||||
return;
|
||||
}
|
||||
|
||||
status = kern_path(rec_dirname, LOOKUP_FOLLOW | LOOKUP_DIRECTORY,
|
||||
&rec_dir);
|
||||
|
|
@ -420,7 +438,7 @@ nfsd4_init_recdir(char *rec_dirname)
|
|||
|
||||
if (!status)
|
||||
rec_dir_init = 1;
|
||||
nfs4_reset_user(uid, gid);
|
||||
nfs4_reset_creds(original_cred);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
|||
|
|
@ -719,8 +719,8 @@ nfsd4_setclientid(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
|
|||
status = nfserr_clid_inuse;
|
||||
if (!same_creds(&conf->cl_cred, &rqstp->rq_cred)
|
||||
|| conf->cl_addr != sin->sin_addr.s_addr) {
|
||||
dprintk("NFSD: setclientid: string in use by client"
|
||||
"at %u.%u.%u.%u\n", NIPQUAD(conf->cl_addr));
|
||||
dprintk("NFSD: setclientid: string in use by clientat %pI4\n",
|
||||
&conf->cl_addr);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -330,7 +330,7 @@ static ssize_t failover_unlock_ip(struct file *file, char *buf, size_t size)
|
|||
return -EINVAL;
|
||||
|
||||
/* get ipv4 address */
|
||||
if (sscanf(fo_path, NIPQUAD_FMT "%c", &b1, &b2, &b3, &b4, &c) != 4)
|
||||
if (sscanf(fo_path, "%u.%u.%u.%u%c", &b1, &b2, &b3, &b4, &c) != 4)
|
||||
return -EINVAL;
|
||||
if (b1 > 255 || b2 > 255 || b3 > 255 || b4 > 255)
|
||||
return -EINVAL;
|
||||
|
|
|
|||
|
|
@ -186,9 +186,14 @@ static __be32 nfsd_set_fh_dentry(struct svc_rqst *rqstp, struct svc_fh *fhp)
|
|||
* access control settings being in effect, we cannot
|
||||
* fix that case easily.
|
||||
*/
|
||||
current->cap_effective =
|
||||
cap_raise_nfsd_set(current->cap_effective,
|
||||
current->cap_permitted);
|
||||
struct cred *new = prepare_creds();
|
||||
if (!new)
|
||||
return nfserrno(-ENOMEM);
|
||||
new->cap_effective =
|
||||
cap_raise_nfsd_set(new->cap_effective,
|
||||
new->cap_permitted);
|
||||
put_cred(override_creds(new));
|
||||
put_cred(new);
|
||||
} else {
|
||||
error = nfsd_setuser_and_check_port(rqstp, exp);
|
||||
if (error)
|
||||
|
|
|
|||
|
|
@ -671,6 +671,7 @@ __be32
|
|||
nfsd_open(struct svc_rqst *rqstp, struct svc_fh *fhp, int type,
|
||||
int access, struct file **filp)
|
||||
{
|
||||
const struct cred *cred = current_cred();
|
||||
struct dentry *dentry;
|
||||
struct inode *inode;
|
||||
int flags = O_RDONLY|O_LARGEFILE;
|
||||
|
|
@ -725,7 +726,7 @@ nfsd_open(struct svc_rqst *rqstp, struct svc_fh *fhp, int type,
|
|||
DQUOT_INIT(inode);
|
||||
}
|
||||
*filp = dentry_open(dget(dentry), mntget(fhp->fh_export->ex_path.mnt),
|
||||
flags);
|
||||
flags, cred);
|
||||
if (IS_ERR(*filp))
|
||||
host_err = PTR_ERR(*filp);
|
||||
out_nfserr:
|
||||
|
|
@ -1169,7 +1170,7 @@ nfsd_create_setattr(struct svc_rqst *rqstp, struct svc_fh *resfhp,
|
|||
* send along the gid on create when it tries to implement
|
||||
* setgid directories via NFS:
|
||||
*/
|
||||
if (current->fsuid != 0)
|
||||
if (current_fsuid() != 0)
|
||||
iap->ia_valid &= ~(ATTR_UID|ATTR_GID);
|
||||
if (iap->ia_valid)
|
||||
return nfsd_setattr(rqstp, resfhp, iap, 0, (time_t)0);
|
||||
|
|
@ -2001,7 +2002,7 @@ nfsd_permission(struct svc_rqst *rqstp, struct svc_export *exp,
|
|||
IS_APPEND(inode)? " append" : "",
|
||||
__mnt_is_readonly(exp->ex_path.mnt)? " ro" : "");
|
||||
dprintk(" owner %d/%d user %d/%d\n",
|
||||
inode->i_uid, inode->i_gid, current->fsuid, current->fsgid);
|
||||
inode->i_uid, inode->i_gid, current_fsuid(), current_fsgid());
|
||||
#endif
|
||||
|
||||
/* Normally we reject any write/sattr etc access on a read-only file
|
||||
|
|
@ -2044,7 +2045,7 @@ nfsd_permission(struct svc_rqst *rqstp, struct svc_export *exp,
|
|||
* with NFSv3.
|
||||
*/
|
||||
if ((acc & NFSD_MAY_OWNER_OVERRIDE) &&
|
||||
inode->i_uid == current->fsuid)
|
||||
inode->i_uid == current_fsuid())
|
||||
return 0;
|
||||
|
||||
/* This assumes NFSD_MAY_{READ,WRITE,EXEC} == MAY_{READ,WRITE,EXEC} */
|
||||
|
|
|
|||
|
|
@ -304,8 +304,8 @@ static int sc_seq_show(struct seq_file *seq, void *v)
|
|||
* use of it here generates a warning with -Wbitwise */
|
||||
seq_printf(seq, "%p:\n"
|
||||
" krefs: %d\n"
|
||||
" sock: %u.%u.%u.%u:%u -> "
|
||||
"%u.%u.%u.%u:%u\n"
|
||||
" sock: %pI4:%u -> "
|
||||
"%pI4:%u\n"
|
||||
" remote node: %s\n"
|
||||
" page off: %zu\n"
|
||||
" handshake ok: %u\n"
|
||||
|
|
@ -319,8 +319,8 @@ static int sc_seq_show(struct seq_file *seq, void *v)
|
|||
" func type: %u\n",
|
||||
sc,
|
||||
atomic_read(&sc->sc_kref.refcount),
|
||||
NIPQUAD(saddr), inet ? ntohs(sport) : 0,
|
||||
NIPQUAD(daddr), inet ? ntohs(dport) : 0,
|
||||
&saddr, inet ? ntohs(sport) : 0,
|
||||
&daddr, inet ? ntohs(dport) : 0,
|
||||
sc->sc_node->nd_name,
|
||||
sc->sc_page_off,
|
||||
sc->sc_handshake_ok,
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue