Skip to content

Commit

Permalink
Fix use-after-free issue with the global 'default_material' (issue 14…
Browse files Browse the repository at this point in the history
…83) (#1583)

* Fix use-after-free issue with the global 'default_material' (issue 1483)

Signed-off-by: Krishna Gadepalli <[email protected]>

* Make all copy_from methods take const ref.

* use size_t instead of 'int' when computing size for memcpy (update existing update_weights too)
  • Loading branch information
kkg4theweb authored Jun 3, 2021
1 parent 30d9016 commit cf14e30
Show file tree
Hide file tree
Showing 3 changed files with 127 additions and 5 deletions.
90 changes: 89 additions & 1 deletion src/material_data.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,18 @@ struct transition {
}

bool operator!=(const transition &other) const { return !(*this == other); }

// NOTE: We could add a copy constructor but that requires a lot more
// code cleanup!
void copy_from(const transition& from) {
from_level = from.from_level;
to_level = from.to_level;
transition_rate = from.transition_rate;
frequency = from.frequency;
sigma_diag = from.sigma_diag;
gamma = from.gamma;
pumping_rate = from.pumping_rate;
}
};

typedef struct susceptibility_struct {
Expand All @@ -69,13 +81,42 @@ typedef struct susceptibility_struct {
bool is_file;
std::vector<transition> transitions;
std::vector<double> initial_populations;

void copy_from(const susceptibility_struct& from) {
sigma_offdiag = from.sigma_offdiag;
sigma_diag = from.sigma_diag;
bias = from.bias;
frequency = from.frequency;
gamma = from.gamma;
alpha = from.alpha;
noise_amp = from.noise_amp;
drude = from.drude;
saturated_gyrotropy = from.saturated_gyrotropy;
is_file = from.is_file;

transitions.resize(from.transitions.size());
for (int i = 0; i < transitions.size(); ++i) {
transitions[i].copy_from(from.transitions[i]);
}
initial_populations.assign(from.initial_populations.begin(),
from.initial_populations.end());
}

} susceptibility;

struct susceptibility_list {
int num_items;
susceptibility *items;

susceptibility_list() : num_items(0), items(NULL) {}

void copy_from(const susceptibility_list& from) {
num_items = from.num_items;
items = new susceptibility[num_items];
for (int i = 0; i < num_items; ++i) {
items[i].copy_from(from.items[i]);
}
}
};

struct medium_struct {
Expand Down Expand Up @@ -139,6 +180,23 @@ struct medium_struct {
B_conductivity_diag.y = 0;
B_conductivity_diag.z = 0;
}

void copy_from(const medium_struct& from) {
epsilon_diag = from.epsilon_diag;
epsilon_offdiag = from.epsilon_offdiag;
mu_diag = from.mu_diag;
mu_offdiag = from.mu_offdiag;

E_susceptibilities.copy_from(from.E_susceptibilities);
H_susceptibilities.copy_from(from.H_susceptibilities);

E_chi2_diag = from.E_chi2_diag;
E_chi3_diag = from.E_chi3_diag;
H_chi2_diag = from.H_chi2_diag;
H_chi3_diag = from.H_chi3_diag;
D_conductivity_diag = from.D_conductivity_diag;
B_conductivity_diag = from.B_conductivity_diag;
}
};

// prototype for user-defined material function,
Expand Down Expand Up @@ -217,7 +275,8 @@ struct material_data {
enum { U_MIN = 0, U_PROD = 1, U_MEAN = 2, U_DEFAULT = 3 } material_grid_kinds;

material_data()
: which_subclass(MEDIUM), medium(), user_func(NULL), user_data(NULL), epsilon_data(NULL),
: which_subclass(MEDIUM), medium(), user_func(NULL), user_data(NULL),
do_averaging(false), epsilon_data(NULL),
weights(NULL), medium_1(), medium_2() {
epsilon_dims[0] = 0;
epsilon_dims[1] = 0;
Expand All @@ -227,6 +286,35 @@ struct material_data {
grid_size.z = 0;
material_grid_kinds = U_DEFAULT;
}

void copy_from(const material_data& from) {
which_subclass = from.which_subclass;
medium.copy_from(from.medium);

user_func = from.user_func;
// NOTE: the user_data field here opaque/void - so this is the best we can do.
user_data = from.user_data;
do_averaging = from.do_averaging;

memcpy(epsilon_dims, from.epsilon_dims, 3 * sizeof(size_t));
if (from.epsilon_data) {
size_t N = from.epsilon_dims[0] * from.epsilon_dims[1] * from.epsilon_dims[2];
epsilon_data = new double[N];
memcpy(epsilon_data, from.epsilon_data, N * sizeof(double));
}

grid_size = from.grid_size;
if (from.weights) {
size_t N = from.grid_size.x * from.grid_size.y * from.grid_size.z;
weights = new double[N];
memcpy(weights, from.weights, N * sizeof(double));
}

medium_1.copy_from(medium_1);
medium_2.copy_from(medium_2);
beta = from.beta;
eta = from.eta;
}
};

typedef material_data *material_type;
Expand Down
41 changes: 37 additions & 4 deletions src/meepgeom.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,20 @@ namespace meep_geom {
material_data vacuum_material_data;
material_type vacuum = &vacuum_material_data;

static void set_default_material(material_type _default_material) {
if (default_material != NULL) {
material_free((material_type)default_material);
delete (material_type)default_material;
default_material = NULL;
}

if (_default_material != NULL) {
material_type new_material = new material_data();
new_material->copy_from(*_default_material);
default_material = (void *)new_material;
}
}

void check_offdiag(medium_struct *m) {
if (m->epsilon_offdiag.x.im != 0 || m->epsilon_offdiag.y.im != 0 ||
m->epsilon_offdiag.z.im != 0 || m->mu_offdiag.x.im != 0 || m->mu_offdiag.y.im != 0 ||
Expand Down Expand Up @@ -105,6 +119,25 @@ void material_gc(material_type m) {
susceptibility_list_gc(&(m->medium_2.H_susceptibilities));
}

void material_free(material_type m) {
if (!m) return;

susceptibility_list_gc(&(m->medium.E_susceptibilities));
susceptibility_list_gc(&(m->medium.H_susceptibilities));
susceptibility_list_gc(&(m->medium_1.E_susceptibilities));
susceptibility_list_gc(&(m->medium_1.H_susceptibilities));
susceptibility_list_gc(&(m->medium_2.E_susceptibilities));
susceptibility_list_gc(&(m->medium_2.H_susceptibilities));

// NOTE: We do not delete the user_data field here since it is an opaque/void
// object so will assume that the caller keeps track of its lifetime.
delete[] m->epsilon_data;
m->epsilon_data = NULL;

delete[] m->weights;
m->weights = NULL;
}

bool material_type_equal(const material_type m1, const material_type m2) {
if (m1 == m2) return true;
if (m1->which_subclass != m2->which_subclass) return false;
Expand Down Expand Up @@ -554,7 +587,7 @@ void epsilon_material_grid(material_data *md, double u) {

// return material of the point p from the file (assumed already read)
void epsilon_file_material(material_data *md, vector3 p) {
default_material = (void *)md;
set_default_material(md);

if (md->which_subclass != material_data::MATERIAL_FILE)
meep::abort("epsilon-input-file only works with a type=file default-material");
Expand Down Expand Up @@ -1806,7 +1839,7 @@ void set_materials_from_geometry(meep::structure *s, geometric_object_list g, ve
_default_material->which_subclass != material_data::PERFECT_METAL) {
check_offdiag(&_default_material->medium);
}
default_material = _default_material;
set_default_material(_default_material);
ensure_periodicity = _ensure_periodicity;
meep::grid_volume gv = s->gv;
double resolution = gv.a;
Expand Down Expand Up @@ -1936,7 +1969,7 @@ material_type make_material_grid(bool do_averaging, double beta, double eta) {
}

void update_weights(material_type matgrid, double *weights) {
int N = matgrid->grid_size.x * matgrid->grid_size.y * matgrid->grid_size.z;
size_t N = matgrid->grid_size.x * matgrid->grid_size.y * matgrid->grid_size.z;
memcpy(matgrid->weights, weights, N * sizeof(double));
}

Expand Down Expand Up @@ -2061,7 +2094,7 @@ void init_libctl(material_type default_mat, bool ensure_per, meep::grid_volume *
vector3 cell_size, vector3 cell_center,
geometric_object_list *geom_) {
geom_initialize();
default_material = default_mat;
set_default_material(default_mat);
ensure_periodicity = ensure_per;
geometry_center = cell_center;
dimensions = meep::number_of_directions(gv->dim);
Expand Down
1 change: 1 addition & 0 deletions src/meepgeom.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,7 @@ bool susceptibility_equal(const susceptibility &s1, const susceptibility &s2);
bool susceptibility_list_equal(const susceptibility_list &s1, const susceptibility_list &s2);
bool medium_struct_equal(const medium_struct *m1, const medium_struct *m2);
void material_gc(material_type m);
void material_free(material_type m);
bool material_type_equal(const material_type m1, const material_type m2);
bool is_material_grid(material_type mt);
bool is_material_grid(void *md);
Expand Down

0 comments on commit cf14e30

Please sign in to comment.