projects
/
yaffs2.git
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
yaffsfs.c: Fix NULL dereference in yaffs_unmount2_reldev()
[yaffs2.git]
/
direct
/
yaffsfs.c
diff --git
a/direct/yaffsfs.c
b/direct/yaffsfs.c
index 3cb11a92a3c4675ec4220cad03e4378625168ec1..823f7edcfc21c9dd7e2247e1da8781e8a74eb7e1 100644
(file)
--- a/
direct/yaffsfs.c
+++ b/
direct/yaffsfs.c
@@
-1,8
+1,7
@@
/*
* YAFFS: Yet Another Flash File System. A NAND-flash specific file system.
*
/*
* YAFFS: Yet Another Flash File System. A NAND-flash specific file system.
*
- * Copyright (C) 2002-2011 Aleph One Ltd.
- * for Toby Churchill Ltd and Brightstar Engineering
+ * Copyright (C) 2002-2018 Aleph One Ltd.
*
* Created by Charles Manning <charles@aleph1.co.uk>
*
*
* Created by Charles Manning <charles@aleph1.co.uk>
*
@@
-19,6
+18,7
@@
#include "string.h"
#include "string.h"
+#define YAFFS_MAX_RW_SIZE 0x70000000
#define YAFFSFS_MAX_SYMLINK_DEREFERENCES 5
#ifndef NULL
#define YAFFSFS_MAX_SYMLINK_DEREFERENCES 5
#ifndef NULL
@@
-892,12
+892,14
@@
int yaffs_open_sharing_reldir(struct yaffs_obj *reldir, const YCHAR *path,
is_dir = (obj->variant_type ==
YAFFS_OBJECT_TYPE_DIRECTORY);
is_dir = (obj->variant_type ==
YAFFS_OBJECT_TYPE_DIRECTORY);
- /* A directory can't be opened except for read */
- if ( is_dir &&
- (writeRequested || !readRequested || rwflags != O_RDONLY)) {
- openDenied = __LINE__;
- yaffsfs_SetError(-EISDIR);
- errorReported = __LINE__;
+ /*
+ * A directory can't be opened except for read, so we
+ * ignore other flags
+ */
+ if (is_dir) {
+ writeRequested = 0;
+ readRequested = 1;
+ rwflags = O_RDONLY;
}
if(is_dir) {
}
if(is_dir) {
@@
-1187,7
+1189,7
@@
static int yaffsfs_do_read(int handle, void *vbuf, unsigned int nbyte,
/* Not a reading handle */
yaffsfs_SetError(-EINVAL);
totalRead = -1;
/* Not a reading handle */
yaffsfs_SetError(-EINVAL);
totalRead = -1;
- } else if (nbyte > YAFFS_MAX_
FILE
_SIZE) {
+ } else if (nbyte > YAFFS_MAX_
RW
_SIZE) {
yaffsfs_SetError(-EINVAL);
totalRead = -1;
} else {
yaffsfs_SetError(-EINVAL);
totalRead = -1;
} else {
@@
-1211,7
+1213,7
@@
static int yaffsfs_do_read(int handle, void *vbuf, unsigned int nbyte,
endPos = pos + nbyte;
if (pos < 0 || pos > YAFFS_MAX_FILE_SIZE ||
endPos = pos + nbyte;
if (pos < 0 || pos > YAFFS_MAX_FILE_SIZE ||
- nbyte > YAFFS_MAX_
FILE
_SIZE ||
+ nbyte > YAFFS_MAX_
RW
_SIZE ||
endPos < 0 || endPos > YAFFS_MAX_FILE_SIZE) {
totalRead = -1;
nbyte = 0;
endPos < 0 || endPos > YAFFS_MAX_FILE_SIZE) {
totalRead = -1;
nbyte = 0;
@@
-1220,7
+1222,7
@@
static int yaffsfs_do_read(int handle, void *vbuf, unsigned int nbyte,
while (nbyte > 0) {
nToRead = YAFFSFS_RW_SIZE -
(pos & (YAFFSFS_RW_SIZE - 1));
while (nbyte > 0) {
nToRead = YAFFSFS_RW_SIZE -
(pos & (YAFFSFS_RW_SIZE - 1));
- if (nToRead > nbyte)
+ if (nToRead >
(int)
nbyte)
nToRead = nbyte;
/* Tricky bit...
nToRead = nbyte;
/* Tricky bit...
@@
-1324,7
+1326,7
@@
static int yaffsfs_do_write(int handle, const void *vbuf, unsigned int nbyte,
endPos = pos + nbyte;
if (pos < 0 || pos > YAFFS_MAX_FILE_SIZE ||
endPos = pos + nbyte;
if (pos < 0 || pos > YAFFS_MAX_FILE_SIZE ||
- nbyte > YAFFS_MAX_
FILE
_SIZE ||
+ nbyte > YAFFS_MAX_
RW
_SIZE ||
endPos < 0 || endPos > YAFFS_MAX_FILE_SIZE) {
totalWritten = -1;
nbyte = 0;
endPos < 0 || endPos > YAFFS_MAX_FILE_SIZE) {
totalWritten = -1;
nbyte = 0;
@@
-1334,7
+1336,7
@@
static int yaffsfs_do_write(int handle, const void *vbuf, unsigned int nbyte,
nToWrite = YAFFSFS_RW_SIZE -
(pos & (YAFFSFS_RW_SIZE - 1));
nToWrite = YAFFSFS_RW_SIZE -
(pos & (YAFFSFS_RW_SIZE - 1));
- if (nToWrite > nbyte)
+ if (nToWrite >
(int)
nbyte)
nToWrite = nbyte;
/* Tricky bit...
nToWrite = nbyte;
/* Tricky bit...
@@
-1622,7
+1624,7
@@
int yaffs_fgetfl(int fd, int *flags)
{
struct yaffsfs_FileDes *fdp = yaffsfs_HandleToFileDes(fd);
int retVal;
{
struct yaffsfs_FileDes *fdp = yaffsfs_HandleToFileDes(fd);
int retVal;
-
+
yaffsfs_Lock();
if(!flags || !fdp) {
yaffsfs_Lock();
if(!flags || !fdp) {
@@
-1637,7
+1639,7
@@
int yaffs_fgetfl(int fd, int *flags)
*flags = O_RDONLY;
retVal = 0;
}
*flags = O_RDONLY;
retVal = 0;
}
-
+
yaffsfs_Unlock();
return retVal;
}
yaffsfs_Unlock();
return retVal;
}
@@
-1790,7
+1792,7
@@
static int yaffsfs_DoStat(struct yaffs_obj *obj, struct yaffs_stat *buf)
obj = yaffs_get_equivalent_obj(obj);
if (obj && buf) {
obj = yaffs_get_equivalent_obj(obj);
if (obj && buf) {
- buf->st_dev =
(int)obj->my_dev->os_context
;
+ buf->st_dev =
0
;
buf->st_ino = obj->obj_id;
buf->st_mode = obj->yst_mode & ~S_IFMT;
buf->st_ino = obj->obj_id;
buf->st_mode = obj->yst_mode & ~S_IFMT;
@@
-1941,17
+1943,21
@@
static int yaffsfs_DoUtime(struct yaffs_obj *obj,
}
#if !CONFIG_YAFFS_WINCE
}
#if !CONFIG_YAFFS_WINCE
+ // if the the buffer is null then create one with the fields set to the current time.
if (!buf) {
local.actime = Y_CURRENT_TIME;
local.modtime = local.actime;
buf = &local;
}
if (!buf) {
local.actime = Y_CURRENT_TIME;
local.modtime = local.actime;
buf = &local;
}
+ // copy the buffer's time into the obj.
if (obj) {
int result;
obj->yst_atime = buf->actime;
obj->yst_mtime = buf->modtime;
if (obj) {
int result;
obj->yst_atime = buf->actime;
obj->yst_mtime = buf->modtime;
+
+ // set the obj to dirty to cause it to be written to flash during the next flush operation.
obj->dirty = 1;
result = yaffs_flush_file(obj, 0, 0, 0);
retVal = result == YAFFS_OK ? 0 : -1;
obj->dirty = 1;
result = yaffs_flush_file(obj, 0, 0, 0);
retVal = result == YAFFS_OK ? 0 : -1;
@@
-3048,6
+3054,7
@@
int yaffs_remount_common(struct yaffs_dev *dev, const YCHAR *path,
int force, int read_only)
{
int retVal = -1;
int force, int read_only)
{
int retVal = -1;
+ int was_read_only;
if (yaffsfs_CheckMemRegion(path, 0, 0) < 0) {
yaffsfs_SetError(-EFAULT);
if (yaffsfs_CheckMemRegion(path, 0, 0) < 0) {
yaffsfs_SetError(-EFAULT);
@@
-3070,7
+3077,11
@@
int yaffs_remount_common(struct yaffs_dev *dev, const YCHAR *path,
if (force || !yaffsfs_IsDevBusy(dev)) {
if (read_only)
yaffs_checkpoint_save(dev);
if (force || !yaffsfs_IsDevBusy(dev)) {
if (read_only)
yaffs_checkpoint_save(dev);
+ was_read_only = dev->read_only;
dev->read_only = read_only ? 1 : 0;
dev->read_only = read_only ? 1 : 0;
+ if (was_read_only && !read_only) {
+ yaffs_guts_cleanup(dev);
+ }
retVal = 0;
} else
yaffsfs_SetError(-EBUSY);
retVal = 0;
} else
yaffsfs_SetError(-EBUSY);
@@
-3099,14
+3110,17
@@
int yaffs_unmount2_common(struct yaffs_dev *dev, const YCHAR *path, int force)
{
int retVal = -1;
{
int retVal = -1;
- if (yaffsfs_CheckMemRegion(path, 0, 0) < 0) {
- yaffsfs_SetError(-EFAULT);
- return -1;
- }
- if (yaffsfs_CheckPath(path) < 0) {
- yaffsfs_SetError(-ENAMETOOLONG);
- return -1;
+ if (!dev) {
+ if (yaffsfs_CheckMemRegion(path, 0, 0) < 0) {
+ yaffsfs_SetError(-EFAULT);
+ return -1;
+ }
+
+ if (yaffsfs_CheckPath(path) < 0) {
+ yaffsfs_SetError(-ENAMETOOLONG);
+ return -1;
+ }
}
yaffsfs_Lock();
}
yaffsfs_Lock();
@@
-3578,7
+3592,7
@@
struct yaffs_dirent *yaffsfs_readdir_no_lock(yaffs_DIR * dirp)
if (dsc->nextReturn) {
dsc->de.d_ino =
yaffs_get_equivalent_obj(dsc->nextReturn)->obj_id;
if (dsc->nextReturn) {
dsc->de.d_ino =
yaffs_get_equivalent_obj(dsc->nextReturn)->obj_id;
- dsc->de.d_dont_use =
(unsigned)dsc->nextReturn
;
+ dsc->de.d_dont_use =
0
;
dsc->de.d_off = dsc->offset++;
yaffs_get_obj_name(dsc->nextReturn,
dsc->de.d_name, NAME_MAX);
dsc->de.d_off = dsc->offset++;
yaffs_get_obj_name(dsc->nextReturn,
dsc->de.d_name, NAME_MAX);
@@
-3634,7
+3648,7
@@
struct yaffs_dirent *yaffs_readdir_fd(int fd)
yaffsfs_Lock();
f = yaffsfs_HandleToFileDes(fd);
yaffsfs_Lock();
f = yaffsfs_HandleToFileDes(fd);
- if(f && f->isDir)
+ if(f && f->isDir
&& f->v.dir
)
ret = yaffsfs_readdir_no_lock(f->v.dir);
yaffsfs_Unlock();
return ret;
ret = yaffsfs_readdir_no_lock(f->v.dir);
yaffsfs_Unlock();
return ret;