mirror of
git://git.code.sf.net/p/xtables-addons/xtables-addons
synced 2025-09-07 21:25:12 +02:00
geoip: use local-portable aligned_u64 pointer values
A 64-bit kernel will interpret the pointer with 64 bits width, while a 32-bit userspace filled in only 32 of it, leaving the other 32 undefined. This must be avoided.
This commit is contained in:
@@ -56,7 +56,7 @@ struct geoip_index {
|
|||||||
u_int32_t offset;
|
u_int32_t offset;
|
||||||
} __attribute__ ((packed));
|
} __attribute__ ((packed));
|
||||||
|
|
||||||
struct geoip_subnet *
|
static struct geoip_subnet *
|
||||||
get_country_subnets(u_int16_t cc, u_int32_t *count)
|
get_country_subnets(u_int16_t cc, u_int32_t *count)
|
||||||
{
|
{
|
||||||
FILE *ixfd, *dbfd;
|
FILE *ixfd, *dbfd;
|
||||||
@@ -122,8 +122,7 @@ get_country_subnets(u_int16_t cc, u_int32_t *count)
|
|||||||
return subnets;
|
return subnets;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct geoip_country_user *
|
static struct geoip_country_user *geoip_load_cc(unsigned short cc)
|
||||||
load_geoip_cc(u_int16_t cc)
|
|
||||||
{
|
{
|
||||||
struct geoip_country_user *ginfo;
|
struct geoip_country_user *ginfo;
|
||||||
ginfo = malloc(sizeof(struct geoip_country_user));
|
ginfo = malloc(sizeof(struct geoip_country_user));
|
||||||
@@ -131,7 +130,7 @@ load_geoip_cc(u_int16_t cc)
|
|||||||
if (!ginfo)
|
if (!ginfo)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
ginfo->subnets = get_country_subnets(cc, &ginfo->count);
|
ginfo->subnets = (unsigned long)get_country_subnets(cc, &ginfo->count);
|
||||||
ginfo->cc = cc;
|
ginfo->cc = cc;
|
||||||
|
|
||||||
return ginfo;
|
return ginfo;
|
||||||
@@ -173,9 +172,8 @@ check_geoip_cc(char *cc, u_int16_t cc_used[], u_int8_t count)
|
|||||||
return cc_int16;
|
return cc_int16;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Based on libipt_multiport.c parsing code. */
|
static unsigned int parse_geoip_cc(const char *ccstr, uint16_t *cc,
|
||||||
static u_int8_t
|
union geoip_country_group *mem)
|
||||||
parse_geoip_cc(const char *ccstr, u_int16_t *cc, union geoip_country_group *mem)
|
|
||||||
{
|
{
|
||||||
char *buffer, *cp, *next;
|
char *buffer, *cp, *next;
|
||||||
u_int8_t i, count = 0;
|
u_int8_t i, count = 0;
|
||||||
@@ -192,7 +190,7 @@ parse_geoip_cc(const char *ccstr, u_int16_t *cc, union geoip_country_group *mem)
|
|||||||
if (next) *next++ = '\0';
|
if (next) *next++ = '\0';
|
||||||
|
|
||||||
if ((cctmp = check_geoip_cc(cp, cc, count)) != 0) {
|
if ((cctmp = check_geoip_cc(cp, cc, count)) != 0) {
|
||||||
if ((mem[count++].user = load_geoip_cc(cctmp)) == NULL)
|
if ((mem[count++].user = (unsigned long)geoip_load_cc(cctmp)) == 0)
|
||||||
exit_error(OTHER_PROBLEM,
|
exit_error(OTHER_PROBLEM,
|
||||||
"geoip: insufficient memory available");
|
"geoip: insufficient memory available");
|
||||||
cc[count-1] = cctmp;
|
cc[count-1] = cctmp;
|
||||||
|
@@ -59,7 +59,8 @@ geoip_add_node(const struct geoip_country_user __user *umem_ptr)
|
|||||||
s = vmalloc(p->count * sizeof(struct geoip_subnet));
|
s = vmalloc(p->count * sizeof(struct geoip_subnet));
|
||||||
if (s == NULL)
|
if (s == NULL)
|
||||||
goto free_p;
|
goto free_p;
|
||||||
if (copy_from_user(s, umem.subnets, p->count * sizeof(struct geoip_subnet)) != 0)
|
if (copy_from_user(s, (const void __user *)(unsigned long)umem.subnets,
|
||||||
|
p->count * sizeof(struct geoip_subnet)) != 0)
|
||||||
goto free_s;
|
goto free_s;
|
||||||
|
|
||||||
spin_lock_bh(&geoip_lock);
|
spin_lock_bh(&geoip_lock);
|
||||||
@@ -189,7 +190,7 @@ static bool xt_geoip_mt_checkentry(const char *table, const void *entry,
|
|||||||
for (i = 0; i < info->count; i++) {
|
for (i = 0; i < info->count; i++) {
|
||||||
node = find_node(info->cc[i]);
|
node = find_node(info->cc[i]);
|
||||||
if (node == NULL)
|
if (node == NULL)
|
||||||
if ((node = geoip_add_node(info->mem[i].user)) == NULL) {
|
if ((node = geoip_add_node((const void __user *)(unsigned long)info->mem[i].user)) == NULL) {
|
||||||
printk(KERN_ERR
|
printk(KERN_ERR
|
||||||
"xt_geoip: unable to load '%c%c' into memory\n",
|
"xt_geoip: unable to load '%c%c' into memory\n",
|
||||||
COUNTRY(info->cc[i]));
|
COUNTRY(info->cc[i]));
|
||||||
|
@@ -25,7 +25,7 @@ struct geoip_subnet {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct geoip_country_user {
|
struct geoip_country_user {
|
||||||
struct geoip_subnet *subnets;
|
aligned_u64 subnets;
|
||||||
u_int32_t count;
|
u_int32_t count;
|
||||||
u_int16_t cc;
|
u_int16_t cc;
|
||||||
};
|
};
|
||||||
@@ -33,7 +33,7 @@ struct geoip_country_user {
|
|||||||
struct geoip_country_kernel;
|
struct geoip_country_kernel;
|
||||||
|
|
||||||
union geoip_country_group {
|
union geoip_country_group {
|
||||||
struct geoip_country_user *user;
|
aligned_u64 user;
|
||||||
struct geoip_country_kernel *kernel;
|
struct geoip_country_kernel *kernel;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user