Допустим, у нас есть следующая структура (где T и U - любой из основных типов данных, таких как int, long, char и т. Д.)
struct S1 {
T t1;
U u1;
};
и другая структура
struct S2 {
T t2;
U u2;
};
Теперь я выделяю
struct S1* s1 = malloc(sizeof(*s1))
И с container_of
, определенным как
#define container_of(ptr, type, member) ({ \
const typeof( ((type *)0)->member ) \
*__mptr = (ptr);
(type *)( (char *)__mptr - offsetof(type,member) );})
, если я перейду к T* x
, следующее может быть сделано
struct S2* s2 = container_of(x, struct S2, t2)
//Here s2->u2 is the same value as that of s1->u1
Теперь мой запрос предполагает, что такие операции происходят не замечая друг друга (например, в разных библиотеках), это может привести к странным изменениям значений.
Контекст:
У меня есть свой собственный код с S1, но когда я передаю t1 другому библиотечному коду, он имеет другую подобную структуру S2 и в конечном итоге тоже изменяет значение u1.Есть ли способ защититься от таких непреднамеренных случаев использования?Также, скажем, на каждом конце интерфейса у нас есть указатель T* x
, но и разработчик интерфейса, и клиент интерфейса для их использования сохраняют его как часть структур S1 и S2.В этом случае также может возникнуть такая же ситуация, когда в основном код сервера будет неизменным.Как мы решаем эту проблему в этих случаях?
Реальный пример из ядра Kernel V4L2 здесь
static void __fill_v4l2_buffer(struct vb2_buffer *vb, void *pb)
{
struct v4l2_buffer *b = pb;
struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
:
:
b->flags = vbuf->flags;
Теперь я выделил структуру следующим образом:
my_v4l2_driver_video_buf{
struct vb2_buffer vb;
dma_addr_t addr;
}
и вот определение vb2_v4l2_buffer
struct vb2_v4l2_buffer {
struct vb2_buffer vb2_buf;
__u32 flags;
__u32 field;
struct timeval timestamp;
struct v4l2_timecode timecode;
__u32 sequence;
};
Примечание: dma_addr_t тоже был 32-битным
А потом я передал указатель наvb
до v4l2 рамки.Он изменил флаги в функции __fill_v4l2_buffer
, и я получил флаги v4l2_buffer* b
, равные dma_addr_t addr
моей структуры