Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
libloc
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
nexedi
libloc
Commits
866ae435
Commit
866ae435
authored
Aug 23, 2022
by
Michael Tremer
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
database: Read header from mapped data
Signed-off-by:
Michael Tremer
<
michael.tremer@ipfire.org
>
parent
3496a16c
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
75 additions
and
119 deletions
+75
-119
src/database.c
src/database.c
+74
-119
src/libloc/format.h
src/libloc/format.h
+1
-0
No files found.
src/database.c
View file @
866ae435
...
@@ -51,12 +51,17 @@
...
@@ -51,12 +51,17 @@
#include <libloc/stringpool.h>
#include <libloc/stringpool.h>
struct
loc_database_objects
{
struct
loc_database_objects
{
void
*
p
;
char
*
data
;
off_t
offset
;
off_t
offset
;
size_t
length
;
size_t
length
;
size_t
count
;
size_t
count
;
};
};
struct
loc_database_signature
{
const
char
*
data
;
size_t
length
;
};
struct
loc_database
{
struct
loc_database
{
struct
loc_ctx
*
ctx
;
struct
loc_ctx
*
ctx
;
int
refcount
;
int
refcount
;
...
@@ -70,10 +75,8 @@ struct loc_database {
...
@@ -70,10 +75,8 @@ struct loc_database {
off_t
license
;
off_t
license
;
// Signatures
// Signatures
char
*
signature1
;
struct
loc_database_signature
signature1
;
size_t
signature1_length
;
struct
loc_database_signature
signature2
;
char
*
signature2
;
size_t
signature2_length
;
// Data mapped into memory
// Data mapped into memory
char
*
data
;
char
*
data
;
...
@@ -151,8 +154,8 @@ static void* __loc_database_read_object(struct loc_database* db, void* buffer,
...
@@ -151,8 +154,8 @@ static void* __loc_database_read_object(struct loc_database* db, void* buffer,
const
off_t
offset
=
pos
*
length
;
const
off_t
offset
=
pos
*
length
;
// Map the object first if possible
// Map the object first if possible
if
(
objects
->
p
)
if
(
objects
->
data
)
return
(
uint8_t
*
)
objects
->
p
+
offset
;
return
objects
->
data
+
offset
;
// Otherwise fall back and read the object into the buffer
// Otherwise fall back and read the object into the buffer
const
int
fd
=
fileno
(
db
->
f
);
const
int
fd
=
fileno
(
db
->
f
);
...
@@ -252,153 +255,123 @@ static int loc_database_mmap(struct loc_database* db) {
...
@@ -252,153 +255,123 @@ static int loc_database_mmap(struct loc_database* db) {
static
int
loc_database_map_objects
(
struct
loc_database
*
db
,
static
int
loc_database_map_objects
(
struct
loc_database
*
db
,
struct
loc_database_objects
*
objects
,
const
size_t
size
,
struct
loc_database_objects
*
objects
,
const
size_t
size
,
off_t
offset
,
size_t
length
)
{
off_t
offset
,
size_t
length
)
{
int
r
=
0
;
// Store parameters
// Store parameters
objects
->
data
=
db
->
data
+
offset
;
objects
->
offset
=
offset
;
objects
->
offset
=
offset
;
objects
->
length
=
length
;
objects
->
length
=
length
;
objects
->
count
=
objects
->
length
/
size
;
objects
->
count
=
objects
->
length
/
size
;
// End if there is nothing to map
return
0
;
if
(
!
objects
->
length
)
}
return
0
;
DEBUG
(
db
->
ctx
,
"Mapping %zu object(s) from %jd (%zu bytes)
\n
"
,
objects
->
count
,
(
intmax_t
)
objects
->
offset
,
objects
->
length
);
// mmap() objects into memory
void
*
p
=
mmap
(
NULL
,
objects
->
length
,
PROT_READ
,
MAP_PRIVATE
,
fileno
(
db
->
f
),
objects
->
offset
);
if
(
p
==
MAP_FAILED
)
{
// Ignore if the database wasn't page aligned for this architecture
// and fall back to use pread().
if
(
errno
==
EINVAL
)
{
DEBUG
(
db
->
ctx
,
"Falling back to pread()
\n
"
);
return
0
;
}
ERROR
(
db
->
ctx
,
"mmap() failed: %m
\n
"
);
static
int
loc_database_read_signature
(
struct
loc_database
*
db
,
struct
loc_database_signature
*
signature
,
const
char
*
data
,
const
size_t
length
)
{
// Check for a plausible signature length
if
(
length
>
LOC_SIGNATURE_MAX_LENGTH
)
{
ERROR
(
db
->
ctx
,
"Signature too long: %zu
\n
"
,
length
);
errno
=
EINVAL
;
return
1
;
return
1
;
}
}
// Store pointer
// Store data & length
objects
->
p
=
p
;
signature
->
data
=
data
;
signature
->
length
=
length
;
return
r
;
}
static
int
loc_database_unmap_objects
(
struct
loc_database
*
db
,
struct
loc_database_objects
*
objects
)
{
int
r
;
// Nothing to do if nothing was mapped
DEBUG
(
db
->
ctx
,
"Read signature of %zu byte(s) at %p
\n
"
,
if
(
!
objects
->
p
)
signature
->
length
,
signature
->
data
);
return
0
;
// Call munmap() to free everything
hexdump
(
db
->
ctx
,
signature
->
data
,
signature
->
length
);
r
=
munmap
(
objects
->
p
,
objects
->
length
);
if
(
r
)
{
ERROR
(
db
->
ctx
,
"Could not unmap objects: %m
\n
"
);
return
r
;
}
return
0
;
return
0
;
}
}
static
int
loc_database_read_signature
(
struct
loc_database
*
db
,
/*
char
**
dst
,
char
*
src
,
size_t
length
)
{
Checks if it is safe to read the buffer of size length starting at p.
// Check for a plausible signature length
*/
if
(
length
>
LOC_SIGNATURE_MAX_LENGTH
)
{
#define loc_database_check_boundaries(db, p) \
ERROR
(
db
->
ctx
,
"Signature too long: %zu
\n
"
,
length
);
__loc_database_check_boundaries(db, (const char*)p, sizeof(*p))
return
-
EINVAL
;
}
DEBUG
(
db
->
ctx
,
"Reading signature of %zu bytes
\n
"
,
length
);
// Allocate space
static
int
__loc_database_check_boundaries
(
struct
loc_database
*
db
,
*
dst
=
malloc
(
length
);
const
char
*
p
,
const
size_t
length
)
{
if
(
!*
dst
)
size_t
offset
=
p
-
db
->
data
;
return
-
ENOMEM
;
// Copy payload
// Return if everything is within the boundary
memcpy
(
*
dst
,
src
,
length
);
if
(
offset
<
db
->
length
-
length
)
return
1
;
// Otherwise raise EFAULT
errno
=
EFAULT
;
return
0
;
return
0
;
}
}
static
int
loc_database_read_header_v1
(
struct
loc_database
*
db
)
{
static
int
loc_database_read_header_v1
(
struct
loc_database
*
db
)
{
struct
loc_database_header_v1
header
;
const
struct
loc_database_header_v1
*
header
=
(
const
struct
loc_database_header_v1
*
)(
db
->
data
+
LOC_DATABASE_MAGIC_SIZE
);
int
r
;
int
r
;
// Read from file
DEBUG
(
db
->
ctx
,
"Reading header at %p
\n
"
,
header
);
size_t
size
=
pread
(
fileno
(
db
->
f
),
&
header
,
sizeof
(
header
),
sizeof
(
struct
loc_database_magic
));
if
(
size
<
sizeof
(
header
))
{
// Check if we can read the header
if
(
!
loc_database_check_boundaries
(
db
,
header
))
{
ERROR
(
db
->
ctx
,
"Could not read enough data for header
\n
"
);
ERROR
(
db
->
ctx
,
"Could not read enough data for header
\n
"
);
errno
=
ENOMSG
;
return
1
;
return
1
;
}
}
// Copy over data
// Dump the entire header
db
->
created_at
=
be64toh
(
header
.
created_at
);
hexdump
(
db
->
ctx
,
header
,
sizeof
(
*
header
));
db
->
vendor
=
be32toh
(
header
.
vendor
);
db
->
description
=
be32toh
(
header
.
description
);
db
->
license
=
be32toh
(
header
.
license
);
db
->
signature1_length
=
be16toh
(
header
.
signature1_length
);
// Copy over data
db
->
signature2_length
=
be16toh
(
header
.
signature2_length
);
db
->
created_at
=
be64toh
(
header
->
created_at
);
db
->
vendor
=
be32toh
(
header
->
vendor
);
db
->
description
=
be32toh
(
header
->
description
);
db
->
license
=
be32toh
(
header
->
license
);
// Read signatures
// Read signatures
if
(
db
->
signature1_length
)
{
r
=
loc_database_read_signature
(
db
,
&
db
->
signature1
,
r
=
loc_database_read_signature
(
db
,
&
db
->
signature1
,
header
->
signature1
,
be16toh
(
header
->
signature1_length
));
header
.
signature1
,
db
->
signature1_length
);
if
(
r
)
if
(
r
)
return
r
;
return
r
;
}
if
(
db
->
signature2_length
)
{
r
=
loc_database_read_signature
(
db
,
&
db
->
signature2
,
r
=
loc_database_read_signature
(
db
,
&
db
->
signature2
,
header
->
signature2
,
be16toh
(
header
->
signature2_length
));
header
.
signature2
,
db
->
signature2_length
);
if
(
r
)
if
(
r
)
return
r
;
return
r
;
}
// Open the stringpool
// Open the stringpool
r
=
loc_stringpool_open
(
db
->
ctx
,
&
db
->
pool
,
db
->
f
,
r
=
loc_stringpool_open
(
db
->
ctx
,
&
db
->
pool
,
db
->
f
,
be32toh
(
header
.
pool_length
),
be32toh
(
header
.
pool_offset
));
be32toh
(
header
->
pool_length
),
be32toh
(
header
->
pool_offset
));
if
(
r
)
if
(
r
)
return
r
;
return
r
;
// Map AS objects
// Map AS objects
r
=
loc_database_map_objects
(
db
,
&
db
->
as_objects
,
r
=
loc_database_map_objects
(
db
,
&
db
->
as_objects
,
sizeof
(
struct
loc_database_as_v1
),
sizeof
(
struct
loc_database_as_v1
),
be32toh
(
header
.
as_offset
),
be32toh
(
header
->
as_offset
),
be32toh
(
header
.
as_length
));
be32toh
(
header
->
as_length
));
if
(
r
)
if
(
r
)
return
r
;
return
r
;
// Map Network Nodes
// Map Network Nodes
r
=
loc_database_map_objects
(
db
,
&
db
->
network_node_objects
,
r
=
loc_database_map_objects
(
db
,
&
db
->
network_node_objects
,
sizeof
(
struct
loc_database_network_node_v1
),
sizeof
(
struct
loc_database_network_node_v1
),
be32toh
(
header
.
network_tree_offset
),
be32toh
(
header
->
network_tree_offset
),
be32toh
(
header
.
network_tree_length
));
be32toh
(
header
->
network_tree_length
));
if
(
r
)
if
(
r
)
return
r
;
return
r
;
// Map Networks
// Map Networks
r
=
loc_database_map_objects
(
db
,
&
db
->
network_objects
,
r
=
loc_database_map_objects
(
db
,
&
db
->
network_objects
,
sizeof
(
struct
loc_database_network_v1
),
sizeof
(
struct
loc_database_network_v1
),
be32toh
(
header
.
network_data_offset
),
be32toh
(
header
->
network_data_offset
),
be32toh
(
header
.
network_data_length
));
be32toh
(
header
->
network_data_length
));
if
(
r
)
if
(
r
)
return
r
;
return
r
;
// Map countries
// Map countries
r
=
loc_database_map_objects
(
db
,
&
db
->
country_objects
,
r
=
loc_database_map_objects
(
db
,
&
db
->
country_objects
,
sizeof
(
struct
loc_database_country_v1
),
sizeof
(
struct
loc_database_country_v1
),
be32toh
(
header
.
countries_offset
),
be32toh
(
header
->
countries_offset
),
be32toh
(
header
.
countries_length
));
be32toh
(
header
->
countries_length
));
if
(
r
)
if
(
r
)
return
r
;
return
r
;
...
@@ -487,28 +460,10 @@ static void loc_database_free(struct loc_database* db) {
...
@@ -487,28 +460,10 @@ static void loc_database_free(struct loc_database* db) {
ERROR
(
db
->
ctx
,
"Could not unmap the database: %m
\n
"
);
ERROR
(
db
->
ctx
,
"Could not unmap the database: %m
\n
"
);
}
}
// Removing all ASes
loc_database_unmap_objects
(
db
,
&
db
->
as_objects
);
// Remove mapped network sections
loc_database_unmap_objects
(
db
,
&
db
->
network_objects
);
// Remove mapped network nodes section
loc_database_unmap_objects
(
db
,
&
db
->
network_node_objects
);
// Remove mapped countries section
loc_database_unmap_objects
(
db
,
&
db
->
country_objects
);
// Free the stringpool
// Free the stringpool
if
(
db
->
pool
)
if
(
db
->
pool
)
loc_stringpool_unref
(
db
->
pool
);
loc_stringpool_unref
(
db
->
pool
);
// Free signature
if
(
db
->
signature1
)
free
(
db
->
signature1
);
if
(
db
->
signature2
)
free
(
db
->
signature2
);
// Close database file
// Close database file
if
(
db
->
f
)
if
(
db
->
f
)
fclose
(
db
->
f
);
fclose
(
db
->
f
);
...
@@ -571,7 +526,7 @@ LOC_EXPORT int loc_database_verify(struct loc_database* db, FILE* f) {
...
@@ -571,7 +526,7 @@ LOC_EXPORT int loc_database_verify(struct loc_database* db, FILE* f) {
size_t
bytes_read
=
0
;
size_t
bytes_read
=
0
;
// Cannot do this when no signature is available
// Cannot do this when no signature is available
if
(
!
db
->
signature1
&&
!
db
->
signature2
)
{
if
(
!
db
->
signature1
.
data
&&
!
db
->
signature2
.
data
)
{
DEBUG
(
db
->
ctx
,
"No signature available to verify
\n
"
);
DEBUG
(
db
->
ctx
,
"No signature available to verify
\n
"
);
return
1
;
return
1
;
}
}
...
@@ -681,11 +636,11 @@ LOC_EXPORT int loc_database_verify(struct loc_database* db, FILE* f) {
...
@@ -681,11 +636,11 @@ LOC_EXPORT int loc_database_verify(struct loc_database* db, FILE* f) {
}
}
// Check first signature
// Check first signature
if
(
db
->
signature1
)
{
if
(
db
->
signature1
.
data
)
{
hexdump
(
db
->
ctx
,
db
->
signature1
,
db
->
signature1_
length
);
hexdump
(
db
->
ctx
,
db
->
signature1
.
data
,
db
->
signature1
.
length
);
r
=
EVP_DigestVerifyFinal
(
mdctx
,
r
=
EVP_DigestVerifyFinal
(
mdctx
,
(
unsigned
char
*
)
db
->
signature1
,
db
->
signature1_
length
);
(
unsigned
char
*
)
db
->
signature1
.
data
,
db
->
signature1
.
length
);
if
(
r
==
0
)
{
if
(
r
==
0
)
{
DEBUG
(
db
->
ctx
,
"The first signature is invalid
\n
"
);
DEBUG
(
db
->
ctx
,
"The first signature is invalid
\n
"
);
...
@@ -701,11 +656,11 @@ LOC_EXPORT int loc_database_verify(struct loc_database* db, FILE* f) {
...
@@ -701,11 +656,11 @@ LOC_EXPORT int loc_database_verify(struct loc_database* db, FILE* f) {
}
}
// Check second signature only when the first one was invalid
// Check second signature only when the first one was invalid
if
(
r
&&
db
->
signature2
)
{
if
(
r
&&
db
->
signature2
.
data
)
{
hexdump
(
db
->
ctx
,
db
->
signature2
,
db
->
signature2_
length
);
hexdump
(
db
->
ctx
,
db
->
signature2
.
data
,
db
->
signature2
.
length
);
r
=
EVP_DigestVerifyFinal
(
mdctx
,
r
=
EVP_DigestVerifyFinal
(
mdctx
,
(
unsigned
char
*
)
db
->
signature2
,
db
->
signature2_
length
);
(
unsigned
char
*
)
db
->
signature2
.
data
,
db
->
signature2
.
length
);
if
(
r
==
0
)
{
if
(
r
==
0
)
{
DEBUG
(
db
->
ctx
,
"The second signature is invalid
\n
"
);
DEBUG
(
db
->
ctx
,
"The second signature is invalid
\n
"
);
...
...
src/libloc/format.h
View file @
866ae435
...
@@ -20,6 +20,7 @@
...
@@ -20,6 +20,7 @@
#include <stdint.h>
#include <stdint.h>
#define LOC_DATABASE_MAGIC "LOCDBXX"
#define LOC_DATABASE_MAGIC "LOCDBXX"
#define LOC_DATABASE_MAGIC_SIZE sizeof(struct loc_database_magic)
enum
loc_database_version
{
enum
loc_database_version
{
LOC_DATABASE_VERSION_UNSET
=
0
,
LOC_DATABASE_VERSION_UNSET
=
0
,
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment