diff --git a/Fat.cpp b/Fat.cpp index 6ac1f8a..018fbeb 100644 --- a/Fat.cpp +++ b/Fat.cpp @@ -227,28 +227,35 @@ int Fat::format(const char *fsPath, unsigned int numSectors, bool wipe) { } void Fat::wipe(const char *fsPath, unsigned int numSectors) { - int fd; unsigned long long range[2]; - fd = open(fsPath, O_RDWR); - if (fd >= 0) { - if (numSectors == 0) { - numSectors = get_blkdev_size(fd); - } - if (numSectors == 0) { - SLOGE("Fat wipe failed to determine size of %s", fsPath); + int fd = open(fsPath, O_RDWR); + if (fd == -1) { + SLOGE("Fat wipe failed to open device %s", fsPath); + return; + } + + if (numSectors == 0) { + unsigned long nr_sec; + get_blkdev_size(fd, &nr_sec); + if (nr_sec > UINT32_MAX) { + SLOGE("Too many sectors for FAT: %ld", nr_sec); close(fd); return; } - range[0] = 0; - range[1] = (unsigned long long)numSectors * 512; - if (ioctl(fd, BLKDISCARD, &range) < 0) { - SLOGE("Fat wipe failed to discard blocks on %s", fsPath); - } else { - SLOGI("Fat wipe %d sectors on %s succeeded", numSectors, fsPath); - } + numSectors = nr_sec; + } + if (numSectors == 0) { + SLOGE("Fat wipe failed to determine size of %s", fsPath); close(fd); + return; + } + range[0] = 0; + range[1] = (unsigned long long)numSectors * 512; + if (ioctl(fd, BLKDISCARD, &range) < 0) { + SLOGE("Fat wipe failed to discard blocks on %s", fsPath); } else { - SLOGE("Fat wipe failed to open device %s", fsPath); + SLOGI("Fat wipe %d sectors on %s succeeded", numSectors, fsPath); } + close(fd); } diff --git a/Loop.cpp b/Loop.cpp index 1ed5bd0..b1e9f6a 100644 --- a/Loop.cpp +++ b/Loop.cpp @@ -35,6 +35,7 @@ #include #include "Loop.h" #include "Asec.h" +#include "VoldUtil.h" #include "sehandle.h" int Loop::dumpState(SocketClient *c) { @@ -296,7 +297,7 @@ int Loop::resizeImageFile(const char *file, unsigned int numSectors) { return 0; } -int Loop::lookupInfo(const char *loopDevice, struct asec_superblock *sb, unsigned int *nr_sec) { +int Loop::lookupInfo(const char *loopDevice, struct asec_superblock *sb, unsigned long *nr_sec) { int fd; struct asec_superblock buffer; @@ -306,7 +307,8 @@ int Loop::lookupInfo(const char *loopDevice, struct asec_superblock *sb, unsigne return -1; } - if (ioctl(fd, BLKGETSIZE, nr_sec)) { + get_blkdev_size(fd, nr_sec); + if (*nr_sec == 0) { SLOGE("Failed to get loop size (%s)", strerror(errno)); destroyByDevice(loopDevice); close(fd); diff --git a/Loop.h b/Loop.h index 45e6115..f7c0392 100644 --- a/Loop.h +++ b/Loop.h @@ -27,7 +27,7 @@ public: static const int LOOP_MAX = 4096; public: static int lookupActive(const char *id, char *buffer, size_t len); - static int lookupInfo(const char *loopDevice, struct asec_superblock *sb, unsigned int *nr_sec); + static int lookupInfo(const char *loopDevice, struct asec_superblock *sb, unsigned long *nr_sec); static int create(const char *id, const char *loopFile, char *loopDeviceBuffer, size_t len); static int destroyByDevice(const char *loopDevice); static int destroyByFile(const char *loopFile); diff --git a/VoldUtil.c b/VoldUtil.c index b5f9946..e5bc912 100644 --- a/VoldUtil.c +++ b/VoldUtil.c @@ -17,13 +17,8 @@ #include #include -unsigned int get_blkdev_size(int fd) -{ - unsigned int nr_sec; - - if ( (ioctl(fd, BLKGETSIZE, &nr_sec)) == -1) { - nr_sec = 0; +void get_blkdev_size(int fd, unsigned long* nr_sec) { + if ((ioctl(fd, BLKGETSIZE, nr_sec)) == -1) { + *nr_sec = 0; } - - return nr_sec; } diff --git a/VoldUtil.h b/VoldUtil.h index 469489a..5738382 100644 --- a/VoldUtil.h +++ b/VoldUtil.h @@ -22,7 +22,7 @@ #define ARRAY_SIZE(a) (sizeof(a) / sizeof(*(a))) __BEGIN_DECLS - unsigned int get_blkdev_size(int fd); +void get_blkdev_size(int fd, unsigned long* nr_sec); __END_DECLS #endif diff --git a/VolumeManager.cpp b/VolumeManager.cpp index 4c5bb58..d6907f2 100644 --- a/VolumeManager.cpp +++ b/VolumeManager.cpp @@ -52,6 +52,7 @@ #include "Devmapper.h" #include "Process.h" #include "Asec.h" +#include "VoldUtil.h" #include "cryptfs.h" #define MASS_STORAGE_FILE_PATH "/sys/class/android_usb/android0/f_mass_storage/lun/file" @@ -759,7 +760,7 @@ int VolumeManager::finalizeAsec(const char *id) { return -1; } - unsigned int nr_sec = 0; + unsigned long nr_sec = 0; struct asec_superblock sb; if (Loop::lookupInfo(loopDevice, &sb, &nr_sec)) { @@ -822,7 +823,7 @@ int VolumeManager::fixupAsecPermissions(const char *id, gid_t gid, const char* f return -1; } - unsigned int nr_sec = 0; + unsigned long nr_sec = 0; struct asec_superblock sb; if (Loop::lookupInfo(loopDevice, &sb, &nr_sec)) { @@ -1297,7 +1298,7 @@ int VolumeManager::mountAsec(const char *id, const char *key, int ownerUid, bool char dmDevice[255]; bool cleanupDm = false; - unsigned int nr_sec = 0; + unsigned long nr_sec = 0; struct asec_superblock sb; if (Loop::lookupInfo(loopDevice, &sb, &nr_sec)) { @@ -1403,7 +1404,7 @@ int VolumeManager::mountObb(const char *img, const char *key, int ownerGid) { char dmDevice[255]; bool cleanupDm = false; int fd; - unsigned int nr_sec = 0; + unsigned long nr_sec = 0; if ((fd = open(loopDevice, O_RDWR)) < 0) { SLOGE("Failed to open loopdevice (%s)", strerror(errno)); @@ -1411,7 +1412,8 @@ int VolumeManager::mountObb(const char *img, const char *key, int ownerGid) { return -1; } - if (ioctl(fd, BLKGETSIZE, &nr_sec)) { + get_blkdev_size(fd, &nr_sec); + if (nr_sec == 0) { SLOGE("Failed to get loop size (%s)", strerror(errno)); Loop::destroyByDevice(loopDevice); close(fd); @@ -1420,7 +1422,7 @@ int VolumeManager::mountObb(const char *img, const char *key, int ownerGid) { close(fd); - if (setupDevMapperDevice(dmDevice, sizeof(loopDevice), loopDevice, img,key, idHash , nr_sec, &cleanupDm, mDebug)) { + if (setupDevMapperDevice(dmDevice, sizeof(loopDevice), loopDevice, img,key, idHash, nr_sec, &cleanupDm, mDebug)) { Loop::destroyByDevice(loopDevice); return -1; } diff --git a/cryptfs.c b/cryptfs.c index 735232d..bbd952b 100644 --- a/cryptfs.c +++ b/cryptfs.c @@ -417,7 +417,6 @@ static int get_crypt_ftr_info(char **metadata_fname, off64_t *off) int fd; char key_loc[PROPERTY_VALUE_MAX]; char real_blkdev[PROPERTY_VALUE_MAX]; - unsigned int nr_sec; int rc = -1; if (!cached_data) { @@ -429,7 +428,9 @@ static int get_crypt_ftr_info(char **metadata_fname, off64_t *off) return -1; } - if ((nr_sec = get_blkdev_size(fd))) { + unsigned long nr_sec = 0; + get_blkdev_size(fd, &nr_sec); + if (nr_sec != 0) { /* If it's an encrypted Android partition, the last 16 Kbytes contain the * encryption info footer and key, and plenty of bytes to spare for future * growth. @@ -1905,17 +1906,22 @@ int cryptfs_setup_volume(const char *label, int major, int minor, char real_blkdev[MAXPATHLEN], crypto_blkdev[MAXPATHLEN]; struct crypt_mnt_ftr sd_crypt_ftr; struct stat statbuf; - unsigned int nr_sec; - int fd; sprintf(real_blkdev, "/dev/block/vold/%d:%d", major, minor); get_crypt_ftr_and_key(&sd_crypt_ftr); /* Update the fs_size field to be the size of the volume */ - fd = open(real_blkdev, O_RDONLY); - nr_sec = get_blkdev_size(fd); + int fd = open(real_blkdev, O_RDONLY); + if (fd == -1) { + SLOGE("Cannot open volume %s\n", real_blkdev); + return -1; + } + + unsigned long nr_sec = 0; + get_blkdev_size(fd, &nr_sec); close(fd); + if (nr_sec == 0) { SLOGE("Cannot get size of volume %s\n", real_blkdev); return -1; @@ -2931,9 +2937,8 @@ int cryptfs_enable_internal(char *howarg, int crypt_type, char *passwd, { int how = 0; char crypto_blkdev[MAXPATHLEN], real_blkdev[MAXPATHLEN]; - unsigned long nr_sec; unsigned char decrypted_master_key[KEY_LEN_BYTES]; - int rc=-1, fd, i; + int rc=-1, i; struct crypt_mnt_ftr crypt_ftr; struct crypt_persist_data *pdata; char encrypted_state[PROPERTY_VALUE_MAX]; @@ -2982,8 +2987,14 @@ int cryptfs_enable_internal(char *howarg, int crypt_type, char *passwd, fs_mgr_get_crypt_info(fstab, 0, real_blkdev, sizeof(real_blkdev)); /* Get the size of the real block device */ - fd = open(real_blkdev, O_RDONLY); - if ( (nr_sec = get_blkdev_size(fd)) == 0) { + int fd = open(real_blkdev, O_RDONLY); + if (fd == -1) { + SLOGE("Cannot open block device %s\n", real_blkdev); + goto error_unencrypted; + } + unsigned long nr_sec; + get_blkdev_size(fd, &nr_sec); + if (nr_sec == 0) { SLOGE("Cannot get size of block device %s\n", real_blkdev); goto error_unencrypted; }