Example #1
0
static void test_safe_lchown_unsafe_link(void)
{
    if (getuid() != 0)
    {
        complain_missing_sudo(__FUNCTION__);
        return;
    }

    setup_tempfiles();

    struct stat statbuf;

    TEST_SYMLINK_COUNTDOWN = 1;
    TEST_SYMLINK_NAME = TEMP_DIR "/" TEST_FILE;
    TEST_SYMLINK_TARGET = TEMP_DIR "/" TEST_SUBDIR "/" TEST_FILE;
    // Not calling this function will call it right in the middle of the
    // safe_open() instead.
    //test_switch_symlink();

    assert_int_equal(lchown(TEST_SUBDIR "/" TEST_FILE, 0, 0), 0);
    assert_int_equal(stat(TEST_SUBDIR "/" TEST_FILE, &statbuf), 0);
    assert_int_equal(statbuf.st_uid, 0);
    assert_int_equal(statbuf.st_gid, 0);
    // Unsafe links should succeed, because we are operating on the *link*, not the target.
    assert_int_equal(safe_lchown(TEST_FILE, 100, 100), 0);
    assert_int_equal(stat(TEST_SUBDIR "/" TEST_FILE, &statbuf), 0);
    assert_int_equal(statbuf.st_uid, 0);
    assert_int_equal(statbuf.st_gid, 0);

    return_to_test_dir();
}
Example #2
0
static void test_safe_lchown_unsafe_link_to_directory(void)
{
    if (getuid() != 0)
    {
        complain_missing_sudo(__FUNCTION__);
        return;
    }

    setup_tempfiles();

    struct stat statbuf;

    TEST_SYMLINK_COUNTDOWN = 1;
    TEST_SYMLINK_NAME = TEMP_DIR "/" TEST_LINK;
    TEST_SYMLINK_TARGET = TEMP_DIR "/" TEST_SUBDIR;
    test_switch_symlink();

    assert_int_equal(lchown(TEST_SUBDIR "/" TEST_FILE, 0, 0), 0);
    assert_int_equal(stat(TEST_SUBDIR "/" TEST_FILE, &statbuf), 0);
    assert_int_equal(statbuf.st_uid, 0);
    assert_int_equal(statbuf.st_gid, 0);
    assert_int_equal(lchown(TEST_SUBDIR, 0, 0), 0);
    assert_int_equal(stat(TEST_SUBDIR, &statbuf), 0);
    assert_int_equal(statbuf.st_uid, 0);
    assert_int_equal(statbuf.st_gid, 0);
    assert_int_equal(safe_lchown(TEST_LINK "/" TEST_FILE, 100, 100), -1);
    assert_int_equal(errno, EACCES);

    assert_int_equal(lchown(TEST_SUBDIR "/" TEST_FILE, 100, 100), 0);
    assert_int_equal(stat(TEST_SUBDIR "/" TEST_FILE, &statbuf), 0);
    assert_int_equal(statbuf.st_uid, 100);
    assert_int_equal(statbuf.st_gid, 100);
    assert_int_equal(lchown(TEST_SUBDIR, 100, 100), 0);
    assert_int_equal(stat(TEST_SUBDIR, &statbuf), 0);
    assert_int_equal(statbuf.st_uid, 100);
    assert_int_equal(statbuf.st_gid, 100);
    assert_int_equal(safe_lchown(TEST_LINK "/" TEST_FILE, 100, 100), 0);
    assert_int_equal(stat(TEST_SUBDIR "/" TEST_FILE, &statbuf), 0);
    assert_int_equal(statbuf.st_uid, 100);
    assert_int_equal(statbuf.st_gid, 100);

    return_to_test_dir();
}
Example #3
0
static void test_safe_lchown_file_extra_slashes(void)
{
    if (getuid() != 0)
    {
        complain_missing_sudo(__FUNCTION__);
        return;
    }

    setup_tempfiles();

    struct stat statbuf;

    assert_int_equal(lchown("/" TEMP_DIR "////" TEST_SUBSUBDIR "//" TEST_FILE, 100, 100), 0);
    assert_int_equal(stat("/" TEMP_DIR "////" TEST_SUBSUBDIR "//" TEST_FILE, &statbuf), 0);
    assert_int_equal(statbuf.st_uid, 100);
    assert_int_equal(statbuf.st_gid, 100);
    assert_int_equal(safe_lchown("/" TEMP_DIR "////" TEST_SUBSUBDIR "//" TEST_FILE, 0, 0), 0);
    assert_int_equal(stat("/" TEMP_DIR "////" TEST_SUBSUBDIR "//" TEST_FILE, &statbuf), 0);
    assert_int_equal(statbuf.st_uid, 0);
    assert_int_equal(statbuf.st_gid, 0);

    return_to_test_dir();
}
Example #4
0
static void test_safe_lchown_plain_directory(void)
{
    if (getuid() != 0)
    {
        complain_missing_sudo(__FUNCTION__);
        return;
    }

    setup_tempfiles();

    struct stat statbuf;

    assert_int_equal(lchown(TEST_SUBDIR, 100, 100), 0);
    assert_int_equal(stat(TEST_SUBDIR, &statbuf), 0);
    assert_int_equal(statbuf.st_uid, 100);
    assert_int_equal(statbuf.st_gid, 100);
    assert_int_equal(safe_lchown(TEST_SUBDIR, 0, 0), 0);
    assert_int_equal(stat(TEST_SUBDIR, &statbuf), 0);
    assert_int_equal(statbuf.st_uid, 0);
    assert_int_equal(statbuf.st_gid, 0);

    return_to_test_dir();
}
Example #5
0
void process_chunk(void) {
	yaffs_ObjectHeader oh;
	yaffs_PackedTags2 *pt;
	object *obj, *eq_obj;
	int out_file, remain, s;

	oh = *(yaffs_ObjectHeader *)chunk_data;
	pt = (yaffs_PackedTags2 *)spare_data;

	if (pt->t.sequenceNumber == 0xffffffff)	/* empty object */
		return;

	if (saved_chunk.objectId != 0 &&	/* saved chunk is not part of object */
	    saved_chunk.objectId != pt->t.objectId) {
		prt_err(0, 0, "Warning: Invalid header at chunk #%d, skipping...",
		        saved_chunk.chunk_no);
		if (++warn_count >= MAX_WARN)
			prt_err(1, 0, "Giving up");
		saved_chunk.objectId = 0;
	}

	if (pt->t.chunkId == 1) {		/* save chunk #1 */
		saved_chunk.objectId = pt->t.objectId;
		saved_chunk.chunk_no = chunk_no;
		memcpy(saved_chunk.data, chunk_data, chunk_size);
		memcpy(saved_chunk.data+chunk_size, spare_data, spare_size);
		return;
	} else if (pt->t.chunkId != 0) {	/* not a new object */
		prt_err(0, 0, "Warning: Invalid header at chunk #%d, skipping...",
		        chunk_no);
		if (++warn_count >= MAX_WARN)
			prt_err(1, 0, "Giving up");
		return;
	}

	obj = add_object(&oh, pt);

	/* listing */
	if (opt_verbose)
		prt_node(obj->path_name, &oh);
	else if (opt_list)
		printf("%s\n", obj->path_name);
	if (opt_list) {
		if (oh.type == YAFFS_OBJECT_TYPE_FILE) {
			remain = oh.fileSize;	/* skip over data chunks */
			while(remain > 0) {
				if (!next_data_chunk())
					prt_err(1, 0, "Broken image file");
				remain -= pt->t.byteCount;
			}
		}
		return;
	}

	switch(oh.type) {
		case YAFFS_OBJECT_TYPE_FILE:
			remain = oh.fileSize;
			out_file = creat(obj->path_name, oh.yst_mode & STD_PERMS);
			if (out_file < 0)
				prt_err(1, errno, "Can't create file %s", obj->path_name);
			while(remain > 0) {
				if (!next_data_chunk())
					prt_err(1, 0, "Broken image file");
				s = (remain < pt->t.byteCount) ? remain : pt->t.byteCount;
				if (safe_write(out_file, chunk_data, s) < 0)
					prt_err(1, errno, "Can't write to %s", obj->path_name);
				remain -= s;
			}
			close(out_file);
			safe_lchown(obj->path_name, oh.yst_uid, oh.yst_gid);
			if ((oh.yst_mode & EXTRA_PERMS) != 0 &&
			    chmod(obj->path_name, oh.yst_mode) < 0)
				prt_err(0, errno, "Warning: Can't chmod %s", obj->path_name);
			break;
		case YAFFS_OBJECT_TYPE_SYMLINK:
			if (symlink(oh.alias, obj->path_name) < 0)
				prt_err(1, errno, "Can't create symlink %s", obj->path_name);
			safe_lchown(obj->path_name, oh.yst_uid, oh.yst_gid);
			break;
		case YAFFS_OBJECT_TYPE_DIRECTORY:
			if (pt->t.objectId != YAFFS_OBJECTID_ROOT &&
			    mkdir(obj->path_name, oh.yst_mode & STD_PERMS) < 0)
					prt_err(1, errno, "Can't create directory %s", obj->path_name);
			safe_lchown(obj->path_name, oh.yst_uid, oh.yst_gid);
			if ((pt->t.objectId == YAFFS_OBJECTID_ROOT ||
			     (oh.yst_mode & EXTRA_PERMS) != 0) &&
			    chmod(obj->path_name, oh.yst_mode) < 0)
				prt_err(0, errno, "Warning: Can't chmod %s", obj->path_name);
			break;
		case YAFFS_OBJECT_TYPE_HARDLINK:
			eq_obj = get_object(oh.equivalentObjectId);
			if (eq_obj == NULL)
				prt_err(1, 0, "Invalid equivalentObjectId %u in object %u (%s)",
				        oh.equivalentObjectId, pt->t.objectId, oh.name);
			if (link(eq_obj->path_name, obj->path_name) < 0)
				prt_err(1, errno, "Can't create hardlink %s", obj->path_name);
			break;
		case YAFFS_OBJECT_TYPE_SPECIAL:
			if (mknod(obj->path_name, oh.yst_mode, oh.yst_rdev) < 0) {
				if (errno == EPERM || errno == EINVAL)
					prt_err(0, errno, "Warning: Can't create device %s", obj->path_name);
				else
					prt_err(1, errno, "Can't create device %s", obj->path_name);
			} else
				safe_lchown(obj->path_name, oh.yst_uid, oh.yst_gid);
			break;
		case YAFFS_OBJECT_TYPE_UNKNOWN:
			break;
	}

	/* set file date and time */
	switch(oh.type) {
		case YAFFS_OBJECT_TYPE_FILE:
		case YAFFS_OBJECT_TYPE_SPECIAL:
#ifdef HAS_LUTIMES
		case YAFFS_OBJECT_TYPE_SYMLINK:
#endif
			set_utime(obj->path_name,
			          oh.yst_atime, oh.yst_mtime);
			break;
		case YAFFS_OBJECT_TYPE_DIRECTORY:
		default:
			break;
	}
}