dev_t DirectVolume::getShareDevice() { if (mPartIdx != -1) { #ifdef VOLD_DISC_HAS_MULTIPLE_MAJORS int major = getMajorNumberForBadPartition(mPartIdx); if(major != -1) { SLOGE("getShareDevice() returning correct major: %d, minor: %d", major, mPartMinors[mPartIdx - 1]); return MKDEV(major, mPartMinors[mPartIdx - 1]); } else #endif return MKDEV(mDiskMajor, mPartIdx); } else { return MKDEV(mDiskMajor, mDiskMinor); } }
int VolumeManager::unmountAsec(const char *id, bool force) { char asecFileName[255]; char mountPoint[255]; snprintf(asecFileName, sizeof(asecFileName), "%s/%s.asec", Volume::SEC_ASECDIR, id); snprintf(mountPoint, sizeof(mountPoint), "%s/%s", Volume::ASECDIR, id); char idHash[33]; if (!asecHash(id, idHash, sizeof(idHash))) { SLOGE("Hash of '%s' failed (%s)", id, strerror(errno)); return -1; } return unmountLoopImage(id, idHash, asecFileName, mountPoint, force); }
int NetlinkManager::stop() { if (mHandler->stop()) { SLOGE("Unable to stop NetlinkHandler: %s", strerror(errno)); return -1; } delete mHandler; mHandler = NULL; close(mSock); mSock = -1; return 0; }
static int load_qseecom_library() { const char *error = NULL; if (loaded_library) return loaded_library; void * handle = dlopen(QSEECOM_LIBRARY_PATH, RTLD_NOW); if(handle) { dlerror(); /* Clear any existing error */ *(void **) (&qseecom_create_key) = dlsym(handle,"QSEECom_create_key"); if((error = dlerror()) == NULL) { SLOGD("Success loading QSEECom_create_key \n"); *(void **) (&qseecom_update_key) = dlsym(handle,"QSEECom_update_key_user_info"); if ((error = dlerror()) == NULL) { SLOGD("Success loading QSEECom_update_key_user_info\n"); *(void **) (&qseecom_wipe_key) = dlsym(handle,"QSEECom_wipe_key"); if ((error = dlerror()) == NULL) { loaded_library = 1; SLOGD("Success loading QSEECom_wipe_key \n"); } else SLOGE("Error %s loading symbols for QSEECom APIs \n", error); } else SLOGE("Error %s loading symbols for QSEECom APIs \n", error); } } else { SLOGE("Could not load libQSEEComAPI.so \n"); } if(error) dlclose(handle); return loaded_library; }
bool SocketClient::decRef() { bool deleteSelf = false; pthread_mutex_lock(&mRefCountMutex); mRefCount--; if (mRefCount == 0) { deleteSelf = true; } else if (mRefCount < 0) { SLOGE("SocketClient refcount went negative!"); } pthread_mutex_unlock(&mRefCountMutex); if (deleteSelf) { delete this; } return deleteSelf; }
int main(int argc, char **argv) { if (argc != 2 || argv[1][0] != '/') { usage(argv[0]); return -1; } SLOGD("Running: %s %s", argv[0], argv[1]); std::string target(argv[1]); destroy_key(target); if (unlink(argv[1]) != 0 && errno != ENOENT) { SLOGE("Unable to delete %s: %s", argv[1], strerror(errno)); return -1; } return 0; }
int SsServerDeleteFile(int sender_pid, const char* data_filepath, ssm_flag flag, const char* cookie, const char* group_id) { const char* in_filepath = data_filepath; char out_filepath[MAX_FILENAME_LEN] = {0, }; //0. privilege check and get directory name if(check_privilege(cookie, group_id) != 0) { SLOGE("[%s] permission denied\n", __func__); return SS_PERMISSION_DENIED; } // 1. create out file name ConvertFileName(sender_pid, out_filepath, in_filepath, flag, group_id); // 2. delete designated file if(unlink(out_filepath) != 0) // unlink fail? { SLOGE("[%s] error occured while deleting file\n", __func__); return SS_FILE_WRITE_ERROR; } return 1; }
int Volume::doUnmount(const char *path, bool force) { int retries = 3; int need_to_wait_count = 0; bool need_to_wait = false; bool isHotPlug = mVm->getHotPlug(); if (isHotPlug == true) { retries = 5; } SLOGD("doUnmount: %s retries = %d, isHotPlug=%d", path, retries, isHotPlug); if (mDebug) { SLOGD("Unmounting {%s}, force = %d", path, force); } while (retries--) { if (!umount(path) || errno == EINVAL || errno == ENOENT) { SLOGI("%s sucessfully unmounted", path); return 0; } int action = 0; if (force) { if (retries == 1) { action = 2; // SIGKILL } else if (retries == 2) { action = 1; // SIGHUP } } SLOGW("Failed to unmount %s (%s, retries %d, action %d)", path, strerror(errno), retries, action); Process::killProcessesWithOpenFiles(path, action); if (retries > 0) usleep(1000*1000); if(isHotPlug && (retries == 1)) usleep(1000*1000); } errno = EBUSY; SLOGE("Giving up on unmount %s (%s)", path, strerror(errno)); Process::FindProcessesWithOpenFiles(path); return -1; }
static int e4crypt_install_key(const ext4_encryption_key &ext4_key, const std::string &ref) { key_serial_t device_keyring = e4crypt_keyring(); SLOGI("Found device_keyring - id is %d", device_keyring); key_serial_t key_id = add_key("logon", ref.c_str(), (void*)&ext4_key, sizeof(ext4_key), device_keyring); if (key_id == -1) { SLOGE("Failed to insert key into keyring with error %s", strerror(errno)); return -1; } SLOGI("Added key %d (%s) to keyring %d in process %d", key_id, ref.c_str(), device_keyring, getpid()); return 0; }
void DirectVolume::handlePartitionAdded(const char *devpath, NetlinkEvent *evt) { int major = atoi(evt->findParam("MAJOR")); int minor = atoi(evt->findParam("MINOR")); int part_num; const char *tmp = evt->findParam("PARTN"); if (tmp) { part_num = atoi(tmp); } else { SLOGW("Kernel block uevent missing 'PARTN'"); part_num = 1; } if (part_num > MAX_PARTITIONS || part_num < 1) { SLOGW("Invalid 'PARTN' value"); part_num = 1; } if (part_num > mDiskNumParts) { mDiskNumParts = part_num; } if (major != mDiskMajor) { SLOGE("Partition '%s' has a different major than its disk!", devpath); return; } #ifdef PARTITION_DEBUG SLOGD("Dv:partAdd: part_num = %d, minor = %d\n", part_num, minor); #endif mPartMinors[part_num -1] = minor; mPendingPartMap &= ~(1 << part_num); if (!mPendingPartMap) { #ifdef PARTITION_DEBUG SLOGD("Dv:partAdd: Got all partitions - ready to rock!"); #endif if (getState() != Volume::State_Formatting) { setState(Volume::State_Idle); } } else { #ifdef PARTITION_DEBUG SLOGD("Dv:partAdd: pending mask now = 0x%x", mPendingPartMap); #endif } }
// hunt down and kill processes that have files open on the given mount point void killProcessesWithOpenFiles(const char *path, int action) { DIR *dir; struct dirent *de; if (!(dir = opendir("/proc"))) { SLOGE("opendir failed (%s)", strerror(errno)); return; } while ((de = readdir(dir))) { int pid = getPid(de->d_name); char name[PATH_MAX]; if (pid == -1) continue; getProcessName(pid, name, sizeof(name)); char openfile[PATH_MAX]; if (checkfileDescriptorSymLinks (pid, path, openfile, sizeof(openfile))) { SLOGE("Process %s (%d) has open file %s", name, pid, openfile); } else if (checkfileMaps(pid, path, openfile, sizeof(openfile))) { SLOGE("Process %s (%d) has open filemap for %s", name, pid, openfile); } else if (checkSymLink(pid, path, "cwd")) { SLOGE("Process %s (%d) has cwd within %s", name, pid, path); } else if (checkSymLink(pid, path, "root")) { SLOGE("Process %s (%d) has chroot within %s", name, pid, path); } else if (checkSymLink(pid, path, "exe")) { SLOGE("Process %s (%d) has executable path within %s", name, pid, path); } else { continue; } if (action == 1) { SLOGW("Sending SIGHUP to process %d", pid); kill(pid, SIGTERM); } else if (action == 2) { SLOGE("Sending SIGKILL to process %d", pid); kill(pid, SIGKILL); } } closedir(dir); }
int VolumeManager::getAsecFilesystemPath(const char *id, char *buffer, int maxlen) { char asecFileName[255]; if (findAsec(id, asecFileName, sizeof(asecFileName))) { SLOGE("Couldn't find ASEC %s", id); return -1; } memset(buffer, 0, maxlen); if (access(asecFileName, F_OK)) { errno = ENOENT; return -1; } snprintf(buffer, maxlen, "%s", asecFileName); return 0; }
int VolumeManager::getObbMountPath(const char *sourceFile, char *mountPath, int mountPathLen) { char idHash[33]; if (!asecHash(sourceFile, idHash, sizeof(idHash))) { SLOGE("Hash of '%s' failed (%s)", sourceFile, strerror(errno)); return -1; } memset(mountPath, 0, mountPathLen); snprintf(mountPath, mountPathLen, "%s/%s", Volume::LOOPDIR, idHash); if (access(mountPath, F_OK)) { errno = ENOENT; return -1; } return 0; }
// BLKSECDISCARD all content in "path", if it's small enough. static void destroy_key(const std::string &path) { uint64_t range[2]; if (file_device_range(path, range) < 0) { return; } int fs_fd = open_block_device_for_path(path); if (fs_fd < 0) { return; } if (ioctl(fs_fd, BLKSECDISCARD, range) != 0) { SLOGE("Unable to BLKSECDISCARD %s: %s", path.c_str(), strerror(errno)); close(fs_fd); return; } close(fs_fd); SLOGD("Discarded %s", path.c_str()); }
bool VolumeManager::isAsecInDirectory(const char *dir, const char *asecName) const { int dirfd = open(dir, O_DIRECTORY); if (dirfd < 0) { SLOGE("Couldn't open internal ASEC dir (%s)", strerror(errno)); return -1; } bool ret = false; if (!faccessat(dirfd, asecName, F_OK, AT_SYMLINK_NOFOLLOW)) { ret = true; } close(dirfd); return ret; }
int IsDirExist(char* dirpath) { DIR* dp = NULL; if((dp = opendir(dirpath)) == NULL) // dir is not exist { SLOGE("[%s] directory [%s] is not exist.\n", __func__, dirpath); return 0; // return value '0' represents dir is not exist } else { closedir(dp); return 1; } return -1; }
bool LogAudit::onDataAvailable(SocketClient *cli) { prctl(PR_SET_NAME, "logd.auditd"); struct audit_message rep; rep.nlh.nlmsg_type = 0; rep.nlh.nlmsg_len = 0; rep.data[0] = '\0'; if (audit_get_reply(cli->getSocket(), &rep, GET_REPLY_BLOCKING, 0) < 0) { SLOGE("Failed on audit_get_reply with error: %s", strerror(errno)); return false; } logPrint("type=%d %.*s", rep.nlh.nlmsg_type, rep.nlh.nlmsg_len, rep.data); return true; }
void Volume::protectFromAutorunStupidity() { char filename[255]; snprintf(filename, sizeof(filename), "%s/autorun.inf", SEC_STGDIR); if (!access(filename, F_OK)) { SLOGW("Volume contains an autorun.inf! - removing"); /* * Ensure the filename is all lower-case so * the process killer can find the inode. * Probably being paranoid here but meh. */ rename(filename, filename); Process::killProcessesWithOpenFiles(filename, 2); if (unlink(filename)) { SLOGE("Failed to remove %s (%s)", filename, strerror(errno)); } } }
/* Should we use keymaster? */ static int keymaster_check_compatibility_old() { keymaster0_device_t *keymaster0_dev = 0; keymaster1_device_t *keymaster1_dev = 0; int rc = 0; if (keymaster_init(&keymaster0_dev, &keymaster1_dev)) { SLOGE("Failed to init keymaster"); rc = -1; goto out; } if (keymaster1_dev) { rc = 1; goto out; } if (!keymaster0_dev || !keymaster0_dev->common.module) { rc = -1; goto out; } // TODO(swillden): Check to see if there's any reason to require v0.3. I think v0.1 and v0.2 // should work. if (keymaster0_dev->common.module->module_api_version < KEYMASTER_MODULE_API_VERSION_0_3) { rc = 0; goto out; } if (!(keymaster0_dev->flags & KEYMASTER_SOFTWARE_ONLY) && (keymaster0_dev->flags & KEYMASTER_BLOBS_ARE_STANDALONE)) { rc = 1; } out: if (keymaster1_dev) { keymaster1_close(keymaster1_dev); } if (keymaster0_dev) { keymaster0_close(keymaster0_dev); } return rc; }
int VolumeManager::listMountedObbs(SocketClient* cli) { char device[256]; char mount_path[256]; char rest[256]; FILE *fp; char line[1024]; if (!(fp = fopen("/proc/mounts", "r"))) { SLOGE("Error opening /proc/mounts (%s)", strerror(errno)); return -1; } // Create a string to compare against that has a trailing slash int loopDirLen = strlen(Volume::LOOPDIR); char loopDir[loopDirLen + 2]; strcpy(loopDir, Volume::LOOPDIR); loopDir[loopDirLen++] = '/'; loopDir[loopDirLen] = '\0'; while(fgets(line, sizeof(line), fp)) { line[strlen(line)-1] = '\0'; /* * Should look like: * /dev/block/loop0 /mnt/obb/fc99df1323fd36424f864dcb76b76d65 ... */ sscanf(line, "%255s %255s %255s\n", device, mount_path, rest); if (!strncmp(mount_path, loopDir, loopDirLen)) { int fd = open(device, O_RDONLY); if (fd >= 0) { struct loop_info64 li; if (ioctl(fd, LOOP_GET_STATUS64, &li) >= 0) { cli->sendMsg(ResponseCode::AsecListResult, (const char*) li.lo_file_name, false); } close(fd); } } } fclose(fp); return 0; }
// Given a file path, look for the corresponding // block device in /proc/mounts and open it. static int open_block_device_for_path(const std::string &path) { std::string mountsfile("/proc/mounts"); std::string mounts; if (read_file_as_string_atomically(mountsfile, mounts) < 0) { return -1; } std::string block_device; if (find_block_device_for_path(mounts, path, block_device) < 0) { return -1; } SLOGD("For path %s block device is %s", path.c_str(), block_device.c_str()); int res = open(block_device.c_str(), O_RDWR | O_LARGEFILE | O_CLOEXEC); if (res < 0) { SLOGE("Failed to open device %s: %s", block_device.c_str(), strerror(errno)); return -1; } return res; }
int Volume::formatVol() { if (getState() == Volume::State_NoMedia) { errno = ENODEV; return -1; } else if (getState() != Volume::State_Idle) { errno = EBUSY; return -1; } if (isMountpointMounted(getMountpoint())) { SLOGW("Volume is idle but appears to be mounted - fixing"); setState(Volume::State_Mounted); // mCurrentlyMountedKdev = XXX errno = EBUSY; return -1; } // Just format one partition but not the whole disk if (devicePath[0] == 0) { dev_t diskNode = getDiskDevice(); dev_t partNode = MKDEV(MAJOR(diskNode), 1); // XXX: Hmmm sprintf(devicePath, "/dev/block/vold/%d:%d", MAJOR(diskNode), MINOR(diskNode)); } if (mDebug) { SLOGI("Formatting volume %s (%s)", getLabel(), devicePath); } setState(Volume::State_Formatting); if (Fat::format(devicePath, 0)) { SLOGE("Failed to format (%s)", strerror(errno)); goto err; } setState(Volume::State_Idle); return 0; err: return -1; }
char* get_preserved_dir() { FILE* fp_conf = NULL; char buf[128]; char* retbuf = NULL; char seps[] = " :\n\r\t"; char* token = NULL; retbuf = (char*)malloc(sizeof(char) * 128); memset(buf, 0x00, 128); memset(retbuf, 0x00, 128); if(!(fp_conf = fopen(CONF_FILE_PATH, "r"))) { SLOGE("[%s] Configuration file is not exist\n", __func__); free(retbuf); return NULL; } while(fgets(buf, 128, fp_conf)) { token = strtok(buf, seps); if(!strncmp(token, "PRESERVE_DIR", 12)) // preserve directory? { token = strtok(NULL, seps); // real path break; } token = NULL; } fclose(fp_conf); if(token) strncpy(retbuf, token, 127); else { if(retbuf != NULL) free(retbuf); return NULL; } return retbuf; }
/* This signs the given object using the keymaster key. */ static int keymaster_sign_object_new(struct crypt_mnt_ftr *ftr, const unsigned char *object, const size_t object_size, unsigned char **signature, size_t *signature_size) { unsigned char to_sign[RSA_KEY_SIZE_BYTES]; size_t to_sign_size = sizeof(to_sign); memset(to_sign, 0, RSA_KEY_SIZE_BYTES); // To sign a message with RSA, the message must satisfy two // constraints: // // 1. The message, when interpreted as a big-endian numeric value, must // be strictly less than the public modulus of the RSA key. Note // that because the most significant bit of the public modulus is // guaranteed to be 1 (else it's an (n-1)-bit key, not an n-bit // key), an n-bit message with most significant bit 0 always // satisfies this requirement. // // 2. The message must have the same length in bits as the public // modulus of the RSA key. This requirement isn't mathematically // necessary, but is necessary to ensure consistency in // implementations. switch (ftr->kdf_type) { case KDF_SCRYPT_KEYMASTER: // This ensures the most significant byte of the signed message // is zero. We could have zero-padded to the left instead, but // this approach is slightly more robust against changes in // object size. However, it's still broken (but not unusably // so) because we really should be using a proper deterministic // RSA padding function, such as PKCS1. memcpy(to_sign + 1, object, min(RSA_KEY_SIZE_BYTES - 1, object_size)); SLOGI("Signing safely-padded object"); break; default: SLOGE("Unknown KDF type %d", ftr->kdf_type); return -1; } return keymaster_sign_object_for_cryptfs_scrypt(ftr->keymaster_blob, ftr->keymaster_blob_size, KEYMASTER_CRYPTFS_RATE_LIMIT, to_sign, to_sign_size, signature, signature_size); }
int main(void) { /* Library initialization. Must be called only once. */ SLOG_Init(SLOG_STDERR, "example02-log.txt"); /* Setting log levels: all messages to console and all to the file. * Default settings are: all messages to file and >= INFO to console. */ SLOG_SetLevel(SLOG_DEBUG, SLOG_DEBUG); SLOGD(TAG, "debug message"); SLOGI(TAG, "info"); SLOGW(TAG, "warning"); SLOGE(TAG, "error"); SLOGI(TAG, "formatted message (%d, %s)", 123, "bar"); /* Library deinitialization. */ SLOG_Deinit(); return 0; }
bool NotificationManager::onDataAvailable(NuSocketClient *cli) { int socket = cli->getSocket(); ssize_t count; count = TEMP_FAILURE_RETRY(read(socket, mBuffer, sizeof(mBuffer))); if (count < 0 || count > 4) { SLOGE("recvmsg failed (%s)", strerror(errno)); return false; } else if (count == 0){ LOGD("count = 0, client closed!"); return false; } int *value = (int *)&mBuffer[0]; onCommand(*value); return true; }
int Ext::format(const char *fsPath) { int fd; const char *args[3]; int rc; args[0] = MKEXTFS_PATH; args[1] = fsPath; args[2] = NULL; rc = logwrap(3, args, 1); if (rc == 0) { SLOGI("Filesystem formatted OK"); return 0; } else { SLOGE("Format failed (unknown exit code %d)", rc); errno = EIO; return -1; } return 0; }
int main (int argc, char* argv[]) { int ret; if (argc != 2) { fprintf(stderr, "Usage: %s <flush-frequency-in-seconds>\n", argv[0]); ret = -1; } else { hw_module_t* module; ret = hw_get_module(MRKNLOG_HARDWARE_MODULE_ID, (hw_module_t const**)&module); if (ret == 0) { struct mrknlog_device_t *dev; ret = module->methods->open(module, 0, (struct hw_device_t **) &dev); if (ret == 0) { int frequency = atoi(argv[1]); int totalSize = dev->get_total_log_size(dev); int usedSize; int count = 1; while(runFlag) { usedSize = dev->get_used_log_size(dev); if (dev->flush_log(dev) == 0) { SLOGI("Flushed log (%d, %d of %d bytes). Waiting %d seconds before the next flush.", count, usedSize, totalSize, frequency); } else { SLOGE("Failed to flush log. Bailing out"); break; } count++; sleep(frequency); } SLOGI("Done after %d iterations.", count); dev->common.close((struct hw_device_t *)dev); } else { fprintf(stderr, "Failed to open device: %d", ret); ret = -2; } } else { fprintf(stderr, "Failed to get module: %s", MRKNLOG_HARDWARE_MODULE_ID); ret = -3; } } return ret; }
int VolumeManager::mkdirs(char* path) { // Require that path lives under a volume we manage const char* emulated_source = getenv("EMULATED_STORAGE_SOURCE"); const char* root = NULL; if (emulated_source && !strncmp(path, emulated_source, strlen(emulated_source))) { root = emulated_source; } else { Volume* vol = getVolumeForFile(path); if (vol) { root = vol->getMountpoint(); } } if (!root) { SLOGE("Failed to find volume for %s", path); return -EINVAL; } /* fs_mkdirs() does symlink checking and relative path enforcement */ return fs_mkdirs(path, 0700); }
bool FrameworkListener::onDataAvailable(SocketClient *c) { char buffer[255]; int len; if ((len = read(c->getSocket(), buffer, sizeof(buffer) -1)) < 0) { SLOGE("read() failed (%s)", strerror(errno)); return false; } else if (!len) return false; int offset = 0; int i; for (i = 0; i < len; i++) { if (buffer[i] == '\0') { dispatchCommand(c, buffer + offset); offset = i + 1; } } return true; }