blob: 9b5e629ef6ef9573f614aa08ce13270c3522cf4e [file] [log] [blame]
/**
* Copyright (C) 2020 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <media/IMediaHTTPService.h>
#include "include/MPEG4Extractor.h"
#include <media/stagefright/MetaData.h>
#include <dlfcn.h>
#include <sys/mman.h>
#include <media/stagefright/DataSource.h>
#include "../includes/common.h"
using namespace android;
#define PSSH_BOX_SIZE 1048576
#define MAX_ENTRIES 1024
void check_memleak(void);
bool track_malloc = false;
#define ALLOCATED_STATE 1
#define FREED_STATE 2
typedef struct {
void* ptr;
size_t size;
int status;
int index;
} allocated_mem_ptr;
static void* (*real_malloc)(unsigned long) = NULL;
static void (*real_free)(void *) = NULL;
static int s_memutils_initialized = 0;
static int index = 0;
static allocated_mem_ptr mem_ptrs[MAX_ENTRIES] = { { 0, 0, 0, 0 } };
void exit_handler(void) {
check_memleak();
}
void memutils_init(void) {
real_malloc = (void *(*)(unsigned long))dlsym(RTLD_NEXT, "malloc");
if (real_malloc == NULL) {
return;
}
real_free = (void (*)(void *))dlsym(RTLD_NEXT, "free");
if (real_free == NULL) {
return;
}
atexit(exit_handler);
s_memutils_initialized = 1;
}
void *malloc(size_t size) {
void* mem_ptr = NULL;
if (s_memutils_initialized == 0) {
memutils_init();
}
if (track_malloc == false) {
return real_malloc(size);
}
if (size != PSSH_BOX_SIZE) {
return real_malloc(size);
}
if (index >= MAX_ENTRIES) {
return real_malloc(size);
}
mem_ptr = real_malloc(size);
mem_ptrs[index].ptr = mem_ptr;
mem_ptrs[index].status = ALLOCATED_STATE;
mem_ptrs[index].size = size;
mem_ptrs[index].index = index;
index++;
return mem_ptr;
}
void free(void *ptr) {
if (s_memutils_initialized == 0) {
memutils_init();
}
if (ptr) {
for (int i = 0; i < MAX_ENTRIES; i++) {
if (ptr == mem_ptrs[i].ptr) {
if ((i == mem_ptrs[i].index)
&& (mem_ptrs[i].status != FREED_STATE)) {
real_free(ptr);
mem_ptrs[i].status = FREED_STATE;
return;
}
}
}
}
real_free(ptr);
return;
}
void check_memleak(void) {
for (int i = 0; i < MAX_ENTRIES; i++) {
if (mem_ptrs[i].status == ALLOCATED_STATE) {
exit (EXIT_VULNERABLE);
}
}
return;
}
int main(int argc, char* argv[]) {
if (argc < 2) {
return EXIT_SUCCESS;
}
sp < DataSource > dataSource = DataSource::CreateFromURI(NULL, argv[1]);
if (dataSource == nullptr) {
return EXIT_SUCCESS;
}
MPEG4Extractor *extractor = new MPEG4Extractor(dataSource);
track_malloc = true;
extractor->getMetaData();
track_malloc = false;
return EXIT_SUCCESS;
}