diff options
author | Lachlan McIlroy <lachlan@redback.melbourne.sgi.com> | 2008-12-29 00:47:18 -0500 |
---|---|---|
committer | Lachlan McIlroy <lachlan@redback.melbourne.sgi.com> | 2008-12-29 00:47:18 -0500 |
commit | 0a8c5395f90f06d128247844b2515c8bf3f2826b (patch) | |
tree | d95382dcdfa303b99d480c01763d6cb6767fdaca /fs | |
parent | 25051158bbed127e8672b43396c71c5eb610e5f1 (diff) | |
parent | 3c92ec8ae91ecf59d88c798301833d7cf83f2179 (diff) |
[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 <lachlan@sgi.com>
Diffstat (limited to 'fs')
129 files changed, 1530 insertions, 1159 deletions
diff --git a/fs/9p/fid.c b/fs/9p/fid.c index 2a983d49d19c..14d944204571 100644 --- a/fs/9p/fid.c +++ b/fs/9p/fid.c | |||
@@ -120,7 +120,7 @@ struct p9_fid *v9fs_fid_lookup(struct dentry *dentry) | |||
120 | switch (access) { | 120 | switch (access) { |
121 | case V9FS_ACCESS_SINGLE: | 121 | case V9FS_ACCESS_SINGLE: |
122 | case V9FS_ACCESS_USER: | 122 | case V9FS_ACCESS_USER: |
123 | uid = current->fsuid; | 123 | uid = current_fsuid(); |
124 | any = 0; | 124 | any = 0; |
125 | break; | 125 | break; |
126 | 126 | ||
diff --git a/fs/9p/vfs_inode.c b/fs/9p/vfs_inode.c index 2dfcf5487efe..81f8bbf12f9f 100644 --- a/fs/9p/vfs_inode.c +++ b/fs/9p/vfs_inode.c | |||
@@ -215,8 +215,8 @@ struct inode *v9fs_get_inode(struct super_block *sb, int mode) | |||
215 | inode = new_inode(sb); | 215 | inode = new_inode(sb); |
216 | if (inode) { | 216 | if (inode) { |
217 | inode->i_mode = mode; | 217 | inode->i_mode = mode; |
218 | inode->i_uid = current->fsuid; | 218 | inode->i_uid = current_fsuid(); |
219 | inode->i_gid = current->fsgid; | 219 | inode->i_gid = current_fsgid(); |
220 | inode->i_blocks = 0; | 220 | inode->i_blocks = 0; |
221 | inode->i_rdev = 0; | 221 | inode->i_rdev = 0; |
222 | inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME; | 222 | inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME; |
diff --git a/fs/9p/vfs_super.c b/fs/9p/vfs_super.c index d6cb1a0ca724..93212e40221a 100644 --- a/fs/9p/vfs_super.c +++ b/fs/9p/vfs_super.c | |||
@@ -113,8 +113,8 @@ static int v9fs_get_sb(struct file_system_type *fs_type, int flags, | |||
113 | struct v9fs_session_info *v9ses = NULL; | 113 | struct v9fs_session_info *v9ses = NULL; |
114 | struct p9_wstat *st = NULL; | 114 | struct p9_wstat *st = NULL; |
115 | int mode = S_IRWXUGO | S_ISVTX; | 115 | int mode = S_IRWXUGO | S_ISVTX; |
116 | uid_t uid = current->fsuid; | 116 | uid_t uid = current_fsuid(); |
117 | gid_t gid = current->fsgid; | 117 | gid_t gid = current_fsgid(); |
118 | struct p9_fid *fid; | 118 | struct p9_fid *fid; |
119 | int retval = 0; | 119 | int retval = 0; |
120 | 120 | ||
diff --git a/fs/affs/inode.c b/fs/affs/inode.c index a13b334a3910..415d9c67ac16 100644 --- a/fs/affs/inode.c +++ b/fs/affs/inode.c | |||
@@ -293,8 +293,8 @@ affs_new_inode(struct inode *dir) | |||
293 | mark_buffer_dirty_inode(bh, inode); | 293 | mark_buffer_dirty_inode(bh, inode); |
294 | affs_brelse(bh); | 294 | affs_brelse(bh); |
295 | 295 | ||
296 | inode->i_uid = current->fsuid; | 296 | inode->i_uid = current_fsuid(); |
297 | inode->i_gid = current->fsgid; | 297 | inode->i_gid = current_fsgid(); |
298 | inode->i_ino = block; | 298 | inode->i_ino = block; |
299 | inode->i_nlink = 1; | 299 | inode->i_nlink = 1; |
300 | inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME_SEC; | 300 | inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME_SEC; |
diff --git a/fs/affs/super.c b/fs/affs/super.c index 8989c93193ed..a19d64b582aa 100644 --- a/fs/affs/super.c +++ b/fs/affs/super.c | |||
@@ -163,8 +163,8 @@ parse_options(char *options, uid_t *uid, gid_t *gid, int *mode, int *reserved, s | |||
163 | 163 | ||
164 | /* Fill in defaults */ | 164 | /* Fill in defaults */ |
165 | 165 | ||
166 | *uid = current->uid; | 166 | *uid = current_uid(); |
167 | *gid = current->gid; | 167 | *gid = current_gid(); |
168 | *reserved = 2; | 168 | *reserved = 2; |
169 | *root = -1; | 169 | *root = -1; |
170 | *blocksize = -1; | 170 | *blocksize = -1; |
diff --git a/fs/afs/proc.c b/fs/afs/proc.c index 9f7d1ae70269..7578c1ab9e0b 100644 --- a/fs/afs/proc.c +++ b/fs/afs/proc.c | |||
@@ -646,7 +646,7 @@ static int afs_proc_cell_vlservers_show(struct seq_file *m, void *v) | |||
646 | } | 646 | } |
647 | 647 | ||
648 | /* display one cell per line on subsequent lines */ | 648 | /* display one cell per line on subsequent lines */ |
649 | seq_printf(m, "%u.%u.%u.%u\n", NIPQUAD(addr->s_addr)); | 649 | seq_printf(m, "%pI4\n", &addr->s_addr); |
650 | return 0; | 650 | return 0; |
651 | } | 651 | } |
652 | 652 | ||
@@ -737,7 +737,7 @@ static int afs_proc_cell_servers_show(struct seq_file *m, void *v) | |||
737 | } | 737 | } |
738 | 738 | ||
739 | /* display one cell per line on subsequent lines */ | 739 | /* display one cell per line on subsequent lines */ |
740 | sprintf(ipaddr, "%u.%u.%u.%u", NIPQUAD(server->addr)); | 740 | sprintf(ipaddr, "%pI4", &server->addr); |
741 | seq_printf(m, "%3d %-15.15s %5d\n", | 741 | seq_printf(m, "%3d %-15.15s %5d\n", |
742 | atomic_read(&server->usage), ipaddr, server->fs_state); | 742 | atomic_read(&server->usage), ipaddr, server->fs_state); |
743 | 743 | ||
diff --git a/fs/afs/server.c b/fs/afs/server.c index 28f2451419e1..f49099516675 100644 --- a/fs/afs/server.c +++ b/fs/afs/server.c | |||
@@ -105,7 +105,7 @@ struct afs_server *afs_lookup_server(struct afs_cell *cell, | |||
105 | { | 105 | { |
106 | struct afs_server *server, *candidate; | 106 | struct afs_server *server, *candidate; |
107 | 107 | ||
108 | _enter("%p,"NIPQUAD_FMT, cell, NIPQUAD(addr->s_addr)); | 108 | _enter("%p,%pI4", cell, &addr->s_addr); |
109 | 109 | ||
110 | /* quick scan of the list to see if we already have the server */ | 110 | /* quick scan of the list to see if we already have the server */ |
111 | read_lock(&cell->servers_lock); | 111 | read_lock(&cell->servers_lock); |
@@ -168,9 +168,8 @@ found_server: | |||
168 | server_in_two_cells: | 168 | server_in_two_cells: |
169 | write_unlock(&cell->servers_lock); | 169 | write_unlock(&cell->servers_lock); |
170 | kfree(candidate); | 170 | kfree(candidate); |
171 | printk(KERN_NOTICE "kAFS:" | 171 | printk(KERN_NOTICE "kAFS: Server %pI4 appears to be in two cells\n", |
172 | " Server "NIPQUAD_FMT" appears to be in two cells\n", | 172 | addr); |
173 | NIPQUAD(*addr)); | ||
174 | _leave(" = -EEXIST"); | 173 | _leave(" = -EEXIST"); |
175 | return ERR_PTR(-EEXIST); | 174 | return ERR_PTR(-EEXIST); |
176 | } | 175 | } |
@@ -184,7 +183,7 @@ struct afs_server *afs_find_server(const struct in_addr *_addr) | |||
184 | struct rb_node *p; | 183 | struct rb_node *p; |
185 | struct in_addr addr = *_addr; | 184 | struct in_addr addr = *_addr; |
186 | 185 | ||
187 | _enter(NIPQUAD_FMT, NIPQUAD(addr.s_addr)); | 186 | _enter("%pI4", &addr.s_addr); |
188 | 187 | ||
189 | read_lock(&afs_servers_lock); | 188 | read_lock(&afs_servers_lock); |
190 | 189 | ||
diff --git a/fs/anon_inodes.c b/fs/anon_inodes.c index 3662dd44896b..c16d9be1b017 100644 --- a/fs/anon_inodes.c +++ b/fs/anon_inodes.c | |||
@@ -154,8 +154,8 @@ static struct inode *anon_inode_mkinode(void) | |||
154 | */ | 154 | */ |
155 | inode->i_state = I_DIRTY; | 155 | inode->i_state = I_DIRTY; |
156 | inode->i_mode = S_IRUSR | S_IWUSR; | 156 | inode->i_mode = S_IRUSR | S_IWUSR; |
157 | inode->i_uid = current->fsuid; | 157 | inode->i_uid = current_fsuid(); |
158 | inode->i_gid = current->fsgid; | 158 | inode->i_gid = current_fsgid(); |
159 | inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME; | 159 | inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME; |
160 | return inode; | 160 | return inode; |
161 | } | 161 | } |
@@ -29,13 +29,13 @@ int inode_change_ok(struct inode *inode, struct iattr *attr) | |||
29 | 29 | ||
30 | /* Make sure a caller can chown. */ | 30 | /* Make sure a caller can chown. */ |
31 | if ((ia_valid & ATTR_UID) && | 31 | if ((ia_valid & ATTR_UID) && |
32 | (current->fsuid != inode->i_uid || | 32 | (current_fsuid() != inode->i_uid || |
33 | attr->ia_uid != inode->i_uid) && !capable(CAP_CHOWN)) | 33 | attr->ia_uid != inode->i_uid) && !capable(CAP_CHOWN)) |
34 | goto error; | 34 | goto error; |
35 | 35 | ||
36 | /* Make sure caller can chgrp. */ | 36 | /* Make sure caller can chgrp. */ |
37 | if ((ia_valid & ATTR_GID) && | 37 | if ((ia_valid & ATTR_GID) && |
38 | (current->fsuid != inode->i_uid || | 38 | (current_fsuid() != inode->i_uid || |
39 | (!in_group_p(attr->ia_gid) && attr->ia_gid != inode->i_gid)) && | 39 | (!in_group_p(attr->ia_gid) && attr->ia_gid != inode->i_gid)) && |
40 | !capable(CAP_CHOWN)) | 40 | !capable(CAP_CHOWN)) |
41 | goto error; | 41 | goto error; |
diff --git a/fs/autofs/inode.c b/fs/autofs/inode.c index b70eea1e8c59..c773680d5c60 100644 --- a/fs/autofs/inode.c +++ b/fs/autofs/inode.c | |||
@@ -76,8 +76,8 @@ static int parse_options(char *options, int *pipefd, uid_t *uid, gid_t *gid, | |||
76 | substring_t args[MAX_OPT_ARGS]; | 76 | substring_t args[MAX_OPT_ARGS]; |
77 | int option; | 77 | int option; |
78 | 78 | ||
79 | *uid = current->uid; | 79 | *uid = current_uid(); |
80 | *gid = current->gid; | 80 | *gid = current_gid(); |
81 | *pgrp = task_pgrp_nr(current); | 81 | *pgrp = task_pgrp_nr(current); |
82 | 82 | ||
83 | *minproto = *maxproto = AUTOFS_PROTO_VERSION; | 83 | *minproto = *maxproto = AUTOFS_PROTO_VERSION; |
diff --git a/fs/autofs4/dev-ioctl.c b/fs/autofs4/dev-ioctl.c index 33bf8cbfd051..63b7c7afe8df 100644 --- a/fs/autofs4/dev-ioctl.c +++ b/fs/autofs4/dev-ioctl.c | |||
@@ -308,7 +308,8 @@ static int autofs_dev_ioctl_open_mountpoint(const char *path, dev_t devid) | |||
308 | goto out; | 308 | goto out; |
309 | } | 309 | } |
310 | 310 | ||
311 | filp = dentry_open(nd.path.dentry, nd.path.mnt, O_RDONLY); | 311 | filp = dentry_open(nd.path.dentry, nd.path.mnt, O_RDONLY, |
312 | current_cred()); | ||
312 | if (IS_ERR(filp)) { | 313 | if (IS_ERR(filp)) { |
313 | err = PTR_ERR(filp); | 314 | err = PTR_ERR(filp); |
314 | goto out; | 315 | goto out; |
diff --git a/fs/autofs4/inode.c b/fs/autofs4/inode.c index c7e65bb30ba0..7b19802cfef4 100644 --- a/fs/autofs4/inode.c +++ b/fs/autofs4/inode.c | |||
@@ -235,8 +235,8 @@ static int parse_options(char *options, int *pipefd, uid_t *uid, gid_t *gid, | |||
235 | substring_t args[MAX_OPT_ARGS]; | 235 | substring_t args[MAX_OPT_ARGS]; |
236 | int option; | 236 | int option; |
237 | 237 | ||
238 | *uid = current->uid; | 238 | *uid = current_uid(); |
239 | *gid = current->gid; | 239 | *gid = current_gid(); |
240 | *pgrp = task_pgrp_nr(current); | 240 | *pgrp = task_pgrp_nr(current); |
241 | 241 | ||
242 | *minproto = AUTOFS_MIN_PROTO_VERSION; | 242 | *minproto = AUTOFS_MIN_PROTO_VERSION; |
diff --git a/fs/autofs4/waitq.c b/fs/autofs4/waitq.c index 4b67c2a2d77c..e02cc8ae5eb3 100644 --- a/fs/autofs4/waitq.c +++ b/fs/autofs4/waitq.c | |||
@@ -391,8 +391,8 @@ int autofs4_wait(struct autofs_sb_info *sbi, struct dentry *dentry, | |||
391 | memcpy(&wq->name, &qstr, sizeof(struct qstr)); | 391 | memcpy(&wq->name, &qstr, sizeof(struct qstr)); |
392 | wq->dev = autofs4_get_dev(sbi); | 392 | wq->dev = autofs4_get_dev(sbi); |
393 | wq->ino = autofs4_get_ino(sbi); | 393 | wq->ino = autofs4_get_ino(sbi); |
394 | wq->uid = current->uid; | 394 | wq->uid = current_uid(); |
395 | wq->gid = current->gid; | 395 | wq->gid = current_gid(); |
396 | wq->pid = current->pid; | 396 | wq->pid = current->pid; |
397 | wq->tgid = current->tgid; | 397 | wq->tgid = current->tgid; |
398 | wq->status = -EINTR; /* Status return if interrupted */ | 398 | wq->status = -EINTR; /* Status return if interrupted */ |
diff --git a/fs/bfs/dir.c b/fs/bfs/dir.c index daae463068e4..4dd1b623f937 100644 --- a/fs/bfs/dir.c +++ b/fs/bfs/dir.c | |||
@@ -106,8 +106,8 @@ static int bfs_create(struct inode *dir, struct dentry *dentry, int mode, | |||
106 | } | 106 | } |
107 | set_bit(ino, info->si_imap); | 107 | set_bit(ino, info->si_imap); |
108 | info->si_freei--; | 108 | info->si_freei--; |
109 | inode->i_uid = current->fsuid; | 109 | inode->i_uid = current_fsuid(); |
110 | inode->i_gid = (dir->i_mode & S_ISGID) ? dir->i_gid : current->fsgid; | 110 | inode->i_gid = (dir->i_mode & S_ISGID) ? dir->i_gid : current_fsgid(); |
111 | inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME_SEC; | 111 | inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME_SEC; |
112 | inode->i_blocks = 0; | 112 | inode->i_blocks = 0; |
113 | inode->i_op = &bfs_file_inops; | 113 | inode->i_op = &bfs_file_inops; |
diff --git a/fs/binfmt_aout.c b/fs/binfmt_aout.c index 204cfd1d7676..f1f3f4192a60 100644 --- a/fs/binfmt_aout.c +++ b/fs/binfmt_aout.c | |||
@@ -320,7 +320,7 @@ static int load_aout_binary(struct linux_binprm * bprm, struct pt_regs * regs) | |||
320 | current->mm->free_area_cache = current->mm->mmap_base; | 320 | current->mm->free_area_cache = current->mm->mmap_base; |
321 | current->mm->cached_hole_size = 0; | 321 | current->mm->cached_hole_size = 0; |
322 | 322 | ||
323 | compute_creds(bprm); | 323 | install_exec_creds(bprm); |
324 | current->flags &= ~PF_FORKNOEXEC; | 324 | current->flags &= ~PF_FORKNOEXEC; |
325 | #ifdef __sparc__ | 325 | #ifdef __sparc__ |
326 | if (N_MAGIC(ex) == NMAGIC) { | 326 | if (N_MAGIC(ex) == NMAGIC) { |
diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c index 8fcfa398d350..c41fa2af7677 100644 --- a/fs/binfmt_elf.c +++ b/fs/binfmt_elf.c | |||
@@ -157,7 +157,7 @@ create_elf_tables(struct linux_binprm *bprm, struct elfhdr *exec, | |||
157 | int items; | 157 | int items; |
158 | elf_addr_t *elf_info; | 158 | elf_addr_t *elf_info; |
159 | int ei_index = 0; | 159 | int ei_index = 0; |
160 | struct task_struct *tsk = current; | 160 | const struct cred *cred = current_cred(); |
161 | struct vm_area_struct *vma; | 161 | struct vm_area_struct *vma; |
162 | 162 | ||
163 | /* | 163 | /* |
@@ -223,10 +223,10 @@ create_elf_tables(struct linux_binprm *bprm, struct elfhdr *exec, | |||
223 | NEW_AUX_ENT(AT_BASE, interp_load_addr); | 223 | NEW_AUX_ENT(AT_BASE, interp_load_addr); |
224 | NEW_AUX_ENT(AT_FLAGS, 0); | 224 | NEW_AUX_ENT(AT_FLAGS, 0); |
225 | NEW_AUX_ENT(AT_ENTRY, exec->e_entry); | 225 | NEW_AUX_ENT(AT_ENTRY, exec->e_entry); |
226 | NEW_AUX_ENT(AT_UID, tsk->uid); | 226 | NEW_AUX_ENT(AT_UID, cred->uid); |
227 | NEW_AUX_ENT(AT_EUID, tsk->euid); | 227 | NEW_AUX_ENT(AT_EUID, cred->euid); |
228 | NEW_AUX_ENT(AT_GID, tsk->gid); | 228 | NEW_AUX_ENT(AT_GID, cred->gid); |
229 | NEW_AUX_ENT(AT_EGID, tsk->egid); | 229 | NEW_AUX_ENT(AT_EGID, cred->egid); |
230 | NEW_AUX_ENT(AT_SECURE, security_bprm_secureexec(bprm)); | 230 | NEW_AUX_ENT(AT_SECURE, security_bprm_secureexec(bprm)); |
231 | NEW_AUX_ENT(AT_EXECFN, bprm->exec); | 231 | NEW_AUX_ENT(AT_EXECFN, bprm->exec); |
232 | if (k_platform) { | 232 | if (k_platform) { |
@@ -949,14 +949,14 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs) | |||
949 | set_binfmt(&elf_format); | 949 | set_binfmt(&elf_format); |
950 | 950 | ||
951 | #ifdef ARCH_HAS_SETUP_ADDITIONAL_PAGES | 951 | #ifdef ARCH_HAS_SETUP_ADDITIONAL_PAGES |
952 | retval = arch_setup_additional_pages(bprm, executable_stack); | 952 | retval = arch_setup_additional_pages(bprm, !!elf_interpreter); |
953 | if (retval < 0) { | 953 | if (retval < 0) { |
954 | send_sig(SIGKILL, current, 0); | 954 | send_sig(SIGKILL, current, 0); |
955 | goto out; | 955 | goto out; |
956 | } | 956 | } |
957 | #endif /* ARCH_HAS_SETUP_ADDITIONAL_PAGES */ | 957 | #endif /* ARCH_HAS_SETUP_ADDITIONAL_PAGES */ |
958 | 958 | ||
959 | compute_creds(bprm); | 959 | install_exec_creds(bprm); |
960 | current->flags &= ~PF_FORKNOEXEC; | 960 | current->flags &= ~PF_FORKNOEXEC; |
961 | retval = create_elf_tables(bprm, &loc->elf_ex, | 961 | retval = create_elf_tables(bprm, &loc->elf_ex, |
962 | load_addr, interp_load_addr); | 962 | load_addr, interp_load_addr); |
@@ -1361,6 +1361,7 @@ static void fill_prstatus(struct elf_prstatus *prstatus, | |||
1361 | static int fill_psinfo(struct elf_prpsinfo *psinfo, struct task_struct *p, | 1361 | static int fill_psinfo(struct elf_prpsinfo *psinfo, struct task_struct *p, |
1362 | struct mm_struct *mm) | 1362 | struct mm_struct *mm) |
1363 | { | 1363 | { |
1364 | const struct cred *cred; | ||
1364 | unsigned int i, len; | 1365 | unsigned int i, len; |
1365 | 1366 | ||
1366 | /* first copy the parameters from user space */ | 1367 | /* first copy the parameters from user space */ |
@@ -1388,8 +1389,11 @@ static int fill_psinfo(struct elf_prpsinfo *psinfo, struct task_struct *p, | |||
1388 | psinfo->pr_zomb = psinfo->pr_sname == 'Z'; | 1389 | psinfo->pr_zomb = psinfo->pr_sname == 'Z'; |
1389 | psinfo->pr_nice = task_nice(p); | 1390 | psinfo->pr_nice = task_nice(p); |
1390 | psinfo->pr_flag = p->flags; | 1391 | psinfo->pr_flag = p->flags; |
1391 | SET_UID(psinfo->pr_uid, p->uid); | 1392 | rcu_read_lock(); |
1392 | SET_GID(psinfo->pr_gid, p->gid); | 1393 | cred = __task_cred(p); |
1394 | SET_UID(psinfo->pr_uid, cred->uid); | ||
1395 | SET_GID(psinfo->pr_gid, cred->gid); | ||
1396 | rcu_read_unlock(); | ||
1393 | strncpy(psinfo->pr_fname, p->comm, sizeof(psinfo->pr_fname)); | 1397 | strncpy(psinfo->pr_fname, p->comm, sizeof(psinfo->pr_fname)); |
1394 | 1398 | ||
1395 | return 0; | 1399 | return 0; |
diff --git a/fs/binfmt_elf_fdpic.c b/fs/binfmt_elf_fdpic.c index 5b5424cb3391..aa5b43205e37 100644 --- a/fs/binfmt_elf_fdpic.c +++ b/fs/binfmt_elf_fdpic.c | |||
@@ -404,7 +404,7 @@ static int load_elf_fdpic_binary(struct linux_binprm *bprm, | |||
404 | current->mm->start_stack = current->mm->start_brk + stack_size; | 404 | current->mm->start_stack = current->mm->start_brk + stack_size; |
405 | #endif | 405 | #endif |
406 | 406 | ||
407 | compute_creds(bprm); | 407 | install_exec_creds(bprm); |
408 | current->flags &= ~PF_FORKNOEXEC; | 408 | current->flags &= ~PF_FORKNOEXEC; |
409 | if (create_elf_fdpic_tables(bprm, current->mm, | 409 | if (create_elf_fdpic_tables(bprm, current->mm, |
410 | &exec_params, &interp_params) < 0) | 410 | &exec_params, &interp_params) < 0) |
@@ -475,6 +475,7 @@ static int create_elf_fdpic_tables(struct linux_binprm *bprm, | |||
475 | struct elf_fdpic_params *exec_params, | 475 | struct elf_fdpic_params *exec_params, |
476 | struct elf_fdpic_params *interp_params) | 476 | struct elf_fdpic_params *interp_params) |
477 | { | 477 | { |
478 | const struct cred *cred = current_cred(); | ||
478 | unsigned long sp, csp, nitems; | 479 | unsigned long sp, csp, nitems; |
479 | elf_caddr_t __user *argv, *envp; | 480 | elf_caddr_t __user *argv, *envp; |
480 | size_t platform_len = 0, len; | 481 | size_t platform_len = 0, len; |
@@ -623,10 +624,10 @@ static int create_elf_fdpic_tables(struct linux_binprm *bprm, | |||
623 | NEW_AUX_ENT(AT_BASE, interp_params->elfhdr_addr); | 624 | NEW_AUX_ENT(AT_BASE, interp_params->elfhdr_addr); |
624 | NEW_AUX_ENT(AT_FLAGS, 0); | 625 | NEW_AUX_ENT(AT_FLAGS, 0); |
625 | NEW_AUX_ENT(AT_ENTRY, exec_params->entry_addr); | 626 | NEW_AUX_ENT(AT_ENTRY, exec_params->entry_addr); |
626 | NEW_AUX_ENT(AT_UID, (elf_addr_t) current->uid); | 627 | NEW_AUX_ENT(AT_UID, (elf_addr_t) cred->uid); |
627 | NEW_AUX_ENT(AT_EUID, (elf_addr_t) current->euid); | 628 | NEW_AUX_ENT(AT_EUID, (elf_addr_t) cred->euid); |
628 | NEW_AUX_ENT(AT_GID, (elf_addr_t) current->gid); | 629 | NEW_AUX_ENT(AT_GID, (elf_addr_t) cred->gid); |
629 | NEW_AUX_ENT(AT_EGID, (elf_addr_t) current->egid); | 630 | NEW_AUX_ENT(AT_EGID, (elf_addr_t) cred->egid); |
630 | NEW_AUX_ENT(AT_SECURE, security_bprm_secureexec(bprm)); | 631 | NEW_AUX_ENT(AT_SECURE, security_bprm_secureexec(bprm)); |
631 | NEW_AUX_ENT(AT_EXECFN, bprm->exec); | 632 | NEW_AUX_ENT(AT_EXECFN, bprm->exec); |
632 | 633 | ||
@@ -1413,6 +1414,7 @@ static void fill_prstatus(struct elf_prstatus *prstatus, | |||
1413 | static int fill_psinfo(struct elf_prpsinfo *psinfo, struct task_struct *p, | 1414 | static int fill_psinfo(struct elf_prpsinfo *psinfo, struct task_struct *p, |
1414 | struct mm_struct *mm) | 1415 | struct mm_struct *mm) |
1415 | { | 1416 | { |
1417 | const struct cred *cred; | ||
1416 | unsigned int i, len; | 1418 | unsigned int i, len; |
1417 | 1419 | ||
1418 | /* first copy the parameters from user space */ | 1420 | /* first copy the parameters from user space */ |
@@ -1440,8 +1442,11 @@ static int fill_psinfo(struct elf_prpsinfo *psinfo, struct task_struct *p, | |||
1440 | psinfo->pr_zomb = psinfo->pr_sname == 'Z'; | 1442 | psinfo->pr_zomb = psinfo->pr_sname == 'Z'; |
1441 | psinfo->pr_nice = task_nice(p); | 1443 | psinfo->pr_nice = task_nice(p); |
1442 | psinfo->pr_flag = p->flags; | 1444 | psinfo->pr_flag = p->flags; |
1443 | SET_UID(psinfo->pr_uid, p->uid); | 1445 | rcu_read_lock(); |
1444 | SET_GID(psinfo->pr_gid, p->gid); | 1446 | cred = __task_cred(p); |
1447 | SET_UID(psinfo->pr_uid, cred->uid); | ||
1448 | SET_GID(psinfo->pr_gid, cred->gid); | ||
1449 | rcu_read_unlock(); | ||
1445 | strncpy(psinfo->pr_fname, p->comm, sizeof(psinfo->pr_fname)); | 1450 | strncpy(psinfo->pr_fname, p->comm, sizeof(psinfo->pr_fname)); |
1446 | 1451 | ||
1447 | return 0; | 1452 | return 0; |
diff --git a/fs/binfmt_flat.c b/fs/binfmt_flat.c index ccb781a6a804..7bbd5c6b3725 100644 --- a/fs/binfmt_flat.c +++ b/fs/binfmt_flat.c | |||
@@ -880,7 +880,7 @@ static int load_flat_binary(struct linux_binprm * bprm, struct pt_regs * regs) | |||
880 | (libinfo.lib_list[j].loaded)? | 880 | (libinfo.lib_list[j].loaded)? |
881 | libinfo.lib_list[j].start_data:UNLOADED_LIB; | 881 | libinfo.lib_list[j].start_data:UNLOADED_LIB; |
882 | 882 | ||
883 | compute_creds(bprm); | 883 | install_exec_creds(bprm); |
884 | current->flags &= ~PF_FORKNOEXEC; | 884 | current->flags &= ~PF_FORKNOEXEC; |
885 | 885 | ||
886 | set_binfmt(&flat_format); | 886 | set_binfmt(&flat_format); |
diff --git a/fs/binfmt_som.c b/fs/binfmt_som.c index 74e587a52796..08644a61616e 100644 --- a/fs/binfmt_som.c +++ b/fs/binfmt_som.c | |||
@@ -255,7 +255,7 @@ load_som_binary(struct linux_binprm * bprm, struct pt_regs * regs) | |||
255 | kfree(hpuxhdr); | 255 | kfree(hpuxhdr); |
256 | 256 | ||
257 | set_binfmt(&som_format); | 257 | set_binfmt(&som_format); |
258 | compute_creds(bprm); | 258 | install_exec_creds(bprm); |
259 | setup_arg_pages(bprm, STACK_TOP, EXSTACK_DEFAULT); | 259 | setup_arg_pages(bprm, STACK_TOP, EXSTACK_DEFAULT); |
260 | 260 | ||
261 | create_som_tables(bprm); | 261 | create_som_tables(bprm); |
@@ -26,8 +26,11 @@ | |||
26 | #include <linux/mempool.h> | 26 | #include <linux/mempool.h> |
27 | #include <linux/workqueue.h> | 27 | #include <linux/workqueue.h> |
28 | #include <linux/blktrace_api.h> | 28 | #include <linux/blktrace_api.h> |
29 | #include <trace/block.h> | ||
29 | #include <scsi/sg.h> /* for struct sg_iovec */ | 30 | #include <scsi/sg.h> /* for struct sg_iovec */ |
30 | 31 | ||
32 | DEFINE_TRACE(block_split); | ||
33 | |||
31 | static struct kmem_cache *bio_slab __read_mostly; | 34 | static struct kmem_cache *bio_slab __read_mostly; |
32 | 35 | ||
33 | static mempool_t *bio_split_pool __read_mostly; | 36 | static mempool_t *bio_split_pool __read_mostly; |
@@ -1263,7 +1266,7 @@ struct bio_pair *bio_split(struct bio *bi, int first_sectors) | |||
1263 | if (!bp) | 1266 | if (!bp) |
1264 | return bp; | 1267 | return bp; |
1265 | 1268 | ||
1266 | blk_add_trace_pdu_int(bdev_get_queue(bi->bi_bdev), BLK_TA_SPLIT, bi, | 1269 | trace_block_split(bdev_get_queue(bi->bi_bdev), bi, |
1267 | bi->bi_sector + first_sectors); | 1270 | bi->bi_sector + first_sectors); |
1268 | 1271 | ||
1269 | BUG_ON(bi->bi_vcnt != 1); | 1272 | BUG_ON(bi->bi_vcnt != 1); |
diff --git a/fs/cifs/AUTHORS b/fs/cifs/AUTHORS index 9c136d7803d9..7f7fa3c302af 100644 --- a/fs/cifs/AUTHORS +++ b/fs/cifs/AUTHORS | |||
@@ -36,7 +36,9 @@ Miklos Szeredi | |||
36 | Kazeon team for various fixes especially for 2.4 version. | 36 | Kazeon team for various fixes especially for 2.4 version. |
37 | Asser Ferno (Change Notify support) | 37 | Asser Ferno (Change Notify support) |
38 | Shaggy (Dave Kleikamp) for inumerable small fs suggestions and some good cleanup | 38 | Shaggy (Dave Kleikamp) for inumerable small fs suggestions and some good cleanup |
39 | Gunter Kukkukk (testing and suggestions for support of old servers) | ||
39 | Igor Mammedov (DFS support) | 40 | Igor Mammedov (DFS support) |
41 | Jeff Layton (many, many fixes, as well as great work on the cifs Kerberos code) | ||
40 | 42 | ||
41 | Test case and Bug Report contributors | 43 | Test case and Bug Report contributors |
42 | ------------------------------------- | 44 | ------------------------------------- |
diff --git a/fs/cifs/CHANGES b/fs/cifs/CHANGES index e078b7aea143..080703a15f44 100644 --- a/fs/cifs/CHANGES +++ b/fs/cifs/CHANGES | |||
@@ -1,3 +1,12 @@ | |||
1 | Version 1.56 | ||
2 | ------------ | ||
3 | Add "forcemandatorylock" mount option to allow user to use mandatory | ||
4 | rather than posix (advisory) byte range locks, even though server would | ||
5 | support posix byte range locks. Fix query of root inode when prefixpath | ||
6 | specified and user does not have access to query information about the | ||
7 | top of the share. Fix problem in 2.6.28 resolving DFS paths to | ||
8 | Samba servers (worked to Windows). | ||
9 | |||
1 | Version 1.55 | 10 | Version 1.55 |
2 | ------------ | 11 | ------------ |
3 | Various fixes to make delete of open files behavior more predictable | 12 | Various fixes to make delete of open files behavior more predictable |
diff --git a/fs/cifs/README b/fs/cifs/README index a439dc1739b3..da4515e3be20 100644 --- a/fs/cifs/README +++ b/fs/cifs/README | |||
@@ -463,9 +463,19 @@ A partial list of the supported mount options follows: | |||
463 | with cifs style mandatory byte range locks (and most | 463 | with cifs style mandatory byte range locks (and most |
464 | cifs servers do not yet support requesting advisory | 464 | cifs servers do not yet support requesting advisory |
465 | byte range locks). | 465 | byte range locks). |
466 | forcemandatorylock Even if the server supports posix (advisory) byte range | ||
467 | locking, send only mandatory lock requests. For some | ||
468 | (presumably rare) applications, originally coded for | ||
469 | DOS/Windows, which require Windows style mandatory byte range | ||
470 | locking, they may be able to take advantage of this option, | ||
471 | forcing the cifs client to only send mandatory locks | ||
472 | even if the cifs server would support posix advisory locks. | ||
473 | "forcemand" is accepted as a shorter form of this mount | ||
474 | option. | ||
466 | nodfs Disable DFS (global name space support) even if the | 475 | nodfs Disable DFS (global name space support) even if the |
467 | server claims to support it. This can help work around | 476 | server claims to support it. This can help work around |
468 | a problem with parsing of DFS paths with Samba 3.0.24 server. | 477 | a problem with parsing of DFS paths with Samba server |
478 | versions 3.0.24 and 3.0.25. | ||
469 | remount remount the share (often used to change from ro to rw mounts | 479 | remount remount the share (often used to change from ro to rw mounts |
470 | or vice versa) | 480 | or vice versa) |
471 | cifsacl Report mode bits (e.g. on stat) based on the Windows ACL for | 481 | cifsacl Report mode bits (e.g. on stat) based on the Windows ACL for |
diff --git a/fs/cifs/cifs_dfs_ref.c b/fs/cifs/cifs_dfs_ref.c index e1c18362ba46..85c0a74d034d 100644 --- a/fs/cifs/cifs_dfs_ref.c +++ b/fs/cifs/cifs_dfs_ref.c | |||
@@ -122,7 +122,7 @@ static char *compose_mount_options(const char *sb_mountdata, | |||
122 | char **devname) | 122 | char **devname) |
123 | { | 123 | { |
124 | int rc; | 124 | int rc; |
125 | char *mountdata; | 125 | char *mountdata = NULL; |
126 | int md_len; | 126 | int md_len; |
127 | char *tkn_e; | 127 | char *tkn_e; |
128 | char *srvIP = NULL; | 128 | char *srvIP = NULL; |
@@ -136,10 +136,9 @@ static char *compose_mount_options(const char *sb_mountdata, | |||
136 | *devname = cifs_get_share_name(ref->node_name); | 136 | *devname = cifs_get_share_name(ref->node_name); |
137 | rc = dns_resolve_server_name_to_ip(*devname, &srvIP); | 137 | rc = dns_resolve_server_name_to_ip(*devname, &srvIP); |
138 | if (rc != 0) { | 138 | if (rc != 0) { |
139 | cERROR(1, ("%s: Failed to resolve server part of %s to IP", | 139 | cERROR(1, ("%s: Failed to resolve server part of %s to IP: %d", |
140 | __func__, *devname)); | 140 | __func__, *devname, rc));; |
141 | mountdata = ERR_PTR(rc); | 141 | goto compose_mount_options_err; |
142 | goto compose_mount_options_out; | ||
143 | } | 142 | } |
144 | /* md_len = strlen(...) + 12 for 'sep+prefixpath=' | 143 | /* md_len = strlen(...) + 12 for 'sep+prefixpath=' |
145 | * assuming that we have 'unc=' and 'ip=' in | 144 | * assuming that we have 'unc=' and 'ip=' in |
@@ -149,8 +148,8 @@ static char *compose_mount_options(const char *sb_mountdata, | |||
149 | strlen(ref->node_name) + 12; | 148 | strlen(ref->node_name) + 12; |
150 | mountdata = kzalloc(md_len+1, GFP_KERNEL); | 149 | mountdata = kzalloc(md_len+1, GFP_KERNEL); |
151 | if (mountdata == NULL) { | 150 | if (mountdata == NULL) { |
152 | mountdata = ERR_PTR(-ENOMEM); | 151 | rc = -ENOMEM; |
153 | goto compose_mount_options_out; | 152 | goto compose_mount_options_err; |
154 | } | 153 | } |
155 | 154 | ||
156 | /* copy all options except of unc,ip,prefixpath */ | 155 | /* copy all options except of unc,ip,prefixpath */ |
@@ -197,18 +196,32 @@ static char *compose_mount_options(const char *sb_mountdata, | |||
197 | 196 | ||
198 | /* find & copy prefixpath */ | 197 | /* find & copy prefixpath */ |
199 | tkn_e = strchr(ref->node_name + 2, '\\'); | 198 | tkn_e = strchr(ref->node_name + 2, '\\'); |
200 | if (tkn_e == NULL) /* invalid unc, missing share name*/ | 199 | if (tkn_e == NULL) { |
201 | goto compose_mount_options_out; | 200 | /* invalid unc, missing share name*/ |
201 | rc = -EINVAL; | ||
202 | goto compose_mount_options_err; | ||
203 | } | ||
202 | 204 | ||
205 | /* | ||
206 | * this function gives us a path with a double backslash prefix. We | ||
207 | * require a single backslash for DFS. Temporarily increment fullpath | ||
208 | * to put it in the proper form and decrement before freeing it. | ||
209 | */ | ||
203 | fullpath = build_path_from_dentry(dentry); | 210 | fullpath = build_path_from_dentry(dentry); |
211 | if (!fullpath) { | ||
212 | rc = -ENOMEM; | ||
213 | goto compose_mount_options_err; | ||
214 | } | ||
215 | ++fullpath; | ||
204 | tkn_e = strchr(tkn_e + 1, '\\'); | 216 | tkn_e = strchr(tkn_e + 1, '\\'); |
205 | if (tkn_e || strlen(fullpath) - (ref->path_consumed)) { | 217 | if (tkn_e || (strlen(fullpath) - ref->path_consumed)) { |
206 | strncat(mountdata, &sep, 1); | 218 | strncat(mountdata, &sep, 1); |
207 | strcat(mountdata, "prefixpath="); | 219 | strcat(mountdata, "prefixpath="); |
208 | if (tkn_e) | 220 | if (tkn_e) |
209 | strcat(mountdata, tkn_e + 1); | 221 | strcat(mountdata, tkn_e + 1); |
210 | strcat(mountdata, fullpath + (ref->path_consumed)); | 222 | strcat(mountdata, fullpath + ref->path_consumed); |
211 | } | 223 | } |
224 | --fullpath; | ||
212 | kfree(fullpath); | 225 | kfree(fullpath); |
213 | 226 | ||
214 | /*cFYI(1,("%s: parent mountdata: %s", __func__,sb_mountdata));*/ | 227 | /*cFYI(1,("%s: parent mountdata: %s", __func__,sb_mountdata));*/ |
@@ -217,6 +230,11 @@ static char *compose_mount_options(const char *sb_mountdata, | |||
217 | compose_mount_options_out: | 230 | compose_mount_options_out: |
218 | kfree(srvIP); | 231 | kfree(srvIP); |
219 | return mountdata; | 232 | return mountdata; |
233 | |||
234 | compose_mount_options_err: | ||
235 | kfree(mountdata); | ||
236 | mountdata = ERR_PTR(rc); | ||
237 | goto compose_mount_options_out; | ||
220 | } | 238 | } |
221 | 239 | ||
222 | 240 | ||
@@ -309,13 +327,19 @@ cifs_dfs_follow_mountpoint(struct dentry *dentry, struct nameidata *nd) | |||
309 | goto out_err; | 327 | goto out_err; |
310 | } | 328 | } |
311 | 329 | ||
330 | /* | ||
331 | * The MSDFS spec states that paths in DFS referral requests and | ||
332 | * responses must be prefixed by a single '\' character instead of | ||
333 | * the double backslashes usually used in the UNC. This function | ||
334 | * gives us the latter, so we must adjust the result. | ||
335 | */ | ||
312 | full_path = build_path_from_dentry(dentry); | 336 | full_path = build_path_from_dentry(dentry); |
313 | if (full_path == NULL) { | 337 | if (full_path == NULL) { |
314 | rc = -ENOMEM; | 338 | rc = -ENOMEM; |
315 | goto out_err; | 339 | goto out_err; |
316 | } | 340 | } |
317 | 341 | ||
318 | rc = get_dfs_path(xid, ses , full_path, cifs_sb->local_nls, | 342 | rc = get_dfs_path(xid, ses , full_path + 1, cifs_sb->local_nls, |
319 | &num_referrals, &referrals, | 343 | &num_referrals, &referrals, |
320 | cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); | 344 | cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); |
321 | 345 | ||
diff --git a/fs/cifs/cifs_fs_sb.h b/fs/cifs/cifs_fs_sb.h index 877c85409f1f..c4c306f7b06f 100644 --- a/fs/cifs/cifs_fs_sb.h +++ b/fs/cifs/cifs_fs_sb.h | |||
@@ -19,8 +19,8 @@ | |||
19 | #define _CIFS_FS_SB_H | 19 | #define _CIFS_FS_SB_H |
20 | 20 | ||
21 | #define CIFS_MOUNT_NO_PERM 1 /* do not do client vfs_perm check */ | 21 | #define CIFS_MOUNT_NO_PERM 1 /* do not do client vfs_perm check */ |
22 | #define CIFS_MOUNT_SET_UID 2 /* set current->euid in create etc. */ | 22 | #define CIFS_MOUNT_SET_UID 2 /* set current's euid in create etc. */ |
23 | #define CIFS_MOUNT_SERVER_INUM 4 /* inode numbers from uniqueid from server */ | 23 | #define CIFS_MOUNT_SERVER_INUM 4 /* inode numbers from uniqueid from server */ |
24 | #define CIFS_MOUNT_DIRECT_IO 8 /* do not write nor read through page cache */ | 24 | #define CIFS_MOUNT_DIRECT_IO 8 /* do not write nor read through page cache */ |
25 | #define CIFS_MOUNT_NO_XATTR 0x10 /* if set - disable xattr support */ | 25 | #define CIFS_MOUNT_NO_XATTR 0x10 /* if set - disable xattr support */ |
26 | #define CIFS_MOUNT_MAP_SPECIAL_CHR 0x20 /* remap illegal chars in filenames */ | 26 | #define CIFS_MOUNT_MAP_SPECIAL_CHR 0x20 /* remap illegal chars in filenames */ |
@@ -30,7 +30,8 @@ | |||
30 | #define CIFS_MOUNT_CIFS_ACL 0x200 /* send ACL requests to non-POSIX srv */ | 30 | #define CIFS_MOUNT_CIFS_ACL 0x200 /* send ACL requests to non-POSIX srv */ |
31 | #define CIFS_MOUNT_OVERR_UID 0x400 /* override uid returned from server */ | 31 | #define CIFS_MOUNT_OVERR_UID 0x400 /* override uid returned from server */ |
32 | #define CIFS_MOUNT_OVERR_GID 0x800 /* override gid returned from server */ | 32 | #define CIFS_MOUNT_OVERR_GID 0x800 /* override gid returned from server */ |
33 | #define CIFS_MOUNT_DYNPERM 0x1000 /* allow in-memory only mode setting */ | 33 | #define CIFS_MOUNT_DYNPERM 0x1000 /* allow in-memory only mode setting */ |
34 | #define CIFS_MOUNT_NOPOSIXBRL 0x2000 /* mandatory not posix byte range lock */ | ||
34 | 35 | ||
35 | struct cifs_sb_info { | 36 | struct cifs_sb_info { |
36 | struct cifsTconInfo *tcon; /* primary mount */ | 37 | struct cifsTconInfo *tcon; /* primary mount */ |
diff --git a/fs/cifs/cifs_spnego.c b/fs/cifs/cifs_spnego.c index 0ab2fb5afef1..3fd3a9df043a 100644 --- a/fs/cifs/cifs_spnego.c +++ b/fs/cifs/cifs_spnego.c | |||
@@ -121,11 +121,9 @@ cifs_get_spnego_key(struct cifsSesInfo *sesInfo) | |||
121 | 121 | ||
122 | /* add the server address */ | 122 | /* add the server address */ |
123 | if (server->addr.sockAddr.sin_family == AF_INET) | 123 | if (server->addr.sockAddr.sin_family == AF_INET) |
124 | sprintf(dp, "ip4=" NIPQUAD_FMT, | 124 | sprintf(dp, "ip4=%pI4", &server->addr.sockAddr.sin_addr); |
125 | NIPQUAD(server->addr.sockAddr.sin_addr)); | ||
126 | else if (server->addr.sockAddr.sin_family == AF_INET6) | 125 | else if (server->addr.sockAddr.sin_family == AF_INET6) |
127 | sprintf(dp, "ip6=" NIP6_SEQFMT, | 126 | sprintf(dp, "ip6=%pi6", &server->addr.sockAddr6.sin6_addr); |
128 | NIP6(server->addr.sockAddr6.sin6_addr)); | ||
129 | else | 127 | else |
130 | goto out; | 128 | goto out; |
131 | 129 | ||
diff --git a/fs/cifs/cifsencrypt.c b/fs/cifs/cifsencrypt.c index bd5f13d38450..d4839cf0cb2c 100644 --- a/fs/cifs/cifsencrypt.c +++ b/fs/cifs/cifsencrypt.c | |||
@@ -37,7 +37,7 @@ | |||
37 | 37 | ||
38 | extern void mdfour(unsigned char *out, unsigned char *in, int n); | 38 | extern void mdfour(unsigned char *out, unsigned char *in, int n); |
39 | extern void E_md4hash(const unsigned char *passwd, unsigned char *p16); | 39 | extern void E_md4hash(const unsigned char *passwd, unsigned char *p16); |
40 | extern void SMBencrypt(unsigned char *passwd, unsigned char *c8, | 40 | extern void SMBencrypt(unsigned char *passwd, const unsigned char *c8, |
41 | unsigned char *p24); | 41 | unsigned char *p24); |
42 | 42 | ||
43 | static int cifs_calculate_signature(const struct smb_hdr *cifs_pdu, | 43 | static int cifs_calculate_signature(const struct smb_hdr *cifs_pdu, |
@@ -280,25 +280,22 @@ int CalcNTLMv2_partial_mac_key(struct cifsSesInfo *ses, | |||
280 | } | 280 | } |
281 | 281 | ||
282 | #ifdef CONFIG_CIFS_WEAK_PW_HASH | 282 | #ifdef CONFIG_CIFS_WEAK_PW_HASH |
283 | void calc_lanman_hash(struct cifsSesInfo *ses, char *lnm_session_key) | 283 | void calc_lanman_hash(const char *password, const char *cryptkey, bool encrypt, |
284 | char *lnm_session_key) | ||
284 | { | 285 | { |
285 | int i; | 286 | int i; |
286 | char password_with_pad[CIFS_ENCPWD_SIZE]; | 287 | char password_with_pad[CIFS_ENCPWD_SIZE]; |
287 | 288 | ||
288 | if (ses->server == NULL) | ||
289 | return; | ||
290 | |||
291 | memset(password_with_pad, 0, CIFS_ENCPWD_SIZE); | 289 | memset(password_with_pad, 0, CIFS_ENCPWD_SIZE); |
292 | if (ses->password) | 290 | if (password) |
293 | strncpy(password_with_pad, ses->password, CIFS_ENCPWD_SIZE); | 291 | strncpy(password_with_pad, password, CIFS_ENCPWD_SIZE); |
294 | 292 | ||
295 | if ((ses->server->secMode & SECMODE_PW_ENCRYPT) == 0) | 293 | if (!encrypt && extended_security & CIFSSEC_MAY_PLNTXT) { |
296 | if (extended_security & CIFSSEC_MAY_PLNTXT) { | 294 | memset(lnm_session_key, 0, CIFS_SESS_KEY_SIZE); |
297 | memset(lnm_session_key, 0, CIFS_SESS_KEY_SIZE); | 295 | memcpy(lnm_session_key, password_with_pad, |
298 | memcpy(lnm_session_key, password_with_pad, | 296 | CIFS_ENCPWD_SIZE); |
299 | CIFS_ENCPWD_SIZE); | 297 | return; |
300 | return; | 298 | } |
301 | } | ||
302 | 299 | ||
303 | /* calculate old style session key */ | 300 | /* calculate old style session key */ |
304 | /* calling toupper is less broken than repeatedly | 301 | /* calling toupper is less broken than repeatedly |
@@ -314,7 +311,8 @@ void calc_lanman_hash(struct cifsSesInfo *ses, char *lnm_session_key) | |||
314 | for (i = 0; i < CIFS_ENCPWD_SIZE; i++) | 311 | for (i = 0; i < CIFS_ENCPWD_SIZE; i++) |
315 | password_with_pad[i] = toupper(password_with_pad[i]); | 312 | password_with_pad[i] = toupper(password_with_pad[i]); |
316 | 313 | ||
317 | SMBencrypt(password_with_pad, ses->server->cryptKey, lnm_session_key); | 314 | SMBencrypt(password_with_pad, cryptkey, lnm_session_key); |
315 | |||
318 | /* clear password before we return/free memory */ | 316 | /* clear password before we return/free memory */ |
319 | memset(password_with_pad, 0, CIFS_ENCPWD_SIZE); | 317 | memset(password_with_pad, 0, CIFS_ENCPWD_SIZE); |
320 | } | 318 | } |
diff --git a/fs/cifs/cifsencrypt.h b/fs/cifs/cifsencrypt.h index 152fa2dcfc6c..15d2ec006474 100644 --- a/fs/cifs/cifsencrypt.h +++ b/fs/cifs/cifsencrypt.h | |||
@@ -26,7 +26,8 @@ | |||
26 | extern void mdfour(unsigned char *out, unsigned char *in, int n); | 26 | extern void mdfour(unsigned char *out, unsigned char *in, int n); |
27 | /* smbdes.c */ | 27 | /* smbdes.c */ |
28 | extern void E_P16(unsigned char *p14, unsigned char *p16); | 28 | extern void E_P16(unsigned char *p14, unsigned char *p16); |
29 | extern void E_P24(unsigned char *p21, unsigned char *c8, unsigned char *p24); | 29 | extern void E_P24(unsigned char *p21, const unsigned char *c8, |
30 | unsigned char *p24); | ||
30 | 31 | ||
31 | 32 | ||
32 | 33 | ||
diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c index d9cf467309e8..0005a194a75c 100644 --- a/fs/cifs/cifsfs.c +++ b/fs/cifs/cifsfs.c | |||
@@ -66,7 +66,9 @@ unsigned int sign_CIFS_PDUs = 1; | |||
66 | extern struct task_struct *oplockThread; /* remove sparse warning */ | 66 | extern struct task_struct *oplockThread; /* remove sparse warning */ |
67 | struct task_struct *oplockThread = NULL; | 67 | struct task_struct *oplockThread = NULL; |
68 | /* extern struct task_struct * dnotifyThread; remove sparse warning */ | 68 | /* extern struct task_struct * dnotifyThread; remove sparse warning */ |
69 | #ifdef CONFIG_CIFS_EXPERIMENTAL | ||
69 | static struct task_struct *dnotifyThread = NULL; | 70 | static struct task_struct *dnotifyThread = NULL; |
71 | #endif | ||
70 | static const struct super_operations cifs_super_ops; | 72 | static const struct super_operations cifs_super_ops; |
71 | unsigned int CIFSMaxBufSize = CIFS_MAX_MSGSIZE; | 73 | unsigned int CIFSMaxBufSize = CIFS_MAX_MSGSIZE; |
72 | module_param(CIFSMaxBufSize, int, 0); | 74 | module_param(CIFSMaxBufSize, int, 0); |
@@ -337,39 +339,58 @@ static int | |||
337 | cifs_show_options(struct seq_file *s, struct vfsmount *m) | 339 | cifs_show_options(struct seq_file *s, struct vfsmount *m) |
338 | { | 340 | { |
339 | struct cifs_sb_info *cifs_sb; | 341 | struct cifs_sb_info *cifs_sb; |
342 | struct cifsTconInfo *tcon; | ||
343 | struct TCP_Server_Info *server; | ||
340 | 344 | ||
341 | cifs_sb = CIFS_SB(m->mnt_sb); | 345 | cifs_sb = CIFS_SB(m->mnt_sb); |
342 | 346 | ||
343 | if (cifs_sb) { | 347 | if (cifs_sb) { |
344 | if (cifs_sb->tcon) { | 348 | tcon = cifs_sb->tcon; |
345 | /* BB add prepath to mount options displayed */ | 349 | if (tcon) { |
346 | seq_printf(s, ",unc=%s", cifs_sb->tcon->treeName); | 350 | seq_printf(s, ",unc=%s", cifs_sb->tcon->treeName); |
347 | if (cifs_sb->tcon->ses) { | 351 | if (tcon->ses) { |
348 | if (cifs_sb->tcon->ses->userName) | 352 | if (tcon->ses->userName) |
349 | seq_printf(s, ",username=%s", | 353 | seq_printf(s, ",username=%s", |
350 | cifs_sb->tcon->ses->userName); | 354 | tcon->ses->userName); |
351 | if (cifs_sb->tcon->ses->domainName) | 355 | if (tcon->ses->domainName) |
352 | seq_printf(s, ",domain=%s", | 356 | seq_printf(s, ",domain=%s", |
353 | cifs_sb->tcon->ses->domainName); | 357 | tcon->ses->domainName); |
358 | server = tcon->ses->server; | ||
359 | if (server) { | ||
360 | seq_printf(s, ",addr="); | ||
361 | switch (server->addr.sockAddr6. | ||
362 | sin6_family) { | ||
363 | case AF_INET6: | ||
364 | seq_printf(s, "%pI6", | ||
365 | &server->addr.sockAddr6.sin6_addr); | ||
366 | break; | ||
367 | case AF_INET: | ||
368 | seq_printf(s, "%pI4", | ||
369 | &server->addr.sockAddr.sin_addr.s_addr); | ||
370 | break; | ||
371 | } | ||
372 | } | ||
354 | } | 373 | } |
355 | if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_UID) || | 374 | if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_UID) || |
356 | !(cifs_sb->tcon->unix_ext)) | 375 | !(tcon->unix_ext)) |
357 | seq_printf(s, ",uid=%d", cifs_sb->mnt_uid); | 376 | seq_printf(s, ",uid=%d", cifs_sb->mnt_uid); |
358 | if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_GID) || | 377 | if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_GID) || |
359 | !(cifs_sb->tcon->unix_ext)) | 378 | !(tcon->unix_ext)) |
360 | seq_printf(s, ",gid=%d", cifs_sb->mnt_gid); | 379 | seq_printf(s, ",gid=%d", cifs_sb->mnt_gid); |
361 | if (!cifs_sb->tcon->unix_ext) { | 380 | if (!tcon->unix_ext) { |
362 | seq_printf(s, ",file_mode=0%o,dir_mode=0%o", | 381 | seq_printf(s, ",file_mode=0%o,dir_mode=0%o", |
363 | cifs_sb->mnt_file_mode, | 382 | cifs_sb->mnt_file_mode, |
364 | cifs_sb->mnt_dir_mode); | 383 | cifs_sb->mnt_dir_mode); |
365 | } | 384 | } |
366 | if (cifs_sb->tcon->seal) | 385 | if (tcon->seal) |
367 | seq_printf(s, ",seal"); | 386 | seq_printf(s, ",seal"); |
368 | if (cifs_sb->tcon->nocase) | 387 | if (tcon->nocase) |
369 | seq_printf(s, ",nocase"); | 388 | seq_printf(s, ",nocase"); |
370 | if (cifs_sb->tcon->retry) | 389 | if (tcon->retry) |
371 | seq_printf(s, ",hard"); | 390 | seq_printf(s, ",hard"); |
372 | } | 391 | } |
392 | if (cifs_sb->prepath) | ||
393 | seq_printf(s, ",prepath=%s", cifs_sb->prepath); | ||
373 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS) | 394 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS) |
374 | seq_printf(s, ",posixpaths"); | 395 | seq_printf(s, ",posixpaths"); |
375 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) | 396 | 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, | |||
417 | xid = GetXid(); | 438 | xid = GetXid(); |
418 | if (pTcon) { | 439 | if (pTcon) { |
419 | cFYI(1, ("set type: 0x%x id: %d", quota_type, qid)); | 440 | cFYI(1, ("set type: 0x%x id: %d", quota_type, qid)); |
420 | } else { | 441 | } else |
421 | rc = -EIO; | 442 | rc = -EIO; |
422 | } | ||
423 | 443 | ||
424 | FreeXid(xid); | 444 | FreeXid(xid); |
425 | return rc; | 445 | return rc; |
@@ -441,9 +461,8 @@ int cifs_xquota_get(struct super_block *sb, int quota_type, qid_t qid, | |||
441 | xid = GetXid(); | 461 | xid = GetXid(); |
442 | if (pTcon) { | 462 | if (pTcon) { |
443 | cFYI(1, ("set type: 0x%x id: %d", quota_type, qid)); | 463 | cFYI(1, ("set type: 0x%x id: %d", quota_type, qid)); |
444 | } else { | 464 | } else |
445 | rc = -EIO; | 465 | rc = -EIO; |
446 | } | ||
447 | 466 | ||
448 | FreeXid(xid); | 467 | FreeXid(xid); |
449 | return rc; | 468 | return rc; |
@@ -464,9 +483,8 @@ int cifs_xstate_set(struct super_block *sb, unsigned int flags, int operation) | |||
464 | xid = GetXid(); | 483 | xid = GetXid(); |
465 | if (pTcon) { | 484 | if (pTcon) { |
466 | cFYI(1, ("flags: 0x%x operation: 0x%x", flags, operation)); | 485 | cFYI(1, ("flags: 0x%x operation: 0x%x", flags, operation)); |
467 | } else { | 486 | } else |
468 | rc = -EIO; | 487 | rc = -EIO; |
469 | } | ||
470 | 488 | ||
471 | FreeXid(xid); | 489 | FreeXid(xid); |
472 | return rc; | 490 | return rc; |
@@ -479,17 +497,16 @@ int cifs_xstate_get(struct super_block *sb, struct fs_quota_stat *qstats) | |||
479 | struct cifs_sb_info *cifs_sb = CIFS_SB(sb); | 497 | struct cifs_sb_info *cifs_sb = CIFS_SB(sb); |
480 | struct cifsTconInfo *pTcon; | 498 | struct cifsTconInfo *pTcon; |
481 | 499 | ||
482 | if (cifs_sb) { | 500 | if (cifs_sb) |
483 | pTcon = cifs_sb->tcon; | 501 | pTcon = cifs_sb->tcon; |
484 | } else { | 502 | else |
485 | return -EIO; | 503 | return -EIO; |
486 | } | 504 | |
487 | xid = GetXid(); | 505 | xid = GetXid(); |
488 | if (pTcon) { | 506 | if (pTcon) { |
489 | cFYI(1, ("pqstats %p", qstats)); | 507 | cFYI(1, ("pqstats %p", qstats)); |
490 | } else { | 508 | } else |
491 | rc = -EIO; | 509 | rc = -EIO; |
492 | } | ||
493 | 510 | ||
494 | FreeXid(xid); | 511 | FreeXid(xid); |
495 | return rc; | 512 | return rc; |
@@ -1029,6 +1046,7 @@ static int cifs_oplock_thread(void *dummyarg) | |||
1029 | return 0; | 1046 | return 0; |
1030 | } | 1047 | } |
1031 | 1048 | ||
1049 | #ifdef CONFIG_CIFS_EXPERIMENTAL | ||
1032 | static int cifs_dnotify_thread(void *dummyarg) | 1050 | static int cifs_dnotify_thread(void *dummyarg) |
1033 | { | 1051 | { |
1034 | struct list_head *tmp; | 1052 | struct list_head *tmp; |
@@ -1054,6 +1072,7 @@ static int cifs_dnotify_thread(void *dummyarg) | |||
1054 | 1072 | ||
1055 | return 0; | 1073 | return 0; |
1056 | } | 1074 | } |
1075 | #endif | ||
1057 | 1076 | ||
1058 | static int __init | 1077 | static int __init |
1059 | init_cifs(void) | 1078 | init_cifs(void) |
@@ -1131,16 +1150,20 @@ init_cifs(void) | |||
1131 | goto out_unregister_dfs_key_type; | 1150 | goto out_unregister_dfs_key_type; |
1132 | } | 1151 | } |
1133 | 1152 | ||
1153 | #ifdef CONFIG_CIFS_EXPERIMENTAL | ||
1134 | dnotifyThread = kthread_run(cifs_dnotify_thread, NULL, "cifsdnotifyd"); | 1154 | dnotifyThread = kthread_run(cifs_dnotify_thread, NULL, "cifsdnotifyd"); |
1135 | if (IS_ERR(dnotifyThread)) { | 1155 | if (IS_ERR(dnotifyThread)) { |
1136 | rc = PTR_ERR(dnotifyThread); | 1156 | rc = PTR_ERR(dnotifyThread); |
1137 | cERROR(1, ("error %d create dnotify thread", rc)); | 1157 | cERROR(1, ("error %d create dnotify thread", rc)); |
1138 | goto out_stop_oplock_thread; | 1158 | goto out_stop_oplock_thread; |
1139 | } | 1159 | } |
1160 | #endif | ||
1140 | 1161 | ||
1141 | return 0; | 1162 | return 0; |
1142 | 1163 | ||
1164 | #ifdef CONFIG_CIFS_EXPERIMENTAL | ||
1143 | out_stop_oplock_thread: | 1165 | out_stop_oplock_thread: |
1166 | #endif | ||
1144 | kthread_stop(oplockThread); | 1167 | kthread_stop(oplockThread); |
1145 | out_unregister_dfs_key_type: | 1168 | out_unregister_dfs_key_type: |
1146 | #ifdef CONFIG_CIFS_DFS_UPCALL | 1169 | #ifdef CONFIG_CIFS_DFS_UPCALL |
@@ -1179,8 +1202,10 @@ exit_cifs(void) | |||
1179 | cifs_destroy_inodecache(); | 1202 | cifs_destroy_inodecache(); |
1180 | cifs_destroy_mids(); | 1203 | cifs_destroy_mids(); |
1181 | cifs_destroy_request_bufs(); | 1204 | cifs_destroy_request_bufs(); |
1182 | kthread_stop(oplockThread); | 1205 | #ifdef CONFIG_CIFS_EXPERIMENTAL |
1183 | kthread_stop(dnotifyThread); | 1206 | kthread_stop(dnotifyThread); |
1207 | #endif | ||
1208 | kthread_stop(oplockThread); | ||
1184 | } | 1209 | } |
1185 | 1210 | ||
1186 | MODULE_AUTHOR("Steve French <sfrench@us.ibm.com>"); | 1211 | MODULE_AUTHOR("Steve French <sfrench@us.ibm.com>"); |
diff --git a/fs/cifs/cifsfs.h b/fs/cifs/cifsfs.h index 074de0b5064d..2ce04c73d74e 100644 --- a/fs/cifs/cifsfs.h +++ b/fs/cifs/cifsfs.h | |||
@@ -101,5 +101,5 @@ extern long cifs_ioctl(struct file *filep, unsigned int cmd, unsigned long arg); | |||
101 | extern const struct export_operations cifs_export_ops; | 101 | extern const struct export_operations cifs_export_ops; |
102 | #endif /* EXPERIMENTAL */ | 102 | #endif /* EXPERIMENTAL */ |
103 | 103 | ||
104 | #define CIFS_VERSION "1.55" | 104 | #define CIFS_VERSION "1.56" |
105 | #endif /* _CIFSFS_H */ | 105 | #endif /* _CIFSFS_H */ |
diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h index c57c0565547f..94c1ca0ec953 100644 --- a/fs/cifs/cifsglob.h +++ b/fs/cifs/cifsglob.h | |||
@@ -47,7 +47,11 @@ | |||
47 | */ | 47 | */ |
48 | #define CIFS_MAX_REQ 50 | 48 | #define CIFS_MAX_REQ 50 |
49 | 49 | ||
50 | #define SERVER_NAME_LENGTH 15 | 50 | #define RFC1001_NAME_LEN 15 |
51 | #define RFC1001_NAME_LEN_WITH_NULL (RFC1001_NAME_LEN + 1) | ||
52 | |||
53 | /* currently length of NIP6_FMT */ | ||
54 | #define SERVER_NAME_LENGTH 40 | ||
51 | #define SERVER_NAME_LEN_WITH_NULL (SERVER_NAME_LENGTH + 1) | 55 | #define SERVER_NAME_LEN_WITH_NULL (SERVER_NAME_LENGTH + 1) |
52 | 56 | ||
53 | /* used to define string lengths for reversing unicode strings */ | 57 | /* used to define string lengths for reversing unicode strings */ |
@@ -125,8 +129,7 @@ struct TCP_Server_Info { | |||
125 | struct list_head smb_ses_list; | 129 | struct list_head smb_ses_list; |
126 | int srv_count; /* reference counter */ | 130 | int srv_count; /* reference counter */ |
127 | /* 15 character server name + 0x20 16th byte indicating type = srv */ | 131 | /* 15 character server name + 0x20 16th byte indicating type = srv */ |
128 | char server_RFC1001_name[SERVER_NAME_LEN_WITH_NULL]; | 132 | char server_RFC1001_name[RFC1001_NAME_LEN_WITH_NULL]; |
129 | char unicode_server_Name[SERVER_NAME_LEN_WITH_NULL * 2]; | ||
130 | char *hostname; /* hostname portion of UNC string */ | 133 | char *hostname; /* hostname portion of UNC string */ |
131 | struct socket *ssocket; | 134 | struct socket *ssocket; |
132 | union { | 135 | union { |
@@ -151,7 +154,7 @@ struct TCP_Server_Info { | |||
151 | atomic_t num_waiters; /* blocked waiting to get in sendrecv */ | 154 | atomic_t num_waiters; /* blocked waiting to get in sendrecv */ |
152 | #endif | 155 | #endif |
153 | enum statusEnum tcpStatus; /* what we think the status is */ | 156 | enum statusEnum tcpStatus; /* what we think the status is */ |
154 | struct semaphore tcpSem; | 157 | struct mutex srv_mutex; |
155 | struct task_struct *tsk; | 158 | struct task_struct *tsk; |
156 | char server_GUID[16]; | 159 | char server_GUID[16]; |
157 | char secMode; | 160 | char secMode; |
@@ -171,7 +174,7 @@ struct TCP_Server_Info { | |||
171 | __u16 CurrentMid; /* multiplex id - rotating counter */ | 174 | __u16 CurrentMid; /* multiplex id - rotating counter */ |
172 | char cryptKey[CIFS_CRYPTO_KEY_SIZE]; | 175 | char cryptKey[CIFS_CRYPTO_KEY_SIZE]; |
173 | /* 16th byte of RFC1001 workstation name is always null */ | 176 | /* 16th byte of RFC1001 workstation name is always null */ |
174 | char workstation_RFC1001_name[SERVER_NAME_LEN_WITH_NULL]; | 177 | char workstation_RFC1001_name[RFC1001_NAME_LEN_WITH_NULL]; |
175 | __u32 sequence_number; /* needed for CIFS PDU signature */ | 178 | __u32 sequence_number; /* needed for CIFS PDU signature */ |
176 | struct mac_key mac_signing_key; | 179 | struct mac_key mac_signing_key; |
177 | char ntlmv2_hash[16]; | 180 | char ntlmv2_hash[16]; |
@@ -239,6 +242,7 @@ struct cifsTconInfo { | |||
239 | struct cifsSesInfo *ses; /* pointer to session associated with */ | 242 | struct cifsSesInfo *ses; /* pointer to session associated with */ |
240 | char treeName[MAX_TREE_SIZE + 1]; /* UNC name of resource in ASCII */ | 243 | char treeName[MAX_TREE_SIZE + 1]; /* UNC name of resource in ASCII */ |
241 | char *nativeFileSystem; | 244 | char *nativeFileSystem; |
245 | char *password; /* for share-level security */ | ||
242 | __u16 tid; /* The 2 byte tree id */ | 246 | __u16 tid; /* The 2 byte tree id */ |
243 | __u16 Flags; /* optional support bits */ | 247 | __u16 Flags; /* optional support bits */ |
244 | enum statusEnum tidStatus; | 248 | enum statusEnum tidStatus; |
@@ -422,7 +426,6 @@ struct mid_q_entry { | |||
422 | unsigned long when_sent; /* time when smb send finished */ | 426 | unsigned long when_sent; /* time when smb send finished */ |
423 | unsigned long when_received; /* when demux complete (taken off wire) */ | 427 | unsigned long when_received; /* when demux complete (taken off wire) */ |
424 | #endif | 428 | #endif |
425 | struct cifsSesInfo *ses; /* smb was sent to this server */ | ||
426 | struct task_struct *tsk; /* task waiting for response */ | 429 | struct task_struct *tsk; /* task waiting for response */ |
427 | struct smb_hdr *resp_buf; /* response buffer */ | 430 | struct smb_hdr *resp_buf; /* response buffer */ |
428 | int midState; /* wish this were enum but can not pass to wait_event */ | 431 | int midState; /* wish this were enum but can not pass to wait_event */ |
diff --git a/fs/cifs/cifspdu.h b/fs/cifs/cifspdu.h index d2a073edd1b8..b4e2e9f0ee3d 100644 --- a/fs/cifs/cifspdu.h +++ b/fs/cifs/cifspdu.h | |||
@@ -1922,7 +1922,7 @@ typedef struct smb_com_transaction2_get_dfs_refer_req { | |||
1922 | /* DFS server target type */ | 1922 | /* DFS server target type */ |
1923 | #define DFS_TYPE_LINK 0x0000 /* also for sysvol targets */ | 1923 | #define DFS_TYPE_LINK 0x0000 /* also for sysvol targets */ |
1924 | #define DFS_TYPE_ROOT 0x0001 | 1924 | #define DFS_TYPE_ROOT 0x0001 |
1925 | 1925 | ||
1926 | /* Referral Entry Flags */ | 1926 | /* Referral Entry Flags */ |
1927 | #define DFS_NAME_LIST_REF 0x0200 | 1927 | #define DFS_NAME_LIST_REF 0x0200 |
1928 | 1928 | ||
diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h index 6f21ecb85ce5..06f6779988bf 100644 --- a/fs/cifs/cifsproto.h +++ b/fs/cifs/cifsproto.h | |||
@@ -39,7 +39,7 @@ extern int smb_send(struct socket *, struct smb_hdr *, | |||
39 | unsigned int /* length */ , struct sockaddr *, bool); | 39 | unsigned int /* length */ , struct sockaddr *, bool); |
40 | extern unsigned int _GetXid(void); | 40 | extern unsigned int _GetXid(void); |
41 | extern void _FreeXid(unsigned int); | 41 | extern void _FreeXid(unsigned int); |
42 | #define GetXid() (int)_GetXid(); cFYI(1,("CIFS VFS: in %s as Xid: %d with uid: %d",__func__, xid,current->fsuid)); | 42 | #define GetXid() (int)_GetXid(); cFYI(1,("CIFS VFS: in %s as Xid: %d with uid: %d",__func__, xid,current_fsuid())); |
43 | #define FreeXid(curr_xid) {_FreeXid(curr_xid); cFYI(1,("CIFS VFS: leaving %s (xid = %d) rc = %d",__func__,curr_xid,(int)rc));} | 43 | #define FreeXid(curr_xid) {_FreeXid(curr_xid); cFYI(1,("CIFS VFS: leaving %s (xid = %d) rc = %d",__func__,curr_xid,(int)rc));} |
44 | extern char *build_path_from_dentry(struct dentry *); | 44 | extern char *build_path_from_dentry(struct dentry *); |
45 | extern char *build_wildcard_path_from_dentry(struct dentry *direntry); | 45 | extern char *build_wildcard_path_from_dentry(struct dentry *direntry); |
@@ -330,7 +330,8 @@ extern void CalcNTLMv2_response(const struct cifsSesInfo *, char *); | |||
330 | extern void setup_ntlmv2_rsp(struct cifsSesInfo *, char *, | 330 | extern void setup_ntlmv2_rsp(struct cifsSesInfo *, char *, |
331 | const struct nls_table *); | 331 | const struct nls_table *); |
332 | #ifdef CONFIG_CIFS_WEAK_PW_HASH | 332 | #ifdef CONFIG_CIFS_WEAK_PW_HASH |
333 | extern void calc_lanman_hash(struct cifsSesInfo *ses, char *lnm_session_key); | 333 | extern void calc_lanman_hash(const char *password, const char *cryptkey, |
334 | bool encrypt, char *lnm_session_key); | ||
334 | #endif /* CIFS_WEAK_PW_HASH */ | 335 | #endif /* CIFS_WEAK_PW_HASH */ |
335 | extern int CIFSSMBCopy(int xid, | 336 | extern int CIFSSMBCopy(int xid, |
336 | struct cifsTconInfo *source_tcon, | 337 | struct cifsTconInfo *source_tcon, |
diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c index 6d51696dc762..552642a507c4 100644 --- a/fs/cifs/cifssmb.c +++ b/fs/cifs/cifssmb.c | |||
@@ -1382,13 +1382,13 @@ openRetry: | |||
1382 | if (cpu_to_le32(FILE_CREATE) == pSMBr->CreateAction) | 1382 | if (cpu_to_le32(FILE_CREATE) == pSMBr->CreateAction) |
1383 | *pOplock |= CIFS_CREATE_ACTION; | 1383 | *pOplock |= CIFS_CREATE_ACTION; |
1384 | if (pfile_info) { | 1384 | if (pfile_info) { |
1385 | memcpy((char *)pfile_info, (char *)&pSMBr->CreationTime, | 1385 | memcpy((char *)pfile_info, (char *)&pSMBr->CreationTime, |
1386 | 36 /* CreationTime to Attributes */); | 1386 | 36 /* CreationTime to Attributes */); |
1387 | /* the file_info buf is endian converted by caller */ | 1387 | /* the file_info buf is endian converted by caller */ |
1388 | pfile_info->AllocationSize = pSMBr->AllocationSize; | 1388 | pfile_info->AllocationSize = pSMBr->AllocationSize; |
1389 | pfile_info->EndOfFile = pSMBr->EndOfFile; | 1389 | pfile_info->EndOfFile = pSMBr->EndOfFile; |
1390 | pfile_info->NumberOfLinks = cpu_to_le32(1); | 1390 | pfile_info->NumberOfLinks = cpu_to_le32(1); |
1391 | pfile_info->DeletePending = 0; | 1391 | pfile_info->DeletePending = 0; |
1392 | } | 1392 | } |
1393 | } | 1393 | } |
1394 | 1394 | ||
@@ -1414,8 +1414,13 @@ CIFSSMBRead(const int xid, struct cifsTconInfo *tcon, const int netfid, | |||
1414 | cFYI(1, ("Reading %d bytes on fid %d", count, netfid)); | 1414 | cFYI(1, ("Reading %d bytes on fid %d", count, netfid)); |
1415 | if (tcon->ses->capabilities & CAP_LARGE_FILES) | 1415 | if (tcon->ses->capabilities & CAP_LARGE_FILES) |
1416 | wct = 12; | 1416 | wct = 12; |
1417 | else | 1417 | else { |
1418 | wct = 10; /* old style read */ | 1418 | wct = 10; /* old style read */ |
1419 | if ((lseek >> 32) > 0) { | ||
1420 | /* can not handle this big offset for old */ | ||
1421 | return -EIO; | ||
1422 | } | ||
1423 | } | ||
1419 | 1424 | ||
1420 | *nbytes = 0; | 1425 | *nbytes = 0; |
1421 | rc = small_smb_init(SMB_COM_READ_ANDX, wct, tcon, (void **) &pSMB); | 1426 | 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, | |||
1431 | pSMB->OffsetLow = cpu_to_le32(lseek & 0xFFFFFFFF); | 1436 | pSMB->OffsetLow = cpu_to_le32(lseek & 0xFFFFFFFF); |
1432 | if (wct == 12) | 1437 | if (wct == 12) |
1433 | pSMB->OffsetHigh = cpu_to_le32(lseek >> 32); | 1438 | pSMB->OffsetHigh = cpu_to_le32(lseek >> 32); |
1434 | else if ((lseek >> 32) > 0) /* can not handle this big offset for old */ | ||
1435 | return -EIO; | ||
1436 | 1439 | ||
1437 | pSMB->Remaining = 0; | 1440 | pSMB->Remaining = 0; |
1438 | pSMB->MaxCount = cpu_to_le16(count & 0xFFFF); | 1441 | pSMB->MaxCount = cpu_to_le16(count & 0xFFFF); |
@@ -1519,8 +1522,13 @@ CIFSSMBWrite(const int xid, struct cifsTconInfo *tcon, | |||
1519 | 1522 | ||
1520 | if (tcon->ses->capabilities & CAP_LARGE_FILES) | 1523 | if (tcon->ses->capabilities & CAP_LARGE_FILES) |
1521 | wct = 14; | 1524 | wct = 14; |
1522 | else | 1525 | else { |
1523 | wct = 12; | 1526 | wct = 12; |
1527 | if ((offset >> 32) > 0) { | ||
1528 | /* can not handle big offset for old srv */ | ||
1529 | return -EIO; | ||
1530 | } | ||
1531 | } | ||
1524 | 1532 | ||
1525 | rc = smb_init(SMB_COM_WRITE_ANDX, wct, tcon, (void **) &pSMB, | 1533 | rc = smb_init(SMB_COM_WRITE_ANDX, wct, tcon, (void **) &pSMB, |
1526 | (void **) &pSMBr); | 1534 | (void **) &pSMBr); |
@@ -1535,8 +1543,6 @@ CIFSSMBWrite(const int xid, struct cifsTconInfo *tcon, | |||
1535 | pSMB->OffsetLow = cpu_to_le32(offset & 0xFFFFFFFF); | 1543 | pSMB->OffsetLow = cpu_to_le32(offset & 0xFFFFFFFF); |
1536 | if (wct == 14) | 1544 | if (wct == 14) |
1537 | pSMB->OffsetHigh = cpu_to_le32(offset >> 32); | 1545 | pSMB->OffsetHigh = cpu_to_le32(offset >> 32); |
1538 | else if ((offset >> 32) > 0) /* can not handle big offset for old srv */ | ||
1539 | return -EIO; | ||
1540 | 1546 | ||
1541 | pSMB->Reserved = 0xFFFFFFFF; | 1547 | pSMB->Reserved = 0xFFFFFFFF; |
1542 | pSMB->WriteMode = 0; | 1548 | pSMB->WriteMode = 0; |
@@ -1558,7 +1564,7 @@ CIFSSMBWrite(const int xid, struct cifsTconInfo *tcon, | |||
1558 | pSMB->DataOffset = | 1564 | pSMB->DataOffset = |
1559 | cpu_to_le16(offsetof(struct smb_com_write_req, Data) - 4); | 1565 | cpu_to_le16(offsetof(struct smb_com_write_req, Data) - 4); |
1560 | if (buf) | 1566 | if (buf) |
1561 | memcpy(pSMB->Data, buf, bytes_sent); | 1567 | memcpy(pSMB->Data, buf, bytes_sent); |
1562 | else if (ubuf) { | 1568 | else if (ubuf) { |
1563 | if (copy_from_user(pSMB->Data, ubuf, bytes_sent)) { | 1569 | if (copy_from_user(pSMB->Data, ubuf, bytes_sent)) { |
1564 | cifs_buf_release(pSMB); | 1570 | cifs_buf_release(pSMB); |
@@ -1621,10 +1627,15 @@ CIFSSMBWrite2(const int xid, struct cifsTconInfo *tcon, | |||
1621 | 1627 | ||
1622 | cFYI(1, ("write2 at %lld %d bytes", (long long)offset, count)); | 1628 | cFYI(1, ("write2 at %lld %d bytes", (long long)offset, count)); |
1623 | 1629 | ||
1624 | if (tcon->ses->capabilities & CAP_LARGE_FILES) | 1630 | if (tcon->ses->capabilities & CAP_LARGE_FILES) { |
1625 | wct = 14; | 1631 | wct = 14; |
1626 | else | 1632 | } else { |
1627 | wct = 12; | 1633 | wct = 12; |
1634 | if ((offset >> 32) > 0) { | ||
1635 | /* can not handle big offset for old srv */ | ||
1636 | return -EIO; | ||
1637 | } | ||
1638 | } | ||
1628 | rc = small_smb_init(SMB_COM_WRITE_ANDX, wct, tcon, (void **) &pSMB); | 1639 | rc = small_smb_init(SMB_COM_WRITE_ANDX, wct, tcon, (void **) &pSMB); |
1629 | if (rc) | 1640 | if (rc) |
1630 | return rc; | 1641 | return rc; |
@@ -1637,8 +1648,6 @@ CIFSSMBWrite2(const int xid, struct cifsTconInfo *tcon, | |||
1637 | pSMB->OffsetLow = cpu_to_le32(offset & 0xFFFFFFFF); | 1648 | pSMB->OffsetLow = cpu_to_le32(offset & 0xFFFFFFFF); |
1638 | if (wct == 14) | 1649 | if (wct == 14) |
1639 | pSMB->OffsetHigh = cpu_to_le32(offset >> 32); | 1650 | pSMB->OffsetHigh = cpu_to_le32(offset >> 32); |
1640 | else if ((offset >> 32) > 0) /* can not handle big offset for old srv */ | ||
1641 | return -EIO; | ||
1642 | pSMB->Reserved = 0xFFFFFFFF; | 1651 | pSMB->Reserved = 0xFFFFFFFF; |
1643 | pSMB->WriteMode = 0; | 1652 | pSMB->WriteMode = 0; |
1644 | pSMB->Remaining = 0; | 1653 | pSMB->Remaining = 0; |
@@ -1862,10 +1871,6 @@ CIFSSMBPosixLock(const int xid, struct cifsTconInfo *tcon, | |||
1862 | rc = -EIO; /* bad smb */ | 1871 | rc = -EIO; /* bad smb */ |
1863 | goto plk_err_exit; | 1872 | goto plk_err_exit; |
1864 | } | 1873 | } |
1865 | if (pLockData == NULL) { | ||
1866 | rc = -EINVAL; | ||
1867 | goto plk_err_exit; | ||
1868 | } | ||
1869 | data_offset = le16_to_cpu(pSMBr->t2.DataOffset); | 1874 | data_offset = le16_to_cpu(pSMBr->t2.DataOffset); |
1870 | data_count = le16_to_cpu(pSMBr->t2.DataCount); | 1875 | data_count = le16_to_cpu(pSMBr->t2.DataCount); |
1871 | if (data_count < sizeof(struct cifs_posix_lock)) { | 1876 | if (data_count < sizeof(struct cifs_posix_lock)) { |
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c index c7d341714586..e9ea394ee075 100644 --- a/fs/cifs/connect.c +++ b/fs/cifs/connect.c | |||
@@ -89,6 +89,7 @@ struct smb_vol { | |||
89 | bool nullauth:1; /* attempt to authenticate with null user */ | 89 | bool nullauth:1; /* attempt to authenticate with null user */ |
90 | bool nocase:1; /* request case insensitive filenames */ | 90 | bool nocase:1; /* request case insensitive filenames */ |
91 | bool nobrl:1; /* disable sending byte range locks to srv */ | 91 | bool nobrl:1; /* disable sending byte range locks to srv */ |
92 | bool mand_lock:1; /* send mandatory not posix byte range lock reqs */ | ||
92 | bool seal:1; /* request transport encryption on share */ | 93 | bool seal:1; /* request transport encryption on share */ |
93 | bool nodfs:1; /* Do not request DFS, even if available */ | 94 | bool nodfs:1; /* Do not request DFS, even if available */ |
94 | bool local_lease:1; /* check leases only on local system, not remote */ | 95 | bool local_lease:1; /* check leases only on local system, not remote */ |
@@ -101,25 +102,17 @@ struct smb_vol { | |||
101 | char *prepath; | 102 | char *prepath; |
102 | }; | 103 | }; |
103 | 104 | ||
104 | static int ipv4_connect(struct sockaddr_in *psin_server, | 105 | static int ipv4_connect(struct TCP_Server_Info *server); |
105 | struct socket **csocket, | 106 | static int ipv6_connect(struct TCP_Server_Info *server); |
106 | char *netb_name, | ||
107 | char *server_netb_name, | ||
108 | bool noblocksnd, | ||
109 | bool nosndbuf); /* ipv6 never set sndbuf size */ | ||
110 | static int ipv6_connect(struct sockaddr_in6 *psin_server, | ||
111 | struct socket **csocket, bool noblocksnd); | ||
112 | |||
113 | |||
114 | /* | ||
115 | * cifs tcp session reconnection | ||
116 | * | ||
117 | * mark tcp session as reconnecting so temporarily locked | ||
118 | * mark all smb sessions as reconnecting for tcp session | ||
119 | * reconnect tcp session | ||
120 | * wake up waiters on reconnection? - (not needed currently) | ||
121 | */ | ||
122 | 107 | ||
108 | /* | ||
109 | * cifs tcp session reconnection | ||
110 | * | ||
111 | * mark tcp session as reconnecting so temporarily locked | ||
112 | * mark all smb sessions as reconnecting for tcp session | ||
113 | * reconnect tcp session | ||
114 | * wake up waiters on reconnection? - (not needed currently) | ||
115 | */ | ||
123 | static int | 116 | static int |
124 | cifs_reconnect(struct TCP_Server_Info *server) | 117 | cifs_reconnect(struct TCP_Server_Info *server) |
125 | { | 118 | { |
@@ -156,7 +149,7 @@ cifs_reconnect(struct TCP_Server_Info *server) | |||
156 | } | 149 | } |
157 | read_unlock(&cifs_tcp_ses_lock); | 150 | read_unlock(&cifs_tcp_ses_lock); |
158 | /* do not want to be sending data on a socket we are freeing */ | 151 | /* do not want to be sending data on a socket we are freeing */ |
159 | down(&server->tcpSem); | 152 | mutex_lock(&server->srv_mutex); |
160 | if (server->ssocket) { | 153 | if (server->ssocket) { |
161 | cFYI(1, ("State: 0x%x Flags: 0x%lx", server->ssocket->state, | 154 | cFYI(1, ("State: 0x%x Flags: 0x%lx", server->ssocket->state, |
162 | server->ssocket->flags)); | 155 | server->ssocket->flags)); |
@@ -182,21 +175,15 @@ cifs_reconnect(struct TCP_Server_Info *server) | |||
182 | } | 175 | } |
183 | } | 176 | } |
184 | spin_unlock(&GlobalMid_Lock); | 177 | spin_unlock(&GlobalMid_Lock); |
185 | up(&server->tcpSem); | 178 | mutex_unlock(&server->srv_mutex); |
186 | 179 | ||
187 | while ((server->tcpStatus != CifsExiting) && | 180 | while ((server->tcpStatus != CifsExiting) && |
188 | (server->tcpStatus != CifsGood)) { | 181 | (server->tcpStatus != CifsGood)) { |
189 | try_to_freeze(); | 182 | try_to_freeze(); |
190 | if (server->addr.sockAddr6.sin6_family == AF_INET6) { | 183 | if (server->addr.sockAddr6.sin6_family == AF_INET6) |
191 | rc = ipv6_connect(&server->addr.sockAddr6, | 184 | rc = ipv6_connect(server); |
192 | &server->ssocket, server->noautotune); | 185 | else |
193 | } else { | 186 | rc = ipv4_connect(server); |
194 | rc = ipv4_connect(&server->addr.sockAddr, | ||
195 | &server->ssocket, | ||
196 | server->workstation_RFC1001_name, | ||
197 | server->server_RFC1001_name, | ||
198 | server->noblocksnd, server->noautotune); | ||
199 | } | ||
200 | if (rc) { | 187 | if (rc) { |
201 | cFYI(1, ("reconnect error %d", rc)); | 188 | cFYI(1, ("reconnect error %d", rc)); |
202 | msleep(3000); | 189 | msleep(3000); |
@@ -776,7 +763,7 @@ multi_t2_fnd: | |||
776 | set_current_state(TASK_RUNNING); | 763 | set_current_state(TASK_RUNNING); |
777 | } | 764 | } |
778 | 765 | ||
779 | return 0; | 766 | module_put_and_exit(0); |
780 | } | 767 | } |
781 | 768 | ||
782 | /* extract the host portion of the UNC string */ | 769 | /* extract the host portion of the UNC string */ |
@@ -836,8 +823,8 @@ cifs_parse_mount_options(char *options, const char *devname, | |||
836 | /* null target name indicates to use *SMBSERVR default called name | 823 | /* null target name indicates to use *SMBSERVR default called name |
837 | if we end up sending RFC1001 session initialize */ | 824 | if we end up sending RFC1001 session initialize */ |
838 | vol->target_rfc1001_name[0] = 0; | 825 | vol->target_rfc1001_name[0] = 0; |
839 | vol->linux_uid = current->uid; /* current->euid instead? */ | 826 | vol->linux_uid = current_uid(); /* use current_euid() instead? */ |
840 | vol->linux_gid = current->gid; | 827 | vol->linux_gid = current_gid(); |
841 | vol->dir_mode = S_IRWXUGO; | 828 | vol->dir_mode = S_IRWXUGO; |
842 | /* 2767 perms indicate mandatory locking support */ | 829 | /* 2767 perms indicate mandatory locking support */ |
843 | vol->file_mode = (S_IRWXUGO | S_ISGID) & (~S_IXGRP); | 830 | vol->file_mode = (S_IRWXUGO | S_ISGID) & (~S_IXGRP); |
@@ -1260,6 +1247,17 @@ cifs_parse_mount_options(char *options, const char *devname, | |||
1260 | if (vol->file_mode == | 1247 | if (vol->file_mode == |
1261 | (S_IALLUGO & ~(S_ISUID | S_IXGRP))) | 1248 | (S_IALLUGO & ~(S_ISUID | S_IXGRP))) |
1262 | vol->file_mode = S_IALLUGO; | 1249 | vol->file_mode = S_IALLUGO; |
1250 | } else if (strnicmp(data, "forcemandatorylock", 9) == 0) { | ||
1251 | /* will take the shorter form "forcemand" as well */ | ||
1252 | /* This mount option will force use of mandatory | ||
1253 | (DOS/Windows style) byte range locks, instead of | ||
1254 | using posix advisory byte range locks, even if the | ||
1255 | Unix extensions are available and posix locks would | ||
1256 | be supported otherwise. If Unix extensions are not | ||
1257 | negotiated this has no effect since mandatory locks | ||
1258 | would be used (mandatory locks is all that those | ||
1259 | those servers support) */ | ||
1260 | vol->mand_lock = 1; | ||
1263 | } else if (strnicmp(data, "setuids", 7) == 0) { | 1261 | } else if (strnicmp(data, "setuids", 7) == 0) { |
1264 | vol->setuids = 1; | 1262 | vol->setuids = 1; |
1265 | } else if (strnicmp(data, "nosetuids", 9) == 0) { | 1263 | } else if (strnicmp(data, "nosetuids", 9) == 0) { |
@@ -1417,6 +1415,143 @@ cifs_put_tcp_session(struct TCP_Server_Info *server) | |||
1417 | force_sig(SIGKILL, task); | 1415 | force_sig(SIGKILL, task); |
1418 | } | 1416 | } |
1419 | 1417 | ||
1418 | static struct TCP_Server_Info * | ||
1419 | cifs_get_tcp_session(struct smb_vol *volume_info) | ||
1420 | { | ||
1421 | struct TCP_Server_Info *tcp_ses = NULL; | ||
1422 | struct sockaddr addr; | ||
1423 | struct sockaddr_in *sin_server = (struct sockaddr_in *) &addr; | ||
1424 | struct sockaddr_in6 *sin_server6 = (struct sockaddr_in6 *) &addr; | ||
1425 | int rc; | ||
1426 | |||
1427 | memset(&addr, 0, sizeof(struct sockaddr)); | ||
1428 | |||
1429 | if (volume_info->UNCip && volume_info->UNC) { | ||
1430 | rc = cifs_inet_pton(AF_INET, volume_info->UNCip, | ||
1431 | &sin_server->sin_addr.s_addr); | ||
1432 | |||
1433 | if (rc <= 0) { | ||
1434 | /* not ipv4 address, try ipv6 */ | ||
1435 | rc = cifs_inet_pton(AF_INET6, volume_info->UNCip, | ||
1436 | &sin_server6->sin6_addr.in6_u); | ||
1437 | if (rc > 0) | ||
1438 | addr.sa_family = AF_INET6; | ||
1439 | } else { | ||
1440 | addr.sa_family = AF_INET; | ||
1441 | } | ||
1442 | |||
1443 | if (rc <= 0) { | ||
1444 | /* we failed translating address */ | ||
1445 | rc = -EINVAL; | ||
1446 | goto out_err; | ||
1447 | } | ||
1448 | |||
1449 | cFYI(1, ("UNC: %s ip: %s", volume_info->UNC, | ||
1450 | volume_info->UNCip)); | ||
1451 | } else if (volume_info->UNCip) { | ||
1452 | /* BB using ip addr as tcp_ses name to connect to the | ||
1453 | DFS root below */ | ||
1454 | cERROR(1, ("Connecting to DFS root not implemented yet")); | ||
1455 | rc = -EINVAL; | ||
1456 | goto out_err; | ||
1457 | } else /* which tcp_sess DFS root would we conect to */ { | ||
1458 | cERROR(1, | ||
1459 | ("CIFS mount error: No UNC path (e.g. -o " | ||
1460 | "unc=//192.168.1.100/public) specified")); | ||
1461 | rc = -EINVAL; | ||
1462 | goto out_err; | ||
1463 | } | ||
1464 | |||
1465 | /* see if we already have a matching tcp_ses */ | ||
1466 | tcp_ses = cifs_find_tcp_session(&addr); | ||
1467 | if (tcp_ses) | ||
1468 | return tcp_ses; | ||
1469 | |||
1470 | tcp_ses = kzalloc(sizeof(struct TCP_Server_Info), GFP_KERNEL); | ||
1471 | if (!tcp_ses) { | ||
1472 | rc = -ENOMEM; | ||
1473 | goto out_err; | ||
1474 | } | ||
1475 | |||
1476 | tcp_ses->hostname = extract_hostname(volume_info->UNC); | ||
1477 | if (IS_ERR(tcp_ses->hostname)) { | ||
1478 | rc = PTR_ERR(tcp_ses->hostname); | ||
1479 | goto out_err; | ||
1480 | } | ||
1481 | |||
1482 | tcp_ses->noblocksnd = volume_info->noblocksnd; | ||
1483 | tcp_ses->noautotune = volume_info->noautotune; | ||
1484 | atomic_set(&tcp_ses->inFlight, 0); | ||
1485 | init_waitqueue_head(&tcp_ses->response_q); | ||
1486 | init_waitqueue_head(&tcp_ses->request_q); | ||
1487 | INIT_LIST_HEAD(&tcp_ses->pending_mid_q); | ||
1488 | mutex_init(&tcp_ses->srv_mutex); | ||
1489 | memcpy(tcp_ses->workstation_RFC1001_name, | ||
1490 | volume_info->source_rfc1001_name, RFC1001_NAME_LEN_WITH_NULL); | ||
1491 | memcpy(tcp_ses->server_RFC1001_name, | ||
1492 | volume_info->target_rfc1001_name, RFC1001_NAME_LEN_WITH_NULL); | ||
1493 | tcp_ses->sequence_number = 0; | ||
1494 | INIT_LIST_HEAD(&tcp_ses->tcp_ses_list); | ||
1495 | INIT_LIST_HEAD(&tcp_ses->smb_ses_list); | ||
1496 | |||
1497 | /* | ||
1498 | * at this point we are the only ones with the pointer | ||
1499 | * to the struct since the kernel thread not created yet | ||
1500 | * no need to spinlock this init of tcpStatus or srv_count | ||
1501 | */ | ||
1502 | tcp_ses->tcpStatus = CifsNew; | ||
1503 | ++tcp_ses->srv_count; | ||
1504 | |||
1505 | if (addr.sa_family == AF_INET6) { | ||
1506 | cFYI(1, ("attempting ipv6 connect")); | ||
1507 | /* BB should we allow ipv6 on port 139? */ | ||
1508 | /* other OS never observed in Wild doing 139 with v6 */ | ||
1509 | memcpy(&tcp_ses->addr.sockAddr6, sin_server6, | ||
1510 | sizeof(struct sockaddr_in6)); | ||
1511 | sin_server6->sin6_port = htons(volume_info->port); | ||
1512 | rc = ipv6_connect(tcp_ses); | ||
1513 | } else { | ||
1514 | memcpy(&tcp_ses->addr.sockAddr, sin_server, | ||
1515 | sizeof(struct sockaddr_in)); | ||
1516 | sin_server->sin_port = htons(volume_info->port); | ||
1517 | rc = ipv4_connect(tcp_ses); | ||
1518 | } | ||
1519 | if (rc < 0) { | ||
1520 | cERROR(1, ("Error connecting to socket. Aborting operation")); | ||
1521 | goto out_err; | ||
1522 | } | ||
1523 | |||
1524 | /* | ||
1525 | * since we're in a cifs function already, we know that | ||
1526 | * this will succeed. No need for try_module_get(). | ||
1527 | */ | ||
1528 | __module_get(THIS_MODULE); | ||
1529 | tcp_ses->tsk = kthread_run((void *)(void *)cifs_demultiplex_thread, | ||
1530 | tcp_ses, "cifsd"); | ||
1531 | if (IS_ERR(tcp_ses->tsk)) { | ||
1532 | rc = PTR_ERR(tcp_ses->tsk); | ||
1533 | cERROR(1, ("error %d create cifsd thread", rc)); | ||
1534 | module_put(THIS_MODULE); | ||
1535 | goto out_err; | ||
1536 | } | ||
1537 | |||
1538 | /* thread spawned, put it on the list */ | ||
1539 | write_lock(&cifs_tcp_ses_lock); | ||
1540 | list_add(&tcp_ses->tcp_ses_list, &cifs_tcp_ses_list); | ||
1541 | write_unlock(&cifs_tcp_ses_lock); | ||
1542 | |||
1543 | return tcp_ses; | ||
1544 | |||
1545 | out_err: | ||
1546 | if (tcp_ses) { | ||
1547 | kfree(tcp_ses->hostname); | ||
1548 | if (tcp_ses->ssocket) | ||
1549 | sock_release(tcp_ses->ssocket); | ||
1550 | kfree(tcp_ses); | ||
1551 | } | ||
1552 | return ERR_PTR(rc); | ||
1553 | } | ||
1554 | |||
1420 | static struct cifsSesInfo * | 1555 | static struct cifsSesInfo * |
1421 | cifs_find_smb_ses(struct TCP_Server_Info *server, char *username) | 1556 | cifs_find_smb_ses(struct TCP_Server_Info *server, char *username) |
1422 | { | 1557 | { |
@@ -1593,93 +1728,96 @@ static void rfc1002mangle(char *target, char *source, unsigned int length) | |||
1593 | 1728 | ||
1594 | 1729 | ||
1595 | static int | 1730 | static int |
1596 | ipv4_connect(struct sockaddr_in *psin_server, struct socket **csocket, | 1731 | ipv4_connect(struct TCP_Server_Info *server) |
1597 | char *netbios_name, char *target_name, | ||
1598 | bool noblocksnd, bool noautotune) | ||
1599 | { | 1732 | { |
1600 | int rc = 0; | 1733 | int rc = 0; |
1601 | int connected = 0; | 1734 | bool connected = false; |
1602 | __be16 orig_port = 0; | 1735 | __be16 orig_port = 0; |
1736 | struct socket *socket = server->ssocket; | ||
1603 | 1737 | ||
1604 | if (*csocket == NULL) { | 1738 | if (socket == NULL) { |
1605 | rc = sock_create_kern(PF_INET, SOCK_STREAM, | 1739 | rc = sock_create_kern(PF_INET, SOCK_STREAM, |
1606 | IPPROTO_TCP, csocket); | 1740 | IPPROTO_TCP, &socket); |
1607 | if (rc < 0) { | 1741 | if (rc < 0) { |
1608 | cERROR(1, ("Error %d creating socket", rc)); | 1742 | cERROR(1, ("Error %d creating socket", rc)); |
1609 | *csocket = NULL; | ||
1610 | return rc; | 1743 | return rc; |
1611 | } else { | ||
1612 | /* BB other socket options to set KEEPALIVE, NODELAY? */ | ||
1613 | cFYI(1, ("Socket created")); | ||
1614 | (*csocket)->sk->sk_allocation = GFP_NOFS; | ||
1615 | cifs_reclassify_socket4(*csocket); | ||
1616 | } | 1744 | } |
1745 | |||
1746 | /* BB other socket options to set KEEPALIVE, NODELAY? */ | ||
1747 | cFYI(1, ("Socket created")); | ||
1748 | server->ssocket = socket; | ||
1749 | socket->sk->sk_allocation = GFP_NOFS; | ||
1750 | cifs_reclassify_socket4(socket); | ||
1617 | } | 1751 | } |
1618 | 1752 | ||
1619 | psin_server->sin_family = AF_INET; | 1753 | /* user overrode default port */ |
1620 | if (psin_server->sin_port) { /* user overrode default port */ | 1754 | if (server->addr.sockAddr.sin_port) { |
1621 | rc = (*csocket)->ops->connect(*csocket, | 1755 | rc = socket->ops->connect(socket, (struct sockaddr *) |
1622 | (struct sockaddr *) psin_server, | 1756 | &server->addr.sockAddr, |
1623 | sizeof(struct sockaddr_in), 0); | 1757 | sizeof(struct sockaddr_in), 0); |
1624 | if (rc >= 0) | 1758 | if (rc >= 0) |
1625 | connected = 1; | 1759 | connected = true; |
1626 | } | 1760 | } |
1627 | 1761 | ||
1628 | if (!connected) { | 1762 | if (!connected) { |
1629 | /* save original port so we can retry user specified port | 1763 | /* save original port so we can retry user specified port |
1630 | later if fall back ports fail this time */ | 1764 | later if fall back ports fail this time */ |
1631 | orig_port = psin_server->sin_port; | 1765 | orig_port = server->addr.sockAddr.sin_port; |
1632 | 1766 | ||
1633 | /* do not retry on the same port we just failed on */ | 1767 | /* do not retry on the same port we just failed on */ |
1634 | if (psin_server->sin_port != htons(CIFS_PORT)) { | 1768 | if (server->addr.sockAddr.sin_port != htons(CIFS_PORT)) { |
1635 | psin_server->sin_port = htons(CIFS_PORT); | 1769 | server->addr.sockAddr.sin_port = htons(CIFS_PORT); |
1636 | 1770 | rc = socket->ops->connect(socket, | |
1637 | rc = (*csocket)->ops->connect(*csocket, | 1771 | (struct sockaddr *) |
1638 | (struct sockaddr *) psin_server, | 1772 | &server->addr.sockAddr, |
1639 | sizeof(struct sockaddr_in), 0); | 1773 | sizeof(struct sockaddr_in), 0); |
1640 | if (rc >= 0) | 1774 | if (rc >= 0) |
1641 | connected = 1; | 1775 | connected = true; |
1642 | } | 1776 | } |
1643 | } | 1777 | } |
1644 | if (!connected) { | 1778 | if (!connected) { |
1645 | psin_server->sin_port = htons(RFC1001_PORT); | 1779 | server->addr.sockAddr.sin_port = htons(RFC1001_PORT); |
1646 | rc = (*csocket)->ops->connect(*csocket, (struct sockaddr *) | 1780 | rc = socket->ops->connect(socket, (struct sockaddr *) |
1647 | psin_server, | 1781 | &server->addr.sockAddr, |
1648 | sizeof(struct sockaddr_in), 0); | 1782 | sizeof(struct sockaddr_in), 0); |
1649 | if (rc >= 0) | 1783 | if (rc >= 0) |
1650 | connected = 1; | 1784 | connected = true; |
1651 | } | 1785 | } |
1652 | 1786 | ||
1653 | /* give up here - unless we want to retry on different | 1787 | /* give up here - unless we want to retry on different |
1654 | protocol families some day */ | 1788 | protocol families some day */ |
1655 | if (!connected) { | 1789 | if (!connected) { |
1656 | if (orig_port) | 1790 | if (orig_port) |
1657 | psin_server->sin_port = orig_port; | 1791 | server->addr.sockAddr.sin_port = orig_port; |
1658 | cFYI(1, ("Error %d connecting to server via ipv4", rc)); | 1792 | cFYI(1, ("Error %d connecting to server via ipv4", rc)); |
1659 | sock_release(*csocket); | 1793 | sock_release(socket); |
1660 | *csocket = NULL; | 1794 | server->ssocket = NULL; |
1661 | return rc; | 1795 | return rc; |
1662 | } | 1796 | } |
1663 | /* Eventually check for other socket options to change from | 1797 | |
1664 | the default. sock_setsockopt not used because it expects | 1798 | |
1665 | user space buffer */ | 1799 | /* |
1666 | cFYI(1, ("sndbuf %d rcvbuf %d rcvtimeo 0x%lx", | 1800 | * Eventually check for other socket options to change from |
1667 | (*csocket)->sk->sk_sndbuf, | 1801 | * the default. sock_setsockopt not used because it expects |
1668 | (*csocket)->sk->sk_rcvbuf, (*csocket)->sk->sk_rcvtimeo)); | 1802 | * user space buffer |
1669 | (*csocket)->sk->sk_rcvtimeo = 7 * HZ; | 1803 | */ |
1670 | if (!noblocksnd) | 1804 | socket->sk->sk_rcvtimeo = 7 * HZ; |
1671 | (*csocket)->sk->sk_sndtimeo = 3 * HZ; | 1805 | socket->sk->sk_sndtimeo = 3 * HZ; |
1672 | 1806 | ||
1673 | /* make the bufsizes depend on wsize/rsize and max requests */ | 1807 | /* make the bufsizes depend on wsize/rsize and max requests */ |
1674 | if (noautotune) { | 1808 | if (server->noautotune) { |
1675 | if ((*csocket)->sk->sk_sndbuf < (200 * 1024)) | 1809 | if (socket->sk->sk_sndbuf < (200 * 1024)) |
1676 | (*csocket)->sk->sk_sndbuf = 200 * 1024; | 1810 | socket->sk->sk_sndbuf = 200 * 1024; |
1677 | if ((*csocket)->sk->sk_rcvbuf < (140 * 1024)) | 1811 | if (socket->sk->sk_rcvbuf < (140 * 1024)) |
1678 | (*csocket)->sk->sk_rcvbuf = 140 * 1024; | 1812 | socket->sk->sk_rcvbuf = 140 * 1024; |
1679 | } | 1813 | } |
1680 | 1814 | ||
1815 | cFYI(1, ("sndbuf %d rcvbuf %d rcvtimeo 0x%lx", | ||
1816 | socket->sk->sk_sndbuf, | ||
1817 | socket->sk->sk_rcvbuf, socket->sk->sk_rcvtimeo)); | ||
1818 | |||
1681 | /* send RFC1001 sessinit */ | 1819 | /* send RFC1001 sessinit */ |
1682 | if (psin_server->sin_port == htons(RFC1001_PORT)) { | 1820 | if (server->addr.sockAddr.sin_port == htons(RFC1001_PORT)) { |
1683 | /* some servers require RFC1001 sessinit before sending | 1821 | /* some servers require RFC1001 sessinit before sending |
1684 | negprot - BB check reconnection in case where second | 1822 | negprot - BB check reconnection in case where second |
1685 | sessinit is sent but no second negprot */ | 1823 | sessinit is sent but no second negprot */ |
@@ -1689,31 +1827,42 @@ ipv4_connect(struct sockaddr_in *psin_server, struct socket **csocket, | |||
1689 | GFP_KERNEL); | 1827 | GFP_KERNEL); |
1690 | if (ses_init_buf) { | 1828 | if (ses_init_buf) { |
1691 | ses_init_buf->trailer.session_req.called_len = 32; | 1829 | ses_init_buf->trailer.session_req.called_len = 32; |
1692 | if (target_name && (target_name[0] != 0)) { | 1830 | if (server->server_RFC1001_name && |
1693 | rfc1002mangle(ses_init_buf->trailer.session_req.called_name, | 1831 | server->server_RFC1001_name[0] != 0) |
1694 | target_name, 16); | 1832 | rfc1002mangle(ses_init_buf->trailer. |
1695 | } else { | 1833 | session_req.called_name, |
1696 | rfc1002mangle(ses_init_buf->trailer.session_req.called_name, | 1834 | server->server_RFC1001_name, |
1697 | DEFAULT_CIFS_CALLED_NAME, 16); | 1835 | RFC1001_NAME_LEN_WITH_NULL); |
1698 | } | 1836 | else |
1837 | rfc1002mangle(ses_init_buf->trailer. | ||
1838 | session_req.called_name, | ||
1839 | DEFAULT_CIFS_CALLED_NAME, | ||
1840 | RFC1001_NAME_LEN_WITH_NULL); | ||
1699 | 1841 | ||
1700 | ses_init_buf->trailer.session_req.calling_len = 32; | 1842 | ses_init_buf->trailer.session_req.calling_len = 32; |
1843 | |||
1701 | /* calling name ends in null (byte 16) from old smb | 1844 | /* calling name ends in null (byte 16) from old smb |
1702 | convention. */ | 1845 | convention. */ |
1703 | if (netbios_name && (netbios_name[0] != 0)) { | 1846 | if (server->workstation_RFC1001_name && |
1704 | rfc1002mangle(ses_init_buf->trailer.session_req.calling_name, | 1847 | server->workstation_RFC1001_name[0] != 0) |
1705 | netbios_name, 16); | 1848 | rfc1002mangle(ses_init_buf->trailer. |
1706 | } else { | 1849 | session_req.calling_name, |
1707 | rfc1002mangle(ses_init_buf->trailer.session_req.calling_name, | 1850 | server->workstation_RFC1001_name, |
1708 | "LINUX_CIFS_CLNT", 16); | 1851 | RFC1001_NAME_LEN_WITH_NULL); |
1709 | } | 1852 | else |
1853 | rfc1002mangle(ses_init_buf->trailer. | ||
1854 | session_req.calling_name, | ||
1855 | "LINUX_CIFS_CLNT", | ||
1856 | RFC1001_NAME_LEN_WITH_NULL); | ||
1857 | |||
1710 | ses_init_buf->trailer.session_req.scope1 = 0; | 1858 | ses_init_buf->trailer.session_req.scope1 = 0; |
1711 | ses_init_buf->trailer.session_req.scope2 = 0; | 1859 | ses_init_buf->trailer.session_req.scope2 = 0; |
1712 | smb_buf = (struct smb_hdr *)ses_init_buf; | 1860 | smb_buf = (struct smb_hdr *)ses_init_buf; |
1713 | /* sizeof RFC1002_SESSION_REQUEST with no scope */ | 1861 | /* sizeof RFC1002_SESSION_REQUEST with no scope */ |
1714 | smb_buf->smb_buf_length = 0x81000044; | 1862 | smb_buf->smb_buf_length = 0x81000044; |
1715 | rc = smb_send(*csocket, smb_buf, 0x44, | 1863 | rc = smb_send(socket, smb_buf, 0x44, |
1716 | (struct sockaddr *)psin_server, noblocksnd); | 1864 | (struct sockaddr *) &server->addr.sockAddr, |
1865 | server->noblocksnd); | ||
1717 | kfree(ses_init_buf); | 1866 | kfree(ses_init_buf); |
1718 | msleep(1); /* RFC1001 layer in at least one server | 1867 | msleep(1); /* RFC1001 layer in at least one server |
1719 | requires very short break before negprot | 1868 | requires very short break before negprot |
@@ -1733,79 +1882,81 @@ ipv4_connect(struct sockaddr_in *psin_server, struct socket **csocket, | |||
1733 | } | 1882 | } |
1734 | 1883 | ||
1735 | static int | 1884 | static int |
1736 | ipv6_connect(struct sockaddr_in6 *psin_server, struct socket **csocket, | 1885 | ipv6_connect(struct TCP_Server_Info *server) |
1737 | bool noblocksnd) | ||
1738 | { | 1886 | { |
1739 | int rc = 0; | 1887 | int rc = 0; |
1740 | int connected = 0; | 1888 | bool connected = false; |
1741 | __be16 orig_port = 0; | 1889 | __be16 orig_port = 0; |
1890 | struct socket *socket = server->ssocket; | ||
1742 | 1891 | ||
1743 | if (*csocket == NULL) { | 1892 | if (socket == NULL) { |
1744 | rc = sock_create_kern(PF_INET6, SOCK_STREAM, | 1893 | rc = sock_create_kern(PF_INET6, SOCK_STREAM, |
1745 | IPPROTO_TCP, csocket); | 1894 | IPPROTO_TCP, &socket); |
1746 | if (rc < 0) { | 1895 | if (rc < 0) { |
1747 | cERROR(1, ("Error %d creating ipv6 socket", rc)); | 1896 | cERROR(1, ("Error %d creating ipv6 socket", rc)); |
1748 | *csocket = NULL; | 1897 | socket = NULL; |
1749 | return rc; | 1898 | return rc; |
1750 | } else { | ||
1751 | /* BB other socket options to set KEEPALIVE, NODELAY? */ | ||
1752 | cFYI(1, ("ipv6 Socket created")); | ||
1753 | (*csocket)->sk->sk_allocation = GFP_NOFS; | ||
1754 | cifs_reclassify_socket6(*csocket); | ||
1755 | } | 1899 | } |
1756 | } | ||
1757 | 1900 | ||
1758 | psin_server->sin6_family = AF_INET6; | 1901 | /* BB other socket options to set KEEPALIVE, NODELAY? */ |
1902 | cFYI(1, ("ipv6 Socket created")); | ||
1903 | server->ssocket = socket; | ||
1904 | socket->sk->sk_allocation = GFP_NOFS; | ||
1905 | cifs_reclassify_socket6(socket); | ||
1906 | } | ||
1759 | 1907 | ||
1760 | if (psin_server->sin6_port) { /* user overrode default port */ | 1908 | /* user overrode default port */ |
1761 | rc = (*csocket)->ops->connect(*csocket, | 1909 | if (server->addr.sockAddr6.sin6_port) { |
1762 | (struct sockaddr *) psin_server, | 1910 | rc = socket->ops->connect(socket, |
1911 | (struct sockaddr *) &server->addr.sockAddr6, | ||
1763 | sizeof(struct sockaddr_in6), 0); | 1912 | sizeof(struct sockaddr_in6), 0); |
1764 | if (rc >= 0) | 1913 | if (rc >= 0) |
1765 | connected = 1; | 1914 | connected = true; |
1766 | } | 1915 | } |
1767 | 1916 | ||
1768 | if (!connected) { | 1917 | if (!connected) { |
1769 | /* save original port so we can retry user specified port | 1918 | /* save original port so we can retry user specified port |
1770 | later if fall back ports fail this time */ | 1919 | later if fall back ports fail this time */ |
1771 | 1920 | ||
1772 | orig_port = psin_server->sin6_port; | 1921 | orig_port = server->addr.sockAddr6.sin6_port; |
1773 | /* do not retry on the same port we just failed on */ | 1922 | /* do not retry on the same port we just failed on */ |
1774 | if (psin_server->sin6_port != htons(CIFS_PORT)) { | 1923 | if (server->addr.sockAddr6.sin6_port != htons(CIFS_PORT)) { |
1775 | psin_server->sin6_port = htons(CIFS_PORT); | 1924 | server->addr.sockAddr6.sin6_port = htons(CIFS_PORT); |
1776 | 1925 | rc = socket->ops->connect(socket, (struct sockaddr *) | |
1777 | rc = (*csocket)->ops->connect(*csocket, | 1926 | &server->addr.sockAddr6, |
1778 | (struct sockaddr *) psin_server, | ||
1779 | sizeof(struct sockaddr_in6), 0); | 1927 | sizeof(struct sockaddr_in6), 0); |
1780 | if (rc >= 0) | 1928 | if (rc >= 0) |
1781 | connected = 1; | 1929 | connected = true; |
1782 | } | 1930 | } |
1783 | } | 1931 | } |
1784 | if (!connected) { | 1932 | if (!connected) { |
1785 | psin_server->sin6_port = htons(RFC1001_PORT); | 1933 | server->addr.sockAddr6.sin6_port = htons(RFC1001_PORT); |
1786 | rc = (*csocket)->ops->connect(*csocket, (struct sockaddr *) | 1934 | rc = socket->ops->connect(socket, (struct sockaddr *) |
1787 | psin_server, sizeof(struct sockaddr_in6), 0); | 1935 | &server->addr.sockAddr6, |
1936 | sizeof(struct sockaddr_in6), 0); | ||
1788 | if (rc >= 0) | 1937 | if (rc >= 0) |
1789 | connected = 1; | 1938 | connected = true; |
1790 | } | 1939 | } |
1791 | 1940 | ||
1792 | /* give up here - unless we want to retry on different | 1941 | /* give up here - unless we want to retry on different |
1793 | protocol families some day */ | 1942 | protocol families some day */ |
1794 | if (!connected) { | 1943 | if (!connected) { |
1795 | if (orig_port) | 1944 | if (orig_port) |
1796 | psin_server->sin6_port = orig_port; | 1945 | server->addr.sockAddr6.sin6_port = orig_port; |
1797 | cFYI(1, ("Error %d connecting to server via ipv6", rc)); | 1946 | cFYI(1, ("Error %d connecting to server via ipv6", rc)); |
1798 | sock_release(*csocket); | 1947 | sock_release(socket); |
1799 | *csocket = NULL; | 1948 | server->ssocket = NULL; |
1800 | return rc; | 1949 | return rc; |
1801 | } | 1950 | } |
1802 | /* Eventually check for other socket options to change from | ||
1803 | the default. sock_setsockopt not used because it expects | ||
1804 | user space buffer */ | ||
1805 | (*csocket)->sk->sk_rcvtimeo = 7 * HZ; | ||
1806 | if (!noblocksnd) | ||
1807 | (*csocket)->sk->sk_sndtimeo = 3 * HZ; | ||
1808 | 1951 | ||
1952 | /* | ||
1953 | * Eventually check for other socket options to change from | ||
1954 | * the default. sock_setsockopt not used because it expects | ||
1955 | * user space buffer | ||
1956 | */ | ||
1957 | socket->sk->sk_rcvtimeo = 7 * HZ; | ||
1958 | socket->sk->sk_sndtimeo = 3 * HZ; | ||
1959 | server->ssocket = socket; | ||
1809 | 1960 | ||
1810 | return rc; | 1961 | return rc; |
1811 | } | 1962 | } |
@@ -2011,6 +2162,8 @@ static void setup_cifs_sb(struct smb_vol *pvolume_info, | |||
2011 | cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_UNX_EMUL; | 2162 | cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_UNX_EMUL; |
2012 | if (pvolume_info->nobrl) | 2163 | if (pvolume_info->nobrl) |
2013 | cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_BRL; | 2164 | cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_BRL; |
2165 | if (pvolume_info->mand_lock) | ||
2166 | cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NOPOSIXBRL; | ||
2014 | if (pvolume_info->cifs_acl) | 2167 | if (pvolume_info->cifs_acl) |
2015 | cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_CIFS_ACL; | 2168 | cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_CIFS_ACL; |
2016 | if (pvolume_info->override_uid) | 2169 | if (pvolume_info->override_uid) |
@@ -2035,32 +2188,30 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb, | |||
2035 | { | 2188 | { |
2036 | int rc = 0; | 2189 | int rc = 0; |
2037 | int xid; | 2190 | int xid; |
2038 | struct socket *csocket = NULL; | 2191 | struct smb_vol *volume_info; |
2039 | struct sockaddr addr; | ||
2040 | struct sockaddr_in *sin_server = (struct sockaddr_in *) &addr; | ||
2041 | struct sockaddr_in6 *sin_server6 = (struct sockaddr_in6 *) &addr; | ||
2042 | struct smb_vol volume_info; | ||
2043 | struct cifsSesInfo *pSesInfo = NULL; | 2192 | struct cifsSesInfo *pSesInfo = NULL; |
2044 | struct cifsTconInfo *tcon = NULL; | 2193 | struct cifsTconInfo *tcon = NULL; |
2045 | struct TCP_Server_Info *srvTcp = NULL; | 2194 | struct TCP_Server_Info *srvTcp = NULL; |
2046 | 2195 | ||
2047 | xid = GetXid(); | 2196 | xid = GetXid(); |
2048 | 2197 | ||
2049 | /* cFYI(1, ("Entering cifs_mount. Xid: %d with: %s", xid, mount_data)); */ | 2198 | volume_info = kzalloc(sizeof(struct smb_vol), GFP_KERNEL); |
2199 | if (!volume_info) { | ||
2200 | rc = -ENOMEM; | ||
2201 | goto out; | ||
2202 | } | ||
2050 | 2203 | ||
2051 | memset(&addr, 0, sizeof(struct sockaddr)); | 2204 | if (cifs_parse_mount_options(mount_data, devname, volume_info)) { |
2052 | memset(&volume_info, 0, sizeof(struct smb_vol)); | ||
2053 | if (cifs_parse_mount_options(mount_data, devname, &volume_info)) { | ||
2054 | rc = -EINVAL; | 2205 | rc = -EINVAL; |
2055 | goto out; | 2206 | goto out; |
2056 | } | 2207 | } |
2057 | 2208 | ||
2058 | if (volume_info.nullauth) { | 2209 | if (volume_info->nullauth) { |
2059 | cFYI(1, ("null user")); | 2210 | cFYI(1, ("null user")); |
2060 | volume_info.username = ""; | 2211 | volume_info->username = ""; |
2061 | } else if (volume_info.username) { | 2212 | } else if (volume_info->username) { |
2062 | /* BB fixme parse for domain name here */ | 2213 | /* BB fixme parse for domain name here */ |
2063 | cFYI(1, ("Username: %s", volume_info.username)); | 2214 | cFYI(1, ("Username: %s", volume_info->username)); |
2064 | } else { | 2215 | } else { |
2065 | cifserror("No username specified"); | 2216 | cifserror("No username specified"); |
2066 | /* In userspace mount helper we can get user name from alternate | 2217 | /* In userspace mount helper we can get user name from alternate |
@@ -2069,139 +2220,29 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb, | |||
2069 | goto out; | 2220 | goto out; |
2070 | } | 2221 | } |
2071 | 2222 | ||
2072 | if (volume_info.UNCip && volume_info.UNC) { | ||
2073 | rc = cifs_inet_pton(AF_INET, volume_info.UNCip, | ||
2074 | &sin_server->sin_addr.s_addr); | ||
2075 | |||
2076 | if (rc <= 0) { | ||
2077 | /* not ipv4 address, try ipv6 */ | ||
2078 | rc = cifs_inet_pton(AF_INET6, volume_info.UNCip, | ||
2079 | &sin_server6->sin6_addr.in6_u); | ||
2080 | if (rc > 0) | ||
2081 | addr.sa_family = AF_INET6; | ||
2082 | } else { | ||
2083 | addr.sa_family = AF_INET; | ||
2084 | } | ||
2085 | |||
2086 | if (rc <= 0) { | ||
2087 | /* we failed translating address */ | ||
2088 | rc = -EINVAL; | ||
2089 | goto out; | ||
2090 | } | ||
2091 | |||
2092 | cFYI(1, ("UNC: %s ip: %s", volume_info.UNC, volume_info.UNCip)); | ||
2093 | /* success */ | ||
2094 | rc = 0; | ||
2095 | } else if (volume_info.UNCip) { | ||
2096 | /* BB using ip addr as server name to connect to the | ||
2097 | DFS root below */ | ||
2098 | cERROR(1, ("Connecting to DFS root not implemented yet")); | ||
2099 | rc = -EINVAL; | ||
2100 | goto out; | ||
2101 | } else /* which servers DFS root would we conect to */ { | ||
2102 | cERROR(1, | ||
2103 | ("CIFS mount error: No UNC path (e.g. -o " | ||
2104 | "unc=//192.168.1.100/public) specified")); | ||
2105 | rc = -EINVAL; | ||
2106 | goto out; | ||
2107 | } | ||
2108 | 2223 | ||
2109 | /* this is needed for ASCII cp to Unicode converts */ | 2224 | /* this is needed for ASCII cp to Unicode converts */ |
2110 | if (volume_info.iocharset == NULL) { | 2225 | if (volume_info->iocharset == NULL) { |
2111 | cifs_sb->local_nls = load_nls_default(); | 2226 | cifs_sb->local_nls = load_nls_default(); |
2112 | /* load_nls_default can not return null */ | 2227 | /* load_nls_default can not return null */ |
2113 | } else { | 2228 | } else { |
2114 | cifs_sb->local_nls = load_nls(volume_info.iocharset); | 2229 | cifs_sb->local_nls = load_nls(volume_info->iocharset); |
2115 | if (cifs_sb->local_nls == NULL) { | 2230 | if (cifs_sb->local_nls == NULL) { |
2116 | cERROR(1, ("CIFS mount error: iocharset %s not found", | 2231 | cERROR(1, ("CIFS mount error: iocharset %s not found", |
2117 | volume_info.iocharset)); | 2232 | volume_info->iocharset)); |
2118 | rc = -ELIBACC; | 2233 | rc = -ELIBACC; |
2119 | goto out; | 2234 | goto out; |
2120 | } | 2235 | } |
2121 | } | 2236 | } |
2122 | 2237 | ||
2123 | srvTcp = cifs_find_tcp_session(&addr); | 2238 | /* get a reference to a tcp session */ |
2124 | if (!srvTcp) { /* create socket */ | 2239 | srvTcp = cifs_get_tcp_session(volume_info); |
2125 | if (addr.sa_family == AF_INET6) { | 2240 | if (IS_ERR(srvTcp)) { |
2126 | cFYI(1, ("attempting ipv6 connect")); | 2241 | rc = PTR_ERR(srvTcp); |
2127 | /* BB should we allow ipv6 on port 139? */ | 2242 | goto out; |
2128 | /* other OS never observed in Wild doing 139 with v6 */ | ||
2129 | sin_server6->sin6_port = htons(volume_info.port); | ||
2130 | rc = ipv6_connect(sin_server6, &csocket, | ||
2131 | volume_info.noblocksnd); | ||
2132 | } else { | ||
2133 | sin_server->sin_port = htons(volume_info.port); | ||
2134 | rc = ipv4_connect(sin_server, &csocket, | ||
2135 | volume_info.source_rfc1001_name, | ||
2136 | volume_info.target_rfc1001_name, | ||
2137 | volume_info.noblocksnd, | ||
2138 | volume_info.noautotune); | ||
2139 | } | ||
2140 | if (rc < 0) { | ||
2141 | cERROR(1, ("Error connecting to socket. " | ||
2142 | "Aborting operation")); | ||
2143 | if (csocket != NULL) | ||
2144 | sock_release(csocket); | ||
2145 | goto out; | ||
2146 | } | ||
2147 | |||
2148 | srvTcp = kzalloc(sizeof(struct TCP_Server_Info), GFP_KERNEL); | ||
2149 | if (!srvTcp) { | ||
2150 | rc = -ENOMEM; | ||
2151 | sock_release(csocket); | ||
2152 | goto out; | ||
2153 | } else { | ||
2154 | srvTcp->noblocksnd = volume_info.noblocksnd; | ||
2155 | srvTcp->noautotune = volume_info.noautotune; | ||
2156 | if (addr.sa_family == AF_INET6) | ||
2157 | memcpy(&srvTcp->addr.sockAddr6, sin_server6, | ||
2158 | sizeof(struct sockaddr_in6)); | ||
2159 | else | ||
2160 | memcpy(&srvTcp->addr.sockAddr, sin_server, | ||
2161 | sizeof(struct sockaddr_in)); | ||
2162 | atomic_set(&srvTcp->inFlight, 0); | ||
2163 | /* BB Add code for ipv6 case too */ | ||
2164 | srvTcp->ssocket = csocket; | ||
2165 | srvTcp->hostname = extract_hostname(volume_info.UNC); | ||
2166 | if (IS_ERR(srvTcp->hostname)) { | ||
2167 | rc = PTR_ERR(srvTcp->hostname); | ||
2168 | sock_release(csocket); | ||
2169 | goto out; | ||
2170 | } | ||
2171 | init_waitqueue_head(&srvTcp->response_q); | ||
2172 | init_waitqueue_head(&srvTcp->request_q); | ||
2173 | INIT_LIST_HEAD(&srvTcp->pending_mid_q); | ||
2174 | /* at this point we are the only ones with the pointer | ||
2175 | to the struct since the kernel thread not created yet | ||
2176 | so no need to spinlock this init of tcpStatus */ | ||
2177 | srvTcp->tcpStatus = CifsNew; | ||
2178 | init_MUTEX(&srvTcp->tcpSem); | ||
2179 | srvTcp->tsk = kthread_run((void *)(void *)cifs_demultiplex_thread, srvTcp, "cifsd"); | ||
2180 | if (IS_ERR(srvTcp->tsk)) { | ||
2181 | rc = PTR_ERR(srvTcp->tsk); | ||
2182 | cERROR(1, ("error %d create cifsd thread", rc)); | ||
2183 | srvTcp->tsk = NULL; | ||
2184 | sock_release(csocket); | ||
2185 | kfree(srvTcp->hostname); | ||
2186 | goto out; | ||
2187 | } | ||
2188 | rc = 0; | ||
2189 | memcpy(srvTcp->workstation_RFC1001_name, | ||
2190 | volume_info.source_rfc1001_name, 16); | ||
2191 | memcpy(srvTcp->server_RFC1001_name, | ||
2192 | volume_info.target_rfc1001_name, 16); | ||
2193 | srvTcp->sequence_number = 0; | ||
2194 | INIT_LIST_HEAD(&srvTcp->tcp_ses_list); | ||
2195 | INIT_LIST_HEAD(&srvTcp->smb_ses_list); | ||
2196 | ++srvTcp->srv_count; | ||
2197 | write_lock(&cifs_tcp_ses_lock); | ||
2198 | list_add(&srvTcp->tcp_ses_list, | ||
2199 | &cifs_tcp_ses_list); | ||
2200 | write_unlock(&cifs_tcp_ses_lock); | ||
2201 | } | ||
2202 | } | 2243 | } |
2203 | 2244 | ||
2204 | pSesInfo = cifs_find_smb_ses(srvTcp, volume_info.username); | 2245 | pSesInfo = cifs_find_smb_ses(srvTcp, volume_info->username); |
2205 | if (pSesInfo) { | 2246 | if (pSesInfo) { |
2206 | cFYI(1, ("Existing smb sess found (status=%d)", | 2247 | cFYI(1, ("Existing smb sess found (status=%d)", |
2207 | pSesInfo->status)); | 2248 | pSesInfo->status)); |
@@ -2228,31 +2269,38 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb, | |||
2228 | 2269 | ||
2229 | /* new SMB session uses our srvTcp ref */ | 2270 | /* new SMB session uses our srvTcp ref */ |
2230 | pSesInfo->server = srvTcp; | 2271 | pSesInfo->server = srvTcp; |
2231 | sprintf(pSesInfo->serverName, "%u.%u.%u.%u", | 2272 | if (srvTcp->addr.sockAddr6.sin6_family == AF_INET6) |
2232 | NIPQUAD(sin_server->sin_addr.s_addr)); | 2273 | sprintf(pSesInfo->serverName, "%pI6", |
2274 | &srvTcp->addr.sockAddr6.sin6_addr); | ||
2275 | else | ||
2276 | sprintf(pSesInfo->serverName, "%pI4", | ||
2277 | &srvTcp->addr.sockAddr.sin_addr.s_addr); | ||
2233 | 2278 | ||
2234 | write_lock(&cifs_tcp_ses_lock); | 2279 | write_lock(&cifs_tcp_ses_lock); |
2235 | list_add(&pSesInfo->smb_ses_list, &srvTcp->smb_ses_list); | 2280 | list_add(&pSesInfo->smb_ses_list, &srvTcp->smb_ses_list); |
2236 | write_unlock(&cifs_tcp_ses_lock); | 2281 | write_unlock(&cifs_tcp_ses_lock); |
2237 | 2282 | ||
2238 | /* volume_info.password freed at unmount */ | 2283 | /* volume_info->password freed at unmount */ |
2239 | if (volume_info.password) { | 2284 | if (volume_info->password) { |
2240 | pSesInfo->password = volume_info.password; | 2285 | pSesInfo->password = kstrdup(volume_info->password, |
2241 | /* set to NULL to prevent freeing on exit */ | 2286 | GFP_KERNEL); |
2242 | volume_info.password = NULL; | 2287 | if (!pSesInfo->password) { |
2288 | rc = -ENOMEM; | ||
2289 | goto mount_fail_check; | ||
2290 | } | ||
2243 | } | 2291 | } |
2244 | if (volume_info.username) | 2292 | if (volume_info->username) |
2245 | strncpy(pSesInfo->userName, volume_info.username, | 2293 | strncpy(pSesInfo->userName, volume_info->username, |
2246 | MAX_USERNAME_SIZE); | 2294 | MAX_USERNAME_SIZE); |
2247 | if (volume_info.domainname) { | 2295 | if (volume_info->domainname) { |
2248 | int len = strlen(volume_info.domainname); | 2296 | int len = strlen(volume_info->domainname); |
2249 | pSesInfo->domainName = kmalloc(len + 1, GFP_KERNEL); | 2297 | pSesInfo->domainName = kmalloc(len + 1, GFP_KERNEL); |
2250 | if (pSesInfo->domainName) | 2298 | if (pSesInfo->domainName) |
2251 | strcpy(pSesInfo->domainName, | 2299 | strcpy(pSesInfo->domainName, |
2252 | volume_info.domainname); | 2300 | volume_info->domainname); |
2253 | } | 2301 | } |
2254 | pSesInfo->linux_uid = volume_info.linux_uid; | 2302 | pSesInfo->linux_uid = volume_info->linux_uid; |
2255 | pSesInfo->overrideSecFlg = volume_info.secFlg; | 2303 | pSesInfo->overrideSecFlg = volume_info->secFlg; |
2256 | down(&pSesInfo->sesSem); | 2304 | down(&pSesInfo->sesSem); |
2257 | 2305 | ||
2258 | /* BB FIXME need to pass vol->secFlgs BB */ | 2306 | /* BB FIXME need to pass vol->secFlgs BB */ |
@@ -2263,14 +2311,14 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb, | |||
2263 | 2311 | ||
2264 | /* search for existing tcon to this server share */ | 2312 | /* search for existing tcon to this server share */ |
2265 | if (!rc) { | 2313 | if (!rc) { |
2266 | setup_cifs_sb(&volume_info, cifs_sb); | 2314 | setup_cifs_sb(volume_info, cifs_sb); |
2267 | 2315 | ||
2268 | tcon = cifs_find_tcon(pSesInfo, volume_info.UNC); | 2316 | tcon = cifs_find_tcon(pSesInfo, volume_info->UNC); |
2269 | if (tcon) { | 2317 | if (tcon) { |
2270 | cFYI(1, ("Found match on UNC path")); | 2318 | cFYI(1, ("Found match on UNC path")); |
2271 | /* existing tcon already has a reference */ | 2319 | /* existing tcon already has a reference */ |
2272 | cifs_put_smb_ses(pSesInfo); | 2320 | cifs_put_smb_ses(pSesInfo); |
2273 | if (tcon->seal != volume_info.seal) | 2321 | if (tcon->seal != volume_info->seal) |
2274 | cERROR(1, ("transport encryption setting " | 2322 | cERROR(1, ("transport encryption setting " |
2275 | "conflicts with existing tid")); | 2323 | "conflicts with existing tid")); |
2276 | } else { | 2324 | } else { |
@@ -2279,11 +2327,20 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb, | |||
2279 | rc = -ENOMEM; | 2327 | rc = -ENOMEM; |
2280 | goto mount_fail_check; | 2328 | goto mount_fail_check; |
2281 | } | 2329 | } |
2330 | |||
2282 | tcon->ses = pSesInfo; | 2331 | tcon->ses = pSesInfo; |
2332 | if (volume_info->password) { | ||
2333 | tcon->password = kstrdup(volume_info->password, | ||
2334 | GFP_KERNEL); | ||
2335 | if (!tcon->password) { | ||
2336 | rc = -ENOMEM; | ||
2337 | goto mount_fail_check; | ||
2338 | } | ||
2339 | } | ||
2283 | 2340 | ||
2284 | /* check for null share name ie connect to dfs root */ | 2341 | /* check for null share name ie connect to dfs root */ |
2285 | if ((strchr(volume_info.UNC + 3, '\\') == NULL) | 2342 | if ((strchr(volume_info->UNC + 3, '\\') == NULL) |
2286 | && (strchr(volume_info.UNC + 3, '/') == NULL)) { | 2343 | && (strchr(volume_info->UNC + 3, '/') == NULL)) { |
2287 | /* rc = connect_to_dfs_path(...) */ | 2344 | /* rc = connect_to_dfs_path(...) */ |
2288 | cFYI(1, ("DFS root not supported")); | 2345 | cFYI(1, ("DFS root not supported")); |
2289 | rc = -ENODEV; | 2346 | rc = -ENODEV; |
@@ -2292,10 +2349,10 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb, | |||
2292 | /* BB Do we need to wrap sesSem around | 2349 | /* BB Do we need to wrap sesSem around |
2293 | * this TCon call and Unix SetFS as | 2350 | * this TCon call and Unix SetFS as |
2294 | * we do on SessSetup and reconnect? */ | 2351 | * we do on SessSetup and reconnect? */ |
2295 | rc = CIFSTCon(xid, pSesInfo, volume_info.UNC, | 2352 | rc = CIFSTCon(xid, pSesInfo, volume_info->UNC, |
2296 | tcon, cifs_sb->local_nls); | 2353 | tcon, cifs_sb->local_nls); |
2297 | cFYI(1, ("CIFS Tcon rc = %d", rc)); | 2354 | cFYI(1, ("CIFS Tcon rc = %d", rc)); |
2298 | if (volume_info.nodfs) { | 2355 | if (volume_info->nodfs) { |
2299 | tcon->Flags &= ~SMB_SHARE_IS_IN_DFS; | 2356 | tcon->Flags &= ~SMB_SHARE_IS_IN_DFS; |
2300 | cFYI(1, ("DFS disabled (%d)", | 2357 | cFYI(1, ("DFS disabled (%d)", |
2301 | tcon->Flags)); | 2358 | tcon->Flags)); |
@@ -2303,7 +2360,7 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb, | |||
2303 | } | 2360 | } |
2304 | if (rc) | 2361 | if (rc) |
2305 | goto mount_fail_check; | 2362 | goto mount_fail_check; |
2306 | tcon->seal = volume_info.seal; | 2363 | tcon->seal = volume_info->seal; |
2307 | write_lock(&cifs_tcp_ses_lock); | 2364 | write_lock(&cifs_tcp_ses_lock); |
2308 | list_add(&tcon->tcon_list, &pSesInfo->tcon_list); | 2365 | list_add(&tcon->tcon_list, &pSesInfo->tcon_list); |
2309 | write_unlock(&cifs_tcp_ses_lock); | 2366 | write_unlock(&cifs_tcp_ses_lock); |
@@ -2313,9 +2370,9 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb, | |||
2313 | to a share so for resources mounted more than once | 2370 | to a share so for resources mounted more than once |
2314 | to the same server share the last value passed in | 2371 | to the same server share the last value passed in |
2315 | for the retry flag is used */ | 2372 | for the retry flag is used */ |
2316 | tcon->retry = volume_info.retry; | 2373 | tcon->retry = volume_info->retry; |
2317 | tcon->nocase = volume_info.nocase; | 2374 | tcon->nocase = volume_info->nocase; |
2318 | tcon->local_lease = volume_info.local_lease; | 2375 | tcon->local_lease = volume_info->local_lease; |
2319 | } | 2376 | } |
2320 | if (pSesInfo) { | 2377 | if (pSesInfo) { |
2321 | if (pSesInfo->capabilities & CAP_LARGE_FILES) { | 2378 | if (pSesInfo->capabilities & CAP_LARGE_FILES) { |
@@ -2352,7 +2409,7 @@ mount_fail_check: | |||
2352 | if (tcon->ses->capabilities & CAP_UNIX) | 2409 | if (tcon->ses->capabilities & CAP_UNIX) |
2353 | /* reset of caps checks mount to see if unix extensions | 2410 | /* reset of caps checks mount to see if unix extensions |
2354 | disabled for just this mount */ | 2411 | disabled for just this mount */ |
2355 | reset_cifs_unix_caps(xid, tcon, sb, &volume_info); | 2412 | reset_cifs_unix_caps(xid, tcon, sb, volume_info); |
2356 | else | 2413 | else |
2357 | tcon->unix_ext = 0; /* server does not support them */ | 2414 | tcon->unix_ext = 0; /* server does not support them */ |
2358 | 2415 | ||
@@ -2371,18 +2428,22 @@ mount_fail_check: | |||
2371 | cifs_sb->rsize = min(cifs_sb->rsize, | 2428 | cifs_sb->rsize = min(cifs_sb->rsize, |
2372 | (tcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE)); | 2429 | (tcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE)); |
2373 | 2430 | ||
2374 | /* volume_info.password is freed above when existing session found | 2431 | /* volume_info->password is freed above when existing session found |
2375 | (in which case it is not needed anymore) but when new sesion is created | 2432 | (in which case it is not needed anymore) but when new sesion is created |
2376 | the password ptr is put in the new session structure (in which case the | 2433 | the password ptr is put in the new session structure (in which case the |
2377 | password will be freed at unmount time) */ | 2434 | password will be freed at unmount time) */ |
2378 | out: | 2435 | out: |
2379 | /* zero out password before freeing */ | 2436 | /* zero out password before freeing */ |
2380 | if (volume_info.password != NULL) { | 2437 | if (volume_info) { |
2381 | memset(volume_info.password, 0, strlen(volume_info.password)); | 2438 | if (volume_info->password != NULL) { |
2382 | kfree(volume_info.password); | 2439 | memset(volume_info->password, 0, |
2440 | strlen(volume_info->password)); | ||
2441 | kfree(volume_info->password); | ||
2442 | } | ||
2443 | kfree(volume_info->UNC); | ||
2444 | kfree(volume_info->prepath); | ||
2445 | kfree(volume_info); | ||
2383 | } | 2446 | } |
2384 | kfree(volume_info.UNC); | ||
2385 | kfree(volume_info.prepath); | ||
2386 | FreeXid(xid); | 2447 | FreeXid(xid); |
2387 | return rc; | 2448 | return rc; |
2388 | } | 2449 | } |
@@ -2533,7 +2594,7 @@ CIFSSessSetup(unsigned int xid, struct cifsSesInfo *ses, | |||
2533 | __u16 action = le16_to_cpu(pSMBr->resp.Action); | 2594 | __u16 action = le16_to_cpu(pSMBr->resp.Action); |
2534 | __u16 blob_len = le16_to_cpu(pSMBr->resp.SecurityBlobLength); | 2595 | __u16 blob_len = le16_to_cpu(pSMBr->resp.SecurityBlobLength); |
2535 | if (action & GUEST_LOGIN) | 2596 | if (action & GUEST_LOGIN) |
2536 | cFYI(1, (" Guest login")); /* BB mark SesInfo struct? */ | 2597 | cFYI(1, ("Guest login")); /* BB mark SesInfo struct? */ |
2537 | ses->Suid = smb_buffer_response->Uid; /* UID left in wire format | 2598 | ses->Suid = smb_buffer_response->Uid; /* UID left in wire format |
2538 | (little endian) */ | 2599 | (little endian) */ |
2539 | cFYI(1, ("UID = %d ", ses->Suid)); | 2600 | cFYI(1, ("UID = %d ", ses->Suid)); |
@@ -2679,13 +2740,11 @@ CIFSSessSetup(unsigned int xid, struct cifsSesInfo *ses, | |||
2679 | len)); | 2740 | len)); |
2680 | } | 2741 | } |
2681 | } else { | 2742 | } else { |
2682 | cERROR(1, | 2743 | cERROR(1, ("Security Blob Length extends beyond " |
2683 | (" Security Blob Length extends beyond " | ||
2684 | "end of SMB")); | 2744 | "end of SMB")); |
2685 | } | 2745 | } |
2686 | } else { | 2746 | } else { |
2687 | cERROR(1, | 2747 | cERROR(1, ("Invalid Word count %d: ", |
2688 | (" Invalid Word count %d: ", | ||
2689 | smb_buffer_response->WordCount)); | 2748 | smb_buffer_response->WordCount)); |
2690 | rc = -EIO; | 2749 | rc = -EIO; |
2691 | } | 2750 | } |
@@ -2843,7 +2902,7 @@ CIFSNTLMSSPNegotiateSessSetup(unsigned int xid, | |||
2843 | __u16 blob_len = le16_to_cpu(pSMBr->resp.SecurityBlobLength); | 2902 | __u16 blob_len = le16_to_cpu(pSMBr->resp.SecurityBlobLength); |
2844 | 2903 | ||
2845 | if (action & GUEST_LOGIN) | 2904 | if (action & GUEST_LOGIN) |
2846 | cFYI(1, (" Guest login")); | 2905 | cFYI(1, ("Guest login")); |
2847 | /* Do we want to set anything in SesInfo struct when guest login? */ | 2906 | /* Do we want to set anything in SesInfo struct when guest login? */ |
2848 | 2907 | ||
2849 | bcc_ptr = pByteArea(smb_buffer_response); | 2908 | bcc_ptr = pByteArea(smb_buffer_response); |
@@ -2851,8 +2910,7 @@ CIFSNTLMSSPNegotiateSessSetup(unsigned int xid, | |||
2851 | 2910 | ||
2852 | SecurityBlob2 = (PCHALLENGE_MESSAGE) bcc_ptr; | 2911 | SecurityBlob2 = (PCHALLENGE_MESSAGE) bcc_ptr; |
2853 | if (SecurityBlob2->MessageType != NtLmChallenge) { | 2912 | if (SecurityBlob2->MessageType != NtLmChallenge) { |
2854 | cFYI(1, | 2913 | cFYI(1, ("Unexpected NTLMSSP message type received %d", |
2855 | ("Unexpected NTLMSSP message type received %d", | ||
2856 | SecurityBlob2->MessageType)); | 2914 | SecurityBlob2->MessageType)); |
2857 | } else if (ses) { | 2915 | } else if (ses) { |
2858 | ses->Suid = smb_buffer_response->Uid; /* UID left in le format */ | 2916 | ses->Suid = smb_buffer_response->Uid; /* UID left in le format */ |
@@ -3024,8 +3082,7 @@ CIFSNTLMSSPNegotiateSessSetup(unsigned int xid, | |||
3024 | cERROR(1, ("No session structure passed in.")); | 3082 | cERROR(1, ("No session structure passed in.")); |
3025 | } | 3083 | } |
3026 | } else { | 3084 | } else { |
3027 | cERROR(1, | 3085 | cERROR(1, ("Invalid Word count %d:", |
3028 | (" Invalid Word count %d:", | ||
3029 | smb_buffer_response->WordCount)); | 3086 | smb_buffer_response->WordCount)); |
3030 | rc = -EIO; | 3087 | rc = -EIO; |
3031 | } | 3088 | } |
@@ -3264,7 +3321,7 @@ CIFSNTLMSSPAuthSessSetup(unsigned int xid, struct cifsSesInfo *ses, | |||
3264 | __u16 action = le16_to_cpu(pSMBr->resp.Action); | 3321 | __u16 action = le16_to_cpu(pSMBr->resp.Action); |
3265 | __u16 blob_len = le16_to_cpu(pSMBr->resp.SecurityBlobLength); | 3322 | __u16 blob_len = le16_to_cpu(pSMBr->resp.SecurityBlobLength); |
3266 | if (action & GUEST_LOGIN) | 3323 | if (action & GUEST_LOGIN) |
3267 | cFYI(1, (" Guest login")); /* BB Should we set anything | 3324 | cFYI(1, ("Guest login")); /* BB Should we set anything |
3268 | in SesInfo struct ? */ | 3325 | in SesInfo struct ? */ |
3269 | /* if (SecurityBlob2->MessageType != NtLm??) { | 3326 | /* if (SecurityBlob2->MessageType != NtLm??) { |
3270 | cFYI("Unexpected message type on auth response is %d")); | 3327 | cFYI("Unexpected message type on auth response is %d")); |
@@ -3487,12 +3544,14 @@ CIFSTCon(unsigned int xid, struct cifsSesInfo *ses, | |||
3487 | NTLMv2 password here) */ | 3544 | NTLMv2 password here) */ |
3488 | #ifdef CONFIG_CIFS_WEAK_PW_HASH | 3545 | #ifdef CONFIG_CIFS_WEAK_PW_HASH |
3489 | if ((extended_security & CIFSSEC_MAY_LANMAN) && | 3546 | if ((extended_security & CIFSSEC_MAY_LANMAN) && |
3490 | (ses->server->secType == LANMAN)) | 3547 | (ses->server->secType == LANMAN)) |
3491 | calc_lanman_hash(ses, bcc_ptr); | 3548 | calc_lanman_hash(tcon->password, ses->server->cryptKey, |
3549 | ses->server->secMode & | ||
3550 | SECMODE_PW_ENCRYPT ? true : false, | ||
3551 | bcc_ptr); | ||
3492 | else | 3552 | else |
3493 | #endif /* CIFS_WEAK_PW_HASH */ | 3553 | #endif /* CIFS_WEAK_PW_HASH */ |
3494 | SMBNTencrypt(ses->password, | 3554 | SMBNTencrypt(tcon->password, ses->server->cryptKey, |
3495 | ses->server->cryptKey, | ||
3496 | bcc_ptr); | 3555 | bcc_ptr); |
3497 | 3556 | ||
3498 | bcc_ptr += CIFS_SESS_KEY_SIZE; | 3557 | bcc_ptr += CIFS_SESS_KEY_SIZE; |
diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c index e962e75e6f7b..838d9c720a5c 100644 --- a/fs/cifs/dir.c +++ b/fs/cifs/dir.c | |||
@@ -235,11 +235,11 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode, | |||
235 | }; | 235 | }; |
236 | 236 | ||
237 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) { | 237 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) { |
238 | args.uid = (__u64) current->fsuid; | 238 | args.uid = (__u64) current_fsuid(); |
239 | if (inode->i_mode & S_ISGID) | 239 | if (inode->i_mode & S_ISGID) |
240 | args.gid = (__u64) inode->i_gid; | 240 | args.gid = (__u64) inode->i_gid; |
241 | else | 241 | else |
242 | args.gid = (__u64) current->fsgid; | 242 | args.gid = (__u64) current_fsgid(); |
243 | } else { | 243 | } else { |
244 | args.uid = NO_CHANGE_64; | 244 | args.uid = NO_CHANGE_64; |
245 | args.gid = NO_CHANGE_64; | 245 | args.gid = NO_CHANGE_64; |
@@ -271,13 +271,13 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode, | |||
271 | if ((oplock & CIFS_CREATE_ACTION) && | 271 | if ((oplock & CIFS_CREATE_ACTION) && |
272 | (cifs_sb->mnt_cifs_flags & | 272 | (cifs_sb->mnt_cifs_flags & |
273 | CIFS_MOUNT_SET_UID)) { | 273 | CIFS_MOUNT_SET_UID)) { |
274 | newinode->i_uid = current->fsuid; | 274 | newinode->i_uid = current_fsuid(); |
275 | if (inode->i_mode & S_ISGID) | 275 | if (inode->i_mode & S_ISGID) |
276 | newinode->i_gid = | 276 | newinode->i_gid = |
277 | inode->i_gid; | 277 | inode->i_gid; |
278 | else | 278 | else |
279 | newinode->i_gid = | 279 | newinode->i_gid = |
280 | current->fsgid; | 280 | current_fsgid(); |
281 | } | 281 | } |
282 | } | 282 | } |
283 | } | 283 | } |
@@ -375,8 +375,8 @@ int cifs_mknod(struct inode *inode, struct dentry *direntry, int mode, | |||
375 | .device = device_number, | 375 | .device = device_number, |
376 | }; | 376 | }; |
377 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) { | 377 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) { |
378 | args.uid = (__u64) current->fsuid; | 378 | args.uid = (__u64) current_fsuid(); |
379 | args.gid = (__u64) current->fsgid; | 379 | args.gid = (__u64) current_fsgid(); |
380 | } else { | 380 | } else { |
381 | args.uid = NO_CHANGE_64; | 381 | args.uid = NO_CHANGE_64; |
382 | args.gid = NO_CHANGE_64; | 382 | args.gid = NO_CHANGE_64; |
@@ -483,7 +483,7 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry, | |||
483 | 483 | ||
484 | xid = GetXid(); | 484 | xid = GetXid(); |
485 | 485 | ||
486 | cFYI(1, (" parent inode = 0x%p name is: %s and dentry = 0x%p", | 486 | cFYI(1, ("parent inode = 0x%p name is: %s and dentry = 0x%p", |
487 | parent_dir_inode, direntry->d_name.name, direntry)); | 487 | parent_dir_inode, direntry->d_name.name, direntry)); |
488 | 488 | ||
489 | /* check whether path exists */ | 489 | /* check whether path exists */ |
@@ -515,12 +515,11 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry, | |||
515 | } | 515 | } |
516 | 516 | ||
517 | if (direntry->d_inode != NULL) { | 517 | if (direntry->d_inode != NULL) { |
518 | cFYI(1, (" non-NULL inode in lookup")); | 518 | cFYI(1, ("non-NULL inode in lookup")); |
519 | } else { | 519 | } else { |
520 | cFYI(1, (" NULL inode in lookup")); | 520 | cFYI(1, ("NULL inode in lookup")); |
521 | } | 521 | } |
522 | cFYI(1, | 522 | cFYI(1, ("Full path: %s inode = 0x%p", full_path, direntry->d_inode)); |
523 | (" Full path: %s inode = 0x%p", full_path, direntry->d_inode)); | ||
524 | 523 | ||
525 | if (pTcon->unix_ext) | 524 | if (pTcon->unix_ext) |
526 | rc = cifs_get_inode_info_unix(&newInode, full_path, | 525 | rc = cifs_get_inode_info_unix(&newInode, full_path, |
diff --git a/fs/cifs/file.c b/fs/cifs/file.c index f0a81e631ae6..b1e1fc6a6e6a 100644 --- a/fs/cifs/file.c +++ b/fs/cifs/file.c | |||
@@ -644,10 +644,10 @@ int cifs_lock(struct file *file, int cmd, struct file_lock *pfLock) | |||
644 | __u64 length; | 644 | __u64 length; |
645 | bool wait_flag = false; | 645 | bool wait_flag = false; |
646 | struct cifs_sb_info *cifs_sb; | 646 | struct cifs_sb_info *cifs_sb; |
647 | struct cifsTconInfo *pTcon; | 647 | struct cifsTconInfo *tcon; |
648 | __u16 netfid; | 648 | __u16 netfid; |
649 | __u8 lockType = LOCKING_ANDX_LARGE_FILES; | 649 | __u8 lockType = LOCKING_ANDX_LARGE_FILES; |
650 | bool posix_locking; | 650 | bool posix_locking = 0; |
651 | 651 | ||
652 | length = 1 + pfLock->fl_end - pfLock->fl_start; | 652 | length = 1 + pfLock->fl_end - pfLock->fl_start; |
653 | rc = -EACCES; | 653 | rc = -EACCES; |
@@ -698,7 +698,7 @@ int cifs_lock(struct file *file, int cmd, struct file_lock *pfLock) | |||
698 | cFYI(1, ("Unknown type of lock")); | 698 | cFYI(1, ("Unknown type of lock")); |
699 | 699 | ||
700 | cifs_sb = CIFS_SB(file->f_path.dentry->d_sb); | 700 | cifs_sb = CIFS_SB(file->f_path.dentry->d_sb); |
701 | pTcon = cifs_sb->tcon; | 701 | tcon = cifs_sb->tcon; |
702 | 702 | ||
703 | if (file->private_data == NULL) { | 703 | if (file->private_data == NULL) { |
704 | FreeXid(xid); | 704 | FreeXid(xid); |
@@ -706,9 +706,10 @@ int cifs_lock(struct file *file, int cmd, struct file_lock *pfLock) | |||
706 | } | 706 | } |
707 | netfid = ((struct cifsFileInfo *)file->private_data)->netfid; | 707 | netfid = ((struct cifsFileInfo *)file->private_data)->netfid; |
708 | 708 | ||
709 | posix_locking = (cifs_sb->tcon->ses->capabilities & CAP_UNIX) && | 709 | if ((tcon->ses->capabilities & CAP_UNIX) && |
710 | (CIFS_UNIX_FCNTL_CAP & le64_to_cpu(cifs_sb->tcon->fsUnixInfo.Capability)); | 710 | (CIFS_UNIX_FCNTL_CAP & le64_to_cpu(tcon->fsUnixInfo.Capability)) && |
711 | 711 | ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NOPOSIXBRL) == 0)) | |
712 | posix_locking = 1; | ||
712 | /* BB add code here to normalize offset and length to | 713 | /* BB add code here to normalize offset and length to |
713 | account for negative length which we can not accept over the | 714 | account for negative length which we can not accept over the |
714 | wire */ | 715 | wire */ |
@@ -719,7 +720,7 @@ int cifs_lock(struct file *file, int cmd, struct file_lock *pfLock) | |||
719 | posix_lock_type = CIFS_RDLCK; | 720 | posix_lock_type = CIFS_RDLCK; |
720 | else | 721 | else |
721 | posix_lock_type = CIFS_WRLCK; | 722 | posix_lock_type = CIFS_WRLCK; |
722 | rc = CIFSSMBPosixLock(xid, pTcon, netfid, 1 /* get */, | 723 | rc = CIFSSMBPosixLock(xid, tcon, netfid, 1 /* get */, |
723 | length, pfLock, | 724 | length, pfLock, |
724 | posix_lock_type, wait_flag); | 725 | posix_lock_type, wait_flag); |
725 | FreeXid(xid); | 726 | FreeXid(xid); |
@@ -727,10 +728,10 @@ int cifs_lock(struct file *file, int cmd, struct file_lock *pfLock) | |||
727 | } | 728 | } |
728 | 729 | ||
729 | /* BB we could chain these into one lock request BB */ | 730 | /* BB we could chain these into one lock request BB */ |
730 | rc = CIFSSMBLock(xid, pTcon, netfid, length, pfLock->fl_start, | 731 | rc = CIFSSMBLock(xid, tcon, netfid, length, pfLock->fl_start, |
731 | 0, 1, lockType, 0 /* wait flag */ ); | 732 | 0, 1, lockType, 0 /* wait flag */ ); |
732 | if (rc == 0) { | 733 | if (rc == 0) { |
733 | rc = CIFSSMBLock(xid, pTcon, netfid, length, | 734 | rc = CIFSSMBLock(xid, tcon, netfid, length, |
734 | pfLock->fl_start, 1 /* numUnlock */ , | 735 | pfLock->fl_start, 1 /* numUnlock */ , |
735 | 0 /* numLock */ , lockType, | 736 | 0 /* numLock */ , lockType, |
736 | 0 /* wait flag */ ); | 737 | 0 /* wait flag */ ); |
@@ -767,7 +768,7 @@ int cifs_lock(struct file *file, int cmd, struct file_lock *pfLock) | |||
767 | if (numUnlock == 1) | 768 | if (numUnlock == 1) |
768 | posix_lock_type = CIFS_UNLCK; | 769 | posix_lock_type = CIFS_UNLCK; |
769 | 770 | ||
770 | rc = CIFSSMBPosixLock(xid, pTcon, netfid, 0 /* set */, | 771 | rc = CIFSSMBPosixLock(xid, tcon, netfid, 0 /* set */, |
771 | length, pfLock, | 772 | length, pfLock, |
772 | posix_lock_type, wait_flag); | 773 | posix_lock_type, wait_flag); |
773 | } else { | 774 | } else { |
@@ -775,7 +776,7 @@ int cifs_lock(struct file *file, int cmd, struct file_lock *pfLock) | |||
775 | (struct cifsFileInfo *)file->private_data; | 776 | (struct cifsFileInfo *)file->private_data; |
776 | 777 | ||
777 | if (numLock) { | 778 | if (numLock) { |
778 | rc = CIFSSMBLock(xid, pTcon, netfid, length, | 779 | rc = CIFSSMBLock(xid, tcon, netfid, length, |
779 | pfLock->fl_start, | 780 | pfLock->fl_start, |
780 | 0, numLock, lockType, wait_flag); | 781 | 0, numLock, lockType, wait_flag); |
781 | 782 | ||
@@ -796,7 +797,7 @@ int cifs_lock(struct file *file, int cmd, struct file_lock *pfLock) | |||
796 | if (pfLock->fl_start <= li->offset && | 797 | if (pfLock->fl_start <= li->offset && |
797 | (pfLock->fl_start + length) >= | 798 | (pfLock->fl_start + length) >= |
798 | (li->offset + li->length)) { | 799 | (li->offset + li->length)) { |
799 | stored_rc = CIFSSMBLock(xid, pTcon, | 800 | stored_rc = CIFSSMBLock(xid, tcon, |
800 | netfid, | 801 | netfid, |
801 | li->length, li->offset, | 802 | li->length, li->offset, |
802 | 1, 0, li->type, false); | 803 | 1, 0, li->type, false); |
diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c index ff8c68de4a92..f247da9f4edc 100644 --- a/fs/cifs/inode.c +++ b/fs/cifs/inode.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * fs/cifs/inode.c | 2 | * fs/cifs/inode.c |
3 | * | 3 | * |
4 | * Copyright (C) International Business Machines Corp., 2002,2007 | 4 | * Copyright (C) International Business Machines Corp., 2002,2008 |
5 | * Author(s): Steve French (sfrench@us.ibm.com) | 5 | * Author(s): Steve French (sfrench@us.ibm.com) |
6 | * | 6 | * |
7 | * This library is free software; you can redistribute it and/or modify | 7 | * 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 = { | |||
621 | .lookup = cifs_lookup, | 621 | .lookup = cifs_lookup, |
622 | }; | 622 | }; |
623 | 623 | ||
624 | static char *build_path_to_root(struct cifs_sb_info *cifs_sb) | ||
625 | { | ||
626 | int pplen = cifs_sb->prepathlen; | ||
627 | int dfsplen; | ||
628 | char *full_path = NULL; | ||
629 | |||
630 | /* if no prefix path, simply set path to the root of share to "" */ | ||
631 | if (pplen == 0) { | ||
632 | full_path = kmalloc(1, GFP_KERNEL); | ||
633 | if (full_path) | ||
634 | full_path[0] = 0; | ||
635 | return full_path; | ||
636 | } | ||
637 | |||
638 | if (cifs_sb->tcon && (cifs_sb->tcon->Flags & SMB_SHARE_IS_IN_DFS)) | ||
639 | dfsplen = strnlen(cifs_sb->tcon->treeName, MAX_TREE_SIZE + 1); | ||
640 | else | ||
641 | dfsplen = 0; | ||
642 | |||
643 | full_path = kmalloc(dfsplen + pplen + 1, GFP_KERNEL); | ||
644 | if (full_path == NULL) | ||
645 | return full_path; | ||
646 | |||
647 | if (dfsplen) { | ||
648 | strncpy(full_path, cifs_sb->tcon->treeName, dfsplen); | ||
649 | /* switch slash direction in prepath depending on whether | ||
650 | * windows or posix style path names | ||
651 | */ | ||
652 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS) { | ||
653 | int i; | ||
654 | for (i = 0; i < dfsplen; i++) { | ||
655 | if (full_path[i] == '\\') | ||
656 | full_path[i] = '/'; | ||
657 | } | ||
658 | } | ||
659 | } | ||
660 | strncpy(full_path + dfsplen, cifs_sb->prepath, pplen); | ||
661 | full_path[dfsplen + pplen] = 0; /* add trailing null */ | ||
662 | return full_path; | ||
663 | } | ||
664 | |||
624 | /* gets root inode */ | 665 | /* gets root inode */ |
625 | struct inode *cifs_iget(struct super_block *sb, unsigned long ino) | 666 | struct inode *cifs_iget(struct super_block *sb, unsigned long ino) |
626 | { | 667 | { |
@@ -628,6 +669,7 @@ struct inode *cifs_iget(struct super_block *sb, unsigned long ino) | |||
628 | struct cifs_sb_info *cifs_sb; | 669 | struct cifs_sb_info *cifs_sb; |
629 | struct inode *inode; | 670 | struct inode *inode; |
630 | long rc; | 671 | long rc; |
672 | char *full_path; | ||
631 | 673 | ||
632 | inode = iget_locked(sb, ino); | 674 | inode = iget_locked(sb, ino); |
633 | if (!inode) | 675 | if (!inode) |
@@ -636,13 +678,17 @@ struct inode *cifs_iget(struct super_block *sb, unsigned long ino) | |||
636 | return inode; | 678 | return inode; |
637 | 679 | ||
638 | cifs_sb = CIFS_SB(inode->i_sb); | 680 | cifs_sb = CIFS_SB(inode->i_sb); |
639 | xid = GetXid(); | 681 | full_path = build_path_to_root(cifs_sb); |
682 | if (full_path == NULL) | ||
683 | return ERR_PTR(-ENOMEM); | ||
640 | 684 | ||
685 | xid = GetXid(); | ||
641 | if (cifs_sb->tcon->unix_ext) | 686 | if (cifs_sb->tcon->unix_ext) |
642 | rc = cifs_get_inode_info_unix(&inode, "", inode->i_sb, xid); | 687 | rc = cifs_get_inode_info_unix(&inode, full_path, inode->i_sb, |
688 | xid); | ||
643 | else | 689 | else |
644 | rc = cifs_get_inode_info(&inode, "", NULL, inode->i_sb, xid, | 690 | rc = cifs_get_inode_info(&inode, full_path, NULL, inode->i_sb, |
645 | NULL); | 691 | xid, NULL); |
646 | if (rc && cifs_sb->tcon->ipc) { | 692 | if (rc && cifs_sb->tcon->ipc) { |
647 | cFYI(1, ("ipc connection - fake read inode")); | 693 | cFYI(1, ("ipc connection - fake read inode")); |
648 | inode->i_mode |= S_IFDIR; | 694 | inode->i_mode |= S_IFDIR; |
@@ -652,6 +698,7 @@ struct inode *cifs_iget(struct super_block *sb, unsigned long ino) | |||
652 | inode->i_uid = cifs_sb->mnt_uid; | 698 | inode->i_uid = cifs_sb->mnt_uid; |
653 | inode->i_gid = cifs_sb->mnt_gid; | 699 | inode->i_gid = cifs_sb->mnt_gid; |
654 | } else if (rc) { | 700 | } else if (rc) { |
701 | kfree(full_path); | ||
655 | _FreeXid(xid); | 702 | _FreeXid(xid); |
656 | iget_failed(inode); | 703 | iget_failed(inode); |
657 | return ERR_PTR(rc); | 704 | return ERR_PTR(rc); |
@@ -659,6 +706,7 @@ struct inode *cifs_iget(struct super_block *sb, unsigned long ino) | |||
659 | 706 | ||
660 | unlock_new_inode(inode); | 707 | unlock_new_inode(inode); |
661 | 708 | ||
709 | kfree(full_path); | ||
662 | /* can not call macro FreeXid here since in a void func | 710 | /* can not call macro FreeXid here since in a void func |
663 | * TODO: This is no longer true | 711 | * TODO: This is no longer true |
664 | */ | 712 | */ |
@@ -1143,11 +1191,11 @@ mkdir_get_info: | |||
1143 | .device = 0, | 1191 | .device = 0, |
1144 | }; | 1192 | }; |
1145 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) { | 1193 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) { |
1146 | args.uid = (__u64)current->fsuid; | 1194 | args.uid = (__u64)current_fsuid(); |
1147 | if (inode->i_mode & S_ISGID) | 1195 | if (inode->i_mode & S_ISGID) |
1148 | args.gid = (__u64)inode->i_gid; | 1196 | args.gid = (__u64)inode->i_gid; |
1149 | else | 1197 | else |
1150 | args.gid = (__u64)current->fsgid; | 1198 | args.gid = (__u64)current_fsgid(); |
1151 | } else { | 1199 | } else { |
1152 | args.uid = NO_CHANGE_64; | 1200 | args.uid = NO_CHANGE_64; |
1153 | args.gid = NO_CHANGE_64; | 1201 | args.gid = NO_CHANGE_64; |
@@ -1184,13 +1232,13 @@ mkdir_get_info: | |||
1184 | if (cifs_sb->mnt_cifs_flags & | 1232 | if (cifs_sb->mnt_cifs_flags & |
1185 | CIFS_MOUNT_SET_UID) { | 1233 | CIFS_MOUNT_SET_UID) { |
1186 | direntry->d_inode->i_uid = | 1234 | direntry->d_inode->i_uid = |
1187 | current->fsuid; | 1235 | current_fsuid(); |
1188 | if (inode->i_mode & S_ISGID) | 1236 | if (inode->i_mode & S_ISGID) |
1189 | direntry->d_inode->i_gid = | 1237 | direntry->d_inode->i_gid = |
1190 | inode->i_gid; | 1238 | inode->i_gid; |
1191 | else | 1239 | else |
1192 | direntry->d_inode->i_gid = | 1240 | direntry->d_inode->i_gid = |
1193 | current->fsgid; | 1241 | current_fsgid(); |
1194 | } | 1242 | } |
1195 | } | 1243 | } |
1196 | } | 1244 | } |
diff --git a/fs/cifs/ioctl.c b/fs/cifs/ioctl.c index 0088a5b52564..f94650683a00 100644 --- a/fs/cifs/ioctl.c +++ b/fs/cifs/ioctl.c | |||
@@ -65,7 +65,7 @@ long cifs_ioctl(struct file *filep, unsigned int command, unsigned long arg) | |||
65 | switch (command) { | 65 | switch (command) { |
66 | case CIFS_IOC_CHECKUMOUNT: | 66 | case CIFS_IOC_CHECKUMOUNT: |
67 | cFYI(1, ("User unmount attempted")); | 67 | cFYI(1, ("User unmount attempted")); |
68 | if (cifs_sb->mnt_uid == current->uid) | 68 | if (cifs_sb->mnt_uid == current_uid()) |
69 | rc = 0; | 69 | rc = 0; |
70 | else { | 70 | else { |
71 | rc = -EACCES; | 71 | rc = -EACCES; |
diff --git a/fs/cifs/misc.c b/fs/cifs/misc.c index 9ee3f689c2b0..4c89c572891a 100644 --- a/fs/cifs/misc.c +++ b/fs/cifs/misc.c | |||
@@ -97,7 +97,10 @@ sesInfoFree(struct cifsSesInfo *buf_to_free) | |||
97 | kfree(buf_to_free->serverOS); | 97 | kfree(buf_to_free->serverOS); |
98 | kfree(buf_to_free->serverDomain); | 98 | kfree(buf_to_free->serverDomain); |
99 | kfree(buf_to_free->serverNOS); | 99 | kfree(buf_to_free->serverNOS); |
100 | kfree(buf_to_free->password); | 100 | if (buf_to_free->password) { |
101 | memset(buf_to_free->password, 0, strlen(buf_to_free->password)); | ||
102 | kfree(buf_to_free->password); | ||
103 | } | ||
101 | kfree(buf_to_free->domainName); | 104 | kfree(buf_to_free->domainName); |
102 | kfree(buf_to_free); | 105 | kfree(buf_to_free); |
103 | } | 106 | } |
@@ -129,6 +132,10 @@ tconInfoFree(struct cifsTconInfo *buf_to_free) | |||
129 | } | 132 | } |
130 | atomic_dec(&tconInfoAllocCount); | 133 | atomic_dec(&tconInfoAllocCount); |
131 | kfree(buf_to_free->nativeFileSystem); | 134 | kfree(buf_to_free->nativeFileSystem); |
135 | if (buf_to_free->password) { | ||
136 | memset(buf_to_free->password, 0, strlen(buf_to_free->password)); | ||
137 | kfree(buf_to_free->password); | ||
138 | } | ||
132 | kfree(buf_to_free); | 139 | kfree(buf_to_free); |
133 | } | 140 | } |
134 | 141 | ||
@@ -338,13 +345,13 @@ header_assemble(struct smb_hdr *buffer, char smb_command /* command */ , | |||
338 | /* BB Add support for establishing new tCon and SMB Session */ | 345 | /* BB Add support for establishing new tCon and SMB Session */ |
339 | /* with userid/password pairs found on the smb session */ | 346 | /* with userid/password pairs found on the smb session */ |
340 | /* for other target tcp/ip addresses BB */ | 347 | /* for other target tcp/ip addresses BB */ |
341 | if (current->fsuid != treeCon->ses->linux_uid) { | 348 | if (current_fsuid() != treeCon->ses->linux_uid) { |
342 | cFYI(1, ("Multiuser mode and UID " | 349 | cFYI(1, ("Multiuser mode and UID " |
343 | "did not match tcon uid")); | 350 | "did not match tcon uid")); |
344 | read_lock(&cifs_tcp_ses_lock); | 351 | read_lock(&cifs_tcp_ses_lock); |
345 | list_for_each(temp_item, &treeCon->ses->server->smb_ses_list) { | 352 | list_for_each(temp_item, &treeCon->ses->server->smb_ses_list) { |
346 | ses = list_entry(temp_item, struct cifsSesInfo, smb_ses_list); | 353 | ses = list_entry(temp_item, struct cifsSesInfo, smb_ses_list); |
347 | if (ses->linux_uid == current->fsuid) { | 354 | if (ses->linux_uid == current_fsuid()) { |
348 | if (ses->server == treeCon->ses->server) { | 355 | if (ses->server == treeCon->ses->server) { |
349 | cFYI(1, ("found matching uid substitute right smb_uid")); | 356 | cFYI(1, ("found matching uid substitute right smb_uid")); |
350 | buffer->Uid = ses->Suid; | 357 | buffer->Uid = ses->Suid; |
diff --git a/fs/cifs/sess.c b/fs/cifs/sess.c index 2851d5da0c8c..5f22de7b79a9 100644 --- a/fs/cifs/sess.c +++ b/fs/cifs/sess.c | |||
@@ -417,7 +417,10 @@ CIFS_SessSetup(unsigned int xid, struct cifsSesInfo *ses, int first_time, | |||
417 | /* BB calculate hash with password */ | 417 | /* BB calculate hash with password */ |
418 | /* and copy into bcc */ | 418 | /* and copy into bcc */ |
419 | 419 | ||
420 | calc_lanman_hash(ses, lnm_session_key); | 420 | calc_lanman_hash(ses->password, ses->server->cryptKey, |
421 | ses->server->secMode & SECMODE_PW_ENCRYPT ? | ||
422 | true : false, lnm_session_key); | ||
423 | |||
421 | ses->flags |= CIFS_SES_LANMAN; | 424 | ses->flags |= CIFS_SES_LANMAN; |
422 | memcpy(bcc_ptr, (char *)lnm_session_key, CIFS_SESS_KEY_SIZE); | 425 | memcpy(bcc_ptr, (char *)lnm_session_key, CIFS_SESS_KEY_SIZE); |
423 | bcc_ptr += CIFS_SESS_KEY_SIZE; | 426 | bcc_ptr += CIFS_SESS_KEY_SIZE; |
diff --git a/fs/cifs/smbdes.c b/fs/cifs/smbdes.c index 04943c976f98..224a1f478966 100644 --- a/fs/cifs/smbdes.c +++ b/fs/cifs/smbdes.c | |||
@@ -318,7 +318,8 @@ str_to_key(unsigned char *str, unsigned char *key) | |||
318 | } | 318 | } |
319 | 319 | ||
320 | static void | 320 | static void |
321 | smbhash(unsigned char *out, unsigned char *in, unsigned char *key, int forw) | 321 | smbhash(unsigned char *out, const unsigned char *in, unsigned char *key, |
322 | int forw) | ||
322 | { | 323 | { |
323 | int i; | 324 | int i; |
324 | char *outb; /* outb[64] */ | 325 | char *outb; /* outb[64] */ |
@@ -363,7 +364,7 @@ E_P16(unsigned char *p14, unsigned char *p16) | |||
363 | } | 364 | } |
364 | 365 | ||
365 | void | 366 | void |
366 | E_P24(unsigned char *p21, unsigned char *c8, unsigned char *p24) | 367 | E_P24(unsigned char *p21, const unsigned char *c8, unsigned char *p24) |
367 | { | 368 | { |
368 | smbhash(p24, c8, p21, 1); | 369 | smbhash(p24, c8, p21, 1); |
369 | smbhash(p24 + 8, c8, p21 + 7, 1); | 370 | smbhash(p24 + 8, c8, p21 + 7, 1); |
diff --git a/fs/cifs/smbencrypt.c b/fs/cifs/smbencrypt.c index ff3232fa1015..93fb09a99c69 100644 --- a/fs/cifs/smbencrypt.c +++ b/fs/cifs/smbencrypt.c | |||
@@ -49,9 +49,10 @@ | |||
49 | 49 | ||
50 | /*The following definitions come from libsmb/smbencrypt.c */ | 50 | /*The following definitions come from libsmb/smbencrypt.c */ |
51 | 51 | ||
52 | void SMBencrypt(unsigned char *passwd, unsigned char *c8, unsigned char *p24); | 52 | void SMBencrypt(unsigned char *passwd, const unsigned char *c8, |
53 | unsigned char *p24); | ||
53 | void E_md4hash(const unsigned char *passwd, unsigned char *p16); | 54 | void E_md4hash(const unsigned char *passwd, unsigned char *p16); |
54 | static void SMBOWFencrypt(unsigned char passwd[16], unsigned char *c8, | 55 | static void SMBOWFencrypt(unsigned char passwd[16], const unsigned char *c8, |
55 | unsigned char p24[24]); | 56 | unsigned char p24[24]); |
56 | void SMBNTencrypt(unsigned char *passwd, unsigned char *c8, unsigned char *p24); | 57 | void SMBNTencrypt(unsigned char *passwd, unsigned char *c8, unsigned char *p24); |
57 | 58 | ||
@@ -61,7 +62,7 @@ void SMBNTencrypt(unsigned char *passwd, unsigned char *c8, unsigned char *p24); | |||
61 | encrypted password into p24 */ | 62 | encrypted password into p24 */ |
62 | /* Note that password must be uppercased and null terminated */ | 63 | /* Note that password must be uppercased and null terminated */ |
63 | void | 64 | void |
64 | SMBencrypt(unsigned char *passwd, unsigned char *c8, unsigned char *p24) | 65 | SMBencrypt(unsigned char *passwd, const unsigned char *c8, unsigned char *p24) |
65 | { | 66 | { |
66 | unsigned char p14[15], p21[21]; | 67 | unsigned char p14[15], p21[21]; |
67 | 68 | ||
@@ -212,7 +213,7 @@ ntv2_owf_gen(const unsigned char owf[16], const char *user_n, | |||
212 | 213 | ||
213 | /* Does the des encryption from the NT or LM MD4 hash. */ | 214 | /* Does the des encryption from the NT or LM MD4 hash. */ |
214 | static void | 215 | static void |
215 | SMBOWFencrypt(unsigned char passwd[16], unsigned char *c8, | 216 | SMBOWFencrypt(unsigned char passwd[16], const unsigned char *c8, |
216 | unsigned char p24[24]) | 217 | unsigned char p24[24]) |
217 | { | 218 | { |
218 | unsigned char p21[21]; | 219 | unsigned char p21[21]; |
diff --git a/fs/cifs/transport.c b/fs/cifs/transport.c index ff8243a8fe3e..7ebe6599ed3a 100644 --- a/fs/cifs/transport.c +++ b/fs/cifs/transport.c | |||
@@ -37,15 +37,11 @@ extern mempool_t *cifs_mid_poolp; | |||
37 | extern struct kmem_cache *cifs_oplock_cachep; | 37 | extern struct kmem_cache *cifs_oplock_cachep; |
38 | 38 | ||
39 | static struct mid_q_entry * | 39 | static struct mid_q_entry * |
40 | AllocMidQEntry(const struct smb_hdr *smb_buffer, struct cifsSesInfo *ses) | 40 | AllocMidQEntry(const struct smb_hdr *smb_buffer, struct TCP_Server_Info *server) |
41 | { | 41 | { |
42 | struct mid_q_entry *temp; | 42 | struct mid_q_entry *temp; |
43 | 43 | ||
44 | if (ses == NULL) { | 44 | if (server == NULL) { |
45 | cERROR(1, ("Null session passed in to AllocMidQEntry")); | ||
46 | return NULL; | ||
47 | } | ||
48 | if (ses->server == NULL) { | ||
49 | cERROR(1, ("Null TCP session in AllocMidQEntry")); | 45 | cERROR(1, ("Null TCP session in AllocMidQEntry")); |
50 | return NULL; | 46 | return NULL; |
51 | } | 47 | } |
@@ -62,12 +58,11 @@ AllocMidQEntry(const struct smb_hdr *smb_buffer, struct cifsSesInfo *ses) | |||
62 | /* do_gettimeofday(&temp->when_sent);*/ /* easier to use jiffies */ | 58 | /* do_gettimeofday(&temp->when_sent);*/ /* easier to use jiffies */ |
63 | /* when mid allocated can be before when sent */ | 59 | /* when mid allocated can be before when sent */ |
64 | temp->when_alloc = jiffies; | 60 | temp->when_alloc = jiffies; |
65 | temp->ses = ses; | ||
66 | temp->tsk = current; | 61 | temp->tsk = current; |
67 | } | 62 | } |
68 | 63 | ||
69 | spin_lock(&GlobalMid_Lock); | 64 | spin_lock(&GlobalMid_Lock); |
70 | list_add_tail(&temp->qhead, &ses->server->pending_mid_q); | 65 | list_add_tail(&temp->qhead, &server->pending_mid_q); |
71 | atomic_inc(&midCount); | 66 | atomic_inc(&midCount); |
72 | temp->midState = MID_REQUEST_ALLOCATED; | 67 | temp->midState = MID_REQUEST_ALLOCATED; |
73 | spin_unlock(&GlobalMid_Lock); | 68 | spin_unlock(&GlobalMid_Lock); |
@@ -349,37 +344,38 @@ static int wait_for_free_request(struct cifsSesInfo *ses, const int long_op) | |||
349 | if (long_op == CIFS_ASYNC_OP) { | 344 | if (long_op == CIFS_ASYNC_OP) { |
350 | /* oplock breaks must not be held up */ | 345 | /* oplock breaks must not be held up */ |
351 | atomic_inc(&ses->server->inFlight); | 346 | atomic_inc(&ses->server->inFlight); |
352 | } else { | 347 | return 0; |
353 | spin_lock(&GlobalMid_Lock); | 348 | } |
354 | while (1) { | 349 | |
355 | if (atomic_read(&ses->server->inFlight) >= | 350 | spin_lock(&GlobalMid_Lock); |
356 | cifs_max_pending){ | 351 | while (1) { |
357 | spin_unlock(&GlobalMid_Lock); | 352 | if (atomic_read(&ses->server->inFlight) >= |
353 | cifs_max_pending){ | ||
354 | spin_unlock(&GlobalMid_Lock); | ||
358 | #ifdef CONFIG_CIFS_STATS2 | 355 | #ifdef CONFIG_CIFS_STATS2 |
359 | atomic_inc(&ses->server->num_waiters); | 356 | atomic_inc(&ses->server->num_waiters); |
360 | #endif | 357 | #endif |
361 | wait_event(ses->server->request_q, | 358 | wait_event(ses->server->request_q, |
362 | atomic_read(&ses->server->inFlight) | 359 | atomic_read(&ses->server->inFlight) |
363 | < cifs_max_pending); | 360 | < cifs_max_pending); |
364 | #ifdef CONFIG_CIFS_STATS2 | 361 | #ifdef CONFIG_CIFS_STATS2 |
365 | atomic_dec(&ses->server->num_waiters); | 362 | atomic_dec(&ses->server->num_waiters); |
366 | #endif | 363 | #endif |
367 | spin_lock(&GlobalMid_Lock); | 364 | spin_lock(&GlobalMid_Lock); |
368 | } else { | 365 | } else { |
369 | if (ses->server->tcpStatus == CifsExiting) { | 366 | if (ses->server->tcpStatus == CifsExiting) { |
370 | spin_unlock(&GlobalMid_Lock); | ||
371 | return -ENOENT; | ||
372 | } | ||
373 | |||
374 | /* can not count locking commands against total | ||
375 | as they are allowed to block on server */ | ||
376 | |||
377 | /* update # of requests on the wire to server */ | ||
378 | if (long_op != CIFS_BLOCKING_OP) | ||
379 | atomic_inc(&ses->server->inFlight); | ||
380 | spin_unlock(&GlobalMid_Lock); | 367 | spin_unlock(&GlobalMid_Lock); |
381 | break; | 368 | return -ENOENT; |
382 | } | 369 | } |
370 | |||
371 | /* can not count locking commands against total | ||
372 | as they are allowed to block on server */ | ||
373 | |||
374 | /* update # of requests on the wire to server */ | ||
375 | if (long_op != CIFS_BLOCKING_OP) | ||
376 | atomic_inc(&ses->server->inFlight); | ||
377 | spin_unlock(&GlobalMid_Lock); | ||
378 | break; | ||
383 | } | 379 | } |
384 | } | 380 | } |
385 | return 0; | 381 | return 0; |
@@ -390,17 +386,21 @@ static int allocate_mid(struct cifsSesInfo *ses, struct smb_hdr *in_buf, | |||
390 | { | 386 | { |
391 | if (ses->server->tcpStatus == CifsExiting) { | 387 | if (ses->server->tcpStatus == CifsExiting) { |
392 | return -ENOENT; | 388 | return -ENOENT; |
393 | } else if (ses->server->tcpStatus == CifsNeedReconnect) { | 389 | } |
390 | |||
391 | if (ses->server->tcpStatus == CifsNeedReconnect) { | ||
394 | cFYI(1, ("tcp session dead - return to caller to retry")); | 392 | cFYI(1, ("tcp session dead - return to caller to retry")); |
395 | return -EAGAIN; | 393 | return -EAGAIN; |
396 | } else if (ses->status != CifsGood) { | 394 | } |
395 | |||
396 | if (ses->status != CifsGood) { | ||
397 | /* check if SMB session is bad because we are setting it up */ | 397 | /* check if SMB session is bad because we are setting it up */ |
398 | if ((in_buf->Command != SMB_COM_SESSION_SETUP_ANDX) && | 398 | if ((in_buf->Command != SMB_COM_SESSION_SETUP_ANDX) && |
399 | (in_buf->Command != SMB_COM_NEGOTIATE)) | 399 | (in_buf->Command != SMB_COM_NEGOTIATE)) |
400 | return -EAGAIN; | 400 | return -EAGAIN; |
401 | /* else ok - we are setting up session */ | 401 | /* else ok - we are setting up session */ |
402 | } | 402 | } |
403 | *ppmidQ = AllocMidQEntry(in_buf, ses); | 403 | *ppmidQ = AllocMidQEntry(in_buf, ses->server); |
404 | if (*ppmidQ == NULL) | 404 | if (*ppmidQ == NULL) |
405 | return -ENOMEM; | 405 | return -ENOMEM; |
406 | return 0; | 406 | return 0; |
@@ -415,11 +415,8 @@ static int wait_for_response(struct cifsSesInfo *ses, | |||
415 | 415 | ||
416 | for (;;) { | 416 | for (;;) { |
417 | curr_timeout = timeout + jiffies; | 417 | curr_timeout = timeout + jiffies; |
418 | wait_event(ses->server->response_q, | 418 | wait_event_timeout(ses->server->response_q, |
419 | (!(midQ->midState == MID_REQUEST_SUBMITTED)) || | 419 | midQ->midState != MID_REQUEST_SUBMITTED, timeout); |
420 | time_after(jiffies, curr_timeout) || | ||
421 | ((ses->server->tcpStatus != CifsGood) && | ||
422 | (ses->server->tcpStatus != CifsNew))); | ||
423 | 420 | ||
424 | if (time_after(jiffies, curr_timeout) && | 421 | if (time_after(jiffies, curr_timeout) && |
425 | (midQ->midState == MID_REQUEST_SUBMITTED) && | 422 | (midQ->midState == MID_REQUEST_SUBMITTED) && |
@@ -521,11 +518,11 @@ SendReceive2(const unsigned int xid, struct cifsSesInfo *ses, | |||
521 | and avoid races inside tcp sendmsg code that could cause corruption | 518 | and avoid races inside tcp sendmsg code that could cause corruption |
522 | of smb data */ | 519 | of smb data */ |
523 | 520 | ||
524 | down(&ses->server->tcpSem); | 521 | mutex_lock(&ses->server->srv_mutex); |
525 | 522 | ||
526 | rc = allocate_mid(ses, in_buf, &midQ); | 523 | rc = allocate_mid(ses, in_buf, &midQ); |
527 | if (rc) { | 524 | if (rc) { |
528 | up(&ses->server->tcpSem); | 525 | mutex_unlock(&ses->server->srv_mutex); |
529 | cifs_small_buf_release(in_buf); | 526 | cifs_small_buf_release(in_buf); |
530 | /* Update # of requests on wire to server */ | 527 | /* Update # of requests on wire to server */ |
531 | atomic_dec(&ses->server->inFlight); | 528 | atomic_dec(&ses->server->inFlight); |
@@ -533,6 +530,11 @@ SendReceive2(const unsigned int xid, struct cifsSesInfo *ses, | |||
533 | return rc; | 530 | return rc; |
534 | } | 531 | } |
535 | rc = cifs_sign_smb2(iov, n_vec, ses->server, &midQ->sequence_number); | 532 | rc = cifs_sign_smb2(iov, n_vec, ses->server, &midQ->sequence_number); |
533 | if (rc) { | ||
534 | mutex_unlock(&ses->server->srv_mutex); | ||
535 | cifs_small_buf_release(in_buf); | ||
536 | goto out; | ||
537 | } | ||
536 | 538 | ||
537 | midQ->midState = MID_REQUEST_SUBMITTED; | 539 | midQ->midState = MID_REQUEST_SUBMITTED; |
538 | #ifdef CONFIG_CIFS_STATS2 | 540 | #ifdef CONFIG_CIFS_STATS2 |
@@ -546,7 +548,7 @@ SendReceive2(const unsigned int xid, struct cifsSesInfo *ses, | |||
546 | midQ->when_sent = jiffies; | 548 | midQ->when_sent = jiffies; |
547 | #endif | 549 | #endif |
548 | 550 | ||
549 | up(&ses->server->tcpSem); | 551 | mutex_unlock(&ses->server->srv_mutex); |
550 | cifs_small_buf_release(in_buf); | 552 | cifs_small_buf_release(in_buf); |
551 | 553 | ||
552 | if (rc < 0) | 554 | if (rc < 0) |
@@ -581,10 +583,8 @@ SendReceive2(const unsigned int xid, struct cifsSesInfo *ses, | |||
581 | wait_for_response(ses, midQ, timeout, 10 * HZ); | 583 | wait_for_response(ses, midQ, timeout, 10 * HZ); |
582 | 584 | ||
583 | spin_lock(&GlobalMid_Lock); | 585 | spin_lock(&GlobalMid_Lock); |
584 | if (midQ->resp_buf) { | 586 | |
585 | spin_unlock(&GlobalMid_Lock); | 587 | if (midQ->resp_buf == NULL) { |
586 | receive_len = midQ->resp_buf->smb_buf_length; | ||
587 | } else { | ||
588 | cERROR(1, ("No response to cmd %d mid %d", | 588 | cERROR(1, ("No response to cmd %d mid %d", |
589 | midQ->command, midQ->mid)); | 589 | midQ->command, midQ->mid)); |
590 | if (midQ->midState == MID_REQUEST_SUBMITTED) { | 590 | if (midQ->midState == MID_REQUEST_SUBMITTED) { |
@@ -612,53 +612,59 @@ SendReceive2(const unsigned int xid, struct cifsSesInfo *ses, | |||
612 | return rc; | 612 | return rc; |
613 | } | 613 | } |
614 | 614 | ||
615 | spin_unlock(&GlobalMid_Lock); | ||
616 | receive_len = midQ->resp_buf->smb_buf_length; | ||
617 | |||
615 | if (receive_len > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE) { | 618 | if (receive_len > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE) { |
616 | cERROR(1, ("Frame too large received. Length: %d Xid: %d", | 619 | cERROR(1, ("Frame too large received. Length: %d Xid: %d", |
617 | receive_len, xid)); | 620 | receive_len, xid)); |
618 | rc = -EIO; | 621 | rc = -EIO; |
619 | } else { /* rcvd frame is ok */ | 622 | goto out; |
620 | if (midQ->resp_buf && | 623 | } |
621 | (midQ->midState == MID_RESPONSE_RECEIVED)) { | 624 | |
622 | 625 | /* rcvd frame is ok */ | |
623 | iov[0].iov_base = (char *)midQ->resp_buf; | 626 | |
624 | if (midQ->largeBuf) | 627 | if (midQ->resp_buf && |
625 | *pRespBufType = CIFS_LARGE_BUFFER; | 628 | (midQ->midState == MID_RESPONSE_RECEIVED)) { |
626 | else | 629 | |
627 | *pRespBufType = CIFS_SMALL_BUFFER; | 630 | iov[0].iov_base = (char *)midQ->resp_buf; |
628 | iov[0].iov_len = receive_len + 4; | 631 | if (midQ->largeBuf) |
629 | 632 | *pRespBufType = CIFS_LARGE_BUFFER; | |
630 | dump_smb(midQ->resp_buf, 80); | 633 | else |
631 | /* convert the length into a more usable form */ | 634 | *pRespBufType = CIFS_SMALL_BUFFER; |
632 | if ((receive_len > 24) && | 635 | iov[0].iov_len = receive_len + 4; |
633 | (ses->server->secMode & (SECMODE_SIGN_REQUIRED | | 636 | |
634 | SECMODE_SIGN_ENABLED))) { | 637 | dump_smb(midQ->resp_buf, 80); |
635 | rc = cifs_verify_signature(midQ->resp_buf, | 638 | /* convert the length into a more usable form */ |
639 | if ((receive_len > 24) && | ||
640 | (ses->server->secMode & (SECMODE_SIGN_REQUIRED | | ||
641 | SECMODE_SIGN_ENABLED))) { | ||
642 | rc = cifs_verify_signature(midQ->resp_buf, | ||
636 | &ses->server->mac_signing_key, | 643 | &ses->server->mac_signing_key, |
637 | midQ->sequence_number+1); | 644 | midQ->sequence_number+1); |
638 | if (rc) { | 645 | if (rc) { |
639 | cERROR(1, ("Unexpected SMB signature")); | 646 | cERROR(1, ("Unexpected SMB signature")); |
640 | /* BB FIXME add code to kill session */ | 647 | /* BB FIXME add code to kill session */ |
641 | } | ||
642 | } | 648 | } |
643 | |||
644 | /* BB special case reconnect tid and uid here? */ | ||
645 | rc = map_smb_to_linux_error(midQ->resp_buf, | ||
646 | flags & CIFS_LOG_ERROR); | ||
647 | |||
648 | /* convert ByteCount if necessary */ | ||
649 | if (receive_len >= sizeof(struct smb_hdr) - 4 | ||
650 | /* do not count RFC1001 header */ + | ||
651 | (2 * midQ->resp_buf->WordCount) + 2 /* bcc */ ) | ||
652 | BCC(midQ->resp_buf) = | ||
653 | le16_to_cpu(BCC_LE(midQ->resp_buf)); | ||
654 | if ((flags & CIFS_NO_RESP) == 0) | ||
655 | midQ->resp_buf = NULL; /* mark it so buf will | ||
656 | not be freed by | ||
657 | DeleteMidQEntry */ | ||
658 | } else { | ||
659 | rc = -EIO; | ||
660 | cFYI(1, ("Bad MID state?")); | ||
661 | } | 649 | } |
650 | |||
651 | /* BB special case reconnect tid and uid here? */ | ||
652 | rc = map_smb_to_linux_error(midQ->resp_buf, | ||
653 | flags & CIFS_LOG_ERROR); | ||
654 | |||
655 | /* convert ByteCount if necessary */ | ||
656 | if (receive_len >= sizeof(struct smb_hdr) - 4 | ||
657 | /* do not count RFC1001 header */ + | ||
658 | (2 * midQ->resp_buf->WordCount) + 2 /* bcc */ ) | ||
659 | BCC(midQ->resp_buf) = | ||
660 | le16_to_cpu(BCC_LE(midQ->resp_buf)); | ||
661 | if ((flags & CIFS_NO_RESP) == 0) | ||
662 | midQ->resp_buf = NULL; /* mark it so buf will | ||
663 | not be freed by | ||
664 | DeleteMidQEntry */ | ||
665 | } else { | ||
666 | rc = -EIO; | ||
667 | cFYI(1, ("Bad MID state?")); | ||
662 | } | 668 | } |
663 | 669 | ||
664 | out: | 670 | out: |
@@ -695,6 +701,12 @@ SendReceive(const unsigned int xid, struct cifsSesInfo *ses, | |||
695 | to the same server. We may make this configurable later or | 701 | to the same server. We may make this configurable later or |
696 | use ses->maxReq */ | 702 | use ses->maxReq */ |
697 | 703 | ||
704 | if (in_buf->smb_buf_length > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE - 4) { | ||
705 | cERROR(1, ("Illegal length, greater than maximum frame, %d", | ||
706 | in_buf->smb_buf_length)); | ||
707 | return -EIO; | ||
708 | } | ||
709 | |||
698 | rc = wait_for_free_request(ses, long_op); | 710 | rc = wait_for_free_request(ses, long_op); |
699 | if (rc) | 711 | if (rc) |
700 | return rc; | 712 | return rc; |
@@ -703,29 +715,22 @@ SendReceive(const unsigned int xid, struct cifsSesInfo *ses, | |||
703 | and avoid races inside tcp sendmsg code that could cause corruption | 715 | and avoid races inside tcp sendmsg code that could cause corruption |
704 | of smb data */ | 716 | of smb data */ |
705 | 717 | ||
706 | down(&ses->server->tcpSem); | 718 | mutex_lock(&ses->server->srv_mutex); |
707 | 719 | ||
708 | rc = allocate_mid(ses, in_buf, &midQ); | 720 | rc = allocate_mid(ses, in_buf, &midQ); |
709 | if (rc) { | 721 | if (rc) { |
710 | up(&ses->server->tcpSem); | 722 | mutex_unlock(&ses->server->srv_mutex); |
711 | /* Update # of requests on wire to server */ | 723 | /* Update # of requests on wire to server */ |
712 | atomic_dec(&ses->server->inFlight); | 724 | atomic_dec(&ses->server->inFlight); |
713 | wake_up(&ses->server->request_q); | 725 | wake_up(&ses->server->request_q); |
714 | return rc; | 726 | return rc; |
715 | } | 727 | } |
716 | 728 | ||
717 | if (in_buf->smb_buf_length > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE - 4) { | ||
718 | cERROR(1, ("Illegal length, greater than maximum frame, %d", | ||
719 | in_buf->smb_buf_length)); | ||
720 | DeleteMidQEntry(midQ); | ||
721 | up(&ses->server->tcpSem); | ||
722 | /* Update # of requests on wire to server */ | ||
723 | atomic_dec(&ses->server->inFlight); | ||
724 | wake_up(&ses->server->request_q); | ||
725 | return -EIO; | ||
726 | } | ||
727 | |||
728 | rc = cifs_sign_smb(in_buf, ses->server, &midQ->sequence_number); | 729 | rc = cifs_sign_smb(in_buf, ses->server, &midQ->sequence_number); |
730 | if (rc) { | ||
731 | mutex_unlock(&ses->server->srv_mutex); | ||
732 | goto out; | ||
733 | } | ||
729 | 734 | ||
730 | midQ->midState = MID_REQUEST_SUBMITTED; | 735 | midQ->midState = MID_REQUEST_SUBMITTED; |
731 | #ifdef CONFIG_CIFS_STATS2 | 736 | #ifdef CONFIG_CIFS_STATS2 |
@@ -738,7 +743,7 @@ SendReceive(const unsigned int xid, struct cifsSesInfo *ses, | |||
738 | atomic_dec(&ses->server->inSend); | 743 | atomic_dec(&ses->server->inSend); |
739 | midQ->when_sent = jiffies; | 744 | midQ->when_sent = jiffies; |
740 | #endif | 745 | #endif |
741 | up(&ses->server->tcpSem); | 746 | mutex_unlock(&ses->server->srv_mutex); |
742 | 747 | ||
743 | if (rc < 0) | 748 | if (rc < 0) |
744 | goto out; | 749 | goto out; |
@@ -772,10 +777,7 @@ SendReceive(const unsigned int xid, struct cifsSesInfo *ses, | |||
772 | wait_for_response(ses, midQ, timeout, 10 * HZ); | 777 | wait_for_response(ses, midQ, timeout, 10 * HZ); |
773 | 778 | ||
774 | spin_lock(&GlobalMid_Lock); | 779 | spin_lock(&GlobalMid_Lock); |
775 | if (midQ->resp_buf) { | 780 | if (midQ->resp_buf == NULL) { |
776 | spin_unlock(&GlobalMid_Lock); | ||
777 | receive_len = midQ->resp_buf->smb_buf_length; | ||
778 | } else { | ||
779 | cERROR(1, ("No response for cmd %d mid %d", | 781 | cERROR(1, ("No response for cmd %d mid %d", |
780 | midQ->command, midQ->mid)); | 782 | midQ->command, midQ->mid)); |
781 | if (midQ->midState == MID_REQUEST_SUBMITTED) { | 783 | if (midQ->midState == MID_REQUEST_SUBMITTED) { |
@@ -803,47 +805,52 @@ SendReceive(const unsigned int xid, struct cifsSesInfo *ses, | |||
803 | return rc; | 805 | return rc; |
804 | } | 806 | } |
805 | 807 | ||
808 | spin_unlock(&GlobalMid_Lock); | ||
809 | receive_len = midQ->resp_buf->smb_buf_length; | ||
810 | |||
806 | if (receive_len > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE) { | 811 | if (receive_len > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE) { |
807 | cERROR(1, ("Frame too large received. Length: %d Xid: %d", | 812 | cERROR(1, ("Frame too large received. Length: %d Xid: %d", |
808 | receive_len, xid)); | 813 | receive_len, xid)); |
809 | rc = -EIO; | 814 | rc = -EIO; |
810 | } else { /* rcvd frame is ok */ | 815 | goto out; |
811 | 816 | } | |
812 | if (midQ->resp_buf && out_buf | 817 | |
813 | && (midQ->midState == MID_RESPONSE_RECEIVED)) { | 818 | /* rcvd frame is ok */ |
814 | out_buf->smb_buf_length = receive_len; | 819 | |
815 | memcpy((char *)out_buf + 4, | 820 | if (midQ->resp_buf && out_buf |
816 | (char *)midQ->resp_buf + 4, | 821 | && (midQ->midState == MID_RESPONSE_RECEIVED)) { |
817 | receive_len); | 822 | out_buf->smb_buf_length = receive_len; |
818 | 823 | memcpy((char *)out_buf + 4, | |
819 | dump_smb(out_buf, 92); | 824 | (char *)midQ->resp_buf + 4, |
820 | /* convert the length into a more usable form */ | 825 | receive_len); |
821 | if ((receive_len > 24) && | 826 | |
822 | (ses->server->secMode & (SECMODE_SIGN_REQUIRED | | 827 | dump_smb(out_buf, 92); |
823 | SECMODE_SIGN_ENABLED))) { | 828 | /* convert the length into a more usable form */ |
824 | rc = cifs_verify_signature(out_buf, | 829 | if ((receive_len > 24) && |
830 | (ses->server->secMode & (SECMODE_SIGN_REQUIRED | | ||
831 | SECMODE_SIGN_ENABLED))) { | ||
832 | rc = cifs_verify_signature(out_buf, | ||
825 | &ses->server->mac_signing_key, | 833 | &ses->server->mac_signing_key, |
826 | midQ->sequence_number+1); | 834 | midQ->sequence_number+1); |
827 | if (rc) { | 835 | if (rc) { |
828 | cERROR(1, ("Unexpected SMB signature")); | 836 | cERROR(1, ("Unexpected SMB signature")); |
829 | /* BB FIXME add code to kill session */ | 837 | /* BB FIXME add code to kill session */ |
830 | } | ||
831 | } | 838 | } |
839 | } | ||
832 | 840 | ||
833 | *pbytes_returned = out_buf->smb_buf_length; | 841 | *pbytes_returned = out_buf->smb_buf_length; |
834 | 842 | ||
835 | /* BB special case reconnect tid and uid here? */ | 843 | /* BB special case reconnect tid and uid here? */ |
836 | rc = map_smb_to_linux_error(out_buf, 0 /* no log */ ); | 844 | rc = map_smb_to_linux_error(out_buf, 0 /* no log */ ); |
837 | 845 | ||
838 | /* convert ByteCount if necessary */ | 846 | /* convert ByteCount if necessary */ |
839 | if (receive_len >= sizeof(struct smb_hdr) - 4 | 847 | if (receive_len >= sizeof(struct smb_hdr) - 4 |
840 | /* do not count RFC1001 header */ + | 848 | /* do not count RFC1001 header */ + |
841 | (2 * out_buf->WordCount) + 2 /* bcc */ ) | 849 | (2 * out_buf->WordCount) + 2 /* bcc */ ) |
842 | BCC(out_buf) = le16_to_cpu(BCC_LE(out_buf)); | 850 | BCC(out_buf) = le16_to_cpu(BCC_LE(out_buf)); |
843 | } else { | 851 | } else { |
844 | rc = -EIO; | 852 | rc = -EIO; |
845 | cERROR(1, ("Bad MID state?")); | 853 | cERROR(1, ("Bad MID state?")); |
846 | } | ||
847 | } | 854 | } |
848 | 855 | ||
849 | out: | 856 | out: |
@@ -866,16 +873,16 @@ send_nt_cancel(struct cifsTconInfo *tcon, struct smb_hdr *in_buf, | |||
866 | 873 | ||
867 | header_assemble(in_buf, SMB_COM_NT_CANCEL, tcon, 0); | 874 | header_assemble(in_buf, SMB_COM_NT_CANCEL, tcon, 0); |
868 | in_buf->Mid = mid; | 875 | in_buf->Mid = mid; |
869 | down(&ses->server->tcpSem); | 876 | mutex_lock(&ses->server->srv_mutex); |
870 | rc = cifs_sign_smb(in_buf, ses->server, &midQ->sequence_number); | 877 | rc = cifs_sign_smb(in_buf, ses->server, &midQ->sequence_number); |
871 | if (rc) { | 878 | if (rc) { |
872 | up(&ses->server->tcpSem); | 879 | mutex_unlock(&ses->server->srv_mutex); |
873 | return rc; | 880 | return rc; |
874 | } | 881 | } |
875 | rc = smb_send(ses->server->ssocket, in_buf, in_buf->smb_buf_length, | 882 | rc = smb_send(ses->server->ssocket, in_buf, in_buf->smb_buf_length, |
876 | (struct sockaddr *) &(ses->server->addr.sockAddr), | 883 | (struct sockaddr *) &(ses->server->addr.sockAddr), |
877 | ses->server->noblocksnd); | 884 | ses->server->noblocksnd); |
878 | up(&ses->server->tcpSem); | 885 | mutex_unlock(&ses->server->srv_mutex); |
879 | return rc; | 886 | return rc; |
880 | } | 887 | } |
881 | 888 | ||
@@ -933,6 +940,12 @@ SendReceiveBlockingLock(const unsigned int xid, struct cifsTconInfo *tcon, | |||
933 | to the same server. We may make this configurable later or | 940 | to the same server. We may make this configurable later or |
934 | use ses->maxReq */ | 941 | use ses->maxReq */ |
935 | 942 | ||
943 | if (in_buf->smb_buf_length > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE - 4) { | ||
944 | cERROR(1, ("Illegal length, greater than maximum frame, %d", | ||
945 | in_buf->smb_buf_length)); | ||
946 | return -EIO; | ||
947 | } | ||
948 | |||
936 | rc = wait_for_free_request(ses, CIFS_BLOCKING_OP); | 949 | rc = wait_for_free_request(ses, CIFS_BLOCKING_OP); |
937 | if (rc) | 950 | if (rc) |
938 | return rc; | 951 | return rc; |
@@ -941,24 +954,21 @@ SendReceiveBlockingLock(const unsigned int xid, struct cifsTconInfo *tcon, | |||
941 | and avoid races inside tcp sendmsg code that could cause corruption | 954 | and avoid races inside tcp sendmsg code that could cause corruption |
942 | of smb data */ | 955 | of smb data */ |
943 | 956 | ||
944 | down(&ses->server->tcpSem); | 957 | mutex_lock(&ses->server->srv_mutex); |
945 | 958 | ||
946 | rc = allocate_mid(ses, in_buf, &midQ); | 959 | rc = allocate_mid(ses, in_buf, &midQ); |
947 | if (rc) { | 960 | if (rc) { |
948 | up(&ses->server->tcpSem); | 961 | mutex_unlock(&ses->server->srv_mutex); |
949 | return rc; | 962 | return rc; |
950 | } | 963 | } |
951 | 964 | ||
952 | if (in_buf->smb_buf_length > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE - 4) { | 965 | rc = cifs_sign_smb(in_buf, ses->server, &midQ->sequence_number); |
953 | up(&ses->server->tcpSem); | 966 | if (rc) { |
954 | cERROR(1, ("Illegal length, greater than maximum frame, %d", | ||
955 | in_buf->smb_buf_length)); | ||
956 | DeleteMidQEntry(midQ); | 967 | DeleteMidQEntry(midQ); |
957 | return -EIO; | 968 | mutex_unlock(&ses->server->srv_mutex); |
969 | return rc; | ||
958 | } | 970 | } |
959 | 971 | ||
960 | rc = cifs_sign_smb(in_buf, ses->server, &midQ->sequence_number); | ||
961 | |||
962 | midQ->midState = MID_REQUEST_SUBMITTED; | 972 | midQ->midState = MID_REQUEST_SUBMITTED; |
963 | #ifdef CONFIG_CIFS_STATS2 | 973 | #ifdef CONFIG_CIFS_STATS2 |
964 | atomic_inc(&ses->server->inSend); | 974 | atomic_inc(&ses->server->inSend); |
@@ -970,7 +980,7 @@ SendReceiveBlockingLock(const unsigned int xid, struct cifsTconInfo *tcon, | |||
970 | atomic_dec(&ses->server->inSend); | 980 | atomic_dec(&ses->server->inSend); |
971 | midQ->when_sent = jiffies; | 981 | midQ->when_sent = jiffies; |
972 | #endif | 982 | #endif |
973 | up(&ses->server->tcpSem); | 983 | mutex_unlock(&ses->server->srv_mutex); |
974 | 984 | ||
975 | if (rc < 0) { | 985 | if (rc < 0) { |
976 | DeleteMidQEntry(midQ); | 986 | DeleteMidQEntry(midQ); |
@@ -1052,44 +1062,48 @@ SendReceiveBlockingLock(const unsigned int xid, struct cifsTconInfo *tcon, | |||
1052 | cERROR(1, ("Frame too large received. Length: %d Xid: %d", | 1062 | cERROR(1, ("Frame too large received. Length: %d Xid: %d", |
1053 | receive_len, xid)); | 1063 | receive_len, xid)); |
1054 | rc = -EIO; | 1064 | rc = -EIO; |
1055 | } else { /* rcvd frame is ok */ | 1065 | goto out; |
1056 | 1066 | } | |
1057 | if (midQ->resp_buf && out_buf | ||
1058 | && (midQ->midState == MID_RESPONSE_RECEIVED)) { | ||
1059 | out_buf->smb_buf_length = receive_len; | ||
1060 | memcpy((char *)out_buf + 4, | ||
1061 | (char *)midQ->resp_buf + 4, | ||
1062 | receive_len); | ||
1063 | |||
1064 | dump_smb(out_buf, 92); | ||
1065 | /* convert the length into a more usable form */ | ||
1066 | if ((receive_len > 24) && | ||
1067 | (ses->server->secMode & (SECMODE_SIGN_REQUIRED | | ||
1068 | SECMODE_SIGN_ENABLED))) { | ||
1069 | rc = cifs_verify_signature(out_buf, | ||
1070 | &ses->server->mac_signing_key, | ||
1071 | midQ->sequence_number+1); | ||
1072 | if (rc) { | ||
1073 | cERROR(1, ("Unexpected SMB signature")); | ||
1074 | /* BB FIXME add code to kill session */ | ||
1075 | } | ||
1076 | } | ||
1077 | 1067 | ||
1078 | *pbytes_returned = out_buf->smb_buf_length; | 1068 | /* rcvd frame is ok */ |
1079 | 1069 | ||
1080 | /* BB special case reconnect tid and uid here? */ | 1070 | if ((out_buf == NULL) || (midQ->midState != MID_RESPONSE_RECEIVED)) { |
1081 | rc = map_smb_to_linux_error(out_buf, 0 /* no log */ ); | 1071 | rc = -EIO; |
1072 | cERROR(1, ("Bad MID state?")); | ||
1073 | goto out; | ||
1074 | } | ||
1082 | 1075 | ||
1083 | /* convert ByteCount if necessary */ | 1076 | out_buf->smb_buf_length = receive_len; |
1084 | if (receive_len >= sizeof(struct smb_hdr) - 4 | 1077 | memcpy((char *)out_buf + 4, |
1085 | /* do not count RFC1001 header */ + | 1078 | (char *)midQ->resp_buf + 4, |
1086 | (2 * out_buf->WordCount) + 2 /* bcc */ ) | 1079 | receive_len); |
1087 | BCC(out_buf) = le16_to_cpu(BCC_LE(out_buf)); | 1080 | |
1088 | } else { | 1081 | dump_smb(out_buf, 92); |
1089 | rc = -EIO; | 1082 | /* convert the length into a more usable form */ |
1090 | cERROR(1, ("Bad MID state?")); | 1083 | if ((receive_len > 24) && |
1084 | (ses->server->secMode & (SECMODE_SIGN_REQUIRED | | ||
1085 | SECMODE_SIGN_ENABLED))) { | ||
1086 | rc = cifs_verify_signature(out_buf, | ||
1087 | &ses->server->mac_signing_key, | ||
1088 | midQ->sequence_number+1); | ||
1089 | if (rc) { | ||
1090 | cERROR(1, ("Unexpected SMB signature")); | ||
1091 | /* BB FIXME add code to kill session */ | ||
1091 | } | 1092 | } |
1092 | } | 1093 | } |
1094 | |||
1095 | *pbytes_returned = out_buf->smb_buf_length; | ||
1096 | |||
1097 | /* BB special case reconnect tid and uid here? */ | ||
1098 | rc = map_smb_to_linux_error(out_buf, 0 /* no log */ ); | ||
1099 | |||
1100 | /* convert ByteCount if necessary */ | ||
1101 | if (receive_len >= sizeof(struct smb_hdr) - 4 | ||
1102 | /* do not count RFC1001 header */ + | ||
1103 | (2 * out_buf->WordCount) + 2 /* bcc */ ) | ||
1104 | BCC(out_buf) = le16_to_cpu(BCC_LE(out_buf)); | ||
1105 | |||
1106 | out: | ||
1093 | DeleteMidQEntry(midQ); | 1107 | DeleteMidQEntry(midQ); |
1094 | if (rstart && rc == -EACCES) | 1108 | if (rstart && rc == -EACCES) |
1095 | return -ERESTARTSYS; | 1109 | return -ERESTARTSYS; |
diff --git a/fs/coda/cache.c b/fs/coda/cache.c index 8a2370341c7a..a5bf5771a22a 100644 --- a/fs/coda/cache.c +++ b/fs/coda/cache.c | |||
@@ -32,8 +32,8 @@ void coda_cache_enter(struct inode *inode, int mask) | |||
32 | struct coda_inode_info *cii = ITOC(inode); | 32 | struct coda_inode_info *cii = ITOC(inode); |
33 | 33 | ||
34 | cii->c_cached_epoch = atomic_read(&permission_epoch); | 34 | cii->c_cached_epoch = atomic_read(&permission_epoch); |
35 | if (cii->c_uid != current->fsuid) { | 35 | if (cii->c_uid != current_fsuid()) { |
36 | cii->c_uid = current->fsuid; | 36 | cii->c_uid = current_fsuid(); |
37 | cii->c_cached_perm = mask; | 37 | cii->c_cached_perm = mask; |
38 | } else | 38 | } else |
39 | cii->c_cached_perm |= mask; | 39 | cii->c_cached_perm |= mask; |
@@ -60,7 +60,7 @@ int coda_cache_check(struct inode *inode, int mask) | |||
60 | int hit; | 60 | int hit; |
61 | 61 | ||
62 | hit = (mask & cii->c_cached_perm) == mask && | 62 | hit = (mask & cii->c_cached_perm) == mask && |
63 | cii->c_uid == current->fsuid && | 63 | cii->c_uid == current_fsuid() && |
64 | cii->c_cached_epoch == atomic_read(&permission_epoch); | 64 | cii->c_cached_epoch == atomic_read(&permission_epoch); |
65 | 65 | ||
66 | return hit; | 66 | return hit; |
diff --git a/fs/coda/file.c b/fs/coda/file.c index 29137ff3ca67..466303db2df6 100644 --- a/fs/coda/file.c +++ b/fs/coda/file.c | |||
@@ -13,6 +13,7 @@ | |||
13 | #include <linux/file.h> | 13 | #include <linux/file.h> |
14 | #include <linux/fs.h> | 14 | #include <linux/fs.h> |
15 | #include <linux/stat.h> | 15 | #include <linux/stat.h> |
16 | #include <linux/cred.h> | ||
16 | #include <linux/errno.h> | 17 | #include <linux/errno.h> |
17 | #include <linux/smp_lock.h> | 18 | #include <linux/smp_lock.h> |
18 | #include <linux/string.h> | 19 | #include <linux/string.h> |
@@ -174,7 +175,7 @@ int coda_release(struct inode *coda_inode, struct file *coda_file) | |||
174 | BUG_ON(!cfi || cfi->cfi_magic != CODA_MAGIC); | 175 | BUG_ON(!cfi || cfi->cfi_magic != CODA_MAGIC); |
175 | 176 | ||
176 | err = venus_close(coda_inode->i_sb, coda_i2f(coda_inode), | 177 | err = venus_close(coda_inode->i_sb, coda_i2f(coda_inode), |
177 | coda_flags, coda_file->f_uid); | 178 | coda_flags, coda_file->f_cred->fsuid); |
178 | 179 | ||
179 | host_inode = cfi->cfi_container->f_path.dentry->d_inode; | 180 | host_inode = cfi->cfi_container->f_path.dentry->d_inode; |
180 | cii = ITOC(coda_inode); | 181 | cii = ITOC(coda_inode); |
diff --git a/fs/coda/upcall.c b/fs/coda/upcall.c index ce432bca95d1..c274d949179d 100644 --- a/fs/coda/upcall.c +++ b/fs/coda/upcall.c | |||
@@ -52,7 +52,7 @@ static void *alloc_upcall(int opcode, int size) | |||
52 | inp->ih.opcode = opcode; | 52 | inp->ih.opcode = opcode; |
53 | inp->ih.pid = current->pid; | 53 | inp->ih.pid = current->pid; |
54 | inp->ih.pgid = task_pgrp_nr(current); | 54 | inp->ih.pgid = task_pgrp_nr(current); |
55 | inp->ih.uid = current->fsuid; | 55 | inp->ih.uid = current_fsuid(); |
56 | 56 | ||
57 | return (void*)inp; | 57 | return (void*)inp; |
58 | } | 58 | } |
diff --git a/fs/compat.c b/fs/compat.c index e5f49f538502..d1ece79b6411 100644 --- a/fs/compat.c +++ b/fs/compat.c | |||
@@ -1393,10 +1393,20 @@ int compat_do_execve(char * filename, | |||
1393 | if (!bprm) | 1393 | if (!bprm) |
1394 | goto out_ret; | 1394 | goto out_ret; |
1395 | 1395 | ||
1396 | retval = mutex_lock_interruptible(¤t->cred_exec_mutex); | ||
1397 | if (retval < 0) | ||
1398 | goto out_free; | ||
1399 | |||
1400 | retval = -ENOMEM; | ||
1401 | bprm->cred = prepare_exec_creds(); | ||
1402 | if (!bprm->cred) | ||
1403 | goto out_unlock; | ||
1404 | check_unsafe_exec(bprm); | ||
1405 | |||
1396 | file = open_exec(filename); | 1406 | file = open_exec(filename); |
1397 | retval = PTR_ERR(file); | 1407 | retval = PTR_ERR(file); |
1398 | if (IS_ERR(file)) | 1408 | if (IS_ERR(file)) |
1399 | goto out_kfree; | 1409 | goto out_unlock; |
1400 | 1410 | ||
1401 | sched_exec(); | 1411 | sched_exec(); |
1402 | 1412 | ||
@@ -1410,14 +1420,10 @@ int compat_do_execve(char * filename, | |||
1410 | 1420 | ||
1411 | bprm->argc = compat_count(argv, MAX_ARG_STRINGS); | 1421 | bprm->argc = compat_count(argv, MAX_ARG_STRINGS); |
1412 | if ((retval = bprm->argc) < 0) | 1422 | if ((retval = bprm->argc) < 0) |
1413 | goto out_mm; | 1423 | goto out; |
1414 | 1424 | ||
1415 | bprm->envc = compat_count(envp, MAX_ARG_STRINGS); | 1425 | bprm->envc = compat_count(envp, MAX_ARG_STRINGS); |
1416 | if ((retval = bprm->envc) < 0) | 1426 | if ((retval = bprm->envc) < 0) |
1417 | goto out_mm; | ||
1418 | |||
1419 | retval = security_bprm_alloc(bprm); | ||
1420 | if (retval) | ||
1421 | goto out; | 1427 | goto out; |
1422 | 1428 | ||
1423 | retval = prepare_binprm(bprm); | 1429 | retval = prepare_binprm(bprm); |
@@ -1438,19 +1444,16 @@ int compat_do_execve(char * filename, | |||
1438 | goto out; | 1444 | goto out; |
1439 | 1445 | ||
1440 | retval = search_binary_handler(bprm, regs); | 1446 | retval = search_binary_handler(bprm, regs); |
1441 | if (retval >= 0) { | 1447 | if (retval < 0) |
1442 | /* execve success */ | 1448 | goto out; |
1443 | security_bprm_free(bprm); | ||
1444 | acct_update_integrals(current); | ||
1445 | free_bprm(bprm); | ||
1446 | return retval; | ||
1447 | } | ||
1448 | 1449 | ||
1449 | out: | 1450 | /* execve succeeded */ |
1450 | if (bprm->security) | 1451 | mutex_unlock(¤t->cred_exec_mutex); |
1451 | security_bprm_free(bprm); | 1452 | acct_update_integrals(current); |
1453 | free_bprm(bprm); | ||
1454 | return retval; | ||
1452 | 1455 | ||
1453 | out_mm: | 1456 | out: |
1454 | if (bprm->mm) | 1457 | if (bprm->mm) |
1455 | mmput(bprm->mm); | 1458 | mmput(bprm->mm); |
1456 | 1459 | ||
@@ -1460,7 +1463,10 @@ out_file: | |||
1460 | fput(bprm->file); | 1463 | fput(bprm->file); |
1461 | } | 1464 | } |
1462 | 1465 | ||
1463 | out_kfree: | 1466 | out_unlock: |
1467 | mutex_unlock(¤t->cred_exec_mutex); | ||
1468 | |||
1469 | out_free: | ||
1464 | free_bprm(bprm); | 1470 | free_bprm(bprm); |
1465 | 1471 | ||
1466 | out_ret: | 1472 | out_ret: |
diff --git a/fs/devpts/inode.c b/fs/devpts/inode.c index 4a714f6c1bed..5d61b7c06e13 100644 --- a/fs/devpts/inode.c +++ b/fs/devpts/inode.c | |||
@@ -222,8 +222,8 @@ int devpts_pty_new(struct inode *ptmx_inode, struct tty_struct *tty) | |||
222 | return -ENOMEM; | 222 | return -ENOMEM; |
223 | 223 | ||
224 | inode->i_ino = number+2; | 224 | inode->i_ino = number+2; |
225 | inode->i_uid = config.setuid ? config.uid : current->fsuid; | 225 | inode->i_uid = config.setuid ? config.uid : current_fsuid(); |
226 | inode->i_gid = config.setgid ? config.gid : current->fsgid; | 226 | inode->i_gid = config.setgid ? config.gid : current_fsgid(); |
227 | inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME; | 227 | inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME; |
228 | init_special_inode(inode, S_IFCHR|config.mode, device); | 228 | init_special_inode(inode, S_IFCHR|config.mode, device); |
229 | inode->i_private = tty; | 229 | inode->i_private = tty; |
diff --git a/fs/dlm/netlink.c b/fs/dlm/netlink.c index 18bda83cc892..aa2a5775a027 100644 --- a/fs/dlm/netlink.c +++ b/fs/dlm/netlink.c | |||
@@ -127,8 +127,8 @@ static void fill_data(struct dlm_lock_data *data, struct dlm_lkb *lkb) | |||
127 | 127 | ||
128 | void dlm_timeout_warn(struct dlm_lkb *lkb) | 128 | void dlm_timeout_warn(struct dlm_lkb *lkb) |
129 | { | 129 | { |
130 | struct sk_buff *uninitialized_var(send_skb); | ||
130 | struct dlm_lock_data *data; | 131 | struct dlm_lock_data *data; |
131 | struct sk_buff *send_skb; | ||
132 | size_t size; | 132 | size_t size; |
133 | int rv; | 133 | int rv; |
134 | 134 | ||
diff --git a/fs/dquot.c b/fs/dquot.c index 5e95261005b2..c237ccc8581c 100644 --- a/fs/dquot.c +++ b/fs/dquot.c | |||
@@ -874,7 +874,7 @@ static inline int need_print_warning(struct dquot *dquot) | |||
874 | 874 | ||
875 | switch (dquot->dq_type) { | 875 | switch (dquot->dq_type) { |
876 | case USRQUOTA: | 876 | case USRQUOTA: |
877 | return current->fsuid == dquot->dq_id; | 877 | return current_fsuid() == dquot->dq_id; |
878 | case GRPQUOTA: | 878 | case GRPQUOTA: |
879 | return in_group_p(dquot->dq_id); | 879 | return in_group_p(dquot->dq_id); |
880 | } | 880 | } |
@@ -981,7 +981,7 @@ static void send_warning(const struct dquot *dquot, const char warntype) | |||
981 | MINOR(dquot->dq_sb->s_dev)); | 981 | MINOR(dquot->dq_sb->s_dev)); |
982 | if (ret) | 982 | if (ret) |
983 | goto attr_err_out; | 983 | goto attr_err_out; |
984 | ret = nla_put_u64(skb, QUOTA_NL_A_CAUSED_ID, current->user->uid); | 984 | ret = nla_put_u64(skb, QUOTA_NL_A_CAUSED_ID, current_uid()); |
985 | if (ret) | 985 | if (ret) |
986 | goto attr_err_out; | 986 | goto attr_err_out; |
987 | genlmsg_end(skb, msg_head); | 987 | genlmsg_end(skb, msg_head); |
diff --git a/fs/ecryptfs/ecryptfs_kernel.h b/fs/ecryptfs/ecryptfs_kernel.h index 3504cf9df358..a75026d35d16 100644 --- a/fs/ecryptfs/ecryptfs_kernel.h +++ b/fs/ecryptfs/ecryptfs_kernel.h | |||
@@ -691,7 +691,8 @@ int ecryptfs_init_kthread(void); | |||
691 | void ecryptfs_destroy_kthread(void); | 691 | void ecryptfs_destroy_kthread(void); |
692 | int ecryptfs_privileged_open(struct file **lower_file, | 692 | int ecryptfs_privileged_open(struct file **lower_file, |
693 | struct dentry *lower_dentry, | 693 | struct dentry *lower_dentry, |
694 | struct vfsmount *lower_mnt); | 694 | struct vfsmount *lower_mnt, |
695 | const struct cred *cred); | ||
695 | int ecryptfs_init_persistent_file(struct dentry *ecryptfs_dentry); | 696 | int ecryptfs_init_persistent_file(struct dentry *ecryptfs_dentry); |
696 | 697 | ||
697 | #endif /* #ifndef ECRYPTFS_KERNEL_H */ | 698 | #endif /* #ifndef ECRYPTFS_KERNEL_H */ |
diff --git a/fs/ecryptfs/kthread.c b/fs/ecryptfs/kthread.c index c440c6b58b2d..c6d7a4d748a0 100644 --- a/fs/ecryptfs/kthread.c +++ b/fs/ecryptfs/kthread.c | |||
@@ -73,7 +73,7 @@ static int ecryptfs_threadfn(void *ignored) | |||
73 | mntget(req->lower_mnt); | 73 | mntget(req->lower_mnt); |
74 | (*req->lower_file) = dentry_open( | 74 | (*req->lower_file) = dentry_open( |
75 | req->lower_dentry, req->lower_mnt, | 75 | req->lower_dentry, req->lower_mnt, |
76 | (O_RDWR | O_LARGEFILE)); | 76 | (O_RDWR | O_LARGEFILE), current_cred()); |
77 | req->flags |= ECRYPTFS_REQ_PROCESSED; | 77 | req->flags |= ECRYPTFS_REQ_PROCESSED; |
78 | } | 78 | } |
79 | wake_up(&req->wait); | 79 | wake_up(&req->wait); |
@@ -132,7 +132,8 @@ void ecryptfs_destroy_kthread(void) | |||
132 | */ | 132 | */ |
133 | int ecryptfs_privileged_open(struct file **lower_file, | 133 | int ecryptfs_privileged_open(struct file **lower_file, |
134 | struct dentry *lower_dentry, | 134 | struct dentry *lower_dentry, |
135 | struct vfsmount *lower_mnt) | 135 | struct vfsmount *lower_mnt, |
136 | const struct cred *cred) | ||
136 | { | 137 | { |
137 | struct ecryptfs_open_req *req; | 138 | struct ecryptfs_open_req *req; |
138 | int rc = 0; | 139 | int rc = 0; |
@@ -143,7 +144,7 @@ int ecryptfs_privileged_open(struct file **lower_file, | |||
143 | dget(lower_dentry); | 144 | dget(lower_dentry); |
144 | mntget(lower_mnt); | 145 | mntget(lower_mnt); |
145 | (*lower_file) = dentry_open(lower_dentry, lower_mnt, | 146 | (*lower_file) = dentry_open(lower_dentry, lower_mnt, |
146 | (O_RDWR | O_LARGEFILE)); | 147 | (O_RDWR | O_LARGEFILE), cred); |
147 | if (!IS_ERR(*lower_file)) | 148 | if (!IS_ERR(*lower_file)) |
148 | goto out; | 149 | goto out; |
149 | req = kmem_cache_alloc(ecryptfs_open_req_cache, GFP_KERNEL); | 150 | req = kmem_cache_alloc(ecryptfs_open_req_cache, GFP_KERNEL); |
@@ -184,7 +185,7 @@ int ecryptfs_privileged_open(struct file **lower_file, | |||
184 | dget(lower_dentry); | 185 | dget(lower_dentry); |
185 | mntget(lower_mnt); | 186 | mntget(lower_mnt); |
186 | (*lower_file) = dentry_open(lower_dentry, lower_mnt, | 187 | (*lower_file) = dentry_open(lower_dentry, lower_mnt, |
187 | (O_RDONLY | O_LARGEFILE)); | 188 | (O_RDONLY | O_LARGEFILE), cred); |
188 | if (IS_ERR(*lower_file)) { | 189 | if (IS_ERR(*lower_file)) { |
189 | rc = PTR_ERR(*req->lower_file); | 190 | rc = PTR_ERR(*req->lower_file); |
190 | (*lower_file) = NULL; | 191 | (*lower_file) = NULL; |
diff --git a/fs/ecryptfs/main.c b/fs/ecryptfs/main.c index 64d2ba980df4..fd630713c5c7 100644 --- a/fs/ecryptfs/main.c +++ b/fs/ecryptfs/main.c | |||
@@ -115,6 +115,7 @@ void __ecryptfs_printk(const char *fmt, ...) | |||
115 | */ | 115 | */ |
116 | int ecryptfs_init_persistent_file(struct dentry *ecryptfs_dentry) | 116 | int ecryptfs_init_persistent_file(struct dentry *ecryptfs_dentry) |
117 | { | 117 | { |
118 | const struct cred *cred = current_cred(); | ||
118 | struct ecryptfs_inode_info *inode_info = | 119 | struct ecryptfs_inode_info *inode_info = |
119 | ecryptfs_inode_to_private(ecryptfs_dentry->d_inode); | 120 | ecryptfs_inode_to_private(ecryptfs_dentry->d_inode); |
120 | int rc = 0; | 121 | int rc = 0; |
@@ -127,7 +128,7 @@ int ecryptfs_init_persistent_file(struct dentry *ecryptfs_dentry) | |||
127 | 128 | ||
128 | lower_dentry = ecryptfs_dentry_to_lower(ecryptfs_dentry); | 129 | lower_dentry = ecryptfs_dentry_to_lower(ecryptfs_dentry); |
129 | rc = ecryptfs_privileged_open(&inode_info->lower_file, | 130 | rc = ecryptfs_privileged_open(&inode_info->lower_file, |
130 | lower_dentry, lower_mnt); | 131 | lower_dentry, lower_mnt, cred); |
131 | if (rc || IS_ERR(inode_info->lower_file)) { | 132 | if (rc || IS_ERR(inode_info->lower_file)) { |
132 | printk(KERN_ERR "Error opening lower persistent file " | 133 | printk(KERN_ERR "Error opening lower persistent file " |
133 | "for lower_dentry [0x%p] and lower_mnt [0x%p]; " | 134 | "for lower_dentry [0x%p] and lower_mnt [0x%p]; " |
diff --git a/fs/ecryptfs/messaging.c b/fs/ecryptfs/messaging.c index c6983978a31e..6913f727624d 100644 --- a/fs/ecryptfs/messaging.c +++ b/fs/ecryptfs/messaging.c | |||
@@ -360,7 +360,8 @@ int ecryptfs_process_response(struct ecryptfs_message *msg, uid_t euid, | |||
360 | struct ecryptfs_msg_ctx *msg_ctx; | 360 | struct ecryptfs_msg_ctx *msg_ctx; |
361 | size_t msg_size; | 361 | size_t msg_size; |
362 | struct nsproxy *nsproxy; | 362 | struct nsproxy *nsproxy; |
363 | struct user_namespace *current_user_ns; | 363 | struct user_namespace *tsk_user_ns; |
364 | uid_t ctx_euid; | ||
364 | int rc; | 365 | int rc; |
365 | 366 | ||
366 | if (msg->index >= ecryptfs_message_buf_len) { | 367 | if (msg->index >= ecryptfs_message_buf_len) { |
@@ -384,9 +385,9 @@ int ecryptfs_process_response(struct ecryptfs_message *msg, uid_t euid, | |||
384 | mutex_unlock(&ecryptfs_daemon_hash_mux); | 385 | mutex_unlock(&ecryptfs_daemon_hash_mux); |
385 | goto wake_up; | 386 | goto wake_up; |
386 | } | 387 | } |
387 | current_user_ns = nsproxy->user_ns; | 388 | tsk_user_ns = __task_cred(msg_ctx->task)->user->user_ns; |
388 | rc = ecryptfs_find_daemon_by_euid(&daemon, msg_ctx->task->euid, | 389 | ctx_euid = task_euid(msg_ctx->task); |
389 | current_user_ns); | 390 | rc = ecryptfs_find_daemon_by_euid(&daemon, ctx_euid, tsk_user_ns); |
390 | rcu_read_unlock(); | 391 | rcu_read_unlock(); |
391 | mutex_unlock(&ecryptfs_daemon_hash_mux); | 392 | mutex_unlock(&ecryptfs_daemon_hash_mux); |
392 | if (rc) { | 393 | if (rc) { |
@@ -394,28 +395,28 @@ int ecryptfs_process_response(struct ecryptfs_message *msg, uid_t euid, | |||
394 | printk(KERN_WARNING "%s: User [%d] received a " | 395 | printk(KERN_WARNING "%s: User [%d] received a " |
395 | "message response from process [0x%p] but does " | 396 | "message response from process [0x%p] but does " |
396 | "not have a registered daemon\n", __func__, | 397 | "not have a registered daemon\n", __func__, |
397 | msg_ctx->task->euid, pid); | 398 | ctx_euid, pid); |
398 | goto wake_up; | 399 | goto wake_up; |
399 | } | 400 | } |
400 | if (msg_ctx->task->euid != euid) { | 401 | if (ctx_euid != euid) { |
401 | rc = -EBADMSG; | 402 | rc = -EBADMSG; |
402 | printk(KERN_WARNING "%s: Received message from user " | 403 | printk(KERN_WARNING "%s: Received message from user " |
403 | "[%d]; expected message from user [%d]\n", __func__, | 404 | "[%d]; expected message from user [%d]\n", __func__, |
404 | euid, msg_ctx->task->euid); | 405 | euid, ctx_euid); |
405 | goto unlock; | 406 | goto unlock; |
406 | } | 407 | } |
407 | if (current_user_ns != user_ns) { | 408 | if (tsk_user_ns != user_ns) { |
408 | rc = -EBADMSG; | 409 | rc = -EBADMSG; |
409 | printk(KERN_WARNING "%s: Received message from user_ns " | 410 | printk(KERN_WARNING "%s: Received message from user_ns " |
410 | "[0x%p]; expected message from user_ns [0x%p]\n", | 411 | "[0x%p]; expected message from user_ns [0x%p]\n", |
411 | __func__, user_ns, nsproxy->user_ns); | 412 | __func__, user_ns, tsk_user_ns); |
412 | goto unlock; | 413 | goto unlock; |
413 | } | 414 | } |
414 | if (daemon->pid != pid) { | 415 | if (daemon->pid != pid) { |
415 | rc = -EBADMSG; | 416 | rc = -EBADMSG; |
416 | printk(KERN_ERR "%s: User [%d] sent a message response " | 417 | printk(KERN_ERR "%s: User [%d] sent a message response " |
417 | "from an unrecognized process [0x%p]\n", | 418 | "from an unrecognized process [0x%p]\n", |
418 | __func__, msg_ctx->task->euid, pid); | 419 | __func__, ctx_euid, pid); |
419 | goto unlock; | 420 | goto unlock; |
420 | } | 421 | } |
421 | if (msg_ctx->state != ECRYPTFS_MSG_CTX_STATE_PENDING) { | 422 | 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, | |||
464 | struct ecryptfs_msg_ctx **msg_ctx) | 465 | struct ecryptfs_msg_ctx **msg_ctx) |
465 | { | 466 | { |
466 | struct ecryptfs_daemon *daemon; | 467 | struct ecryptfs_daemon *daemon; |
468 | uid_t euid = current_euid(); | ||
467 | int rc; | 469 | int rc; |
468 | 470 | ||
469 | rc = ecryptfs_find_daemon_by_euid(&daemon, current->euid, | 471 | rc = ecryptfs_find_daemon_by_euid(&daemon, euid, current_user_ns()); |
470 | current->nsproxy->user_ns); | ||
471 | if (rc || !daemon) { | 472 | if (rc || !daemon) { |
472 | rc = -ENOTCONN; | 473 | rc = -ENOTCONN; |
473 | printk(KERN_ERR "%s: User [%d] does not have a daemon " | 474 | printk(KERN_ERR "%s: User [%d] does not have a daemon " |
474 | "registered\n", __func__, current->euid); | 475 | "registered\n", __func__, euid); |
475 | goto out; | 476 | goto out; |
476 | } | 477 | } |
477 | mutex_lock(&ecryptfs_msg_ctx_lists_mux); | 478 | mutex_lock(&ecryptfs_msg_ctx_lists_mux); |
diff --git a/fs/ecryptfs/miscdev.c b/fs/ecryptfs/miscdev.c index b484792a0996..efd95a0ed1ea 100644 --- a/fs/ecryptfs/miscdev.c +++ b/fs/ecryptfs/miscdev.c | |||
@@ -42,12 +42,12 @@ ecryptfs_miscdev_poll(struct file *file, poll_table *pt) | |||
42 | { | 42 | { |
43 | struct ecryptfs_daemon *daemon; | 43 | struct ecryptfs_daemon *daemon; |
44 | unsigned int mask = 0; | 44 | unsigned int mask = 0; |
45 | uid_t euid = current_euid(); | ||
45 | int rc; | 46 | int rc; |
46 | 47 | ||
47 | mutex_lock(&ecryptfs_daemon_hash_mux); | 48 | mutex_lock(&ecryptfs_daemon_hash_mux); |
48 | /* TODO: Just use file->private_data? */ | 49 | /* TODO: Just use file->private_data? */ |
49 | rc = ecryptfs_find_daemon_by_euid(&daemon, current->euid, | 50 | rc = ecryptfs_find_daemon_by_euid(&daemon, euid, current_user_ns()); |
50 | current->nsproxy->user_ns); | ||
51 | BUG_ON(rc || !daemon); | 51 | BUG_ON(rc || !daemon); |
52 | mutex_lock(&daemon->mux); | 52 | mutex_lock(&daemon->mux); |
53 | mutex_unlock(&ecryptfs_daemon_hash_mux); | 53 | mutex_unlock(&ecryptfs_daemon_hash_mux); |
@@ -83,6 +83,7 @@ static int | |||
83 | ecryptfs_miscdev_open(struct inode *inode, struct file *file) | 83 | ecryptfs_miscdev_open(struct inode *inode, struct file *file) |
84 | { | 84 | { |
85 | struct ecryptfs_daemon *daemon = NULL; | 85 | struct ecryptfs_daemon *daemon = NULL; |
86 | uid_t euid = current_euid(); | ||
86 | int rc; | 87 | int rc; |
87 | 88 | ||
88 | mutex_lock(&ecryptfs_daemon_hash_mux); | 89 | mutex_lock(&ecryptfs_daemon_hash_mux); |
@@ -93,11 +94,9 @@ ecryptfs_miscdev_open(struct inode *inode, struct file *file) | |||
93 | "count; rc = [%d]\n", __func__, rc); | 94 | "count; rc = [%d]\n", __func__, rc); |
94 | goto out_unlock_daemon_list; | 95 | goto out_unlock_daemon_list; |
95 | } | 96 | } |
96 | rc = ecryptfs_find_daemon_by_euid(&daemon, current->euid, | 97 | rc = ecryptfs_find_daemon_by_euid(&daemon, euid, current_user_ns()); |
97 | current->nsproxy->user_ns); | ||
98 | if (rc || !daemon) { | 98 | if (rc || !daemon) { |
99 | rc = ecryptfs_spawn_daemon(&daemon, current->euid, | 99 | rc = ecryptfs_spawn_daemon(&daemon, euid, current_user_ns(), |
100 | current->nsproxy->user_ns, | ||
101 | task_pid(current)); | 100 | task_pid(current)); |
102 | if (rc) { | 101 | if (rc) { |
103 | printk(KERN_ERR "%s: Error attempting to spawn daemon; " | 102 | printk(KERN_ERR "%s: Error attempting to spawn daemon; " |
@@ -147,11 +146,11 @@ static int | |||
147 | ecryptfs_miscdev_release(struct inode *inode, struct file *file) | 146 | ecryptfs_miscdev_release(struct inode *inode, struct file *file) |
148 | { | 147 | { |
149 | struct ecryptfs_daemon *daemon = NULL; | 148 | struct ecryptfs_daemon *daemon = NULL; |
149 | uid_t euid = current_euid(); | ||
150 | int rc; | 150 | int rc; |
151 | 151 | ||
152 | mutex_lock(&ecryptfs_daemon_hash_mux); | 152 | mutex_lock(&ecryptfs_daemon_hash_mux); |
153 | rc = ecryptfs_find_daemon_by_euid(&daemon, current->euid, | 153 | rc = ecryptfs_find_daemon_by_euid(&daemon, euid, current_user_ns()); |
154 | current->nsproxy->user_ns); | ||
155 | BUG_ON(rc || !daemon); | 154 | BUG_ON(rc || !daemon); |
156 | mutex_lock(&daemon->mux); | 155 | mutex_lock(&daemon->mux); |
157 | BUG_ON(daemon->pid != task_pid(current)); | 156 | BUG_ON(daemon->pid != task_pid(current)); |
@@ -246,12 +245,12 @@ ecryptfs_miscdev_read(struct file *file, char __user *buf, size_t count, | |||
246 | char packet_length[3]; | 245 | char packet_length[3]; |
247 | size_t i; | 246 | size_t i; |
248 | size_t total_length; | 247 | size_t total_length; |
248 | uid_t euid = current_euid(); | ||
249 | int rc; | 249 | int rc; |
250 | 250 | ||
251 | mutex_lock(&ecryptfs_daemon_hash_mux); | 251 | mutex_lock(&ecryptfs_daemon_hash_mux); |
252 | /* TODO: Just use file->private_data? */ | 252 | /* TODO: Just use file->private_data? */ |
253 | rc = ecryptfs_find_daemon_by_euid(&daemon, current->euid, | 253 | rc = ecryptfs_find_daemon_by_euid(&daemon, euid, current_user_ns()); |
254 | current->nsproxy->user_ns); | ||
255 | BUG_ON(rc || !daemon); | 254 | BUG_ON(rc || !daemon); |
256 | mutex_lock(&daemon->mux); | 255 | mutex_lock(&daemon->mux); |
257 | if (daemon->flags & ECRYPTFS_DAEMON_ZOMBIE) { | 256 | if (daemon->flags & ECRYPTFS_DAEMON_ZOMBIE) { |
@@ -290,8 +289,8 @@ check_list: | |||
290 | * message from the queue; try again */ | 289 | * message from the queue; try again */ |
291 | goto check_list; | 290 | goto check_list; |
292 | } | 291 | } |
293 | BUG_ON(current->euid != daemon->euid); | 292 | BUG_ON(euid != daemon->euid); |
294 | BUG_ON(current->nsproxy->user_ns != daemon->user_ns); | 293 | BUG_ON(current_user_ns() != daemon->user_ns); |
295 | BUG_ON(task_pid(current) != daemon->pid); | 294 | BUG_ON(task_pid(current) != daemon->pid); |
296 | msg_ctx = list_first_entry(&daemon->msg_ctx_out_queue, | 295 | msg_ctx = list_first_entry(&daemon->msg_ctx_out_queue, |
297 | struct ecryptfs_msg_ctx, daemon_out_list); | 296 | struct ecryptfs_msg_ctx, daemon_out_list); |
@@ -414,6 +413,7 @@ ecryptfs_miscdev_write(struct file *file, const char __user *buf, | |||
414 | size_t packet_size, packet_size_length, i; | 413 | size_t packet_size, packet_size_length, i; |
415 | ssize_t sz = 0; | 414 | ssize_t sz = 0; |
416 | char *data; | 415 | char *data; |
416 | uid_t euid = current_euid(); | ||
417 | int rc; | 417 | int rc; |
418 | 418 | ||
419 | if (count == 0) | 419 | if (count == 0) |
@@ -463,8 +463,7 @@ ecryptfs_miscdev_write(struct file *file, const char __user *buf, | |||
463 | goto out_free; | 463 | goto out_free; |
464 | } | 464 | } |
465 | rc = ecryptfs_miscdev_response(&data[i], packet_size, | 465 | rc = ecryptfs_miscdev_response(&data[i], packet_size, |
466 | current->euid, | 466 | euid, current_user_ns(), |
467 | current->nsproxy->user_ns, | ||
468 | task_pid(current), seq); | 467 | task_pid(current), seq); |
469 | if (rc) | 468 | if (rc) |
470 | printk(KERN_WARNING "%s: Failed to deliver miscdev " | 469 | printk(KERN_WARNING "%s: Failed to deliver miscdev " |
@@ -55,6 +55,7 @@ | |||
55 | #include <asm/uaccess.h> | 55 | #include <asm/uaccess.h> |
56 | #include <asm/mmu_context.h> | 56 | #include <asm/mmu_context.h> |
57 | #include <asm/tlb.h> | 57 | #include <asm/tlb.h> |
58 | #include "internal.h" | ||
58 | 59 | ||
59 | #ifdef __alpha__ | 60 | #ifdef __alpha__ |
60 | /* for /sbin/loader handling in search_binary_handler() */ | 61 | /* for /sbin/loader handling in search_binary_handler() */ |
@@ -980,7 +981,7 @@ int flush_old_exec(struct linux_binprm * bprm) | |||
980 | /* This is the point of no return */ | 981 | /* This is the point of no return */ |
981 | current->sas_ss_sp = current->sas_ss_size = 0; | 982 | current->sas_ss_sp = current->sas_ss_size = 0; |
982 | 983 | ||
983 | if (current->euid == current->uid && current->egid == current->gid) | 984 | if (current_euid() == current_uid() && current_egid() == current_gid()) |
984 | set_dumpable(current->mm, 1); | 985 | set_dumpable(current->mm, 1); |
985 | else | 986 | else |
986 | set_dumpable(current->mm, suid_dumpable); | 987 | set_dumpable(current->mm, suid_dumpable); |
@@ -1007,16 +1008,17 @@ int flush_old_exec(struct linux_binprm * bprm) | |||
1007 | */ | 1008 | */ |
1008 | current->mm->task_size = TASK_SIZE; | 1009 | current->mm->task_size = TASK_SIZE; |
1009 | 1010 | ||
1010 | if (bprm->e_uid != current->euid || bprm->e_gid != current->egid) { | 1011 | /* install the new credentials */ |
1011 | suid_keys(current); | 1012 | if (bprm->cred->uid != current_euid() || |
1012 | set_dumpable(current->mm, suid_dumpable); | 1013 | bprm->cred->gid != current_egid()) { |
1013 | current->pdeath_signal = 0; | 1014 | current->pdeath_signal = 0; |
1014 | } else if (file_permission(bprm->file, MAY_READ) || | 1015 | } else if (file_permission(bprm->file, MAY_READ) || |
1015 | (bprm->interp_flags & BINPRM_FLAGS_ENFORCE_NONDUMP)) { | 1016 | bprm->interp_flags & BINPRM_FLAGS_ENFORCE_NONDUMP) { |
1016 | suid_keys(current); | ||
1017 | set_dumpable(current->mm, suid_dumpable); | 1017 | set_dumpable(current->mm, suid_dumpable); |
1018 | } | 1018 | } |
1019 | 1019 | ||
1020 | current->personality &= ~bprm->per_clear; | ||
1021 | |||
1020 | /* An exec changes our domain. We are no longer part of the thread | 1022 | /* An exec changes our domain. We are no longer part of the thread |
1021 | group */ | 1023 | group */ |
1022 | 1024 | ||
@@ -1033,13 +1035,50 @@ out: | |||
1033 | 1035 | ||
1034 | EXPORT_SYMBOL(flush_old_exec); | 1036 | EXPORT_SYMBOL(flush_old_exec); |
1035 | 1037 | ||
1038 | /* | ||
1039 | * install the new credentials for this executable | ||
1040 | */ | ||
1041 | void install_exec_creds(struct linux_binprm *bprm) | ||
1042 | { | ||
1043 | security_bprm_committing_creds(bprm); | ||
1044 | |||
1045 | commit_creds(bprm->cred); | ||
1046 | bprm->cred = NULL; | ||
1047 | |||
1048 | /* cred_exec_mutex must be held at least to this point to prevent | ||
1049 | * ptrace_attach() from altering our determination of the task's | ||
1050 | * credentials; any time after this it may be unlocked */ | ||
1051 | |||
1052 | security_bprm_committed_creds(bprm); | ||
1053 | } | ||
1054 | EXPORT_SYMBOL(install_exec_creds); | ||
1055 | |||
1056 | /* | ||
1057 | * determine how safe it is to execute the proposed program | ||
1058 | * - the caller must hold current->cred_exec_mutex to protect against | ||
1059 | * PTRACE_ATTACH | ||
1060 | */ | ||
1061 | void check_unsafe_exec(struct linux_binprm *bprm) | ||
1062 | { | ||
1063 | struct task_struct *p = current; | ||
1064 | |||
1065 | bprm->unsafe = tracehook_unsafe_exec(p); | ||
1066 | |||
1067 | if (atomic_read(&p->fs->count) > 1 || | ||
1068 | atomic_read(&p->files->count) > 1 || | ||
1069 | atomic_read(&p->sighand->count) > 1) | ||
1070 | bprm->unsafe |= LSM_UNSAFE_SHARE; | ||
1071 | } | ||
1072 | |||
1036 | /* | 1073 | /* |
1037 | * Fill the binprm structure from the inode. | 1074 | * Fill the binprm structure from the inode. |
1038 | * Check permissions, then read the first 128 (BINPRM_BUF_SIZE) bytes | 1075 | * Check permissions, then read the first 128 (BINPRM_BUF_SIZE) bytes |
1076 | * | ||
1077 | * This may be called multiple times for binary chains (scripts for example). | ||
1039 | */ | 1078 | */ |
1040 | int prepare_binprm(struct linux_binprm *bprm) | 1079 | int prepare_binprm(struct linux_binprm *bprm) |
1041 | { | 1080 | { |
1042 | int mode; | 1081 | umode_t mode; |
1043 | struct inode * inode = bprm->file->f_path.dentry->d_inode; | 1082 | struct inode * inode = bprm->file->f_path.dentry->d_inode; |
1044 | int retval; | 1083 | int retval; |
1045 | 1084 | ||
@@ -1047,14 +1086,15 @@ int prepare_binprm(struct linux_binprm *bprm) | |||
1047 | if (bprm->file->f_op == NULL) | 1086 | if (bprm->file->f_op == NULL) |
1048 | return -EACCES; | 1087 | return -EACCES; |
1049 | 1088 | ||
1050 | bprm->e_uid = current->euid; | 1089 | /* clear any previous set[ug]id data from a previous binary */ |
1051 | bprm->e_gid = current->egid; | 1090 | bprm->cred->euid = current_euid(); |
1091 | bprm->cred->egid = current_egid(); | ||
1052 | 1092 | ||
1053 | if(!(bprm->file->f_path.mnt->mnt_flags & MNT_NOSUID)) { | 1093 | if (!(bprm->file->f_path.mnt->mnt_flags & MNT_NOSUID)) { |
1054 | /* Set-uid? */ | 1094 | /* Set-uid? */ |
1055 | if (mode & S_ISUID) { | 1095 | if (mode & S_ISUID) { |
1056 | current->personality &= ~PER_CLEAR_ON_SETID; | 1096 | bprm->per_clear |= PER_CLEAR_ON_SETID; |
1057 | bprm->e_uid = inode->i_uid; | 1097 | bprm->cred->euid = inode->i_uid; |
1058 | } | 1098 | } |
1059 | 1099 | ||
1060 | /* Set-gid? */ | 1100 | /* Set-gid? */ |
@@ -1064,52 +1104,23 @@ int prepare_binprm(struct linux_binprm *bprm) | |||
1064 | * executable. | 1104 | * executable. |
1065 | */ | 1105 | */ |
1066 | if ((mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP)) { | 1106 | if ((mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP)) { |
1067 | current->personality &= ~PER_CLEAR_ON_SETID; | 1107 | bprm->per_clear |= PER_CLEAR_ON_SETID; |
1068 | bprm->e_gid = inode->i_gid; | 1108 | bprm->cred->egid = inode->i_gid; |
1069 | } | 1109 | } |
1070 | } | 1110 | } |
1071 | 1111 | ||
1072 | /* fill in binprm security blob */ | 1112 | /* fill in binprm security blob */ |
1073 | retval = security_bprm_set(bprm); | 1113 | retval = security_bprm_set_creds(bprm); |
1074 | if (retval) | 1114 | if (retval) |
1075 | return retval; | 1115 | return retval; |
1116 | bprm->cred_prepared = 1; | ||
1076 | 1117 | ||
1077 | memset(bprm->buf,0,BINPRM_BUF_SIZE); | 1118 | memset(bprm->buf, 0, BINPRM_BUF_SIZE); |
1078 | return kernel_read(bprm->file,0,bprm->buf,BINPRM_BUF_SIZE); | 1119 | return kernel_read(bprm->file, 0, bprm->buf, BINPRM_BUF_SIZE); |
1079 | } | 1120 | } |
1080 | 1121 | ||
1081 | EXPORT_SYMBOL(prepare_binprm); | 1122 | EXPORT_SYMBOL(prepare_binprm); |
1082 | 1123 | ||
1083 | static int unsafe_exec(struct task_struct *p) | ||
1084 | { | ||
1085 | int unsafe = tracehook_unsafe_exec(p); | ||
1086 | |||
1087 | if (atomic_read(&p->fs->count) > 1 || | ||
1088 | atomic_read(&p->files->count) > 1 || | ||
1089 | atomic_read(&p->sighand->count) > 1) | ||
1090 | unsafe |= LSM_UNSAFE_SHARE; | ||
1091 | |||
1092 | return unsafe; | ||
1093 | } | ||
1094 | |||
1095 | void compute_creds(struct linux_binprm *bprm) | ||
1096 | { | ||
1097 | int unsafe; | ||
1098 | |||
1099 | if (bprm->e_uid != current->uid) { | ||
1100 | suid_keys(current); | ||
1101 | current->pdeath_signal = 0; | ||
1102 | } | ||
1103 | exec_keys(current); | ||
1104 | |||
1105 | task_lock(current); | ||
1106 | unsafe = unsafe_exec(current); | ||
1107 | security_bprm_apply_creds(bprm, unsafe); | ||
1108 | task_unlock(current); | ||
1109 | security_bprm_post_apply_creds(bprm); | ||
1110 | } | ||
1111 | EXPORT_SYMBOL(compute_creds); | ||
1112 | |||
1113 | /* | 1124 | /* |
1114 | * Arguments are '\0' separated strings found at the location bprm->p | 1125 | * Arguments are '\0' separated strings found at the location bprm->p |
1115 | * points to; chop off the first by relocating brpm->p to right after | 1126 | * points to; chop off the first by relocating brpm->p to right after |
@@ -1270,6 +1281,8 @@ EXPORT_SYMBOL(search_binary_handler); | |||
1270 | void free_bprm(struct linux_binprm *bprm) | 1281 | void free_bprm(struct linux_binprm *bprm) |
1271 | { | 1282 | { |
1272 | free_arg_pages(bprm); | 1283 | free_arg_pages(bprm); |
1284 | if (bprm->cred) | ||
1285 | abort_creds(bprm->cred); | ||
1273 | kfree(bprm); | 1286 | kfree(bprm); |
1274 | } | 1287 | } |
1275 | 1288 | ||
@@ -1295,10 +1308,20 @@ int do_execve(char * filename, | |||
1295 | if (!bprm) | 1308 | if (!bprm) |
1296 | goto out_files; | 1309 | goto out_files; |
1297 | 1310 | ||
1311 | retval = mutex_lock_interruptible(¤t->cred_exec_mutex); | ||
1312 | if (retval < 0) | ||
1313 | goto out_free; | ||
1314 | |||
1315 | retval = -ENOMEM; | ||
1316 | bprm->cred = prepare_exec_creds(); | ||
1317 | if (!bprm->cred) | ||
1318 | goto out_unlock; | ||
1319 | check_unsafe_exec(bprm); | ||
1320 | |||
1298 | file = open_exec(filename); | 1321 | file = open_exec(filename); |
1299 | retval = PTR_ERR(file); | 1322 | retval = PTR_ERR(file); |
1300 | if (IS_ERR(file)) | 1323 | if (IS_ERR(file)) |
1301 | goto out_kfree; | 1324 | goto out_unlock; |
1302 | 1325 | ||
1303 | sched_exec(); | 1326 | sched_exec(); |
1304 | 1327 | ||
@@ -1312,14 +1335,10 @@ int do_execve(char * filename, | |||
1312 | 1335 | ||
1313 | bprm->argc = count(argv, MAX_ARG_STRINGS); | 1336 | bprm->argc = count(argv, MAX_ARG_STRINGS); |
1314 | if ((retval = bprm->argc) < 0) | 1337 | if ((retval = bprm->argc) < 0) |
1315 | goto out_mm; | 1338 | goto out; |
1316 | 1339 | ||
1317 | bprm->envc = count(envp, MAX_ARG_STRINGS); | 1340 | bprm->envc = count(envp, MAX_ARG_STRINGS); |
1318 | if ((retval = bprm->envc) < 0) | 1341 | if ((retval = bprm->envc) < 0) |
1319 | goto out_mm; | ||
1320 | |||
1321 | retval = security_bprm_alloc(bprm); | ||
1322 | if (retval) | ||
1323 | goto out; | 1342 | goto out; |
1324 | 1343 | ||
1325 | retval = prepare_binprm(bprm); | 1344 | retval = prepare_binprm(bprm); |
@@ -1341,21 +1360,18 @@ int do_execve(char * filename, | |||
1341 | 1360 | ||
1342 | current->flags &= ~PF_KTHREAD; | 1361 | current->flags &= ~PF_KTHREAD; |
1343 | retval = search_binary_handler(bprm,regs); | 1362 | retval = search_binary_handler(bprm,regs); |
1344 | if (retval >= 0) { | 1363 | if (retval < 0) |
1345 | /* execve success */ | 1364 | goto out; |
1346 | security_bprm_free(bprm); | ||
1347 | acct_update_integrals(current); | ||
1348 | free_bprm(bprm); | ||
1349 | if (displaced) | ||
1350 | put_files_struct(displaced); | ||
1351 | return retval; | ||
1352 | } | ||
1353 | 1365 | ||
1354 | out: | 1366 | /* execve succeeded */ |
1355 | if (bprm->security) | 1367 | mutex_unlock(¤t->cred_exec_mutex); |
1356 | security_bprm_free(bprm); | 1368 | acct_update_integrals(current); |
1369 | free_bprm(bprm); | ||
1370 | if (displaced) | ||
1371 | put_files_struct(displaced); | ||
1372 | return retval; | ||
1357 | 1373 | ||
1358 | out_mm: | 1374 | out: |
1359 | if (bprm->mm) | 1375 | if (bprm->mm) |
1360 | mmput (bprm->mm); | 1376 | mmput (bprm->mm); |
1361 | 1377 | ||
@@ -1364,7 +1380,11 @@ out_file: | |||
1364 | allow_write_access(bprm->file); | 1380 | allow_write_access(bprm->file); |
1365 | fput(bprm->file); | 1381 | fput(bprm->file); |
1366 | } | 1382 | } |
1367 | out_kfree: | 1383 | |
1384 | out_unlock: | ||
1385 | mutex_unlock(¤t->cred_exec_mutex); | ||
1386 | |||
1387 | out_free: | ||
1368 | free_bprm(bprm); | 1388 | free_bprm(bprm); |
1369 | 1389 | ||
1370 | out_files: | 1390 | out_files: |
@@ -1396,6 +1416,7 @@ EXPORT_SYMBOL(set_binfmt); | |||
1396 | */ | 1416 | */ |
1397 | static int format_corename(char *corename, long signr) | 1417 | static int format_corename(char *corename, long signr) |
1398 | { | 1418 | { |
1419 | const struct cred *cred = current_cred(); | ||
1399 | const char *pat_ptr = core_pattern; | 1420 | const char *pat_ptr = core_pattern; |
1400 | int ispipe = (*pat_ptr == '|'); | 1421 | int ispipe = (*pat_ptr == '|'); |
1401 | char *out_ptr = corename; | 1422 | char *out_ptr = corename; |
@@ -1432,7 +1453,7 @@ static int format_corename(char *corename, long signr) | |||
1432 | /* uid */ | 1453 | /* uid */ |
1433 | case 'u': | 1454 | case 'u': |
1434 | rc = snprintf(out_ptr, out_end - out_ptr, | 1455 | rc = snprintf(out_ptr, out_end - out_ptr, |
1435 | "%d", current->uid); | 1456 | "%d", cred->uid); |
1436 | if (rc > out_end - out_ptr) | 1457 | if (rc > out_end - out_ptr) |
1437 | goto out; | 1458 | goto out; |
1438 | out_ptr += rc; | 1459 | out_ptr += rc; |
@@ -1440,7 +1461,7 @@ static int format_corename(char *corename, long signr) | |||
1440 | /* gid */ | 1461 | /* gid */ |
1441 | case 'g': | 1462 | case 'g': |
1442 | rc = snprintf(out_ptr, out_end - out_ptr, | 1463 | rc = snprintf(out_ptr, out_end - out_ptr, |
1443 | "%d", current->gid); | 1464 | "%d", cred->gid); |
1444 | if (rc > out_end - out_ptr) | 1465 | if (rc > out_end - out_ptr) |
1445 | goto out; | 1466 | goto out; |
1446 | out_ptr += rc; | 1467 | out_ptr += rc; |
@@ -1716,8 +1737,9 @@ int do_coredump(long signr, int exit_code, struct pt_regs * regs) | |||
1716 | struct linux_binfmt * binfmt; | 1737 | struct linux_binfmt * binfmt; |
1717 | struct inode * inode; | 1738 | struct inode * inode; |
1718 | struct file * file; | 1739 | struct file * file; |
1740 | const struct cred *old_cred; | ||
1741 | struct cred *cred; | ||
1719 | int retval = 0; | 1742 | int retval = 0; |
1720 | int fsuid = current->fsuid; | ||
1721 | int flag = 0; | 1743 | int flag = 0; |
1722 | int ispipe = 0; | 1744 | int ispipe = 0; |
1723 | unsigned long core_limit = current->signal->rlim[RLIMIT_CORE].rlim_cur; | 1745 | 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) | |||
1730 | binfmt = current->binfmt; | 1752 | binfmt = current->binfmt; |
1731 | if (!binfmt || !binfmt->core_dump) | 1753 | if (!binfmt || !binfmt->core_dump) |
1732 | goto fail; | 1754 | goto fail; |
1755 | |||
1756 | cred = prepare_creds(); | ||
1757 | if (!cred) { | ||
1758 | retval = -ENOMEM; | ||
1759 | goto fail; | ||
1760 | } | ||
1761 | |||
1733 | down_write(&mm->mmap_sem); | 1762 | down_write(&mm->mmap_sem); |
1734 | /* | 1763 | /* |
1735 | * If another thread got here first, or we are not dumpable, bail out. | 1764 | * If another thread got here first, or we are not dumpable, bail out. |
1736 | */ | 1765 | */ |
1737 | if (mm->core_state || !get_dumpable(mm)) { | 1766 | if (mm->core_state || !get_dumpable(mm)) { |
1738 | up_write(&mm->mmap_sem); | 1767 | up_write(&mm->mmap_sem); |
1768 | put_cred(cred); | ||
1739 | goto fail; | 1769 | goto fail; |
1740 | } | 1770 | } |
1741 | 1771 | ||
@@ -1746,12 +1776,16 @@ int do_coredump(long signr, int exit_code, struct pt_regs * regs) | |||
1746 | */ | 1776 | */ |
1747 | if (get_dumpable(mm) == 2) { /* Setuid core dump mode */ | 1777 | if (get_dumpable(mm) == 2) { /* Setuid core dump mode */ |
1748 | flag = O_EXCL; /* Stop rewrite attacks */ | 1778 | flag = O_EXCL; /* Stop rewrite attacks */ |
1749 | current->fsuid = 0; /* Dump root private */ | 1779 | cred->fsuid = 0; /* Dump root private */ |
1750 | } | 1780 | } |
1751 | 1781 | ||
1752 | retval = coredump_wait(exit_code, &core_state); | 1782 | retval = coredump_wait(exit_code, &core_state); |
1753 | if (retval < 0) | 1783 | if (retval < 0) { |
1784 | put_cred(cred); | ||
1754 | goto fail; | 1785 | goto fail; |
1786 | } | ||
1787 | |||
1788 | old_cred = override_creds(cred); | ||
1755 | 1789 | ||
1756 | /* | 1790 | /* |
1757 | * Clear any false indication of pending signals that might | 1791 | * 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) | |||
1823 | * Dont allow local users get cute and trick others to coredump | 1857 | * Dont allow local users get cute and trick others to coredump |
1824 | * into their pre-created files: | 1858 | * into their pre-created files: |
1825 | */ | 1859 | */ |
1826 | if (inode->i_uid != current->fsuid) | 1860 | if (inode->i_uid != current_fsuid()) |
1827 | goto close_fail; | 1861 | goto close_fail; |
1828 | if (!file->f_op) | 1862 | if (!file->f_op) |
1829 | goto close_fail; | 1863 | goto close_fail; |
@@ -1842,7 +1876,8 @@ fail_unlock: | |||
1842 | if (helper_argv) | 1876 | if (helper_argv) |
1843 | argv_free(helper_argv); | 1877 | argv_free(helper_argv); |
1844 | 1878 | ||
1845 | current->fsuid = fsuid; | 1879 | revert_creds(old_cred); |
1880 | put_cred(cred); | ||
1846 | coredump_finish(mm); | 1881 | coredump_finish(mm); |
1847 | fail: | 1882 | fail: |
1848 | return retval; | 1883 | return retval; |
diff --git a/fs/exportfs/expfs.c b/fs/exportfs/expfs.c index 890e01828817..197c7db583c7 100644 --- a/fs/exportfs/expfs.c +++ b/fs/exportfs/expfs.c | |||
@@ -14,6 +14,7 @@ | |||
14 | #include <linux/module.h> | 14 | #include <linux/module.h> |
15 | #include <linux/mount.h> | 15 | #include <linux/mount.h> |
16 | #include <linux/namei.h> | 16 | #include <linux/namei.h> |
17 | #include <linux/sched.h> | ||
17 | 18 | ||
18 | #define dprintk(fmt, args...) do{}while(0) | 19 | #define dprintk(fmt, args...) do{}while(0) |
19 | 20 | ||
@@ -249,6 +250,7 @@ static int filldir_one(void * __buf, const char * name, int len, | |||
249 | static int get_name(struct vfsmount *mnt, struct dentry *dentry, | 250 | static int get_name(struct vfsmount *mnt, struct dentry *dentry, |
250 | char *name, struct dentry *child) | 251 | char *name, struct dentry *child) |
251 | { | 252 | { |
253 | const struct cred *cred = current_cred(); | ||
252 | struct inode *dir = dentry->d_inode; | 254 | struct inode *dir = dentry->d_inode; |
253 | int error; | 255 | int error; |
254 | struct file *file; | 256 | struct file *file; |
@@ -263,7 +265,7 @@ static int get_name(struct vfsmount *mnt, struct dentry *dentry, | |||
263 | /* | 265 | /* |
264 | * Open the directory ... | 266 | * Open the directory ... |
265 | */ | 267 | */ |
266 | file = dentry_open(dget(dentry), mntget(mnt), O_RDONLY); | 268 | file = dentry_open(dget(dentry), mntget(mnt), O_RDONLY, cred); |
267 | error = PTR_ERR(file); | 269 | error = PTR_ERR(file); |
268 | if (IS_ERR(file)) | 270 | if (IS_ERR(file)) |
269 | goto out; | 271 | goto out; |
diff --git a/fs/ext2/balloc.c b/fs/ext2/balloc.c index 6dac7ba2d22d..4a29d6376081 100644 --- a/fs/ext2/balloc.c +++ b/fs/ext2/balloc.c | |||
@@ -1193,7 +1193,7 @@ static int ext2_has_free_blocks(struct ext2_sb_info *sbi) | |||
1193 | free_blocks = percpu_counter_read_positive(&sbi->s_freeblocks_counter); | 1193 | free_blocks = percpu_counter_read_positive(&sbi->s_freeblocks_counter); |
1194 | root_blocks = le32_to_cpu(sbi->s_es->s_r_blocks_count); | 1194 | root_blocks = le32_to_cpu(sbi->s_es->s_r_blocks_count); |
1195 | if (free_blocks < root_blocks + 1 && !capable(CAP_SYS_RESOURCE) && | 1195 | if (free_blocks < root_blocks + 1 && !capable(CAP_SYS_RESOURCE) && |
1196 | sbi->s_resuid != current->fsuid && | 1196 | sbi->s_resuid != current_fsuid() && |
1197 | (sbi->s_resgid == 0 || !in_group_p (sbi->s_resgid))) { | 1197 | (sbi->s_resgid == 0 || !in_group_p (sbi->s_resgid))) { |
1198 | return 0; | 1198 | return 0; |
1199 | } | 1199 | } |
diff --git a/fs/ext2/ialloc.c b/fs/ext2/ialloc.c index f59741346760..8d0add625870 100644 --- a/fs/ext2/ialloc.c +++ b/fs/ext2/ialloc.c | |||
@@ -550,7 +550,7 @@ got: | |||
550 | 550 | ||
551 | sb->s_dirt = 1; | 551 | sb->s_dirt = 1; |
552 | mark_buffer_dirty(bh2); | 552 | mark_buffer_dirty(bh2); |
553 | inode->i_uid = current->fsuid; | 553 | inode->i_uid = current_fsuid(); |
554 | if (test_opt (sb, GRPID)) | 554 | if (test_opt (sb, GRPID)) |
555 | inode->i_gid = dir->i_gid; | 555 | inode->i_gid = dir->i_gid; |
556 | else if (dir->i_mode & S_ISGID) { | 556 | else if (dir->i_mode & S_ISGID) { |
@@ -558,7 +558,7 @@ got: | |||
558 | if (S_ISDIR(mode)) | 558 | if (S_ISDIR(mode)) |
559 | mode |= S_ISGID; | 559 | mode |= S_ISGID; |
560 | } else | 560 | } else |
561 | inode->i_gid = current->fsgid; | 561 | inode->i_gid = current_fsgid(); |
562 | inode->i_mode = mode; | 562 | inode->i_mode = mode; |
563 | 563 | ||
564 | inode->i_ino = ino; | 564 | inode->i_ino = ino; |
diff --git a/fs/ext3/balloc.c b/fs/ext3/balloc.c index f5b57a2ca35a..0dbf1c048475 100644 --- a/fs/ext3/balloc.c +++ b/fs/ext3/balloc.c | |||
@@ -1422,7 +1422,7 @@ static int ext3_has_free_blocks(struct ext3_sb_info *sbi) | |||
1422 | free_blocks = percpu_counter_read_positive(&sbi->s_freeblocks_counter); | 1422 | free_blocks = percpu_counter_read_positive(&sbi->s_freeblocks_counter); |
1423 | root_blocks = le32_to_cpu(sbi->s_es->s_r_blocks_count); | 1423 | root_blocks = le32_to_cpu(sbi->s_es->s_r_blocks_count); |
1424 | if (free_blocks < root_blocks + 1 && !capable(CAP_SYS_RESOURCE) && | 1424 | if (free_blocks < root_blocks + 1 && !capable(CAP_SYS_RESOURCE) && |
1425 | sbi->s_resuid != current->fsuid && | 1425 | sbi->s_resuid != current_fsuid() && |
1426 | (sbi->s_resgid == 0 || !in_group_p (sbi->s_resgid))) { | 1426 | (sbi->s_resgid == 0 || !in_group_p (sbi->s_resgid))) { |
1427 | return 0; | 1427 | return 0; |
1428 | } | 1428 | } |
diff --git a/fs/ext3/ialloc.c b/fs/ext3/ialloc.c index 47b678d73e7a..490bd0ed7896 100644 --- a/fs/ext3/ialloc.c +++ b/fs/ext3/ialloc.c | |||
@@ -539,7 +539,7 @@ got: | |||
539 | percpu_counter_inc(&sbi->s_dirs_counter); | 539 | percpu_counter_inc(&sbi->s_dirs_counter); |
540 | sb->s_dirt = 1; | 540 | sb->s_dirt = 1; |
541 | 541 | ||
542 | inode->i_uid = current->fsuid; | 542 | inode->i_uid = current_fsuid(); |
543 | if (test_opt (sb, GRPID)) | 543 | if (test_opt (sb, GRPID)) |
544 | inode->i_gid = dir->i_gid; | 544 | inode->i_gid = dir->i_gid; |
545 | else if (dir->i_mode & S_ISGID) { | 545 | else if (dir->i_mode & S_ISGID) { |
@@ -547,7 +547,7 @@ got: | |||
547 | if (S_ISDIR(mode)) | 547 | if (S_ISDIR(mode)) |
548 | mode |= S_ISGID; | 548 | mode |= S_ISGID; |
549 | } else | 549 | } else |
550 | inode->i_gid = current->fsgid; | 550 | inode->i_gid = current_fsgid(); |
551 | inode->i_mode = mode; | 551 | inode->i_mode = mode; |
552 | 552 | ||
553 | inode->i_ino = ino; | 553 | inode->i_ino = ino; |
diff --git a/fs/ext4/balloc.c b/fs/ext4/balloc.c index db35cfdb3c8b..38b3acf5683b 100644 --- a/fs/ext4/balloc.c +++ b/fs/ext4/balloc.c | |||
@@ -624,7 +624,7 @@ int ext4_has_free_blocks(struct ext4_sb_info *sbi, s64 nblocks) | |||
624 | return 1; | 624 | return 1; |
625 | 625 | ||
626 | /* Hm, nope. Are (enough) root reserved blocks available? */ | 626 | /* Hm, nope. Are (enough) root reserved blocks available? */ |
627 | if (sbi->s_resuid == current->fsuid || | 627 | if (sbi->s_resuid == current_fsuid() || |
628 | ((sbi->s_resgid != 0) && in_group_p(sbi->s_resgid)) || | 628 | ((sbi->s_resgid != 0) && in_group_p(sbi->s_resgid)) || |
629 | capable(CAP_SYS_RESOURCE)) { | 629 | capable(CAP_SYS_RESOURCE)) { |
630 | if (free_blocks >= (nblocks + dirty_blocks)) | 630 | if (free_blocks >= (nblocks + dirty_blocks)) |
diff --git a/fs/ext4/ialloc.c b/fs/ext4/ialloc.c index 2a117e286e54..08cac9fcace2 100644 --- a/fs/ext4/ialloc.c +++ b/fs/ext4/ialloc.c | |||
@@ -787,7 +787,7 @@ got: | |||
787 | spin_unlock(sb_bgl_lock(sbi, flex_group)); | 787 | spin_unlock(sb_bgl_lock(sbi, flex_group)); |
788 | } | 788 | } |
789 | 789 | ||
790 | inode->i_uid = current->fsuid; | 790 | inode->i_uid = current_fsuid(); |
791 | if (test_opt(sb, GRPID)) | 791 | if (test_opt(sb, GRPID)) |
792 | inode->i_gid = dir->i_gid; | 792 | inode->i_gid = dir->i_gid; |
793 | else if (dir->i_mode & S_ISGID) { | 793 | else if (dir->i_mode & S_ISGID) { |
@@ -795,7 +795,7 @@ got: | |||
795 | if (S_ISDIR(mode)) | 795 | if (S_ISDIR(mode)) |
796 | mode |= S_ISGID; | 796 | mode |= S_ISGID; |
797 | } else | 797 | } else |
798 | inode->i_gid = current->fsgid; | 798 | inode->i_gid = current_fsgid(); |
799 | inode->i_mode = mode; | 799 | inode->i_mode = mode; |
800 | 800 | ||
801 | inode->i_ino = ino + group * EXT4_INODES_PER_GROUP(sb); | 801 | inode->i_ino = ino + group * EXT4_INODES_PER_GROUP(sb); |
diff --git a/fs/fat/file.c b/fs/fat/file.c index f06a4e525ece..0a7f4a9918b3 100644 --- a/fs/fat/file.c +++ b/fs/fat/file.c | |||
@@ -304,7 +304,7 @@ static int fat_allow_set_time(struct msdos_sb_info *sbi, struct inode *inode) | |||
304 | { | 304 | { |
305 | mode_t allow_utime = sbi->options.allow_utime; | 305 | mode_t allow_utime = sbi->options.allow_utime; |
306 | 306 | ||
307 | if (current->fsuid != inode->i_uid) { | 307 | if (current_fsuid() != inode->i_uid) { |
308 | if (in_group_p(inode->i_gid)) | 308 | if (in_group_p(inode->i_gid)) |
309 | allow_utime >>= 3; | 309 | allow_utime >>= 3; |
310 | if (allow_utime & MAY_WRITE) | 310 | if (allow_utime & MAY_WRITE) |
diff --git a/fs/fat/inode.c b/fs/fat/inode.c index bdd8fb7be2ca..d937aaf77374 100644 --- a/fs/fat/inode.c +++ b/fs/fat/inode.c | |||
@@ -926,8 +926,8 @@ static int parse_options(char *options, int is_vfat, int silent, int *debug, | |||
926 | 926 | ||
927 | opts->isvfat = is_vfat; | 927 | opts->isvfat = is_vfat; |
928 | 928 | ||
929 | opts->fs_uid = current->uid; | 929 | opts->fs_uid = current_uid(); |
930 | opts->fs_gid = current->gid; | 930 | opts->fs_gid = current_gid(); |
931 | opts->fs_fmask = opts->fs_dmask = current->fs->umask; | 931 | opts->fs_fmask = opts->fs_dmask = current->fs->umask; |
932 | opts->allow_utime = -1; | 932 | opts->allow_utime = -1; |
933 | opts->codepage = fat_default_codepage; | 933 | opts->codepage = fat_default_codepage; |
diff --git a/fs/fcntl.c b/fs/fcntl.c index 549daf8005fb..cdc141946724 100644 --- a/fs/fcntl.c +++ b/fs/fcntl.c | |||
@@ -212,13 +212,14 @@ static void f_modown(struct file *filp, struct pid *pid, enum pid_type type, | |||
212 | int __f_setown(struct file *filp, struct pid *pid, enum pid_type type, | 212 | int __f_setown(struct file *filp, struct pid *pid, enum pid_type type, |
213 | int force) | 213 | int force) |
214 | { | 214 | { |
215 | const struct cred *cred = current_cred(); | ||
215 | int err; | 216 | int err; |
216 | 217 | ||
217 | err = security_file_set_fowner(filp); | 218 | err = security_file_set_fowner(filp); |
218 | if (err) | 219 | if (err) |
219 | return err; | 220 | return err; |
220 | 221 | ||
221 | f_modown(filp, pid, type, current->uid, current->euid, force); | 222 | f_modown(filp, pid, type, cred->uid, cred->euid, force); |
222 | return 0; | 223 | return 0; |
223 | } | 224 | } |
224 | EXPORT_SYMBOL(__f_setown); | 225 | EXPORT_SYMBOL(__f_setown); |
@@ -407,10 +408,17 @@ static const long band_table[NSIGPOLL] = { | |||
407 | static inline int sigio_perm(struct task_struct *p, | 408 | static inline int sigio_perm(struct task_struct *p, |
408 | struct fown_struct *fown, int sig) | 409 | struct fown_struct *fown, int sig) |
409 | { | 410 | { |
410 | return (((fown->euid == 0) || | 411 | const struct cred *cred; |
411 | (fown->euid == p->suid) || (fown->euid == p->uid) || | 412 | int ret; |
412 | (fown->uid == p->suid) || (fown->uid == p->uid)) && | 413 | |
413 | !security_file_send_sigiotask(p, fown, sig)); | 414 | rcu_read_lock(); |
415 | cred = __task_cred(p); | ||
416 | ret = ((fown->euid == 0 || | ||
417 | fown->euid == cred->suid || fown->euid == cred->uid || | ||
418 | fown->uid == cred->suid || fown->uid == cred->uid) && | ||
419 | !security_file_send_sigiotask(p, fown, sig)); | ||
420 | rcu_read_unlock(); | ||
421 | return ret; | ||
414 | } | 422 | } |
415 | 423 | ||
416 | static void send_sigio_to_task(struct task_struct *p, | 424 | static void send_sigio_to_task(struct task_struct *p, |
diff --git a/fs/file_table.c b/fs/file_table.c index 5ad0eca6eea2..0fbcacc3ea75 100644 --- a/fs/file_table.c +++ b/fs/file_table.c | |||
@@ -36,7 +36,9 @@ static struct percpu_counter nr_files __cacheline_aligned_in_smp; | |||
36 | 36 | ||
37 | static inline void file_free_rcu(struct rcu_head *head) | 37 | static inline void file_free_rcu(struct rcu_head *head) |
38 | { | 38 | { |
39 | struct file *f = container_of(head, struct file, f_u.fu_rcuhead); | 39 | struct file *f = container_of(head, struct file, f_u.fu_rcuhead); |
40 | |||
41 | put_cred(f->f_cred); | ||
40 | kmem_cache_free(filp_cachep, f); | 42 | kmem_cache_free(filp_cachep, f); |
41 | } | 43 | } |
42 | 44 | ||
@@ -94,7 +96,7 @@ int proc_nr_files(ctl_table *table, int write, struct file *filp, | |||
94 | */ | 96 | */ |
95 | struct file *get_empty_filp(void) | 97 | struct file *get_empty_filp(void) |
96 | { | 98 | { |
97 | struct task_struct *tsk; | 99 | const struct cred *cred = current_cred(); |
98 | static int old_max; | 100 | static int old_max; |
99 | struct file * f; | 101 | struct file * f; |
100 | 102 | ||
@@ -118,12 +120,10 @@ struct file *get_empty_filp(void) | |||
118 | if (security_file_alloc(f)) | 120 | if (security_file_alloc(f)) |
119 | goto fail_sec; | 121 | goto fail_sec; |
120 | 122 | ||
121 | tsk = current; | ||
122 | INIT_LIST_HEAD(&f->f_u.fu_list); | 123 | INIT_LIST_HEAD(&f->f_u.fu_list); |
123 | atomic_long_set(&f->f_count, 1); | 124 | atomic_long_set(&f->f_count, 1); |
124 | rwlock_init(&f->f_owner.lock); | 125 | rwlock_init(&f->f_owner.lock); |
125 | f->f_uid = tsk->fsuid; | 126 | f->f_cred = get_cred(cred); |
126 | f->f_gid = tsk->fsgid; | ||
127 | eventpoll_init_file(f); | 127 | eventpoll_init_file(f); |
128 | /* f->f_version: 0 */ | 128 | /* f->f_version: 0 */ |
129 | return f; | 129 | return f; |
diff --git a/fs/fuse/dev.c b/fs/fuse/dev.c index b72361479be2..fba571648a8e 100644 --- a/fs/fuse/dev.c +++ b/fs/fuse/dev.c | |||
@@ -87,8 +87,8 @@ static void __fuse_put_request(struct fuse_req *req) | |||
87 | 87 | ||
88 | static void fuse_req_init_context(struct fuse_req *req) | 88 | static void fuse_req_init_context(struct fuse_req *req) |
89 | { | 89 | { |
90 | req->in.h.uid = current->fsuid; | 90 | req->in.h.uid = current_fsuid(); |
91 | req->in.h.gid = current->fsgid; | 91 | req->in.h.gid = current_fsgid(); |
92 | req->in.h.pid = current->pid; | 92 | req->in.h.pid = current->pid; |
93 | } | 93 | } |
94 | 94 | ||
diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c index fd03330cadeb..95bc22bdd060 100644 --- a/fs/fuse/dir.c +++ b/fs/fuse/dir.c | |||
@@ -869,18 +869,25 @@ int fuse_update_attributes(struct inode *inode, struct kstat *stat, | |||
869 | */ | 869 | */ |
870 | int fuse_allow_task(struct fuse_conn *fc, struct task_struct *task) | 870 | int fuse_allow_task(struct fuse_conn *fc, struct task_struct *task) |
871 | { | 871 | { |
872 | const struct cred *cred; | ||
873 | int ret; | ||
874 | |||
872 | if (fc->flags & FUSE_ALLOW_OTHER) | 875 | if (fc->flags & FUSE_ALLOW_OTHER) |
873 | return 1; | 876 | return 1; |
874 | 877 | ||
875 | if (task->euid == fc->user_id && | 878 | rcu_read_lock(); |
876 | task->suid == fc->user_id && | 879 | ret = 0; |
877 | task->uid == fc->user_id && | 880 | cred = __task_cred(task); |
878 | task->egid == fc->group_id && | 881 | if (cred->euid == fc->user_id && |
879 | task->sgid == fc->group_id && | 882 | cred->suid == fc->user_id && |
880 | task->gid == fc->group_id) | 883 | cred->uid == fc->user_id && |
881 | return 1; | 884 | cred->egid == fc->group_id && |
885 | cred->sgid == fc->group_id && | ||
886 | cred->gid == fc->group_id) | ||
887 | ret = 1; | ||
888 | rcu_read_unlock(); | ||
882 | 889 | ||
883 | return 0; | 890 | return ret; |
884 | } | 891 | } |
885 | 892 | ||
886 | static int fuse_access(struct inode *inode, int mask) | 893 | static int fuse_access(struct inode *inode, int mask) |
diff --git a/fs/gfs2/inode.c b/fs/gfs2/inode.c index 7cee695fa441..d57616840e89 100644 --- a/fs/gfs2/inode.c +++ b/fs/gfs2/inode.c | |||
@@ -705,18 +705,18 @@ static void munge_mode_uid_gid(struct gfs2_inode *dip, unsigned int *mode, | |||
705 | (dip->i_inode.i_mode & S_ISUID) && dip->i_inode.i_uid) { | 705 | (dip->i_inode.i_mode & S_ISUID) && dip->i_inode.i_uid) { |
706 | if (S_ISDIR(*mode)) | 706 | if (S_ISDIR(*mode)) |
707 | *mode |= S_ISUID; | 707 | *mode |= S_ISUID; |
708 | else if (dip->i_inode.i_uid != current->fsuid) | 708 | else if (dip->i_inode.i_uid != current_fsuid()) |
709 | *mode &= ~07111; | 709 | *mode &= ~07111; |
710 | *uid = dip->i_inode.i_uid; | 710 | *uid = dip->i_inode.i_uid; |
711 | } else | 711 | } else |
712 | *uid = current->fsuid; | 712 | *uid = current_fsuid(); |
713 | 713 | ||
714 | if (dip->i_inode.i_mode & S_ISGID) { | 714 | if (dip->i_inode.i_mode & S_ISGID) { |
715 | if (S_ISDIR(*mode)) | 715 | if (S_ISDIR(*mode)) |
716 | *mode |= S_ISGID; | 716 | *mode |= S_ISGID; |
717 | *gid = dip->i_inode.i_gid; | 717 | *gid = dip->i_inode.i_gid; |
718 | } else | 718 | } else |
719 | *gid = current->fsgid; | 719 | *gid = current_fsgid(); |
720 | } | 720 | } |
721 | 721 | ||
722 | static int alloc_dinode(struct gfs2_inode *dip, u64 *no_addr, u64 *generation) | 722 | 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, | |||
1124 | return -EPERM; | 1124 | return -EPERM; |
1125 | 1125 | ||
1126 | if ((dip->i_inode.i_mode & S_ISVTX) && | 1126 | if ((dip->i_inode.i_mode & S_ISVTX) && |
1127 | dip->i_inode.i_uid != current->fsuid && | 1127 | dip->i_inode.i_uid != current_fsuid() && |
1128 | ip->i_inode.i_uid != current->fsuid && !capable(CAP_FOWNER)) | 1128 | ip->i_inode.i_uid != current_fsuid() && !capable(CAP_FOWNER)) |
1129 | return -EPERM; | 1129 | return -EPERM; |
1130 | 1130 | ||
1131 | if (IS_APPEND(&dip->i_inode)) | 1131 | if (IS_APPEND(&dip->i_inode)) |
diff --git a/fs/hfs/inode.c b/fs/hfs/inode.c index c69b7ac75bf7..9435dda8f1e0 100644 --- a/fs/hfs/inode.c +++ b/fs/hfs/inode.c | |||
@@ -155,8 +155,8 @@ struct inode *hfs_new_inode(struct inode *dir, struct qstr *name, int mode) | |||
155 | hfs_cat_build_key(sb, (btree_key *)&HFS_I(inode)->cat_key, dir->i_ino, name); | 155 | hfs_cat_build_key(sb, (btree_key *)&HFS_I(inode)->cat_key, dir->i_ino, name); |
156 | inode->i_ino = HFS_SB(sb)->next_id++; | 156 | inode->i_ino = HFS_SB(sb)->next_id++; |
157 | inode->i_mode = mode; | 157 | inode->i_mode = mode; |
158 | inode->i_uid = current->fsuid; | 158 | inode->i_uid = current_fsuid(); |
159 | inode->i_gid = current->fsgid; | 159 | inode->i_gid = current_fsgid(); |
160 | inode->i_nlink = 1; | 160 | inode->i_nlink = 1; |
161 | inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME_SEC; | 161 | inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME_SEC; |
162 | HFS_I(inode)->flags = 0; | 162 | HFS_I(inode)->flags = 0; |
diff --git a/fs/hfs/super.c b/fs/hfs/super.c index 3c7c7637719c..c8b5acf4b0b7 100644 --- a/fs/hfs/super.c +++ b/fs/hfs/super.c | |||
@@ -210,8 +210,8 @@ static int parse_options(char *options, struct hfs_sb_info *hsb) | |||
210 | int tmp, token; | 210 | int tmp, token; |
211 | 211 | ||
212 | /* initialize the sb with defaults */ | 212 | /* initialize the sb with defaults */ |
213 | hsb->s_uid = current->uid; | 213 | hsb->s_uid = current_uid(); |
214 | hsb->s_gid = current->gid; | 214 | hsb->s_gid = current_gid(); |
215 | hsb->s_file_umask = 0133; | 215 | hsb->s_file_umask = 0133; |
216 | hsb->s_dir_umask = 0022; | 216 | hsb->s_dir_umask = 0022; |
217 | hsb->s_type = hsb->s_creator = cpu_to_be32(0x3f3f3f3f); /* == '????' */ | 217 | hsb->s_type = hsb->s_creator = cpu_to_be32(0x3f3f3f3f); /* == '????' */ |
diff --git a/fs/hfsplus/inode.c b/fs/hfsplus/inode.c index b207f0e6fc22..f105ee9e1cc4 100644 --- a/fs/hfsplus/inode.c +++ b/fs/hfsplus/inode.c | |||
@@ -296,8 +296,8 @@ struct inode *hfsplus_new_inode(struct super_block *sb, int mode) | |||
296 | 296 | ||
297 | inode->i_ino = HFSPLUS_SB(sb).next_cnid++; | 297 | inode->i_ino = HFSPLUS_SB(sb).next_cnid++; |
298 | inode->i_mode = mode; | 298 | inode->i_mode = mode; |
299 | inode->i_uid = current->fsuid; | 299 | inode->i_uid = current_fsuid(); |
300 | inode->i_gid = current->fsgid; | 300 | inode->i_gid = current_fsgid(); |
301 | inode->i_nlink = 1; | 301 | inode->i_nlink = 1; |
302 | inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME_SEC; | 302 | inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME_SEC; |
303 | INIT_LIST_HEAD(&HFSPLUS_I(inode).open_dir_list); | 303 | INIT_LIST_HEAD(&HFSPLUS_I(inode).open_dir_list); |
diff --git a/fs/hfsplus/options.c b/fs/hfsplus/options.c index 9699c56d323f..bab7f8d1bdfa 100644 --- a/fs/hfsplus/options.c +++ b/fs/hfsplus/options.c | |||
@@ -49,8 +49,8 @@ void hfsplus_fill_defaults(struct hfsplus_sb_info *opts) | |||
49 | opts->creator = HFSPLUS_DEF_CR_TYPE; | 49 | opts->creator = HFSPLUS_DEF_CR_TYPE; |
50 | opts->type = HFSPLUS_DEF_CR_TYPE; | 50 | opts->type = HFSPLUS_DEF_CR_TYPE; |
51 | opts->umask = current->fs->umask; | 51 | opts->umask = current->fs->umask; |
52 | opts->uid = current->uid; | 52 | opts->uid = current_uid(); |
53 | opts->gid = current->gid; | 53 | opts->gid = current_gid(); |
54 | opts->part = -1; | 54 | opts->part = -1; |
55 | opts->session = -1; | 55 | opts->session = -1; |
56 | } | 56 | } |
diff --git a/fs/hpfs/namei.c b/fs/hpfs/namei.c index 10783f3d265a..b649232dde97 100644 --- a/fs/hpfs/namei.c +++ b/fs/hpfs/namei.c | |||
@@ -92,11 +92,11 @@ static int hpfs_mkdir(struct inode *dir, struct dentry *dentry, int mode) | |||
92 | inc_nlink(dir); | 92 | inc_nlink(dir); |
93 | insert_inode_hash(result); | 93 | insert_inode_hash(result); |
94 | 94 | ||
95 | if (result->i_uid != current->fsuid || | 95 | if (result->i_uid != current_fsuid() || |
96 | result->i_gid != current->fsgid || | 96 | result->i_gid != current_fsgid() || |
97 | result->i_mode != (mode | S_IFDIR)) { | 97 | result->i_mode != (mode | S_IFDIR)) { |
98 | result->i_uid = current->fsuid; | 98 | result->i_uid = current_fsuid(); |
99 | result->i_gid = current->fsgid; | 99 | result->i_gid = current_fsgid(); |
100 | result->i_mode = mode | S_IFDIR; | 100 | result->i_mode = mode | S_IFDIR; |
101 | hpfs_write_inode_nolock(result); | 101 | hpfs_write_inode_nolock(result); |
102 | } | 102 | } |
@@ -184,11 +184,11 @@ static int hpfs_create(struct inode *dir, struct dentry *dentry, int mode, struc | |||
184 | 184 | ||
185 | insert_inode_hash(result); | 185 | insert_inode_hash(result); |
186 | 186 | ||
187 | if (result->i_uid != current->fsuid || | 187 | if (result->i_uid != current_fsuid() || |
188 | result->i_gid != current->fsgid || | 188 | result->i_gid != current_fsgid() || |
189 | result->i_mode != (mode | S_IFREG)) { | 189 | result->i_mode != (mode | S_IFREG)) { |
190 | result->i_uid = current->fsuid; | 190 | result->i_uid = current_fsuid(); |
191 | result->i_gid = current->fsgid; | 191 | result->i_gid = current_fsgid(); |
192 | result->i_mode = mode | S_IFREG; | 192 | result->i_mode = mode | S_IFREG; |
193 | hpfs_write_inode_nolock(result); | 193 | hpfs_write_inode_nolock(result); |
194 | } | 194 | } |
@@ -247,8 +247,8 @@ static int hpfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t | |||
247 | result->i_mtime.tv_nsec = 0; | 247 | result->i_mtime.tv_nsec = 0; |
248 | result->i_atime.tv_nsec = 0; | 248 | result->i_atime.tv_nsec = 0; |
249 | hpfs_i(result)->i_ea_size = 0; | 249 | hpfs_i(result)->i_ea_size = 0; |
250 | result->i_uid = current->fsuid; | 250 | result->i_uid = current_fsuid(); |
251 | result->i_gid = current->fsgid; | 251 | result->i_gid = current_fsgid(); |
252 | result->i_nlink = 1; | 252 | result->i_nlink = 1; |
253 | result->i_size = 0; | 253 | result->i_size = 0; |
254 | result->i_blocks = 1; | 254 | result->i_blocks = 1; |
@@ -325,8 +325,8 @@ static int hpfs_symlink(struct inode *dir, struct dentry *dentry, const char *sy | |||
325 | result->i_atime.tv_nsec = 0; | 325 | result->i_atime.tv_nsec = 0; |
326 | hpfs_i(result)->i_ea_size = 0; | 326 | hpfs_i(result)->i_ea_size = 0; |
327 | result->i_mode = S_IFLNK | 0777; | 327 | result->i_mode = S_IFLNK | 0777; |
328 | result->i_uid = current->fsuid; | 328 | result->i_uid = current_fsuid(); |
329 | result->i_gid = current->fsgid; | 329 | result->i_gid = current_fsgid(); |
330 | result->i_blocks = 1; | 330 | result->i_blocks = 1; |
331 | result->i_nlink = 1; | 331 | result->i_nlink = 1; |
332 | result->i_size = strlen(symlink); | 332 | result->i_size = strlen(symlink); |
diff --git a/fs/hpfs/super.c b/fs/hpfs/super.c index 29ad461d568f..0d049b8919c4 100644 --- a/fs/hpfs/super.c +++ b/fs/hpfs/super.c | |||
@@ -475,8 +475,8 @@ static int hpfs_fill_super(struct super_block *s, void *options, int silent) | |||
475 | 475 | ||
476 | init_MUTEX(&sbi->hpfs_creation_de); | 476 | init_MUTEX(&sbi->hpfs_creation_de); |
477 | 477 | ||
478 | uid = current->uid; | 478 | uid = current_uid(); |
479 | gid = current->gid; | 479 | gid = current_gid(); |
480 | umask = current->fs->umask; | 480 | umask = current->fs->umask; |
481 | lowercase = 0; | 481 | lowercase = 0; |
482 | conv = CONV_BINARY; | 482 | conv = CONV_BINARY; |
diff --git a/fs/hppfs/hppfs.c b/fs/hppfs/hppfs.c index 2b3d1828db99..b278f7f52024 100644 --- a/fs/hppfs/hppfs.c +++ b/fs/hppfs/hppfs.c | |||
@@ -426,6 +426,7 @@ static int file_mode(int fmode) | |||
426 | 426 | ||
427 | static int hppfs_open(struct inode *inode, struct file *file) | 427 | static int hppfs_open(struct inode *inode, struct file *file) |
428 | { | 428 | { |
429 | const struct cred *cred = file->f_cred; | ||
429 | struct hppfs_private *data; | 430 | struct hppfs_private *data; |
430 | struct vfsmount *proc_mnt; | 431 | struct vfsmount *proc_mnt; |
431 | struct dentry *proc_dentry; | 432 | struct dentry *proc_dentry; |
@@ -446,7 +447,7 @@ static int hppfs_open(struct inode *inode, struct file *file) | |||
446 | 447 | ||
447 | /* XXX This isn't closed anywhere */ | 448 | /* XXX This isn't closed anywhere */ |
448 | data->proc_file = dentry_open(dget(proc_dentry), mntget(proc_mnt), | 449 | data->proc_file = dentry_open(dget(proc_dentry), mntget(proc_mnt), |
449 | file_mode(file->f_mode)); | 450 | file_mode(file->f_mode), cred); |
450 | err = PTR_ERR(data->proc_file); | 451 | err = PTR_ERR(data->proc_file); |
451 | if (IS_ERR(data->proc_file)) | 452 | if (IS_ERR(data->proc_file)) |
452 | goto out_free1; | 453 | goto out_free1; |
@@ -489,6 +490,7 @@ static int hppfs_open(struct inode *inode, struct file *file) | |||
489 | 490 | ||
490 | static int hppfs_dir_open(struct inode *inode, struct file *file) | 491 | static int hppfs_dir_open(struct inode *inode, struct file *file) |
491 | { | 492 | { |
493 | const struct cred *cred = file->f_cred; | ||
492 | struct hppfs_private *data; | 494 | struct hppfs_private *data; |
493 | struct vfsmount *proc_mnt; | 495 | struct vfsmount *proc_mnt; |
494 | struct dentry *proc_dentry; | 496 | struct dentry *proc_dentry; |
@@ -502,7 +504,7 @@ static int hppfs_dir_open(struct inode *inode, struct file *file) | |||
502 | proc_dentry = HPPFS_I(inode)->proc_dentry; | 504 | proc_dentry = HPPFS_I(inode)->proc_dentry; |
503 | proc_mnt = inode->i_sb->s_fs_info; | 505 | proc_mnt = inode->i_sb->s_fs_info; |
504 | data->proc_file = dentry_open(dget(proc_dentry), mntget(proc_mnt), | 506 | data->proc_file = dentry_open(dget(proc_dentry), mntget(proc_mnt), |
505 | file_mode(file->f_mode)); | 507 | file_mode(file->f_mode), cred); |
506 | err = PTR_ERR(data->proc_file); | 508 | err = PTR_ERR(data->proc_file); |
507 | if (IS_ERR(data->proc_file)) | 509 | if (IS_ERR(data->proc_file)) |
508 | goto out_free; | 510 | goto out_free; |
diff --git a/fs/hugetlbfs/inode.c b/fs/hugetlbfs/inode.c index 61edc701b0e6..7d479ce3aceb 100644 --- a/fs/hugetlbfs/inode.c +++ b/fs/hugetlbfs/inode.c | |||
@@ -551,9 +551,9 @@ static int hugetlbfs_mknod(struct inode *dir, | |||
551 | if (S_ISDIR(mode)) | 551 | if (S_ISDIR(mode)) |
552 | mode |= S_ISGID; | 552 | mode |= S_ISGID; |
553 | } else { | 553 | } else { |
554 | gid = current->fsgid; | 554 | gid = current_fsgid(); |
555 | } | 555 | } |
556 | inode = hugetlbfs_get_inode(dir->i_sb, current->fsuid, gid, mode, dev); | 556 | inode = hugetlbfs_get_inode(dir->i_sb, current_fsuid(), gid, mode, dev); |
557 | if (inode) { | 557 | if (inode) { |
558 | dir->i_ctime = dir->i_mtime = CURRENT_TIME; | 558 | dir->i_ctime = dir->i_mtime = CURRENT_TIME; |
559 | d_instantiate(dentry, inode); | 559 | d_instantiate(dentry, inode); |
@@ -586,9 +586,9 @@ static int hugetlbfs_symlink(struct inode *dir, | |||
586 | if (dir->i_mode & S_ISGID) | 586 | if (dir->i_mode & S_ISGID) |
587 | gid = dir->i_gid; | 587 | gid = dir->i_gid; |
588 | else | 588 | else |
589 | gid = current->fsgid; | 589 | gid = current_fsgid(); |
590 | 590 | ||
591 | inode = hugetlbfs_get_inode(dir->i_sb, current->fsuid, | 591 | inode = hugetlbfs_get_inode(dir->i_sb, current_fsuid(), |
592 | gid, S_IFLNK|S_IRWXUGO, 0); | 592 | gid, S_IFLNK|S_IRWXUGO, 0); |
593 | if (inode) { | 593 | if (inode) { |
594 | int l = strlen(symname)+1; | 594 | int l = strlen(symname)+1; |
@@ -854,8 +854,8 @@ hugetlbfs_fill_super(struct super_block *sb, void *data, int silent) | |||
854 | 854 | ||
855 | config.nr_blocks = -1; /* No limit on size by default */ | 855 | config.nr_blocks = -1; /* No limit on size by default */ |
856 | config.nr_inodes = -1; /* No limit on number of inodes by default */ | 856 | config.nr_inodes = -1; /* No limit on number of inodes by default */ |
857 | config.uid = current->fsuid; | 857 | config.uid = current_fsuid(); |
858 | config.gid = current->fsgid; | 858 | config.gid = current_fsgid(); |
859 | config.mode = 0755; | 859 | config.mode = 0755; |
860 | config.hstate = &default_hstate; | 860 | config.hstate = &default_hstate; |
861 | ret = hugetlbfs_parse_options(data, &config); | 861 | ret = hugetlbfs_parse_options(data, &config); |
@@ -951,6 +951,7 @@ struct file *hugetlb_file_setup(const char *name, size_t size) | |||
951 | struct inode *inode; | 951 | struct inode *inode; |
952 | struct dentry *dentry, *root; | 952 | struct dentry *dentry, *root; |
953 | struct qstr quick_string; | 953 | struct qstr quick_string; |
954 | struct user_struct *user = current_user(); | ||
954 | 955 | ||
955 | if (!hugetlbfs_vfsmount) | 956 | if (!hugetlbfs_vfsmount) |
956 | return ERR_PTR(-ENOENT); | 957 | return ERR_PTR(-ENOENT); |
@@ -958,7 +959,7 @@ struct file *hugetlb_file_setup(const char *name, size_t size) | |||
958 | if (!can_do_hugetlb_shm()) | 959 | if (!can_do_hugetlb_shm()) |
959 | return ERR_PTR(-EPERM); | 960 | return ERR_PTR(-EPERM); |
960 | 961 | ||
961 | if (!user_shm_lock(size, current->user)) | 962 | if (!user_shm_lock(size, user)) |
962 | return ERR_PTR(-ENOMEM); | 963 | return ERR_PTR(-ENOMEM); |
963 | 964 | ||
964 | root = hugetlbfs_vfsmount->mnt_root; | 965 | root = hugetlbfs_vfsmount->mnt_root; |
@@ -970,8 +971,8 @@ struct file *hugetlb_file_setup(const char *name, size_t size) | |||
970 | goto out_shm_unlock; | 971 | goto out_shm_unlock; |
971 | 972 | ||
972 | error = -ENOSPC; | 973 | error = -ENOSPC; |
973 | inode = hugetlbfs_get_inode(root->d_sb, current->fsuid, | 974 | inode = hugetlbfs_get_inode(root->d_sb, current_fsuid(), |
974 | current->fsgid, S_IFREG | S_IRWXUGO, 0); | 975 | current_fsgid(), S_IFREG | S_IRWXUGO, 0); |
975 | if (!inode) | 976 | if (!inode) |
976 | goto out_dentry; | 977 | goto out_dentry; |
977 | 978 | ||
@@ -998,7 +999,7 @@ out_inode: | |||
998 | out_dentry: | 999 | out_dentry: |
999 | dput(dentry); | 1000 | dput(dentry); |
1000 | out_shm_unlock: | 1001 | out_shm_unlock: |
1001 | user_shm_unlock(size, current->user); | 1002 | user_shm_unlock(size, user); |
1002 | return ERR_PTR(error); | 1003 | return ERR_PTR(error); |
1003 | } | 1004 | } |
1004 | 1005 | ||
diff --git a/fs/inotify_user.c b/fs/inotify_user.c index d367e9b92862..e2425bbd871f 100644 --- a/fs/inotify_user.c +++ b/fs/inotify_user.c | |||
@@ -601,7 +601,7 @@ asmlinkage long sys_inotify_init1(int flags) | |||
601 | goto out_put_fd; | 601 | goto out_put_fd; |
602 | } | 602 | } |
603 | 603 | ||
604 | user = get_uid(current->user); | 604 | user = get_current_user(); |
605 | if (unlikely(atomic_read(&user->inotify_devs) >= | 605 | if (unlikely(atomic_read(&user->inotify_devs) >= |
606 | inotify_max_user_instances)) { | 606 | inotify_max_user_instances)) { |
607 | ret = -EMFILE; | 607 | ret = -EMFILE; |
diff --git a/fs/internal.h b/fs/internal.h index 80aa9a023372..53af885f1732 100644 --- a/fs/internal.h +++ b/fs/internal.h | |||
@@ -10,6 +10,7 @@ | |||
10 | */ | 10 | */ |
11 | 11 | ||
12 | struct super_block; | 12 | struct super_block; |
13 | struct linux_binprm; | ||
13 | 14 | ||
14 | /* | 15 | /* |
15 | * block_dev.c | 16 | * block_dev.c |
@@ -40,6 +41,11 @@ static inline int sb_is_blkdev_sb(struct super_block *sb) | |||
40 | extern void __init chrdev_init(void); | 41 | extern void __init chrdev_init(void); |
41 | 42 | ||
42 | /* | 43 | /* |
44 | * exec.c | ||
45 | */ | ||
46 | extern void check_unsafe_exec(struct linux_binprm *); | ||
47 | |||
48 | /* | ||
43 | * namespace.c | 49 | * namespace.c |
44 | */ | 50 | */ |
45 | extern int copy_mount_options(const void __user *, unsigned long *); | 51 | extern int copy_mount_options(const void __user *, unsigned long *); |
diff --git a/fs/ioprio.c b/fs/ioprio.c index da3cc460d4df..3569e0ad86a2 100644 --- a/fs/ioprio.c +++ b/fs/ioprio.c | |||
@@ -31,10 +31,16 @@ static int set_task_ioprio(struct task_struct *task, int ioprio) | |||
31 | { | 31 | { |
32 | int err; | 32 | int err; |
33 | struct io_context *ioc; | 33 | struct io_context *ioc; |
34 | const struct cred *cred = current_cred(), *tcred; | ||
34 | 35 | ||
35 | if (task->uid != current->euid && | 36 | rcu_read_lock(); |
36 | task->uid != current->uid && !capable(CAP_SYS_NICE)) | 37 | tcred = __task_cred(task); |
38 | if (tcred->uid != cred->euid && | ||
39 | tcred->uid != cred->uid && !capable(CAP_SYS_NICE)) { | ||
40 | rcu_read_unlock(); | ||
37 | return -EPERM; | 41 | return -EPERM; |
42 | } | ||
43 | rcu_read_unlock(); | ||
38 | 44 | ||
39 | err = security_task_setioprio(task, ioprio); | 45 | err = security_task_setioprio(task, ioprio); |
40 | if (err) | 46 | if (err) |
@@ -123,7 +129,7 @@ asmlinkage long sys_ioprio_set(int which, int who, int ioprio) | |||
123 | break; | 129 | break; |
124 | case IOPRIO_WHO_USER: | 130 | case IOPRIO_WHO_USER: |
125 | if (!who) | 131 | if (!who) |
126 | user = current->user; | 132 | user = current_user(); |
127 | else | 133 | else |
128 | user = find_user(who); | 134 | user = find_user(who); |
129 | 135 | ||
@@ -131,7 +137,7 @@ asmlinkage long sys_ioprio_set(int which, int who, int ioprio) | |||
131 | break; | 137 | break; |
132 | 138 | ||
133 | do_each_thread(g, p) { | 139 | do_each_thread(g, p) { |
134 | if (p->uid != who) | 140 | if (__task_cred(p)->uid != who) |
135 | continue; | 141 | continue; |
136 | ret = set_task_ioprio(p, ioprio); | 142 | ret = set_task_ioprio(p, ioprio); |
137 | if (ret) | 143 | if (ret) |
@@ -216,7 +222,7 @@ asmlinkage long sys_ioprio_get(int which, int who) | |||
216 | break; | 222 | break; |
217 | case IOPRIO_WHO_USER: | 223 | case IOPRIO_WHO_USER: |
218 | if (!who) | 224 | if (!who) |
219 | user = current->user; | 225 | user = current_user(); |
220 | else | 226 | else |
221 | user = find_user(who); | 227 | user = find_user(who); |
222 | 228 | ||
@@ -224,7 +230,7 @@ asmlinkage long sys_ioprio_get(int which, int who) | |||
224 | break; | 230 | break; |
225 | 231 | ||
226 | do_each_thread(g, p) { | 232 | do_each_thread(g, p) { |
227 | if (p->uid != user->uid) | 233 | if (__task_cred(p)->uid != user->uid) |
228 | continue; | 234 | continue; |
229 | tmpio = get_task_ioprio(p); | 235 | tmpio = get_task_ioprio(p); |
230 | if (tmpio < 0) | 236 | if (tmpio < 0) |
diff --git a/fs/jfs/jfs_inode.c b/fs/jfs/jfs_inode.c index ed6574bee51a..70022fd1c539 100644 --- a/fs/jfs/jfs_inode.c +++ b/fs/jfs/jfs_inode.c | |||
@@ -93,13 +93,13 @@ struct inode *ialloc(struct inode *parent, umode_t mode) | |||
93 | return ERR_PTR(rc); | 93 | return ERR_PTR(rc); |
94 | } | 94 | } |
95 | 95 | ||
96 | inode->i_uid = current->fsuid; | 96 | inode->i_uid = current_fsuid(); |
97 | if (parent->i_mode & S_ISGID) { | 97 | if (parent->i_mode & S_ISGID) { |
98 | inode->i_gid = parent->i_gid; | 98 | inode->i_gid = parent->i_gid; |
99 | if (S_ISDIR(mode)) | 99 | if (S_ISDIR(mode)) |
100 | mode |= S_ISGID; | 100 | mode |= S_ISGID; |
101 | } else | 101 | } else |
102 | inode->i_gid = current->fsgid; | 102 | inode->i_gid = current_fsgid(); |
103 | 103 | ||
104 | /* | 104 | /* |
105 | * New inodes need to save sane values on disk when | 105 | * New inodes need to save sane values on disk when |
diff --git a/fs/lockd/host.c b/fs/lockd/host.c index 70fc63a1727b..e05d04416037 100644 --- a/fs/lockd/host.c +++ b/fs/lockd/host.c | |||
@@ -115,14 +115,14 @@ static void nlm_display_address(const struct sockaddr *sap, | |||
115 | snprintf(buf, len, "unspecified"); | 115 | snprintf(buf, len, "unspecified"); |
116 | break; | 116 | break; |
117 | case AF_INET: | 117 | case AF_INET: |
118 | snprintf(buf, len, NIPQUAD_FMT, NIPQUAD(sin->sin_addr.s_addr)); | 118 | snprintf(buf, len, "%pI4", &sin->sin_addr.s_addr); |
119 | break; | 119 | break; |
120 | case AF_INET6: | 120 | case AF_INET6: |
121 | if (ipv6_addr_v4mapped(&sin6->sin6_addr)) | 121 | if (ipv6_addr_v4mapped(&sin6->sin6_addr)) |
122 | snprintf(buf, len, NIPQUAD_FMT, | 122 | snprintf(buf, len, "%pI4", |
123 | NIPQUAD(sin6->sin6_addr.s6_addr32[3])); | 123 | &sin6->sin6_addr.s6_addr32[3]); |
124 | else | 124 | else |
125 | snprintf(buf, len, NIP6_FMT, NIP6(sin6->sin6_addr)); | 125 | snprintf(buf, len, "%pI6", &sin6->sin6_addr); |
126 | break; | 126 | break; |
127 | default: | 127 | default: |
128 | snprintf(buf, len, "unsupported address family"); | 128 | snprintf(buf, len, "unsupported address family"); |
diff --git a/fs/lockd/mon.c b/fs/lockd/mon.c index 4e7e958e8f67..ffd3461f75ef 100644 --- a/fs/lockd/mon.c +++ b/fs/lockd/mon.c | |||
@@ -179,7 +179,7 @@ static __be32 *xdr_encode_mon_name(__be32 *p, struct nsm_args *argp) | |||
179 | 179 | ||
180 | if (!nsm_use_hostnames) { | 180 | if (!nsm_use_hostnames) { |
181 | snprintf(buffer, XDR_ADDRBUF_LEN, | 181 | snprintf(buffer, XDR_ADDRBUF_LEN, |
182 | NIPQUAD_FMT, NIPQUAD(argp->addr)); | 182 | "%pI4", &argp->addr); |
183 | name = buffer; | 183 | name = buffer; |
184 | } | 184 | } |
185 | 185 | ||
diff --git a/fs/locks.c b/fs/locks.c index 09062e3ff104..46a2e12f7d42 100644 --- a/fs/locks.c +++ b/fs/locks.c | |||
@@ -1349,7 +1349,7 @@ int generic_setlease(struct file *filp, long arg, struct file_lock **flp) | |||
1349 | struct inode *inode = dentry->d_inode; | 1349 | struct inode *inode = dentry->d_inode; |
1350 | int error, rdlease_count = 0, wrlease_count = 0; | 1350 | int error, rdlease_count = 0, wrlease_count = 0; |
1351 | 1351 | ||
1352 | if ((current->fsuid != inode->i_uid) && !capable(CAP_LEASE)) | 1352 | if ((current_fsuid() != inode->i_uid) && !capable(CAP_LEASE)) |
1353 | return -EACCES; | 1353 | return -EACCES; |
1354 | if (!S_ISREG(inode->i_mode)) | 1354 | if (!S_ISREG(inode->i_mode)) |
1355 | return -EINVAL; | 1355 | return -EINVAL; |
diff --git a/fs/minix/bitmap.c b/fs/minix/bitmap.c index 703cc35e04b9..3aebe322271a 100644 --- a/fs/minix/bitmap.c +++ b/fs/minix/bitmap.c | |||
@@ -262,8 +262,8 @@ struct inode * minix_new_inode(const struct inode * dir, int * error) | |||
262 | iput(inode); | 262 | iput(inode); |
263 | return NULL; | 263 | return NULL; |
264 | } | 264 | } |
265 | inode->i_uid = current->fsuid; | 265 | inode->i_uid = current_fsuid(); |
266 | inode->i_gid = (dir->i_mode & S_ISGID) ? dir->i_gid : current->fsgid; | 266 | inode->i_gid = (dir->i_mode & S_ISGID) ? dir->i_gid : current_fsgid(); |
267 | inode->i_ino = j; | 267 | inode->i_ino = j; |
268 | inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME_SEC; | 268 | inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME_SEC; |
269 | inode->i_blocks = 0; | 269 | inode->i_blocks = 0; |
diff --git a/fs/namei.c b/fs/namei.c index d34e0f9681c6..af3783fff1de 100644 --- a/fs/namei.c +++ b/fs/namei.c | |||
@@ -186,7 +186,7 @@ int generic_permission(struct inode *inode, int mask, | |||
186 | 186 | ||
187 | mask &= MAY_READ | MAY_WRITE | MAY_EXEC; | 187 | mask &= MAY_READ | MAY_WRITE | MAY_EXEC; |
188 | 188 | ||
189 | if (current->fsuid == inode->i_uid) | 189 | if (current_fsuid() == inode->i_uid) |
190 | mode >>= 6; | 190 | mode >>= 6; |
191 | else { | 191 | else { |
192 | if (IS_POSIXACL(inode) && (mode & S_IRWXG) && check_acl) { | 192 | if (IS_POSIXACL(inode) && (mode & S_IRWXG) && check_acl) { |
@@ -441,7 +441,7 @@ static int exec_permission_lite(struct inode *inode) | |||
441 | if (inode->i_op && inode->i_op->permission) | 441 | if (inode->i_op && inode->i_op->permission) |
442 | return -EAGAIN; | 442 | return -EAGAIN; |
443 | 443 | ||
444 | if (current->fsuid == inode->i_uid) | 444 | if (current_fsuid() == inode->i_uid) |
445 | mode >>= 6; | 445 | mode >>= 6; |
446 | else if (in_group_p(inode->i_gid)) | 446 | else if (in_group_p(inode->i_gid)) |
447 | mode >>= 3; | 447 | mode >>= 3; |
@@ -1334,11 +1334,13 @@ static int user_path_parent(int dfd, const char __user *path, | |||
1334 | */ | 1334 | */ |
1335 | static inline int check_sticky(struct inode *dir, struct inode *inode) | 1335 | static inline int check_sticky(struct inode *dir, struct inode *inode) |
1336 | { | 1336 | { |
1337 | uid_t fsuid = current_fsuid(); | ||
1338 | |||
1337 | if (!(dir->i_mode & S_ISVTX)) | 1339 | if (!(dir->i_mode & S_ISVTX)) |
1338 | return 0; | 1340 | return 0; |
1339 | if (inode->i_uid == current->fsuid) | 1341 | if (inode->i_uid == fsuid) |
1340 | return 0; | 1342 | return 0; |
1341 | if (dir->i_uid == current->fsuid) | 1343 | if (dir->i_uid == fsuid) |
1342 | return 0; | 1344 | return 0; |
1343 | return !capable(CAP_FOWNER); | 1345 | return !capable(CAP_FOWNER); |
1344 | } | 1346 | } |
diff --git a/fs/namespace.c b/fs/namespace.c index 65b3dc844c87..1c09cab8f7cf 100644 --- a/fs/namespace.c +++ b/fs/namespace.c | |||
@@ -1176,7 +1176,7 @@ static int mount_is_safe(struct path *path) | |||
1176 | if (S_ISLNK(path->dentry->d_inode->i_mode)) | 1176 | if (S_ISLNK(path->dentry->d_inode->i_mode)) |
1177 | return -EPERM; | 1177 | return -EPERM; |
1178 | if (path->dentry->d_inode->i_mode & S_ISVTX) { | 1178 | if (path->dentry->d_inode->i_mode & S_ISVTX) { |
1179 | if (current->uid != path->dentry->d_inode->i_uid) | 1179 | if (current_uid() != path->dentry->d_inode->i_uid) |
1180 | return -EPERM; | 1180 | return -EPERM; |
1181 | } | 1181 | } |
1182 | if (inode_permission(path->dentry->d_inode, MAY_WRITE)) | 1182 | if (inode_permission(path->dentry->d_inode, MAY_WRITE)) |
diff --git a/fs/ncpfs/ioctl.c b/fs/ncpfs/ioctl.c index 3a97c95e1ca2..6d04e050c74e 100644 --- a/fs/ncpfs/ioctl.c +++ b/fs/ncpfs/ioctl.c | |||
@@ -40,10 +40,10 @@ ncp_get_fs_info(struct ncp_server * server, struct file *file, | |||
40 | struct inode *inode = file->f_path.dentry->d_inode; | 40 | struct inode *inode = file->f_path.dentry->d_inode; |
41 | struct ncp_fs_info info; | 41 | struct ncp_fs_info info; |
42 | 42 | ||
43 | if ((file_permission(file, MAY_WRITE) != 0) | 43 | if (file_permission(file, MAY_WRITE) != 0 |
44 | && (current->uid != server->m.mounted_uid)) { | 44 | && current_uid() != server->m.mounted_uid) |
45 | return -EACCES; | 45 | return -EACCES; |
46 | } | 46 | |
47 | if (copy_from_user(&info, arg, sizeof(info))) | 47 | if (copy_from_user(&info, arg, sizeof(info))) |
48 | return -EFAULT; | 48 | return -EFAULT; |
49 | 49 | ||
@@ -70,10 +70,10 @@ ncp_get_fs_info_v2(struct ncp_server * server, struct file *file, | |||
70 | struct inode *inode = file->f_path.dentry->d_inode; | 70 | struct inode *inode = file->f_path.dentry->d_inode; |
71 | struct ncp_fs_info_v2 info2; | 71 | struct ncp_fs_info_v2 info2; |
72 | 72 | ||
73 | if ((file_permission(file, MAY_WRITE) != 0) | 73 | if (file_permission(file, MAY_WRITE) != 0 |
74 | && (current->uid != server->m.mounted_uid)) { | 74 | && current_uid() != server->m.mounted_uid) |
75 | return -EACCES; | 75 | return -EACCES; |
76 | } | 76 | |
77 | if (copy_from_user(&info2, arg, sizeof(info2))) | 77 | if (copy_from_user(&info2, arg, sizeof(info2))) |
78 | return -EFAULT; | 78 | return -EFAULT; |
79 | 79 | ||
@@ -141,10 +141,10 @@ ncp_get_compat_fs_info_v2(struct ncp_server * server, struct file *file, | |||
141 | struct inode *inode = file->f_path.dentry->d_inode; | 141 | struct inode *inode = file->f_path.dentry->d_inode; |
142 | struct compat_ncp_fs_info_v2 info2; | 142 | struct compat_ncp_fs_info_v2 info2; |
143 | 143 | ||
144 | if ((file_permission(file, MAY_WRITE) != 0) | 144 | if (file_permission(file, MAY_WRITE) != 0 |
145 | && (current->uid != server->m.mounted_uid)) { | 145 | && current_uid() != server->m.mounted_uid) |
146 | return -EACCES; | 146 | return -EACCES; |
147 | } | 147 | |
148 | if (copy_from_user(&info2, arg, sizeof(info2))) | 148 | if (copy_from_user(&info2, arg, sizeof(info2))) |
149 | return -EFAULT; | 149 | return -EFAULT; |
150 | 150 | ||
@@ -270,16 +270,17 @@ static int __ncp_ioctl(struct inode *inode, struct file *filp, | |||
270 | struct ncp_ioctl_request request; | 270 | struct ncp_ioctl_request request; |
271 | char* bouncebuffer; | 271 | char* bouncebuffer; |
272 | void __user *argp = (void __user *)arg; | 272 | void __user *argp = (void __user *)arg; |
273 | uid_t uid = current_uid(); | ||
273 | 274 | ||
274 | switch (cmd) { | 275 | switch (cmd) { |
275 | #ifdef CONFIG_COMPAT | 276 | #ifdef CONFIG_COMPAT |
276 | case NCP_IOC_NCPREQUEST_32: | 277 | case NCP_IOC_NCPREQUEST_32: |
277 | #endif | 278 | #endif |
278 | case NCP_IOC_NCPREQUEST: | 279 | case NCP_IOC_NCPREQUEST: |
279 | if ((file_permission(filp, MAY_WRITE) != 0) | 280 | if (file_permission(filp, MAY_WRITE) != 0 |
280 | && (current->uid != server->m.mounted_uid)) { | 281 | && uid != server->m.mounted_uid) |
281 | return -EACCES; | 282 | return -EACCES; |
282 | } | 283 | |
283 | #ifdef CONFIG_COMPAT | 284 | #ifdef CONFIG_COMPAT |
284 | if (cmd == NCP_IOC_NCPREQUEST_32) { | 285 | if (cmd == NCP_IOC_NCPREQUEST_32) { |
285 | struct compat_ncp_ioctl_request request32; | 286 | struct compat_ncp_ioctl_request request32; |
@@ -356,10 +357,10 @@ static int __ncp_ioctl(struct inode *inode, struct file *filp, | |||
356 | case NCP_IOC_GETMOUNTUID16: | 357 | case NCP_IOC_GETMOUNTUID16: |
357 | case NCP_IOC_GETMOUNTUID32: | 358 | case NCP_IOC_GETMOUNTUID32: |
358 | case NCP_IOC_GETMOUNTUID64: | 359 | case NCP_IOC_GETMOUNTUID64: |
359 | if ((file_permission(filp, MAY_READ) != 0) | 360 | if (file_permission(filp, MAY_READ) != 0 |
360 | && (current->uid != server->m.mounted_uid)) { | 361 | && uid != server->m.mounted_uid) |
361 | return -EACCES; | 362 | return -EACCES; |
362 | } | 363 | |
363 | if (cmd == NCP_IOC_GETMOUNTUID16) { | 364 | if (cmd == NCP_IOC_GETMOUNTUID16) { |
364 | u16 uid; | 365 | u16 uid; |
365 | SET_UID(uid, server->m.mounted_uid); | 366 | SET_UID(uid, server->m.mounted_uid); |
@@ -380,11 +381,10 @@ static int __ncp_ioctl(struct inode *inode, struct file *filp, | |||
380 | { | 381 | { |
381 | struct ncp_setroot_ioctl sr; | 382 | struct ncp_setroot_ioctl sr; |
382 | 383 | ||
383 | if ((file_permission(filp, MAY_READ) != 0) | 384 | if (file_permission(filp, MAY_READ) != 0 |
384 | && (current->uid != server->m.mounted_uid)) | 385 | && uid != server->m.mounted_uid) |
385 | { | ||
386 | return -EACCES; | 386 | return -EACCES; |
387 | } | 387 | |
388 | if (server->m.mounted_vol[0]) { | 388 | if (server->m.mounted_vol[0]) { |
389 | struct dentry* dentry = inode->i_sb->s_root; | 389 | struct dentry* dentry = inode->i_sb->s_root; |
390 | 390 | ||
@@ -408,6 +408,7 @@ static int __ncp_ioctl(struct inode *inode, struct file *filp, | |||
408 | return -EFAULT; | 408 | return -EFAULT; |
409 | return 0; | 409 | return 0; |
410 | } | 410 | } |
411 | |||
411 | case NCP_IOC_SETROOT: | 412 | case NCP_IOC_SETROOT: |
412 | { | 413 | { |
413 | struct ncp_setroot_ioctl sr; | 414 | struct ncp_setroot_ioctl sr; |
@@ -455,11 +456,10 @@ static int __ncp_ioctl(struct inode *inode, struct file *filp, | |||
455 | 456 | ||
456 | #ifdef CONFIG_NCPFS_PACKET_SIGNING | 457 | #ifdef CONFIG_NCPFS_PACKET_SIGNING |
457 | case NCP_IOC_SIGN_INIT: | 458 | case NCP_IOC_SIGN_INIT: |
458 | if ((file_permission(filp, MAY_WRITE) != 0) | 459 | if (file_permission(filp, MAY_WRITE) != 0 |
459 | && (current->uid != server->m.mounted_uid)) | 460 | && uid != server->m.mounted_uid) |
460 | { | ||
461 | return -EACCES; | 461 | return -EACCES; |
462 | } | 462 | |
463 | if (argp) { | 463 | if (argp) { |
464 | if (server->sign_wanted) | 464 | if (server->sign_wanted) |
465 | { | 465 | { |
@@ -478,24 +478,22 @@ static int __ncp_ioctl(struct inode *inode, struct file *filp, | |||
478 | return 0; | 478 | return 0; |
479 | 479 | ||
480 | case NCP_IOC_SIGN_WANTED: | 480 | case NCP_IOC_SIGN_WANTED: |
481 | if ((file_permission(filp, MAY_READ) != 0) | 481 | if (file_permission(filp, MAY_READ) != 0 |
482 | && (current->uid != server->m.mounted_uid)) | 482 | && uid != server->m.mounted_uid) |
483 | { | ||
484 | return -EACCES; | 483 | return -EACCES; |
485 | } | ||
486 | 484 | ||
487 | if (put_user(server->sign_wanted, (int __user *)argp)) | 485 | if (put_user(server->sign_wanted, (int __user *)argp)) |
488 | return -EFAULT; | 486 | return -EFAULT; |
489 | return 0; | 487 | return 0; |
488 | |||
490 | case NCP_IOC_SET_SIGN_WANTED: | 489 | case NCP_IOC_SET_SIGN_WANTED: |
491 | { | 490 | { |
492 | int newstate; | 491 | int newstate; |
493 | 492 | ||
494 | if ((file_permission(filp, MAY_WRITE) != 0) | 493 | if (file_permission(filp, MAY_WRITE) != 0 |
495 | && (current->uid != server->m.mounted_uid)) | 494 | && uid != server->m.mounted_uid) |
496 | { | ||
497 | return -EACCES; | 495 | return -EACCES; |
498 | } | 496 | |
499 | /* get only low 8 bits... */ | 497 | /* get only low 8 bits... */ |
500 | if (get_user(newstate, (unsigned char __user *)argp)) | 498 | if (get_user(newstate, (unsigned char __user *)argp)) |
501 | return -EFAULT; | 499 | return -EFAULT; |
@@ -512,11 +510,10 @@ static int __ncp_ioctl(struct inode *inode, struct file *filp, | |||
512 | 510 | ||
513 | #ifdef CONFIG_NCPFS_IOCTL_LOCKING | 511 | #ifdef CONFIG_NCPFS_IOCTL_LOCKING |
514 | case NCP_IOC_LOCKUNLOCK: | 512 | case NCP_IOC_LOCKUNLOCK: |
515 | if ((file_permission(filp, MAY_WRITE) != 0) | 513 | if (file_permission(filp, MAY_WRITE) != 0 |
516 | && (current->uid != server->m.mounted_uid)) | 514 | && uid != server->m.mounted_uid) |
517 | { | ||
518 | return -EACCES; | 515 | return -EACCES; |
519 | } | 516 | |
520 | { | 517 | { |
521 | struct ncp_lock_ioctl rqdata; | 518 | struct ncp_lock_ioctl rqdata; |
522 | 519 | ||
@@ -585,9 +582,8 @@ outrel: | |||
585 | 582 | ||
586 | #ifdef CONFIG_COMPAT | 583 | #ifdef CONFIG_COMPAT |
587 | case NCP_IOC_GETOBJECTNAME_32: | 584 | case NCP_IOC_GETOBJECTNAME_32: |
588 | if (current->uid != server->m.mounted_uid) { | 585 | if (uid != server->m.mounted_uid) |
589 | return -EACCES; | 586 | return -EACCES; |
590 | } | ||
591 | { | 587 | { |
592 | struct compat_ncp_objectname_ioctl user; | 588 | struct compat_ncp_objectname_ioctl user; |
593 | size_t outl; | 589 | size_t outl; |
@@ -609,10 +605,10 @@ outrel: | |||
609 | return 0; | 605 | return 0; |
610 | } | 606 | } |
611 | #endif | 607 | #endif |
608 | |||
612 | case NCP_IOC_GETOBJECTNAME: | 609 | case NCP_IOC_GETOBJECTNAME: |
613 | if (current->uid != server->m.mounted_uid) { | 610 | if (uid != server->m.mounted_uid) |
614 | return -EACCES; | 611 | return -EACCES; |
615 | } | ||
616 | { | 612 | { |
617 | struct ncp_objectname_ioctl user; | 613 | struct ncp_objectname_ioctl user; |
618 | size_t outl; | 614 | size_t outl; |
@@ -633,13 +629,13 @@ outrel: | |||
633 | return -EFAULT; | 629 | return -EFAULT; |
634 | return 0; | 630 | return 0; |
635 | } | 631 | } |
632 | |||
636 | #ifdef CONFIG_COMPAT | 633 | #ifdef CONFIG_COMPAT |
637 | case NCP_IOC_SETOBJECTNAME_32: | 634 | case NCP_IOC_SETOBJECTNAME_32: |
638 | #endif | 635 | #endif |
639 | case NCP_IOC_SETOBJECTNAME: | 636 | case NCP_IOC_SETOBJECTNAME: |
640 | if (current->uid != server->m.mounted_uid) { | 637 | if (uid != server->m.mounted_uid) |
641 | return -EACCES; | 638 | return -EACCES; |
642 | } | ||
643 | { | 639 | { |
644 | struct ncp_objectname_ioctl user; | 640 | struct ncp_objectname_ioctl user; |
645 | void* newname; | 641 | void* newname; |
@@ -691,13 +687,13 @@ outrel: | |||
691 | kfree(oldname); | 687 | kfree(oldname); |
692 | return 0; | 688 | return 0; |
693 | } | 689 | } |
690 | |||
694 | #ifdef CONFIG_COMPAT | 691 | #ifdef CONFIG_COMPAT |
695 | case NCP_IOC_GETPRIVATEDATA_32: | 692 | case NCP_IOC_GETPRIVATEDATA_32: |
696 | #endif | 693 | #endif |
697 | case NCP_IOC_GETPRIVATEDATA: | 694 | case NCP_IOC_GETPRIVATEDATA: |
698 | if (current->uid != server->m.mounted_uid) { | 695 | if (uid != server->m.mounted_uid) |
699 | return -EACCES; | 696 | return -EACCES; |
700 | } | ||
701 | { | 697 | { |
702 | struct ncp_privatedata_ioctl user; | 698 | struct ncp_privatedata_ioctl user; |
703 | size_t outl; | 699 | size_t outl; |
@@ -736,13 +732,13 @@ outrel: | |||
736 | 732 | ||
737 | return 0; | 733 | return 0; |
738 | } | 734 | } |
735 | |||
739 | #ifdef CONFIG_COMPAT | 736 | #ifdef CONFIG_COMPAT |
740 | case NCP_IOC_SETPRIVATEDATA_32: | 737 | case NCP_IOC_SETPRIVATEDATA_32: |
741 | #endif | 738 | #endif |
742 | case NCP_IOC_SETPRIVATEDATA: | 739 | case NCP_IOC_SETPRIVATEDATA: |
743 | if (current->uid != server->m.mounted_uid) { | 740 | if (uid != server->m.mounted_uid) |
744 | return -EACCES; | 741 | return -EACCES; |
745 | } | ||
746 | { | 742 | { |
747 | struct ncp_privatedata_ioctl user; | 743 | struct ncp_privatedata_ioctl user; |
748 | void* new; | 744 | void* new; |
@@ -794,9 +790,10 @@ outrel: | |||
794 | #endif /* CONFIG_NCPFS_NLS */ | 790 | #endif /* CONFIG_NCPFS_NLS */ |
795 | 791 | ||
796 | case NCP_IOC_SETDENTRYTTL: | 792 | case NCP_IOC_SETDENTRYTTL: |
797 | if ((file_permission(filp, MAY_WRITE) != 0) && | 793 | if (file_permission(filp, MAY_WRITE) != 0 && |
798 | (current->uid != server->m.mounted_uid)) | 794 | uid != server->m.mounted_uid) |
799 | return -EACCES; | 795 | return -EACCES; |
796 | |||
800 | { | 797 | { |
801 | u_int32_t user; | 798 | u_int32_t user; |
802 | 799 | ||
diff --git a/fs/nfs/nfsroot.c b/fs/nfs/nfsroot.c index 8478fc25daee..d74d16ce0d49 100644 --- a/fs/nfs/nfsroot.c +++ b/fs/nfs/nfsroot.c | |||
@@ -329,7 +329,7 @@ static int __init root_nfs_addr(void) | |||
329 | } | 329 | } |
330 | 330 | ||
331 | snprintf(nfs_data.hostname, sizeof(nfs_data.hostname), | 331 | snprintf(nfs_data.hostname, sizeof(nfs_data.hostname), |
332 | "%u.%u.%u.%u", NIPQUAD(servaddr)); | 332 | "%pI4", &servaddr); |
333 | return 0; | 333 | return 0; |
334 | } | 334 | } |
335 | 335 | ||
@@ -421,8 +421,8 @@ static int __init root_nfs_getport(int program, int version, int proto) | |||
421 | { | 421 | { |
422 | struct sockaddr_in sin; | 422 | struct sockaddr_in sin; |
423 | 423 | ||
424 | printk(KERN_NOTICE "Looking up port of RPC %d/%d on %u.%u.%u.%u\n", | 424 | printk(KERN_NOTICE "Looking up port of RPC %d/%d on %pI4\n", |
425 | program, version, NIPQUAD(servaddr)); | 425 | program, version, &servaddr); |
426 | set_sockaddr(&sin, servaddr, 0); | 426 | set_sockaddr(&sin, servaddr, 0); |
427 | return rpcb_getport_sync(&sin, program, version, proto); | 427 | return rpcb_getport_sync(&sin, program, version, proto); |
428 | } | 428 | } |
diff --git a/fs/nfs/super.c b/fs/nfs/super.c index f48db679a1c6..bb0313ac9e1f 100644 --- a/fs/nfs/super.c +++ b/fs/nfs/super.c | |||
@@ -462,14 +462,12 @@ static void nfs_show_mountd_options(struct seq_file *m, struct nfs_server *nfss, | |||
462 | switch (sap->sa_family) { | 462 | switch (sap->sa_family) { |
463 | case AF_INET: { | 463 | case AF_INET: { |
464 | struct sockaddr_in *sin = (struct sockaddr_in *)sap; | 464 | struct sockaddr_in *sin = (struct sockaddr_in *)sap; |
465 | seq_printf(m, ",mountaddr=" NIPQUAD_FMT, | 465 | seq_printf(m, ",mountaddr=%pI4", &sin->sin_addr.s_addr); |
466 | NIPQUAD(sin->sin_addr.s_addr)); | ||
467 | break; | 466 | break; |
468 | } | 467 | } |
469 | case AF_INET6: { | 468 | case AF_INET6: { |
470 | struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)sap; | 469 | struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)sap; |
471 | seq_printf(m, ",mountaddr=" NIP6_FMT, | 470 | seq_printf(m, ",mountaddr=%pI6", &sin6->sin6_addr); |
472 | NIP6(sin6->sin6_addr)); | ||
473 | break; | 471 | break; |
474 | } | 472 | } |
475 | default: | 473 | default: |
diff --git a/fs/nfsctl.c b/fs/nfsctl.c index aed8145d9087..b1acbd6ab6fb 100644 --- a/fs/nfsctl.c +++ b/fs/nfsctl.c | |||
@@ -10,6 +10,8 @@ | |||
10 | #include <linux/sunrpc/svc.h> | 10 | #include <linux/sunrpc/svc.h> |
11 | #include <linux/nfsd/nfsd.h> | 11 | #include <linux/nfsd/nfsd.h> |
12 | #include <linux/nfsd/syscall.h> | 12 | #include <linux/nfsd/syscall.h> |
13 | #include <linux/cred.h> | ||
14 | #include <linux/sched.h> | ||
13 | #include <linux/linkage.h> | 15 | #include <linux/linkage.h> |
14 | #include <linux/namei.h> | 16 | #include <linux/namei.h> |
15 | #include <linux/mount.h> | 17 | #include <linux/mount.h> |
@@ -41,7 +43,8 @@ static struct file *do_open(char *name, int flags) | |||
41 | error = may_open(&nd, MAY_WRITE, FMODE_WRITE); | 43 | error = may_open(&nd, MAY_WRITE, FMODE_WRITE); |
42 | 44 | ||
43 | if (!error) | 45 | if (!error) |
44 | return dentry_open(nd.path.dentry, nd.path.mnt, flags); | 46 | return dentry_open(nd.path.dentry, nd.path.mnt, flags, |
47 | current_cred()); | ||
45 | 48 | ||
46 | path_put(&nd.path); | 49 | path_put(&nd.path); |
47 | return ERR_PTR(error); | 50 | return ERR_PTR(error); |
diff --git a/fs/nfsd/auth.c b/fs/nfsd/auth.c index 294992e9bf69..0184fe9b514c 100644 --- a/fs/nfsd/auth.c +++ b/fs/nfsd/auth.c | |||
@@ -27,53 +27,70 @@ int nfsexp_flags(struct svc_rqst *rqstp, struct svc_export *exp) | |||
27 | 27 | ||
28 | int nfsd_setuser(struct svc_rqst *rqstp, struct svc_export *exp) | 28 | int nfsd_setuser(struct svc_rqst *rqstp, struct svc_export *exp) |
29 | { | 29 | { |
30 | struct svc_cred cred = rqstp->rq_cred; | 30 | struct group_info *rqgi; |
31 | struct group_info *gi; | ||
32 | struct cred *new; | ||
31 | int i; | 33 | int i; |
32 | int flags = nfsexp_flags(rqstp, exp); | 34 | int flags = nfsexp_flags(rqstp, exp); |
33 | int ret; | 35 | int ret; |
34 | 36 | ||
37 | /* discard any old override before preparing the new set */ | ||
38 | revert_creds(get_cred(current->real_cred)); | ||
39 | new = prepare_creds(); | ||
40 | if (!new) | ||
41 | return -ENOMEM; | ||
42 | |||
43 | new->fsuid = rqstp->rq_cred.cr_uid; | ||
44 | new->fsgid = rqstp->rq_cred.cr_gid; | ||
45 | |||
46 | rqgi = rqstp->rq_cred.cr_group_info; | ||
47 | |||
35 | if (flags & NFSEXP_ALLSQUASH) { | 48 | if (flags & NFSEXP_ALLSQUASH) { |
36 | cred.cr_uid = exp->ex_anon_uid; | 49 | new->fsuid = exp->ex_anon_uid; |
37 | cred.cr_gid = exp->ex_anon_gid; | 50 | new->fsgid = exp->ex_anon_gid; |
38 | cred.cr_group_info = groups_alloc(0); | 51 | gi = groups_alloc(0); |
39 | } else if (flags & NFSEXP_ROOTSQUASH) { | 52 | } else if (flags & NFSEXP_ROOTSQUASH) { |
40 | struct group_info *gi; | 53 | if (!new->fsuid) |
41 | if (!cred.cr_uid) | 54 | new->fsuid = exp->ex_anon_uid; |
42 | cred.cr_uid = exp->ex_anon_uid; | 55 | if (!new->fsgid) |
43 | if (!cred.cr_gid) | 56 | new->fsgid = exp->ex_anon_gid; |
44 | cred.cr_gid = exp->ex_anon_gid; | ||
45 | gi = groups_alloc(cred.cr_group_info->ngroups); | ||
46 | if (gi) | ||
47 | for (i = 0; i < cred.cr_group_info->ngroups; i++) { | ||
48 | if (!GROUP_AT(cred.cr_group_info, i)) | ||
49 | GROUP_AT(gi, i) = exp->ex_anon_gid; | ||
50 | else | ||
51 | GROUP_AT(gi, i) = GROUP_AT(cred.cr_group_info, i); | ||
52 | } | ||
53 | cred.cr_group_info = gi; | ||
54 | } else | ||
55 | get_group_info(cred.cr_group_info); | ||
56 | |||
57 | if (cred.cr_uid != (uid_t) -1) | ||
58 | current->fsuid = cred.cr_uid; | ||
59 | else | ||
60 | current->fsuid = exp->ex_anon_uid; | ||
61 | if (cred.cr_gid != (gid_t) -1) | ||
62 | current->fsgid = cred.cr_gid; | ||
63 | else | ||
64 | current->fsgid = exp->ex_anon_gid; | ||
65 | 57 | ||
66 | if (!cred.cr_group_info) | 58 | gi = groups_alloc(rqgi->ngroups); |
67 | return -ENOMEM; | 59 | if (!gi) |
68 | ret = set_current_groups(cred.cr_group_info); | 60 | goto oom; |
69 | put_group_info(cred.cr_group_info); | 61 | |
70 | if ((cred.cr_uid)) { | 62 | for (i = 0; i < rqgi->ngroups; i++) { |
71 | current->cap_effective = | 63 | if (!GROUP_AT(rqgi, i)) |
72 | cap_drop_nfsd_set(current->cap_effective); | 64 | GROUP_AT(gi, i) = exp->ex_anon_gid; |
65 | else | ||
66 | GROUP_AT(gi, i) = GROUP_AT(rqgi, i); | ||
67 | } | ||
73 | } else { | 68 | } else { |
74 | current->cap_effective = | 69 | gi = get_group_info(rqgi); |
75 | cap_raise_nfsd_set(current->cap_effective, | ||
76 | current->cap_permitted); | ||
77 | } | 70 | } |
71 | |||
72 | if (new->fsuid == (uid_t) -1) | ||
73 | new->fsuid = exp->ex_anon_uid; | ||
74 | if (new->fsgid == (gid_t) -1) | ||
75 | new->fsgid = exp->ex_anon_gid; | ||
76 | |||
77 | ret = set_groups(new, gi); | ||
78 | put_group_info(gi); | ||
79 | if (!ret) | ||
80 | goto error; | ||
81 | |||
82 | if (new->uid) | ||
83 | new->cap_effective = cap_drop_nfsd_set(new->cap_effective); | ||
84 | else | ||
85 | new->cap_effective = cap_raise_nfsd_set(new->cap_effective, | ||
86 | new->cap_permitted); | ||
87 | put_cred(override_creds(new)); | ||
88 | return 0; | ||
89 | |||
90 | oom: | ||
91 | ret = -ENOMEM; | ||
92 | error: | ||
93 | abort_creds(new); | ||
78 | return ret; | 94 | return ret; |
79 | } | 95 | } |
96 | |||
diff --git a/fs/nfsd/nfs4recover.c b/fs/nfsd/nfs4recover.c index b79ec930d9f1..0f9d6efaa62b 100644 --- a/fs/nfsd/nfs4recover.c +++ b/fs/nfsd/nfs4recover.c | |||
@@ -54,20 +54,26 @@ | |||
54 | static struct path rec_dir; | 54 | static struct path rec_dir; |
55 | static int rec_dir_init = 0; | 55 | static int rec_dir_init = 0; |
56 | 56 | ||
57 | static void | 57 | static int |
58 | nfs4_save_user(uid_t *saveuid, gid_t *savegid) | 58 | nfs4_save_creds(const struct cred **original_creds) |
59 | { | 59 | { |
60 | *saveuid = current->fsuid; | 60 | struct cred *new; |
61 | *savegid = current->fsgid; | 61 | |
62 | current->fsuid = 0; | 62 | new = prepare_creds(); |
63 | current->fsgid = 0; | 63 | if (!new) |
64 | return -ENOMEM; | ||
65 | |||
66 | new->fsuid = 0; | ||
67 | new->fsgid = 0; | ||
68 | *original_creds = override_creds(new); | ||
69 | put_cred(new); | ||
70 | return 0; | ||
64 | } | 71 | } |
65 | 72 | ||
66 | static void | 73 | static void |
67 | nfs4_reset_user(uid_t saveuid, gid_t savegid) | 74 | nfs4_reset_creds(const struct cred *original) |
68 | { | 75 | { |
69 | current->fsuid = saveuid; | 76 | revert_creds(original); |
70 | current->fsgid = savegid; | ||
71 | } | 77 | } |
72 | 78 | ||
73 | static void | 79 | static void |
@@ -129,10 +135,9 @@ nfsd4_sync_rec_dir(void) | |||
129 | int | 135 | int |
130 | nfsd4_create_clid_dir(struct nfs4_client *clp) | 136 | nfsd4_create_clid_dir(struct nfs4_client *clp) |
131 | { | 137 | { |
138 | const struct cred *original_cred; | ||
132 | char *dname = clp->cl_recdir; | 139 | char *dname = clp->cl_recdir; |
133 | struct dentry *dentry; | 140 | struct dentry *dentry; |
134 | uid_t uid; | ||
135 | gid_t gid; | ||
136 | int status; | 141 | int status; |
137 | 142 | ||
138 | dprintk("NFSD: nfsd4_create_clid_dir for \"%s\"\n", dname); | 143 | dprintk("NFSD: nfsd4_create_clid_dir for \"%s\"\n", dname); |
@@ -140,7 +145,9 @@ nfsd4_create_clid_dir(struct nfs4_client *clp) | |||
140 | if (!rec_dir_init || clp->cl_firststate) | 145 | if (!rec_dir_init || clp->cl_firststate) |
141 | return 0; | 146 | return 0; |
142 | 147 | ||
143 | nfs4_save_user(&uid, &gid); | 148 | status = nfs4_save_creds(&original_cred); |
149 | if (status < 0) | ||
150 | return status; | ||
144 | 151 | ||
145 | /* lock the parent */ | 152 | /* lock the parent */ |
146 | mutex_lock(&rec_dir.dentry->d_inode->i_mutex); | 153 | mutex_lock(&rec_dir.dentry->d_inode->i_mutex); |
@@ -168,7 +175,7 @@ out_unlock: | |||
168 | clp->cl_firststate = 1; | 175 | clp->cl_firststate = 1; |
169 | nfsd4_sync_rec_dir(); | 176 | nfsd4_sync_rec_dir(); |
170 | } | 177 | } |
171 | nfs4_reset_user(uid, gid); | 178 | nfs4_reset_creds(original_cred); |
172 | dprintk("NFSD: nfsd4_create_clid_dir returns %d\n", status); | 179 | dprintk("NFSD: nfsd4_create_clid_dir returns %d\n", status); |
173 | return status; | 180 | return status; |
174 | } | 181 | } |
@@ -211,26 +218,29 @@ nfsd4_build_dentrylist(void *arg, const char *name, int namlen, | |||
211 | static int | 218 | static int |
212 | nfsd4_list_rec_dir(struct dentry *dir, recdir_func *f) | 219 | nfsd4_list_rec_dir(struct dentry *dir, recdir_func *f) |
213 | { | 220 | { |
221 | const struct cred *original_cred; | ||
214 | struct file *filp; | 222 | struct file *filp; |
215 | struct dentry_list_arg dla = { | 223 | struct dentry_list_arg dla = { |
216 | .parent = dir, | 224 | .parent = dir, |
217 | }; | 225 | }; |
218 | struct list_head *dentries = &dla.dentries; | 226 | struct list_head *dentries = &dla.dentries; |
219 | struct dentry_list *child; | 227 | struct dentry_list *child; |
220 | uid_t uid; | ||
221 | gid_t gid; | ||
222 | int status; | 228 | int status; |
223 | 229 | ||
224 | if (!rec_dir_init) | 230 | if (!rec_dir_init) |
225 | return 0; | 231 | return 0; |
226 | 232 | ||
227 | nfs4_save_user(&uid, &gid); | 233 | status = nfs4_save_creds(&original_cred); |
234 | if (status < 0) | ||
235 | return status; | ||
228 | INIT_LIST_HEAD(dentries); | 236 | INIT_LIST_HEAD(dentries); |
229 | 237 | ||
230 | filp = dentry_open(dget(dir), mntget(rec_dir.mnt), O_RDONLY); | 238 | filp = dentry_open(dget(dir), mntget(rec_dir.mnt), O_RDONLY, |
239 | current_cred()); | ||
231 | status = PTR_ERR(filp); | 240 | status = PTR_ERR(filp); |
232 | if (IS_ERR(filp)) | 241 | if (IS_ERR(filp)) |
233 | goto out; | 242 | goto out; |
243 | INIT_LIST_HEAD(dentries); | ||
234 | status = vfs_readdir(filp, nfsd4_build_dentrylist, &dla); | 244 | status = vfs_readdir(filp, nfsd4_build_dentrylist, &dla); |
235 | fput(filp); | 245 | fput(filp); |
236 | while (!list_empty(dentries)) { | 246 | while (!list_empty(dentries)) { |
@@ -249,7 +259,7 @@ out: | |||
249 | dput(child->dentry); | 259 | dput(child->dentry); |
250 | kfree(child); | 260 | kfree(child); |
251 | } | 261 | } |
252 | nfs4_reset_user(uid, gid); | 262 | nfs4_reset_creds(original_cred); |
253 | return status; | 263 | return status; |
254 | } | 264 | } |
255 | 265 | ||
@@ -311,8 +321,7 @@ out: | |||
311 | void | 321 | void |
312 | nfsd4_remove_clid_dir(struct nfs4_client *clp) | 322 | nfsd4_remove_clid_dir(struct nfs4_client *clp) |
313 | { | 323 | { |
314 | uid_t uid; | 324 | const struct cred *original_cred; |
315 | gid_t gid; | ||
316 | int status; | 325 | int status; |
317 | 326 | ||
318 | if (!rec_dir_init || !clp->cl_firststate) | 327 | if (!rec_dir_init || !clp->cl_firststate) |
@@ -322,9 +331,13 @@ nfsd4_remove_clid_dir(struct nfs4_client *clp) | |||
322 | if (status) | 331 | if (status) |
323 | goto out; | 332 | goto out; |
324 | clp->cl_firststate = 0; | 333 | clp->cl_firststate = 0; |
325 | nfs4_save_user(&uid, &gid); | 334 | |
335 | status = nfs4_save_creds(&original_cred); | ||
336 | if (status < 0) | ||
337 | goto out; | ||
338 | |||
326 | status = nfsd4_unlink_clid_dir(clp->cl_recdir, HEXDIR_LEN-1); | 339 | status = nfsd4_unlink_clid_dir(clp->cl_recdir, HEXDIR_LEN-1); |
327 | nfs4_reset_user(uid, gid); | 340 | nfs4_reset_creds(original_cred); |
328 | if (status == 0) | 341 | if (status == 0) |
329 | nfsd4_sync_rec_dir(); | 342 | nfsd4_sync_rec_dir(); |
330 | mnt_drop_write(rec_dir.mnt); | 343 | mnt_drop_write(rec_dir.mnt); |
@@ -401,16 +414,21 @@ nfsd4_recdir_load(void) { | |||
401 | void | 414 | void |
402 | nfsd4_init_recdir(char *rec_dirname) | 415 | nfsd4_init_recdir(char *rec_dirname) |
403 | { | 416 | { |
404 | uid_t uid = 0; | 417 | const struct cred *original_cred; |
405 | gid_t gid = 0; | 418 | int status; |
406 | int status; | ||
407 | 419 | ||
408 | printk("NFSD: Using %s as the NFSv4 state recovery directory\n", | 420 | printk("NFSD: Using %s as the NFSv4 state recovery directory\n", |
409 | rec_dirname); | 421 | rec_dirname); |
410 | 422 | ||
411 | BUG_ON(rec_dir_init); | 423 | BUG_ON(rec_dir_init); |
412 | 424 | ||
413 | nfs4_save_user(&uid, &gid); | 425 | status = nfs4_save_creds(&original_cred); |
426 | if (status < 0) { | ||
427 | printk("NFSD: Unable to change credentials to find recovery" | ||
428 | " directory: error %d\n", | ||
429 | status); | ||
430 | return; | ||
431 | } | ||
414 | 432 | ||
415 | status = kern_path(rec_dirname, LOOKUP_FOLLOW | LOOKUP_DIRECTORY, | 433 | status = kern_path(rec_dirname, LOOKUP_FOLLOW | LOOKUP_DIRECTORY, |
416 | &rec_dir); | 434 | &rec_dir); |
@@ -420,7 +438,7 @@ nfsd4_init_recdir(char *rec_dirname) | |||
420 | 438 | ||
421 | if (!status) | 439 | if (!status) |
422 | rec_dir_init = 1; | 440 | rec_dir_init = 1; |
423 | nfs4_reset_user(uid, gid); | 441 | nfs4_reset_creds(original_cred); |
424 | } | 442 | } |
425 | 443 | ||
426 | void | 444 | void |
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index 1a052ac2bde9..bf4cd46a5a11 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c | |||
@@ -719,8 +719,8 @@ nfsd4_setclientid(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, | |||
719 | status = nfserr_clid_inuse; | 719 | status = nfserr_clid_inuse; |
720 | if (!same_creds(&conf->cl_cred, &rqstp->rq_cred) | 720 | if (!same_creds(&conf->cl_cred, &rqstp->rq_cred) |
721 | || conf->cl_addr != sin->sin_addr.s_addr) { | 721 | || conf->cl_addr != sin->sin_addr.s_addr) { |
722 | dprintk("NFSD: setclientid: string in use by client" | 722 | dprintk("NFSD: setclientid: string in use by clientat %pI4\n", |
723 | "at %u.%u.%u.%u\n", NIPQUAD(conf->cl_addr)); | 723 | &conf->cl_addr); |
724 | goto out; | 724 | goto out; |
725 | } | 725 | } |
726 | } | 726 | } |
diff --git a/fs/nfsd/nfsctl.c b/fs/nfsd/nfsctl.c index e3f9783fdcf7..77d7b8c531a6 100644 --- a/fs/nfsd/nfsctl.c +++ b/fs/nfsd/nfsctl.c | |||
@@ -330,7 +330,7 @@ static ssize_t failover_unlock_ip(struct file *file, char *buf, size_t size) | |||
330 | return -EINVAL; | 330 | return -EINVAL; |
331 | 331 | ||
332 | /* get ipv4 address */ | 332 | /* get ipv4 address */ |
333 | if (sscanf(fo_path, NIPQUAD_FMT "%c", &b1, &b2, &b3, &b4, &c) != 4) | 333 | if (sscanf(fo_path, "%u.%u.%u.%u%c", &b1, &b2, &b3, &b4, &c) != 4) |
334 | return -EINVAL; | 334 | return -EINVAL; |
335 | if (b1 > 255 || b2 > 255 || b3 > 255 || b4 > 255) | 335 | if (b1 > 255 || b2 > 255 || b3 > 255 || b4 > 255) |
336 | return -EINVAL; | 336 | return -EINVAL; |
diff --git a/fs/nfsd/nfsfh.c b/fs/nfsd/nfsfh.c index cd25d91895a1..f0da7d9c3a92 100644 --- a/fs/nfsd/nfsfh.c +++ b/fs/nfsd/nfsfh.c | |||
@@ -186,9 +186,14 @@ static __be32 nfsd_set_fh_dentry(struct svc_rqst *rqstp, struct svc_fh *fhp) | |||
186 | * access control settings being in effect, we cannot | 186 | * access control settings being in effect, we cannot |
187 | * fix that case easily. | 187 | * fix that case easily. |
188 | */ | 188 | */ |
189 | current->cap_effective = | 189 | struct cred *new = prepare_creds(); |
190 | cap_raise_nfsd_set(current->cap_effective, | 190 | if (!new) |
191 | current->cap_permitted); | 191 | return nfserrno(-ENOMEM); |
192 | new->cap_effective = | ||
193 | cap_raise_nfsd_set(new->cap_effective, | ||
194 | new->cap_permitted); | ||
195 | put_cred(override_creds(new)); | ||
196 | put_cred(new); | ||
192 | } else { | 197 | } else { |
193 | error = nfsd_setuser_and_check_port(rqstp, exp); | 198 | error = nfsd_setuser_and_check_port(rqstp, exp); |
194 | if (error) | 199 | if (error) |
diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c index 4433c8f00163..d1c5f787b365 100644 --- a/fs/nfsd/vfs.c +++ b/fs/nfsd/vfs.c | |||
@@ -671,6 +671,7 @@ __be32 | |||
671 | nfsd_open(struct svc_rqst *rqstp, struct svc_fh *fhp, int type, | 671 | nfsd_open(struct svc_rqst *rqstp, struct svc_fh *fhp, int type, |
672 | int access, struct file **filp) | 672 | int access, struct file **filp) |
673 | { | 673 | { |
674 | const struct cred *cred = current_cred(); | ||
674 | struct dentry *dentry; | 675 | struct dentry *dentry; |
675 | struct inode *inode; | 676 | struct inode *inode; |
676 | int flags = O_RDONLY|O_LARGEFILE; | 677 | int flags = O_RDONLY|O_LARGEFILE; |
@@ -725,7 +726,7 @@ nfsd_open(struct svc_rqst *rqstp, struct svc_fh *fhp, int type, | |||
725 | DQUOT_INIT(inode); | 726 | DQUOT_INIT(inode); |
726 | } | 727 | } |
727 | *filp = dentry_open(dget(dentry), mntget(fhp->fh_export->ex_path.mnt), | 728 | *filp = dentry_open(dget(dentry), mntget(fhp->fh_export->ex_path.mnt), |
728 | flags); | 729 | flags, cred); |
729 | if (IS_ERR(*filp)) | 730 | if (IS_ERR(*filp)) |
730 | host_err = PTR_ERR(*filp); | 731 | host_err = PTR_ERR(*filp); |
731 | out_nfserr: | 732 | out_nfserr: |
@@ -1169,7 +1170,7 @@ nfsd_create_setattr(struct svc_rqst *rqstp, struct svc_fh *resfhp, | |||
1169 | * send along the gid on create when it tries to implement | 1170 | * send along the gid on create when it tries to implement |
1170 | * setgid directories via NFS: | 1171 | * setgid directories via NFS: |
1171 | */ | 1172 | */ |
1172 | if (current->fsuid != 0) | 1173 | if (current_fsuid() != 0) |
1173 | iap->ia_valid &= ~(ATTR_UID|ATTR_GID); | 1174 | iap->ia_valid &= ~(ATTR_UID|ATTR_GID); |
1174 | if (iap->ia_valid) | 1175 | if (iap->ia_valid) |
1175 | return nfsd_setattr(rqstp, resfhp, iap, 0, (time_t)0); | 1176 | return nfsd_setattr(rqstp, resfhp, iap, 0, (time_t)0); |
@@ -2001,7 +2002,7 @@ nfsd_permission(struct svc_rqst *rqstp, struct svc_export *exp, | |||
2001 | IS_APPEND(inode)? " append" : "", | 2002 | IS_APPEND(inode)? " append" : "", |
2002 | __mnt_is_readonly(exp->ex_path.mnt)? " ro" : ""); | 2003 | __mnt_is_readonly(exp->ex_path.mnt)? " ro" : ""); |
2003 | dprintk(" owner %d/%d user %d/%d\n", | 2004 | dprintk(" owner %d/%d user %d/%d\n", |
2004 | inode->i_uid, inode->i_gid, current->fsuid, current->fsgid); | 2005 | inode->i_uid, inode->i_gid, current_fsuid(), current_fsgid()); |
2005 | #endif | 2006 | #endif |
2006 | 2007 | ||
2007 | /* Normally we reject any write/sattr etc access on a read-only file | 2008 | /* 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, | |||
2044 | * with NFSv3. | 2045 | * with NFSv3. |
2045 | */ | 2046 | */ |
2046 | if ((acc & NFSD_MAY_OWNER_OVERRIDE) && | 2047 | if ((acc & NFSD_MAY_OWNER_OVERRIDE) && |
2047 | inode->i_uid == current->fsuid) | 2048 | inode->i_uid == current_fsuid()) |
2048 | return 0; | 2049 | return 0; |
2049 | 2050 | ||
2050 | /* This assumes NFSD_MAY_{READ,WRITE,EXEC} == MAY_{READ,WRITE,EXEC} */ | 2051 | /* This assumes NFSD_MAY_{READ,WRITE,EXEC} == MAY_{READ,WRITE,EXEC} */ |
diff --git a/fs/ocfs2/cluster/netdebug.c b/fs/ocfs2/cluster/netdebug.c index 52276c02f710..f8424874fa07 100644 --- a/fs/ocfs2/cluster/netdebug.c +++ b/fs/ocfs2/cluster/netdebug.c | |||
@@ -304,8 +304,8 @@ static int sc_seq_show(struct seq_file *seq, void *v) | |||
304 | * use of it here generates a warning with -Wbitwise */ | 304 | * use of it here generates a warning with -Wbitwise */ |
305 | seq_printf(seq, "%p:\n" | 305 | seq_printf(seq, "%p:\n" |
306 | " krefs: %d\n" | 306 | " krefs: %d\n" |
307 | " sock: %u.%u.%u.%u:%u -> " | 307 | " sock: %pI4:%u -> " |
308 | "%u.%u.%u.%u:%u\n" | 308 | "%pI4:%u\n" |
309 | " remote node: %s\n" | 309 | " remote node: %s\n" |
310 | " page off: %zu\n" | 310 | " page off: %zu\n" |
311 | " handshake ok: %u\n" | 311 | " handshake ok: %u\n" |
@@ -319,8 +319,8 @@ static int sc_seq_show(struct seq_file *seq, void *v) | |||
319 | " func type: %u\n", | 319 | " func type: %u\n", |
320 | sc, | 320 | sc, |
321 | atomic_read(&sc->sc_kref.refcount), | 321 | atomic_read(&sc->sc_kref.refcount), |
322 | NIPQUAD(saddr), inet ? ntohs(sport) : 0, | 322 | &saddr, inet ? ntohs(sport) : 0, |
323 | NIPQUAD(daddr), inet ? ntohs(dport) : 0, | 323 | &daddr, inet ? ntohs(dport) : 0, |
324 | sc->sc_node->nd_name, | 324 | sc->sc_node->nd_name, |
325 | sc->sc_page_off, | 325 | sc->sc_page_off, |
326 | sc->sc_handshake_ok, | 326 | sc->sc_handshake_ok, |
diff --git a/fs/ocfs2/cluster/nodemanager.c b/fs/ocfs2/cluster/nodemanager.c index 816a3f61330c..70e8fa9e2539 100644 --- a/fs/ocfs2/cluster/nodemanager.c +++ b/fs/ocfs2/cluster/nodemanager.c | |||
@@ -250,7 +250,7 @@ static ssize_t o2nm_node_ipv4_port_write(struct o2nm_node *node, | |||
250 | 250 | ||
251 | static ssize_t o2nm_node_ipv4_address_read(struct o2nm_node *node, char *page) | 251 | static ssize_t o2nm_node_ipv4_address_read(struct o2nm_node *node, char *page) |
252 | { | 252 | { |
253 | return sprintf(page, "%u.%u.%u.%u\n", NIPQUAD(node->nd_ipv4_address)); | 253 | return sprintf(page, "%pI4\n", &node->nd_ipv4_address); |
254 | } | 254 | } |
255 | 255 | ||
256 | static ssize_t o2nm_node_ipv4_address_write(struct o2nm_node *node, | 256 | static ssize_t o2nm_node_ipv4_address_write(struct o2nm_node *node, |
diff --git a/fs/ocfs2/cluster/tcp.c b/fs/ocfs2/cluster/tcp.c index 2bcf706d9dd3..9fbe849f6344 100644 --- a/fs/ocfs2/cluster/tcp.c +++ b/fs/ocfs2/cluster/tcp.c | |||
@@ -1597,8 +1597,8 @@ static void o2net_start_connect(struct work_struct *work) | |||
1597 | ret = sock->ops->bind(sock, (struct sockaddr *)&myaddr, | 1597 | ret = sock->ops->bind(sock, (struct sockaddr *)&myaddr, |
1598 | sizeof(myaddr)); | 1598 | sizeof(myaddr)); |
1599 | if (ret) { | 1599 | if (ret) { |
1600 | mlog(ML_ERROR, "bind failed with %d at address %u.%u.%u.%u\n", | 1600 | mlog(ML_ERROR, "bind failed with %d at address %pI4\n", |
1601 | ret, NIPQUAD(mynode->nd_ipv4_address)); | 1601 | ret, &mynode->nd_ipv4_address); |
1602 | goto out; | 1602 | goto out; |
1603 | } | 1603 | } |
1604 | 1604 | ||
@@ -1790,17 +1790,16 @@ static int o2net_accept_one(struct socket *sock) | |||
1790 | 1790 | ||
1791 | node = o2nm_get_node_by_ip(sin.sin_addr.s_addr); | 1791 | node = o2nm_get_node_by_ip(sin.sin_addr.s_addr); |
1792 | if (node == NULL) { | 1792 | if (node == NULL) { |
1793 | mlog(ML_NOTICE, "attempt to connect from unknown node at " | 1793 | mlog(ML_NOTICE, "attempt to connect from unknown node at %pI4:%d\n", |
1794 | "%u.%u.%u.%u:%d\n", NIPQUAD(sin.sin_addr.s_addr), | 1794 | &sin.sin_addr.s_addr, ntohs(sin.sin_port)); |
1795 | ntohs(sin.sin_port)); | ||
1796 | ret = -EINVAL; | 1795 | ret = -EINVAL; |
1797 | goto out; | 1796 | goto out; |
1798 | } | 1797 | } |
1799 | 1798 | ||
1800 | if (o2nm_this_node() > node->nd_num) { | 1799 | if (o2nm_this_node() > node->nd_num) { |
1801 | mlog(ML_NOTICE, "unexpected connect attempted from a lower " | 1800 | mlog(ML_NOTICE, "unexpected connect attempted from a lower " |
1802 | "numbered node '%s' at " "%u.%u.%u.%u:%d with num %u\n", | 1801 | "numbered node '%s' at " "%pI4:%d with num %u\n", |
1803 | node->nd_name, NIPQUAD(sin.sin_addr.s_addr), | 1802 | node->nd_name, &sin.sin_addr.s_addr, |
1804 | ntohs(sin.sin_port), node->nd_num); | 1803 | ntohs(sin.sin_port), node->nd_num); |
1805 | ret = -EINVAL; | 1804 | ret = -EINVAL; |
1806 | goto out; | 1805 | goto out; |
@@ -1810,8 +1809,8 @@ static int o2net_accept_one(struct socket *sock) | |||
1810 | * and tries to connect before we see their heartbeat */ | 1809 | * and tries to connect before we see their heartbeat */ |
1811 | if (!o2hb_check_node_heartbeating_from_callback(node->nd_num)) { | 1810 | if (!o2hb_check_node_heartbeating_from_callback(node->nd_num)) { |
1812 | mlog(ML_CONN, "attempt to connect from node '%s' at " | 1811 | mlog(ML_CONN, "attempt to connect from node '%s' at " |
1813 | "%u.%u.%u.%u:%d but it isn't heartbeating\n", | 1812 | "%pI4:%d but it isn't heartbeating\n", |
1814 | node->nd_name, NIPQUAD(sin.sin_addr.s_addr), | 1813 | node->nd_name, &sin.sin_addr.s_addr, |
1815 | ntohs(sin.sin_port)); | 1814 | ntohs(sin.sin_port)); |
1816 | ret = -EINVAL; | 1815 | ret = -EINVAL; |
1817 | goto out; | 1816 | goto out; |
@@ -1827,8 +1826,8 @@ static int o2net_accept_one(struct socket *sock) | |||
1827 | spin_unlock(&nn->nn_lock); | 1826 | spin_unlock(&nn->nn_lock); |
1828 | if (ret) { | 1827 | if (ret) { |
1829 | mlog(ML_NOTICE, "attempt to connect from node '%s' at " | 1828 | mlog(ML_NOTICE, "attempt to connect from node '%s' at " |
1830 | "%u.%u.%u.%u:%d but it already has an open connection\n", | 1829 | "%pI4:%d but it already has an open connection\n", |
1831 | node->nd_name, NIPQUAD(sin.sin_addr.s_addr), | 1830 | node->nd_name, &sin.sin_addr.s_addr, |
1832 | ntohs(sin.sin_port)); | 1831 | ntohs(sin.sin_port)); |
1833 | goto out; | 1832 | goto out; |
1834 | } | 1833 | } |
@@ -1924,15 +1923,15 @@ static int o2net_open_listening_sock(__be32 addr, __be16 port) | |||
1924 | sock->sk->sk_reuse = 1; | 1923 | sock->sk->sk_reuse = 1; |
1925 | ret = sock->ops->bind(sock, (struct sockaddr *)&sin, sizeof(sin)); | 1924 | ret = sock->ops->bind(sock, (struct sockaddr *)&sin, sizeof(sin)); |
1926 | if (ret < 0) { | 1925 | if (ret < 0) { |
1927 | mlog(ML_ERROR, "unable to bind socket at %u.%u.%u.%u:%u, " | 1926 | mlog(ML_ERROR, "unable to bind socket at %pI4:%u, " |
1928 | "ret=%d\n", NIPQUAD(addr), ntohs(port), ret); | 1927 | "ret=%d\n", &addr, ntohs(port), ret); |
1929 | goto out; | 1928 | goto out; |
1930 | } | 1929 | } |
1931 | 1930 | ||
1932 | ret = sock->ops->listen(sock, 64); | 1931 | ret = sock->ops->listen(sock, 64); |
1933 | if (ret < 0) { | 1932 | if (ret < 0) { |
1934 | mlog(ML_ERROR, "unable to listen on %u.%u.%u.%u:%u, ret=%d\n", | 1933 | mlog(ML_ERROR, "unable to listen on %pI4:%u, ret=%d\n", |
1935 | NIPQUAD(addr), ntohs(port), ret); | 1934 | &addr, ntohs(port), ret); |
1936 | } | 1935 | } |
1937 | 1936 | ||
1938 | out: | 1937 | out: |
diff --git a/fs/ocfs2/dlm/dlmfs.c b/fs/ocfs2/dlm/dlmfs.c index ba962d71b34d..6f7a77d54020 100644 --- a/fs/ocfs2/dlm/dlmfs.c +++ b/fs/ocfs2/dlm/dlmfs.c | |||
@@ -339,8 +339,8 @@ static struct inode *dlmfs_get_root_inode(struct super_block *sb) | |||
339 | ip = DLMFS_I(inode); | 339 | ip = DLMFS_I(inode); |
340 | 340 | ||
341 | inode->i_mode = mode; | 341 | inode->i_mode = mode; |
342 | inode->i_uid = current->fsuid; | 342 | inode->i_uid = current_fsuid(); |
343 | inode->i_gid = current->fsgid; | 343 | inode->i_gid = current_fsgid(); |
344 | inode->i_blocks = 0; | 344 | inode->i_blocks = 0; |
345 | inode->i_mapping->backing_dev_info = &dlmfs_backing_dev_info; | 345 | inode->i_mapping->backing_dev_info = &dlmfs_backing_dev_info; |
346 | inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME; | 346 | inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME; |
@@ -365,8 +365,8 @@ static struct inode *dlmfs_get_inode(struct inode *parent, | |||
365 | return NULL; | 365 | return NULL; |
366 | 366 | ||
367 | inode->i_mode = mode; | 367 | inode->i_mode = mode; |
368 | inode->i_uid = current->fsuid; | 368 | inode->i_uid = current_fsuid(); |
369 | inode->i_gid = current->fsgid; | 369 | inode->i_gid = current_fsgid(); |
370 | inode->i_blocks = 0; | 370 | inode->i_blocks = 0; |
371 | inode->i_mapping->backing_dev_info = &dlmfs_backing_dev_info; | 371 | inode->i_mapping->backing_dev_info = &dlmfs_backing_dev_info; |
372 | inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME; | 372 | inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME; |
diff --git a/fs/ocfs2/namei.c b/fs/ocfs2/namei.c index f4967e634ffd..2545e7402efe 100644 --- a/fs/ocfs2/namei.c +++ b/fs/ocfs2/namei.c | |||
@@ -421,13 +421,13 @@ static int ocfs2_mknod_locked(struct ocfs2_super *osb, | |||
421 | fe->i_blkno = cpu_to_le64(fe_blkno); | 421 | fe->i_blkno = cpu_to_le64(fe_blkno); |
422 | fe->i_suballoc_bit = cpu_to_le16(suballoc_bit); | 422 | fe->i_suballoc_bit = cpu_to_le16(suballoc_bit); |
423 | fe->i_suballoc_slot = cpu_to_le16(inode_ac->ac_alloc_slot); | 423 | fe->i_suballoc_slot = cpu_to_le16(inode_ac->ac_alloc_slot); |
424 | fe->i_uid = cpu_to_le32(current->fsuid); | 424 | fe->i_uid = cpu_to_le32(current_fsuid()); |
425 | if (dir->i_mode & S_ISGID) { | 425 | if (dir->i_mode & S_ISGID) { |
426 | fe->i_gid = cpu_to_le32(dir->i_gid); | 426 | fe->i_gid = cpu_to_le32(dir->i_gid); |
427 | if (S_ISDIR(mode)) | 427 | if (S_ISDIR(mode)) |
428 | mode |= S_ISGID; | 428 | mode |= S_ISGID; |
429 | } else | 429 | } else |
430 | fe->i_gid = cpu_to_le32(current->fsgid); | 430 | fe->i_gid = cpu_to_le32(current_fsgid()); |
431 | fe->i_mode = cpu_to_le16(mode); | 431 | fe->i_mode = cpu_to_le16(mode); |
432 | if (S_ISCHR(mode) || S_ISBLK(mode)) | 432 | if (S_ISCHR(mode) || S_ISBLK(mode)) |
433 | fe->id1.dev1.i_rdev = cpu_to_le64(huge_encode_dev(dev)); | 433 | fe->id1.dev1.i_rdev = cpu_to_le64(huge_encode_dev(dev)); |
diff --git a/fs/omfs/inode.c b/fs/omfs/inode.c index cbf047a847c5..6afe57c84f84 100644 --- a/fs/omfs/inode.c +++ b/fs/omfs/inode.c | |||
@@ -37,8 +37,8 @@ struct inode *omfs_new_inode(struct inode *dir, int mode) | |||
37 | 37 | ||
38 | inode->i_ino = new_block; | 38 | inode->i_ino = new_block; |
39 | inode->i_mode = mode; | 39 | inode->i_mode = mode; |
40 | inode->i_uid = current->fsuid; | 40 | inode->i_uid = current_fsuid(); |
41 | inode->i_gid = current->fsgid; | 41 | inode->i_gid = current_fsgid(); |
42 | inode->i_blocks = 0; | 42 | inode->i_blocks = 0; |
43 | inode->i_mapping->a_ops = &omfs_aops; | 43 | inode->i_mapping->a_ops = &omfs_aops; |
44 | 44 | ||
@@ -420,8 +420,8 @@ static int omfs_fill_super(struct super_block *sb, void *data, int silent) | |||
420 | 420 | ||
421 | sb->s_fs_info = sbi; | 421 | sb->s_fs_info = sbi; |
422 | 422 | ||
423 | sbi->s_uid = current->uid; | 423 | sbi->s_uid = current_uid(); |
424 | sbi->s_gid = current->gid; | 424 | sbi->s_gid = current_gid(); |
425 | sbi->s_dmask = sbi->s_fmask = current->fs->umask; | 425 | sbi->s_dmask = sbi->s_fmask = current->fs->umask; |
426 | 426 | ||
427 | if (!parse_options((char *) data, sbi)) | 427 | if (!parse_options((char *) data, sbi)) |
@@ -425,39 +425,33 @@ out: | |||
425 | */ | 425 | */ |
426 | asmlinkage long sys_faccessat(int dfd, const char __user *filename, int mode) | 426 | asmlinkage long sys_faccessat(int dfd, const char __user *filename, int mode) |
427 | { | 427 | { |
428 | const struct cred *old_cred; | ||
429 | struct cred *override_cred; | ||
428 | struct path path; | 430 | struct path path; |
429 | struct inode *inode; | 431 | struct inode *inode; |
430 | int old_fsuid, old_fsgid; | ||
431 | kernel_cap_t uninitialized_var(old_cap); /* !SECURE_NO_SETUID_FIXUP */ | ||
432 | int res; | 432 | int res; |
433 | 433 | ||
434 | if (mode & ~S_IRWXO) /* where's F_OK, X_OK, W_OK, R_OK? */ | 434 | if (mode & ~S_IRWXO) /* where's F_OK, X_OK, W_OK, R_OK? */ |
435 | return -EINVAL; | 435 | return -EINVAL; |
436 | 436 | ||
437 | old_fsuid = current->fsuid; | 437 | override_cred = prepare_creds(); |
438 | old_fsgid = current->fsgid; | 438 | if (!override_cred) |
439 | return -ENOMEM; | ||
439 | 440 | ||
440 | current->fsuid = current->uid; | 441 | override_cred->fsuid = override_cred->uid; |
441 | current->fsgid = current->gid; | 442 | override_cred->fsgid = override_cred->gid; |
442 | 443 | ||
443 | if (!issecure(SECURE_NO_SETUID_FIXUP)) { | 444 | if (!issecure(SECURE_NO_SETUID_FIXUP)) { |
444 | /* | 445 | /* Clear the capabilities if we switch to a non-root user */ |
445 | * Clear the capabilities if we switch to a non-root user | 446 | if (override_cred->uid) |
446 | */ | 447 | cap_clear(override_cred->cap_effective); |
447 | #ifndef CONFIG_SECURITY_FILE_CAPABILITIES | ||
448 | /* | ||
449 | * FIXME: There is a race here against sys_capset. The | ||
450 | * capabilities can change yet we will restore the old | ||
451 | * value below. We should hold task_capabilities_lock, | ||
452 | * but we cannot because user_path_at can sleep. | ||
453 | */ | ||
454 | #endif /* ndef CONFIG_SECURITY_FILE_CAPABILITIES */ | ||
455 | if (current->uid) | ||
456 | old_cap = cap_set_effective(__cap_empty_set); | ||
457 | else | 448 | else |
458 | old_cap = cap_set_effective(current->cap_permitted); | 449 | override_cred->cap_effective = |
450 | override_cred->cap_permitted; | ||
459 | } | 451 | } |
460 | 452 | ||
453 | old_cred = override_creds(override_cred); | ||
454 | |||
461 | res = user_path_at(dfd, filename, LOOKUP_FOLLOW, &path); | 455 | res = user_path_at(dfd, filename, LOOKUP_FOLLOW, &path); |
462 | if (res) | 456 | if (res) |
463 | goto out; | 457 | goto out; |
@@ -494,12 +488,8 @@ asmlinkage long sys_faccessat(int dfd, const char __user *filename, int mode) | |||
494 | out_path_release: | 488 | out_path_release: |
495 | path_put(&path); | 489 | path_put(&path); |
496 | out: | 490 | out: |
497 | current->fsuid = old_fsuid; | 491 | revert_creds(old_cred); |
498 | current->fsgid = old_fsgid; | 492 | put_cred(override_cred); |
499 | |||
500 | if (!issecure(SECURE_NO_SETUID_FIXUP)) | ||
501 | cap_set_effective(old_cap); | ||
502 | |||
503 | return res; | 493 | return res; |
504 | } | 494 | } |
505 | 495 | ||
@@ -792,7 +782,8 @@ static inline int __get_file_write_access(struct inode *inode, | |||
792 | 782 | ||
793 | static struct file *__dentry_open(struct dentry *dentry, struct vfsmount *mnt, | 783 | static struct file *__dentry_open(struct dentry *dentry, struct vfsmount *mnt, |
794 | int flags, struct file *f, | 784 | int flags, struct file *f, |
795 | int (*open)(struct inode *, struct file *)) | 785 | int (*open)(struct inode *, struct file *), |
786 | const struct cred *cred) | ||
796 | { | 787 | { |
797 | struct inode *inode; | 788 | struct inode *inode; |
798 | int error; | 789 | int error; |
@@ -816,7 +807,7 @@ static struct file *__dentry_open(struct dentry *dentry, struct vfsmount *mnt, | |||
816 | f->f_op = fops_get(inode->i_fop); | 807 | f->f_op = fops_get(inode->i_fop); |
817 | file_move(f, &inode->i_sb->s_files); | 808 | file_move(f, &inode->i_sb->s_files); |
818 | 809 | ||
819 | error = security_dentry_open(f); | 810 | error = security_dentry_open(f, cred); |
820 | if (error) | 811 | if (error) |
821 | goto cleanup_all; | 812 | goto cleanup_all; |
822 | 813 | ||
@@ -891,6 +882,8 @@ cleanup_file: | |||
891 | struct file *lookup_instantiate_filp(struct nameidata *nd, struct dentry *dentry, | 882 | struct file *lookup_instantiate_filp(struct nameidata *nd, struct dentry *dentry, |
892 | int (*open)(struct inode *, struct file *)) | 883 | int (*open)(struct inode *, struct file *)) |
893 | { | 884 | { |
885 | const struct cred *cred = current_cred(); | ||
886 | |||
894 | if (IS_ERR(nd->intent.open.file)) | 887 | if (IS_ERR(nd->intent.open.file)) |
895 | goto out; | 888 | goto out; |
896 | if (IS_ERR(dentry)) | 889 | if (IS_ERR(dentry)) |
@@ -898,7 +891,7 @@ struct file *lookup_instantiate_filp(struct nameidata *nd, struct dentry *dentry | |||
898 | nd->intent.open.file = __dentry_open(dget(dentry), mntget(nd->path.mnt), | 891 | nd->intent.open.file = __dentry_open(dget(dentry), mntget(nd->path.mnt), |
899 | nd->intent.open.flags - 1, | 892 | nd->intent.open.flags - 1, |
900 | nd->intent.open.file, | 893 | nd->intent.open.file, |
901 | open); | 894 | open, cred); |
902 | out: | 895 | out: |
903 | return nd->intent.open.file; | 896 | return nd->intent.open.file; |
904 | out_err: | 897 | out_err: |
@@ -917,6 +910,7 @@ EXPORT_SYMBOL_GPL(lookup_instantiate_filp); | |||
917 | */ | 910 | */ |
918 | struct file *nameidata_to_filp(struct nameidata *nd, int flags) | 911 | struct file *nameidata_to_filp(struct nameidata *nd, int flags) |
919 | { | 912 | { |
913 | const struct cred *cred = current_cred(); | ||
920 | struct file *filp; | 914 | struct file *filp; |
921 | 915 | ||
922 | /* Pick up the filp from the open intent */ | 916 | /* Pick up the filp from the open intent */ |
@@ -924,7 +918,7 @@ struct file *nameidata_to_filp(struct nameidata *nd, int flags) | |||
924 | /* Has the filesystem initialised the file for us? */ | 918 | /* Has the filesystem initialised the file for us? */ |
925 | if (filp->f_path.dentry == NULL) | 919 | if (filp->f_path.dentry == NULL) |
926 | filp = __dentry_open(nd->path.dentry, nd->path.mnt, flags, filp, | 920 | filp = __dentry_open(nd->path.dentry, nd->path.mnt, flags, filp, |
927 | NULL); | 921 | NULL, cred); |
928 | else | 922 | else |
929 | path_put(&nd->path); | 923 | path_put(&nd->path); |
930 | return filp; | 924 | return filp; |
@@ -934,7 +928,8 @@ struct file *nameidata_to_filp(struct nameidata *nd, int flags) | |||
934 | * dentry_open() will have done dput(dentry) and mntput(mnt) if it returns an | 928 | * dentry_open() will have done dput(dentry) and mntput(mnt) if it returns an |
935 | * error. | 929 | * error. |
936 | */ | 930 | */ |
937 | struct file *dentry_open(struct dentry *dentry, struct vfsmount *mnt, int flags) | 931 | struct file *dentry_open(struct dentry *dentry, struct vfsmount *mnt, int flags, |
932 | const struct cred *cred) | ||
938 | { | 933 | { |
939 | int error; | 934 | int error; |
940 | struct file *f; | 935 | struct file *f; |
@@ -959,7 +954,7 @@ struct file *dentry_open(struct dentry *dentry, struct vfsmount *mnt, int flags) | |||
959 | return ERR_PTR(error); | 954 | return ERR_PTR(error); |
960 | } | 955 | } |
961 | 956 | ||
962 | return __dentry_open(dentry, mnt, flags, f, NULL); | 957 | return __dentry_open(dentry, mnt, flags, f, NULL, cred); |
963 | } | 958 | } |
964 | EXPORT_SYMBOL(dentry_open); | 959 | EXPORT_SYMBOL(dentry_open); |
965 | 960 | ||
@@ -899,8 +899,8 @@ static struct inode * get_pipe_inode(void) | |||
899 | */ | 899 | */ |
900 | inode->i_state = I_DIRTY; | 900 | inode->i_state = I_DIRTY; |
901 | inode->i_mode = S_IFIFO | S_IRUSR | S_IWUSR; | 901 | inode->i_mode = S_IFIFO | S_IRUSR | S_IWUSR; |
902 | inode->i_uid = current->fsuid; | 902 | inode->i_uid = current_fsuid(); |
903 | inode->i_gid = current->fsgid; | 903 | inode->i_gid = current_fsgid(); |
904 | inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME; | 904 | inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME; |
905 | 905 | ||
906 | return inode; | 906 | return inode; |
diff --git a/fs/posix_acl.c b/fs/posix_acl.c index aec931e09973..39df95a0ec25 100644 --- a/fs/posix_acl.c +++ b/fs/posix_acl.c | |||
@@ -217,11 +217,11 @@ posix_acl_permission(struct inode *inode, const struct posix_acl *acl, int want) | |||
217 | switch(pa->e_tag) { | 217 | switch(pa->e_tag) { |
218 | case ACL_USER_OBJ: | 218 | case ACL_USER_OBJ: |
219 | /* (May have been checked already) */ | 219 | /* (May have been checked already) */ |
220 | if (inode->i_uid == current->fsuid) | 220 | if (inode->i_uid == current_fsuid()) |
221 | goto check_perm; | 221 | goto check_perm; |
222 | break; | 222 | break; |
223 | case ACL_USER: | 223 | case ACL_USER: |
224 | if (pa->e_id == current->fsuid) | 224 | if (pa->e_id == current_fsuid()) |
225 | goto mask; | 225 | goto mask; |
226 | break; | 226 | break; |
227 | case ACL_GROUP_OBJ: | 227 | case ACL_GROUP_OBJ: |
diff --git a/fs/proc/array.c b/fs/proc/array.c index 6af7fba7abb1..7e4877d9dcb5 100644 --- a/fs/proc/array.c +++ b/fs/proc/array.c | |||
@@ -159,6 +159,7 @@ static inline void task_state(struct seq_file *m, struct pid_namespace *ns, | |||
159 | struct group_info *group_info; | 159 | struct group_info *group_info; |
160 | int g; | 160 | int g; |
161 | struct fdtable *fdt = NULL; | 161 | struct fdtable *fdt = NULL; |
162 | const struct cred *cred; | ||
162 | pid_t ppid, tpid; | 163 | pid_t ppid, tpid; |
163 | 164 | ||
164 | rcu_read_lock(); | 165 | rcu_read_lock(); |
@@ -170,6 +171,7 @@ static inline void task_state(struct seq_file *m, struct pid_namespace *ns, | |||
170 | if (tracer) | 171 | if (tracer) |
171 | tpid = task_pid_nr_ns(tracer, ns); | 172 | tpid = task_pid_nr_ns(tracer, ns); |
172 | } | 173 | } |
174 | cred = get_cred((struct cred *) __task_cred(p)); | ||
173 | seq_printf(m, | 175 | seq_printf(m, |
174 | "State:\t%s\n" | 176 | "State:\t%s\n" |
175 | "Tgid:\t%d\n" | 177 | "Tgid:\t%d\n" |
@@ -182,8 +184,8 @@ static inline void task_state(struct seq_file *m, struct pid_namespace *ns, | |||
182 | task_tgid_nr_ns(p, ns), | 184 | task_tgid_nr_ns(p, ns), |
183 | pid_nr_ns(pid, ns), | 185 | pid_nr_ns(pid, ns), |
184 | ppid, tpid, | 186 | ppid, tpid, |
185 | p->uid, p->euid, p->suid, p->fsuid, | 187 | cred->uid, cred->euid, cred->suid, cred->fsuid, |
186 | p->gid, p->egid, p->sgid, p->fsgid); | 188 | cred->gid, cred->egid, cred->sgid, cred->fsgid); |
187 | 189 | ||
188 | task_lock(p); | 190 | task_lock(p); |
189 | if (p->files) | 191 | if (p->files) |
@@ -194,13 +196,12 @@ static inline void task_state(struct seq_file *m, struct pid_namespace *ns, | |||
194 | fdt ? fdt->max_fds : 0); | 196 | fdt ? fdt->max_fds : 0); |
195 | rcu_read_unlock(); | 197 | rcu_read_unlock(); |
196 | 198 | ||
197 | group_info = p->group_info; | 199 | group_info = cred->group_info; |
198 | get_group_info(group_info); | ||
199 | task_unlock(p); | 200 | task_unlock(p); |
200 | 201 | ||
201 | for (g = 0; g < min(group_info->ngroups, NGROUPS_SMALL); g++) | 202 | for (g = 0; g < min(group_info->ngroups, NGROUPS_SMALL); g++) |
202 | seq_printf(m, "%d ", GROUP_AT(group_info, g)); | 203 | seq_printf(m, "%d ", GROUP_AT(group_info, g)); |
203 | put_group_info(group_info); | 204 | put_cred(cred); |
204 | 205 | ||
205 | seq_printf(m, "\n"); | 206 | seq_printf(m, "\n"); |
206 | } | 207 | } |
@@ -262,7 +263,7 @@ static inline void task_sig(struct seq_file *m, struct task_struct *p) | |||
262 | blocked = p->blocked; | 263 | blocked = p->blocked; |
263 | collect_sigign_sigcatch(p, &ignored, &caught); | 264 | collect_sigign_sigcatch(p, &ignored, &caught); |
264 | num_threads = atomic_read(&p->signal->count); | 265 | num_threads = atomic_read(&p->signal->count); |
265 | qsize = atomic_read(&p->user->sigpending); | 266 | qsize = atomic_read(&__task_cred(p)->user->sigpending); |
266 | qlim = p->signal->rlim[RLIMIT_SIGPENDING].rlim_cur; | 267 | qlim = p->signal->rlim[RLIMIT_SIGPENDING].rlim_cur; |
267 | unlock_task_sighand(p, &flags); | 268 | unlock_task_sighand(p, &flags); |
268 | } | 269 | } |
@@ -293,10 +294,21 @@ static void render_cap_t(struct seq_file *m, const char *header, | |||
293 | 294 | ||
294 | static inline void task_cap(struct seq_file *m, struct task_struct *p) | 295 | static inline void task_cap(struct seq_file *m, struct task_struct *p) |
295 | { | 296 | { |
296 | render_cap_t(m, "CapInh:\t", &p->cap_inheritable); | 297 | const struct cred *cred; |
297 | render_cap_t(m, "CapPrm:\t", &p->cap_permitted); | 298 | kernel_cap_t cap_inheritable, cap_permitted, cap_effective, cap_bset; |
298 | render_cap_t(m, "CapEff:\t", &p->cap_effective); | 299 | |
299 | render_cap_t(m, "CapBnd:\t", &p->cap_bset); | 300 | rcu_read_lock(); |
301 | cred = __task_cred(p); | ||
302 | cap_inheritable = cred->cap_inheritable; | ||
303 | cap_permitted = cred->cap_permitted; | ||
304 | cap_effective = cred->cap_effective; | ||
305 | cap_bset = cred->cap_bset; | ||
306 | rcu_read_unlock(); | ||
307 | |||
308 | render_cap_t(m, "CapInh:\t", &cap_inheritable); | ||
309 | render_cap_t(m, "CapPrm:\t", &cap_permitted); | ||
310 | render_cap_t(m, "CapEff:\t", &cap_effective); | ||
311 | render_cap_t(m, "CapBnd:\t", &cap_bset); | ||
300 | } | 312 | } |
301 | 313 | ||
302 | static inline void task_context_switch_counts(struct seq_file *m, | 314 | static inline void task_context_switch_counts(struct seq_file *m, |
diff --git a/fs/proc/base.c b/fs/proc/base.c index d4677603c889..cad92c1ac2b3 100644 --- a/fs/proc/base.c +++ b/fs/proc/base.c | |||
@@ -347,8 +347,8 @@ static int proc_pid_wchan(struct task_struct *task, char *buffer) | |||
347 | static int proc_pid_schedstat(struct task_struct *task, char *buffer) | 347 | static int proc_pid_schedstat(struct task_struct *task, char *buffer) |
348 | { | 348 | { |
349 | return sprintf(buffer, "%llu %llu %lu\n", | 349 | return sprintf(buffer, "%llu %llu %lu\n", |
350 | task->sched_info.cpu_time, | 350 | (unsigned long long)task->se.sum_exec_runtime, |
351 | task->sched_info.run_delay, | 351 | (unsigned long long)task->sched_info.run_delay, |
352 | task->sched_info.pcount); | 352 | task->sched_info.pcount); |
353 | } | 353 | } |
354 | #endif | 354 | #endif |
@@ -1406,6 +1406,7 @@ static struct inode *proc_pid_make_inode(struct super_block * sb, struct task_st | |||
1406 | { | 1406 | { |
1407 | struct inode * inode; | 1407 | struct inode * inode; |
1408 | struct proc_inode *ei; | 1408 | struct proc_inode *ei; |
1409 | const struct cred *cred; | ||
1409 | 1410 | ||
1410 | /* We need a new inode */ | 1411 | /* We need a new inode */ |
1411 | 1412 | ||
@@ -1428,8 +1429,11 @@ static struct inode *proc_pid_make_inode(struct super_block * sb, struct task_st | |||
1428 | inode->i_uid = 0; | 1429 | inode->i_uid = 0; |
1429 | inode->i_gid = 0; | 1430 | inode->i_gid = 0; |
1430 | if (task_dumpable(task)) { | 1431 | if (task_dumpable(task)) { |
1431 | inode->i_uid = task->euid; | 1432 | rcu_read_lock(); |
1432 | inode->i_gid = task->egid; | 1433 | cred = __task_cred(task); |
1434 | inode->i_uid = cred->euid; | ||
1435 | inode->i_gid = cred->egid; | ||
1436 | rcu_read_unlock(); | ||
1433 | } | 1437 | } |
1434 | security_task_to_inode(task, inode); | 1438 | security_task_to_inode(task, inode); |
1435 | 1439 | ||
@@ -1445,6 +1449,8 @@ static int pid_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat | |||
1445 | { | 1449 | { |
1446 | struct inode *inode = dentry->d_inode; | 1450 | struct inode *inode = dentry->d_inode; |
1447 | struct task_struct *task; | 1451 | struct task_struct *task; |
1452 | const struct cred *cred; | ||
1453 | |||
1448 | generic_fillattr(inode, stat); | 1454 | generic_fillattr(inode, stat); |
1449 | 1455 | ||
1450 | rcu_read_lock(); | 1456 | rcu_read_lock(); |
@@ -1454,8 +1460,9 @@ static int pid_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat | |||
1454 | if (task) { | 1460 | if (task) { |
1455 | if ((inode->i_mode == (S_IFDIR|S_IRUGO|S_IXUGO)) || | 1461 | if ((inode->i_mode == (S_IFDIR|S_IRUGO|S_IXUGO)) || |
1456 | task_dumpable(task)) { | 1462 | task_dumpable(task)) { |
1457 | stat->uid = task->euid; | 1463 | cred = __task_cred(task); |
1458 | stat->gid = task->egid; | 1464 | stat->uid = cred->euid; |
1465 | stat->gid = cred->egid; | ||
1459 | } | 1466 | } |
1460 | } | 1467 | } |
1461 | rcu_read_unlock(); | 1468 | rcu_read_unlock(); |
@@ -1483,11 +1490,16 @@ static int pid_revalidate(struct dentry *dentry, struct nameidata *nd) | |||
1483 | { | 1490 | { |
1484 | struct inode *inode = dentry->d_inode; | 1491 | struct inode *inode = dentry->d_inode; |
1485 | struct task_struct *task = get_proc_task(inode); | 1492 | struct task_struct *task = get_proc_task(inode); |
1493 | const struct cred *cred; | ||
1494 | |||
1486 | if (task) { | 1495 | if (task) { |
1487 | if ((inode->i_mode == (S_IFDIR|S_IRUGO|S_IXUGO)) || | 1496 | if ((inode->i_mode == (S_IFDIR|S_IRUGO|S_IXUGO)) || |
1488 | task_dumpable(task)) { | 1497 | task_dumpable(task)) { |
1489 | inode->i_uid = task->euid; | 1498 | rcu_read_lock(); |
1490 | inode->i_gid = task->egid; | 1499 | cred = __task_cred(task); |
1500 | inode->i_uid = cred->euid; | ||
1501 | inode->i_gid = cred->egid; | ||
1502 | rcu_read_unlock(); | ||
1491 | } else { | 1503 | } else { |
1492 | inode->i_uid = 0; | 1504 | inode->i_uid = 0; |
1493 | inode->i_gid = 0; | 1505 | inode->i_gid = 0; |
@@ -1649,6 +1661,7 @@ static int tid_fd_revalidate(struct dentry *dentry, struct nameidata *nd) | |||
1649 | struct task_struct *task = get_proc_task(inode); | 1661 | struct task_struct *task = get_proc_task(inode); |
1650 | int fd = proc_fd(inode); | 1662 | int fd = proc_fd(inode); |
1651 | struct files_struct *files; | 1663 | struct files_struct *files; |
1664 | const struct cred *cred; | ||
1652 | 1665 | ||
1653 | if (task) { | 1666 | if (task) { |
1654 | files = get_files_struct(task); | 1667 | files = get_files_struct(task); |
@@ -1658,8 +1671,11 @@ static int tid_fd_revalidate(struct dentry *dentry, struct nameidata *nd) | |||
1658 | rcu_read_unlock(); | 1671 | rcu_read_unlock(); |
1659 | put_files_struct(files); | 1672 | put_files_struct(files); |
1660 | if (task_dumpable(task)) { | 1673 | if (task_dumpable(task)) { |
1661 | inode->i_uid = task->euid; | 1674 | rcu_read_lock(); |
1662 | inode->i_gid = task->egid; | 1675 | cred = __task_cred(task); |
1676 | inode->i_uid = cred->euid; | ||
1677 | inode->i_gid = cred->egid; | ||
1678 | rcu_read_unlock(); | ||
1663 | } else { | 1679 | } else { |
1664 | inode->i_uid = 0; | 1680 | inode->i_uid = 0; |
1665 | inode->i_gid = 0; | 1681 | inode->i_gid = 0; |
diff --git a/fs/proc/proc_devtree.c b/fs/proc/proc_devtree.c index d777789b7a89..de2bba5a3440 100644 --- a/fs/proc/proc_devtree.c +++ b/fs/proc/proc_devtree.c | |||
@@ -218,8 +218,7 @@ void proc_device_tree_add_node(struct device_node *np, | |||
218 | void __init proc_device_tree_init(void) | 218 | void __init proc_device_tree_init(void) |
219 | { | 219 | { |
220 | struct device_node *root; | 220 | struct device_node *root; |
221 | if ( !have_of ) | 221 | |
222 | return; | ||
223 | proc_device_tree = proc_mkdir("device-tree", NULL); | 222 | proc_device_tree = proc_mkdir("device-tree", NULL); |
224 | if (proc_device_tree == 0) | 223 | if (proc_device_tree == 0) |
225 | return; | 224 | return; |
diff --git a/fs/quota.c b/fs/quota.c index 7f4386ebc23a..b7fe44e01618 100644 --- a/fs/quota.c +++ b/fs/quota.c | |||
@@ -79,7 +79,7 @@ static int generic_quotactl_valid(struct super_block *sb, int type, int cmd, qid | |||
79 | 79 | ||
80 | /* Check privileges */ | 80 | /* Check privileges */ |
81 | if (cmd == Q_GETQUOTA) { | 81 | if (cmd == Q_GETQUOTA) { |
82 | if (((type == USRQUOTA && current->euid != id) || | 82 | if (((type == USRQUOTA && current_euid() != id) || |
83 | (type == GRPQUOTA && !in_egroup_p(id))) && | 83 | (type == GRPQUOTA && !in_egroup_p(id))) && |
84 | !capable(CAP_SYS_ADMIN)) | 84 | !capable(CAP_SYS_ADMIN)) |
85 | return -EPERM; | 85 | return -EPERM; |
@@ -130,7 +130,7 @@ static int xqm_quotactl_valid(struct super_block *sb, int type, int cmd, qid_t i | |||
130 | 130 | ||
131 | /* Check privileges */ | 131 | /* Check privileges */ |
132 | if (cmd == Q_XGETQUOTA) { | 132 | if (cmd == Q_XGETQUOTA) { |
133 | if (((type == XQM_USRQUOTA && current->euid != id) || | 133 | if (((type == XQM_USRQUOTA && current_euid() != id) || |
134 | (type == XQM_GRPQUOTA && !in_egroup_p(id))) && | 134 | (type == XQM_GRPQUOTA && !in_egroup_p(id))) && |
135 | !capable(CAP_SYS_ADMIN)) | 135 | !capable(CAP_SYS_ADMIN)) |
136 | return -EPERM; | 136 | return -EPERM; |
diff --git a/fs/ramfs/inode.c b/fs/ramfs/inode.c index f031d1c925f0..a83a3518ae33 100644 --- a/fs/ramfs/inode.c +++ b/fs/ramfs/inode.c | |||
@@ -55,8 +55,8 @@ struct inode *ramfs_get_inode(struct super_block *sb, int mode, dev_t dev) | |||
55 | 55 | ||
56 | if (inode) { | 56 | if (inode) { |
57 | inode->i_mode = mode; | 57 | inode->i_mode = mode; |
58 | inode->i_uid = current->fsuid; | 58 | inode->i_uid = current_fsuid(); |
59 | inode->i_gid = current->fsgid; | 59 | inode->i_gid = current_fsgid(); |
60 | inode->i_blocks = 0; | 60 | inode->i_blocks = 0; |
61 | inode->i_mapping->a_ops = &ramfs_aops; | 61 | inode->i_mapping->a_ops = &ramfs_aops; |
62 | inode->i_mapping->backing_dev_info = &ramfs_backing_dev_info; | 62 | inode->i_mapping->backing_dev_info = &ramfs_backing_dev_info; |
diff --git a/fs/reiserfs/namei.c b/fs/reiserfs/namei.c index f89ebb943f3f..4f322e5ed840 100644 --- a/fs/reiserfs/namei.c +++ b/fs/reiserfs/namei.c | |||
@@ -573,7 +573,7 @@ static int new_inode_init(struct inode *inode, struct inode *dir, int mode) | |||
573 | /* the quota init calls have to know who to charge the quota to, so | 573 | /* the quota init calls have to know who to charge the quota to, so |
574 | ** we have to set uid and gid here | 574 | ** we have to set uid and gid here |
575 | */ | 575 | */ |
576 | inode->i_uid = current->fsuid; | 576 | inode->i_uid = current_fsuid(); |
577 | inode->i_mode = mode; | 577 | inode->i_mode = mode; |
578 | /* Make inode invalid - just in case we are going to drop it before | 578 | /* Make inode invalid - just in case we are going to drop it before |
579 | * the initialization happens */ | 579 | * the initialization happens */ |
@@ -584,7 +584,7 @@ static int new_inode_init(struct inode *inode, struct inode *dir, int mode) | |||
584 | if (S_ISDIR(mode)) | 584 | if (S_ISDIR(mode)) |
585 | inode->i_mode |= S_ISGID; | 585 | inode->i_mode |= S_ISGID; |
586 | } else { | 586 | } else { |
587 | inode->i_gid = current->fsgid; | 587 | inode->i_gid = current_fsgid(); |
588 | } | 588 | } |
589 | DQUOT_INIT(inode); | 589 | DQUOT_INIT(inode); |
590 | return 0; | 590 | return 0; |
diff --git a/fs/seq_file.c b/fs/seq_file.c index eba2eabcd2b8..16c211558c22 100644 --- a/fs/seq_file.c +++ b/fs/seq_file.c | |||
@@ -357,7 +357,18 @@ int seq_printf(struct seq_file *m, const char *f, ...) | |||
357 | } | 357 | } |
358 | EXPORT_SYMBOL(seq_printf); | 358 | EXPORT_SYMBOL(seq_printf); |
359 | 359 | ||
360 | static char *mangle_path(char *s, char *p, char *esc) | 360 | /** |
361 | * mangle_path - mangle and copy path to buffer beginning | ||
362 | * @s: buffer start | ||
363 | * @p: beginning of path in above buffer | ||
364 | * @esc: set of characters that need escaping | ||
365 | * | ||
366 | * Copy the path from @p to @s, replacing each occurrence of character from | ||
367 | * @esc with usual octal escape. | ||
368 | * Returns pointer past last written character in @s, or NULL in case of | ||
369 | * failure. | ||
370 | */ | ||
371 | char *mangle_path(char *s, char *p, char *esc) | ||
361 | { | 372 | { |
362 | while (s <= p) { | 373 | while (s <= p) { |
363 | char c = *p++; | 374 | char c = *p++; |
@@ -376,6 +387,7 @@ static char *mangle_path(char *s, char *p, char *esc) | |||
376 | } | 387 | } |
377 | return NULL; | 388 | return NULL; |
378 | } | 389 | } |
390 | EXPORT_SYMBOL(mangle_path); | ||
379 | 391 | ||
380 | /* | 392 | /* |
381 | * return the absolute path of 'dentry' residing in mount 'mnt'. | 393 | * return the absolute path of 'dentry' residing in mount 'mnt'. |
diff --git a/fs/smbfs/dir.c b/fs/smbfs/dir.c index 48da4fa6b7d4..e7ddd0328ddc 100644 --- a/fs/smbfs/dir.c +++ b/fs/smbfs/dir.c | |||
@@ -667,8 +667,7 @@ smb_make_node(struct inode *dir, struct dentry *dentry, int mode, dev_t dev) | |||
667 | 667 | ||
668 | attr.ia_valid = ATTR_MODE | ATTR_UID | ATTR_GID; | 668 | attr.ia_valid = ATTR_MODE | ATTR_UID | ATTR_GID; |
669 | attr.ia_mode = mode; | 669 | attr.ia_mode = mode; |
670 | attr.ia_uid = current->euid; | 670 | current_euid_egid(&attr.ia_uid, &attr.ia_gid); |
671 | attr.ia_gid = current->egid; | ||
672 | 671 | ||
673 | if (!new_valid_dev(dev)) | 672 | if (!new_valid_dev(dev)) |
674 | return -EINVAL; | 673 | return -EINVAL; |
diff --git a/fs/smbfs/inode.c b/fs/smbfs/inode.c index 3528f40ffb0f..fc27fbfc5397 100644 --- a/fs/smbfs/inode.c +++ b/fs/smbfs/inode.c | |||
@@ -586,7 +586,7 @@ static int smb_fill_super(struct super_block *sb, void *raw_data, int silent) | |||
586 | if (parse_options(mnt, raw_data)) | 586 | if (parse_options(mnt, raw_data)) |
587 | goto out_bad_option; | 587 | goto out_bad_option; |
588 | } | 588 | } |
589 | mnt->mounted_uid = current->uid; | 589 | mnt->mounted_uid = current_uid(); |
590 | smb_setcodepage(server, &mnt->codepage); | 590 | smb_setcodepage(server, &mnt->codepage); |
591 | 591 | ||
592 | /* | 592 | /* |
diff --git a/fs/smbfs/proc.c b/fs/smbfs/proc.c index ee536e8a649a..9468168b9af5 100644 --- a/fs/smbfs/proc.c +++ b/fs/smbfs/proc.c | |||
@@ -864,7 +864,7 @@ smb_newconn(struct smb_sb_info *server, struct smb_conn_opt *opt) | |||
864 | goto out; | 864 | goto out; |
865 | 865 | ||
866 | error = -EACCES; | 866 | error = -EACCES; |
867 | if (current->uid != server->mnt->mounted_uid && | 867 | if (current_uid() != server->mnt->mounted_uid && |
868 | !capable(CAP_SYS_ADMIN)) | 868 | !capable(CAP_SYS_ADMIN)) |
869 | goto out; | 869 | goto out; |
870 | 870 | ||
diff --git a/fs/super.c b/fs/super.c index 400a7608f15e..ddba069d7a99 100644 --- a/fs/super.c +++ b/fs/super.c | |||
@@ -914,7 +914,7 @@ vfs_kern_mount(struct file_system_type *type, int flags, const char *name, void | |||
914 | goto out_free_secdata; | 914 | goto out_free_secdata; |
915 | BUG_ON(!mnt->mnt_sb); | 915 | BUG_ON(!mnt->mnt_sb); |
916 | 916 | ||
917 | error = security_sb_kern_mount(mnt->mnt_sb, secdata); | 917 | error = security_sb_kern_mount(mnt->mnt_sb, flags, secdata); |
918 | if (error) | 918 | if (error) |
919 | goto out_sb; | 919 | goto out_sb; |
920 | 920 | ||
diff --git a/fs/sysv/ialloc.c b/fs/sysv/ialloc.c index 115ab0d6f4bc..241e9765cfad 100644 --- a/fs/sysv/ialloc.c +++ b/fs/sysv/ialloc.c | |||
@@ -165,9 +165,9 @@ struct inode * sysv_new_inode(const struct inode * dir, mode_t mode) | |||
165 | if (S_ISDIR(mode)) | 165 | if (S_ISDIR(mode)) |
166 | mode |= S_ISGID; | 166 | mode |= S_ISGID; |
167 | } else | 167 | } else |
168 | inode->i_gid = current->fsgid; | 168 | inode->i_gid = current_fsgid(); |
169 | 169 | ||
170 | inode->i_uid = current->fsuid; | 170 | inode->i_uid = current_fsuid(); |
171 | inode->i_ino = fs16_to_cpu(sbi, ino); | 171 | inode->i_ino = fs16_to_cpu(sbi, ino); |
172 | inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME_SEC; | 172 | inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME_SEC; |
173 | inode->i_blocks = 0; | 173 | inode->i_blocks = 0; |
diff --git a/fs/ubifs/budget.c b/fs/ubifs/budget.c index 1a4973e10664..4a18f084cc42 100644 --- a/fs/ubifs/budget.c +++ b/fs/ubifs/budget.c | |||
@@ -363,7 +363,7 @@ long long ubifs_calc_available(const struct ubifs_info *c, int min_idx_lebs) | |||
363 | */ | 363 | */ |
364 | static int can_use_rp(struct ubifs_info *c) | 364 | static int can_use_rp(struct ubifs_info *c) |
365 | { | 365 | { |
366 | if (current->fsuid == c->rp_uid || capable(CAP_SYS_RESOURCE) || | 366 | if (current_fsuid() == c->rp_uid || capable(CAP_SYS_RESOURCE) || |
367 | (c->rp_gid != 0 && in_group_p(c->rp_gid))) | 367 | (c->rp_gid != 0 && in_group_p(c->rp_gid))) |
368 | return 1; | 368 | return 1; |
369 | return 0; | 369 | return 0; |
diff --git a/fs/ubifs/dir.c b/fs/ubifs/dir.c index 0422c98e1793..f448ab1f9c38 100644 --- a/fs/ubifs/dir.c +++ b/fs/ubifs/dir.c | |||
@@ -104,13 +104,13 @@ struct inode *ubifs_new_inode(struct ubifs_info *c, const struct inode *dir, | |||
104 | */ | 104 | */ |
105 | inode->i_flags |= (S_NOCMTIME); | 105 | inode->i_flags |= (S_NOCMTIME); |
106 | 106 | ||
107 | inode->i_uid = current->fsuid; | 107 | inode->i_uid = current_fsuid(); |
108 | if (dir->i_mode & S_ISGID) { | 108 | if (dir->i_mode & S_ISGID) { |
109 | inode->i_gid = dir->i_gid; | 109 | inode->i_gid = dir->i_gid; |
110 | if (S_ISDIR(mode)) | 110 | if (S_ISDIR(mode)) |
111 | mode |= S_ISGID; | 111 | mode |= S_ISGID; |
112 | } else | 112 | } else |
113 | inode->i_gid = current->fsgid; | 113 | inode->i_gid = current_fsgid(); |
114 | inode->i_mode = mode; | 114 | inode->i_mode = mode; |
115 | inode->i_mtime = inode->i_atime = inode->i_ctime = | 115 | inode->i_mtime = inode->i_atime = inode->i_ctime = |
116 | ubifs_current_time(inode); | 116 | ubifs_current_time(inode); |
diff --git a/fs/udf/ialloc.c b/fs/udf/ialloc.c index a4f2b3ce45b0..31fc84297ddb 100644 --- a/fs/udf/ialloc.c +++ b/fs/udf/ialloc.c | |||
@@ -126,13 +126,13 @@ struct inode *udf_new_inode(struct inode *dir, int mode, int *err) | |||
126 | } | 126 | } |
127 | mutex_unlock(&sbi->s_alloc_mutex); | 127 | mutex_unlock(&sbi->s_alloc_mutex); |
128 | inode->i_mode = mode; | 128 | inode->i_mode = mode; |
129 | inode->i_uid = current->fsuid; | 129 | inode->i_uid = current_fsuid(); |
130 | if (dir->i_mode & S_ISGID) { | 130 | if (dir->i_mode & S_ISGID) { |
131 | inode->i_gid = dir->i_gid; | 131 | inode->i_gid = dir->i_gid; |
132 | if (S_ISDIR(mode)) | 132 | if (S_ISDIR(mode)) |
133 | mode |= S_ISGID; | 133 | mode |= S_ISGID; |
134 | } else { | 134 | } else { |
135 | inode->i_gid = current->fsgid; | 135 | inode->i_gid = current_fsgid(); |
136 | } | 136 | } |
137 | 137 | ||
138 | iinfo->i_location.logicalBlockNum = block; | 138 | iinfo->i_location.logicalBlockNum = block; |
diff --git a/fs/udf/namei.c b/fs/udf/namei.c index 082409cd4b8a..f84bfaa8d941 100644 --- a/fs/udf/namei.c +++ b/fs/udf/namei.c | |||
@@ -604,7 +604,7 @@ static int udf_mknod(struct inode *dir, struct dentry *dentry, int mode, | |||
604 | goto out; | 604 | goto out; |
605 | 605 | ||
606 | iinfo = UDF_I(inode); | 606 | iinfo = UDF_I(inode); |
607 | inode->i_uid = current->fsuid; | 607 | inode->i_uid = current_fsuid(); |
608 | init_special_inode(inode, mode, rdev); | 608 | init_special_inode(inode, mode, rdev); |
609 | fi = udf_add_entry(dir, dentry, &fibh, &cfi, &err); | 609 | fi = udf_add_entry(dir, dentry, &fibh, &cfi, &err); |
610 | if (!fi) { | 610 | if (!fi) { |
diff --git a/fs/ufs/ialloc.c b/fs/ufs/ialloc.c index ac181f6806a3..6f5dcf006096 100644 --- a/fs/ufs/ialloc.c +++ b/fs/ufs/ialloc.c | |||
@@ -304,13 +304,13 @@ cg_found: | |||
304 | 304 | ||
305 | inode->i_ino = cg * uspi->s_ipg + bit; | 305 | inode->i_ino = cg * uspi->s_ipg + bit; |
306 | inode->i_mode = mode; | 306 | inode->i_mode = mode; |
307 | inode->i_uid = current->fsuid; | 307 | inode->i_uid = current_fsuid(); |
308 | if (dir->i_mode & S_ISGID) { | 308 | if (dir->i_mode & S_ISGID) { |
309 | inode->i_gid = dir->i_gid; | 309 | inode->i_gid = dir->i_gid; |
310 | if (S_ISDIR(mode)) | 310 | if (S_ISDIR(mode)) |
311 | inode->i_mode |= S_ISGID; | 311 | inode->i_mode |= S_ISGID; |
312 | } else | 312 | } else |
313 | inode->i_gid = current->fsgid; | 313 | inode->i_gid = current_fsgid(); |
314 | 314 | ||
315 | inode->i_blocks = 0; | 315 | inode->i_blocks = 0; |
316 | inode->i_generation = 0; | 316 | inode->i_generation = 0; |
diff --git a/fs/xfs/linux-2.6/xfs_cred.h b/fs/xfs/linux-2.6/xfs_cred.h index e279d00779f4..55bddf3b6091 100644 --- a/fs/xfs/linux-2.6/xfs_cred.h +++ b/fs/xfs/linux-2.6/xfs_cred.h | |||
@@ -23,8 +23,6 @@ | |||
23 | /* | 23 | /* |
24 | * Credentials | 24 | * Credentials |
25 | */ | 25 | */ |
26 | typedef struct cred { | 26 | typedef const struct cred cred_t; |
27 | /* EMPTY */ | ||
28 | } cred_t; | ||
29 | 27 | ||
30 | #endif /* __XFS_CRED_H__ */ | 28 | #endif /* __XFS_CRED_H__ */ |
diff --git a/fs/xfs/linux-2.6/xfs_ioctl.c b/fs/xfs/linux-2.6/xfs_ioctl.c index 0264c8719ffd..67205f6198ba 100644 --- a/fs/xfs/linux-2.6/xfs_ioctl.c +++ b/fs/xfs/linux-2.6/xfs_ioctl.c | |||
@@ -252,6 +252,7 @@ xfs_open_by_handle( | |||
252 | struct file *parfilp, | 252 | struct file *parfilp, |
253 | struct inode *parinode) | 253 | struct inode *parinode) |
254 | { | 254 | { |
255 | const struct cred *cred = current_cred(); | ||
255 | int error; | 256 | int error; |
256 | int new_fd; | 257 | int new_fd; |
257 | int permflag; | 258 | int permflag; |
@@ -314,7 +315,7 @@ xfs_open_by_handle( | |||
314 | mntget(parfilp->f_path.mnt); | 315 | mntget(parfilp->f_path.mnt); |
315 | 316 | ||
316 | /* Create file pointer. */ | 317 | /* Create file pointer. */ |
317 | filp = dentry_open(dentry, parfilp->f_path.mnt, hreq->oflags); | 318 | filp = dentry_open(dentry, parfilp->f_path.mnt, hreq->oflags, cred); |
318 | if (IS_ERR(filp)) { | 319 | if (IS_ERR(filp)) { |
319 | put_unused_fd(new_fd); | 320 | put_unused_fd(new_fd); |
320 | return -XFS_ERROR(-PTR_ERR(filp)); | 321 | return -XFS_ERROR(-PTR_ERR(filp)); |
diff --git a/fs/xfs/xfs_inode.h b/fs/xfs/xfs_inode.h index f0e4d79833e1..1f175fa34b22 100644 --- a/fs/xfs/xfs_inode.h +++ b/fs/xfs/xfs_inode.h | |||
@@ -503,7 +503,7 @@ void xfs_ireclaim(xfs_inode_t *); | |||
503 | * xfs_inode.c prototypes. | 503 | * xfs_inode.c prototypes. |
504 | */ | 504 | */ |
505 | int xfs_ialloc(struct xfs_trans *, xfs_inode_t *, mode_t, | 505 | int xfs_ialloc(struct xfs_trans *, xfs_inode_t *, mode_t, |
506 | xfs_nlink_t, xfs_dev_t, struct cred *, xfs_prid_t, | 506 | xfs_nlink_t, xfs_dev_t, cred_t *, xfs_prid_t, |
507 | int, struct xfs_buf **, boolean_t *, xfs_inode_t **); | 507 | int, struct xfs_buf **, boolean_t *, xfs_inode_t **); |
508 | 508 | ||
509 | uint xfs_ip2xflags(struct xfs_inode *); | 509 | uint xfs_ip2xflags(struct xfs_inode *); |
diff --git a/fs/xfs/xfs_vnodeops.h b/fs/xfs/xfs_vnodeops.h index 55d955ec4ece..76df328c61b4 100644 --- a/fs/xfs/xfs_vnodeops.h +++ b/fs/xfs/xfs_vnodeops.h | |||
@@ -26,18 +26,18 @@ int xfs_inactive(struct xfs_inode *ip); | |||
26 | int xfs_lookup(struct xfs_inode *dp, struct xfs_name *name, | 26 | int xfs_lookup(struct xfs_inode *dp, struct xfs_name *name, |
27 | struct xfs_inode **ipp, struct xfs_name *ci_name); | 27 | struct xfs_inode **ipp, struct xfs_name *ci_name); |
28 | int xfs_create(struct xfs_inode *dp, struct xfs_name *name, mode_t mode, | 28 | int xfs_create(struct xfs_inode *dp, struct xfs_name *name, mode_t mode, |
29 | xfs_dev_t rdev, struct xfs_inode **ipp, struct cred *credp); | 29 | xfs_dev_t rdev, struct xfs_inode **ipp, cred_t *credp); |
30 | int xfs_remove(struct xfs_inode *dp, struct xfs_name *name, | 30 | int xfs_remove(struct xfs_inode *dp, struct xfs_name *name, |
31 | struct xfs_inode *ip); | 31 | struct xfs_inode *ip); |
32 | int xfs_link(struct xfs_inode *tdp, struct xfs_inode *sip, | 32 | int xfs_link(struct xfs_inode *tdp, struct xfs_inode *sip, |
33 | struct xfs_name *target_name); | 33 | struct xfs_name *target_name); |
34 | int xfs_mkdir(struct xfs_inode *dp, struct xfs_name *dir_name, | 34 | int xfs_mkdir(struct xfs_inode *dp, struct xfs_name *dir_name, |
35 | mode_t mode, struct xfs_inode **ipp, struct cred *credp); | 35 | mode_t mode, struct xfs_inode **ipp, cred_t *credp); |
36 | int xfs_readdir(struct xfs_inode *dp, void *dirent, size_t bufsize, | 36 | int xfs_readdir(struct xfs_inode *dp, void *dirent, size_t bufsize, |
37 | xfs_off_t *offset, filldir_t filldir); | 37 | xfs_off_t *offset, filldir_t filldir); |
38 | int xfs_symlink(struct xfs_inode *dp, struct xfs_name *link_name, | 38 | int xfs_symlink(struct xfs_inode *dp, struct xfs_name *link_name, |
39 | const char *target_path, mode_t mode, struct xfs_inode **ipp, | 39 | const char *target_path, mode_t mode, struct xfs_inode **ipp, |
40 | struct cred *credp); | 40 | cred_t *credp); |
41 | int xfs_inode_flush(struct xfs_inode *ip, int flags); | 41 | int xfs_inode_flush(struct xfs_inode *ip, int flags); |
42 | int xfs_set_dmattrs(struct xfs_inode *ip, u_int evmask, u_int16_t state); | 42 | int xfs_set_dmattrs(struct xfs_inode *ip, u_int evmask, u_int16_t state); |
43 | int xfs_reclaim(struct xfs_inode *ip); | 43 | int xfs_reclaim(struct xfs_inode *ip); |