aboutsummaryrefslogtreecommitdiffstats
path: root/lib/libzpool/kernel.c
diff options
context:
space:
mode:
authorBrian Behlendorf <[email protected]>2010-08-26 11:03:04 -0700
committerBrian Behlendorf <[email protected]>2010-08-31 08:38:49 -0700
commit5ae4e2c2c660269d87dd5bbac6f590f69d0c7d8c (patch)
tree1e907d08953069867e246c27aef8b9854edcf7e6 /lib/libzpool/kernel.c
parent5fed499defe68b57fab349ac945a84416fb024ba (diff)
Fix stack vn_open()
We should not put a 4k maxpathlen buffer on the stack, instead locate it to the heap. Even in user space we run ztest with 8K stacks to verify correctness Signed-off-by: Brian Behlendorf <[email protected]>
Diffstat (limited to 'lib/libzpool/kernel.c')
-rw-r--r--lib/libzpool/kernel.c23
1 files changed, 17 insertions, 6 deletions
diff --git a/lib/libzpool/kernel.c b/lib/libzpool/kernel.c
index 4bd08cdd4..0559347e9 100644
--- a/lib/libzpool/kernel.c
+++ b/lib/libzpool/kernel.c
@@ -517,10 +517,12 @@ vn_open(char *path, int x1, int flags, int mode, vnode_t **vpp, int x2, int x3)
int fd;
vnode_t *vp;
int old_umask;
- char realpath[MAXPATHLEN];
+ char *realpath;
struct stat64 st;
int err;
+ realpath = umem_alloc(MAXPATHLEN, UMEM_NOFAIL);
+
/*
* If we're accessing a real disk from userland, we need to use
* the character interface to avoid caching. This is particularly
@@ -534,11 +536,16 @@ vn_open(char *path, int x1, int flags, int mode, vnode_t **vpp, int x2, int x3)
if (strncmp(path, "/dev/", 5) == 0) {
char *dsk;
fd = open64(path, O_RDONLY);
- if (fd == -1)
- return (errno);
+ if (fd == -1) {
+ err = errno;
+ free(realpath);
+ return (err);
+ }
if (fstat64(fd, &st) == -1) {
+ err = errno;
close(fd);
- return (errno);
+ free(realpath);
+ return (err);
}
close(fd);
(void) sprintf(realpath, "%s", path);
@@ -548,8 +555,11 @@ vn_open(char *path, int x1, int flags, int mode, vnode_t **vpp, int x2, int x3)
dsk + 1);
} else {
(void) sprintf(realpath, "%s", path);
- if (!(flags & FCREAT) && stat64(realpath, &st) == -1)
- return (errno);
+ if (!(flags & FCREAT) && stat64(realpath, &st) == -1) {
+ err = errno;
+ free(realpath);
+ return (err);
+ }
}
if (flags & FCREAT)
@@ -560,6 +570,7 @@ vn_open(char *path, int x1, int flags, int mode, vnode_t **vpp, int x2, int x3)
* FREAD and FWRITE to the corresponding O_RDONLY, O_WRONLY, and O_RDWR.
*/
fd = open64(realpath, flags - FREAD, mode);
+ free(realpath);
if (flags & FCREAT)
(void) umask(old_umask);