Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
L
lxc
Project
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Chen Yisong
lxc
Commits
3b5796aa
Unverified
Commit
3b5796aa
authored
Jul 05, 2020
by
Christian Brauner
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
cgroups: fix bpf device program generation
Closes: #3473. Signed-off-by:
Christian Brauner
<
christian.brauner@ubuntu.com
>
parent
f19295e8
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
44 additions
and
40 deletions
+44
-40
cgfsng.c
src/lxc/cgroups/cgfsng.c
+7
-11
cgroup2_devices.c
src/lxc/cgroups/cgroup2_devices.c
+37
-29
No files found.
src/lxc/cgroups/cgfsng.c
View file @
3b5796aa
...
@@ -2936,17 +2936,13 @@ __cgfsng_ops static bool cgfsng_setup_limits(struct cgroup_ops *ops,
...
@@ -2936,17 +2936,13 @@ __cgfsng_ops static bool cgfsng_setup_limits(struct cgroup_ops *ops,
struct
lxc_cgroup
*
cg
=
iterator
->
elem
;
struct
lxc_cgroup
*
cg
=
iterator
->
elem
;
int
ret
;
int
ret
;
if
(
strncmp
(
"devices"
,
cg
->
subsystem
,
7
)
==
0
)
{
if
(
strncmp
(
"devices"
,
cg
->
subsystem
,
7
)
==
0
)
ret
=
bpf_device_cgroup_prepare
(
ops
,
conf
,
cg
->
subsystem
,
ret
=
bpf_device_cgroup_prepare
(
ops
,
conf
,
cg
->
subsystem
,
cg
->
value
);
cg
->
value
);
else
}
else
{
ret
=
lxc_write_openat
(
h
->
container_limit_path
,
cg
->
subsystem
,
cg
->
value
,
strlen
(
cg
->
value
));
ret
=
lxc_write_openat
(
h
->
container_limit_path
,
if
(
ret
<
0
)
cg
->
subsystem
,
cg
->
value
,
return
log_error_errno
(
false
,
errno
,
"Failed to set
\"
%s
\"
to
\"
%s
\"
"
,
cg
->
subsystem
,
cg
->
value
);
strlen
(
cg
->
value
));
if
(
ret
<
0
)
return
log_error_errno
(
false
,
errno
,
"Failed to set
\"
%s
\"
to
\"
%s
\"
"
,
cg
->
subsystem
,
cg
->
value
);
}
TRACE
(
"Set
\"
%s
\"
to
\"
%s
\"
"
,
cg
->
subsystem
,
cg
->
value
);
TRACE
(
"Set
\"
%s
\"
to
\"
%s
\"
"
,
cg
->
subsystem
,
cg
->
value
);
}
}
...
...
src/lxc/cgroups/cgroup2_devices.c
View file @
3b5796aa
...
@@ -27,6 +27,18 @@
...
@@ -27,6 +27,18 @@
lxc_log_define
(
cgroup2_devices
,
cgroup
);
lxc_log_define
(
cgroup2_devices
,
cgroup
);
#ifndef BPF_LOG_LEVEL1
#define BPF_LOG_LEVEL1 1
#endif
#ifndef BPF_LOG_LEVEL2
#define BPF_LOG_LEVEL2 2
#endif
#ifndef BPF_LOG_LEVEL
#define BPF_LOG_LEVEL (BPF_LOG_LEVEL1 | BPF_LOG_LEVEL2)
#endif
static
int
bpf_program_add_instructions
(
struct
bpf_program
*
prog
,
static
int
bpf_program_add_instructions
(
struct
bpf_program
*
prog
,
const
struct
bpf_insn
*
instructions
,
const
struct
bpf_insn
*
instructions
,
size_t
count
)
size_t
count
)
...
@@ -118,10 +130,8 @@ void bpf_program_free(struct bpf_program *prog)
...
@@ -118,10 +130,8 @@ void bpf_program_free(struct bpf_program *prog)
.off = 0, \
.off = 0, \
.imm = 0})
.imm = 0})
static
int
bpf_access_mask
(
const
char
*
acc
,
int
*
mask
)
static
int
bpf_access_mask
(
const
char
*
acc
,
__u32
*
mask
)
{
{
*
mask
=
0
;
if
(
!
acc
)
if
(
!
acc
)
return
0
;
return
0
;
...
@@ -136,8 +146,6 @@ static int bpf_access_mask(const char *acc, int *mask)
...
@@ -136,8 +146,6 @@ static int bpf_access_mask(const char *acc, int *mask)
case
'm'
:
case
'm'
:
*
mask
|=
BPF_DEVCG_ACC_MKNOD
;
*
mask
|=
BPF_DEVCG_ACC_MKNOD
;
break
;
break
;
case
'\0'
:
continue
;
default:
default:
return
-
EINVAL
;
return
-
EINVAL
;
}
}
...
@@ -160,10 +168,9 @@ static int bpf_device_type(char type)
...
@@ -160,10 +168,9 @@ static int bpf_device_type(char type)
return
-
1
;
return
-
1
;
}
}
static
inline
bool
bpf_device_all_access
(
int
access_mask
)
static
inline
bool
bpf_device_all_access
(
__u32
access_mask
)
{
{
return
(
access_mask
==
(
BPF_DEVCG_ACC_READ
|
BPF_DEVCG_ACC_WRITE
|
return
access_mask
==
(
BPF_DEVCG_ACC_READ
|
BPF_DEVCG_ACC_WRITE
|
BPF_DEVCG_ACC_MKNOD
);
BPF_DEVCG_ACC_MKNOD
));
}
}
struct
bpf_program
*
bpf_program_new
(
uint32_t
prog_type
)
struct
bpf_program
*
bpf_program_new
(
uint32_t
prog_type
)
...
@@ -211,7 +218,8 @@ int bpf_program_init(struct bpf_program *prog)
...
@@ -211,7 +218,8 @@ int bpf_program_init(struct bpf_program *prog)
int
bpf_program_append_device
(
struct
bpf_program
*
prog
,
struct
device_item
*
device
)
int
bpf_program_append_device
(
struct
bpf_program
*
prog
,
struct
device_item
*
device
)
{
{
int
jump_nr
=
1
;
int
jump_nr
=
1
;
int
access_mask
,
device_type
,
ret
;
__u32
access_mask
=
0
;
int
device_type
,
ret
;
struct
bpf_insn
bpf_access_decision
[
2
];
struct
bpf_insn
bpf_access_decision
[
2
];
if
(
!
prog
||
!
device
)
if
(
!
prog
||
!
device
)
...
@@ -223,6 +231,13 @@ int bpf_program_append_device(struct bpf_program *prog, struct device_item *devi
...
@@ -223,6 +231,13 @@ int bpf_program_append_device(struct bpf_program *prog, struct device_item *devi
return
0
;
return
0
;
}
}
ret
=
bpf_access_mask
(
device
->
access
,
&
access_mask
);
if
(
ret
<
0
)
return
log_error_errno
(
ret
,
-
ret
,
"Invalid access mask specified %s"
,
device
->
access
);
if
(
!
bpf_device_all_access
(
access_mask
))
jump_nr
++
;
device_type
=
bpf_device_type
(
device
->
type
);
device_type
=
bpf_device_type
(
device
->
type
);
if
(
device_type
<
0
)
if
(
device_type
<
0
)
return
log_error_errno
(
-
1
,
EINVAL
,
"Invalid bpf cgroup device type %c"
,
device
->
type
);
return
log_error_errno
(
-
1
,
EINVAL
,
"Invalid bpf cgroup device type %c"
,
device
->
type
);
...
@@ -230,22 +245,17 @@ int bpf_program_append_device(struct bpf_program *prog, struct device_item *devi
...
@@ -230,22 +245,17 @@ int bpf_program_append_device(struct bpf_program *prog, struct device_item *devi
if
(
device_type
>
0
)
if
(
device_type
>
0
)
jump_nr
++
;
jump_nr
++
;
ret
=
bpf_access_mask
(
device
->
access
,
&
access_mask
);
if
(
ret
<
0
)
return
log_error_errno
(
ret
,
-
ret
,
"Invalid access mask specified %s"
,
device
->
access
);
if
(
!
bpf_device_all_access
(
access_mask
))
jump_nr
+=
3
;
if
(
device
->
major
!=
-
1
)
if
(
device
->
major
!=
-
1
)
jump_nr
++
;
jump_nr
++
;
if
(
device
->
minor
!=
-
1
)
if
(
device
->
minor
!=
-
1
)
jump_nr
++
;
jump_nr
++
;
if
(
device_type
>
0
)
{
if
(
!
bpf_device_all_access
(
access_mask
)
)
{
struct
bpf_insn
ins
[]
=
{
struct
bpf_insn
ins
[]
=
{
BPF_JMP_IMM
(
BPF_JNE
,
BPF_REG_2
,
device_type
,
jump_nr
--
),
BPF_MOV32_REG
(
BPF_REG_1
,
BPF_REG_3
),
BPF_ALU32_IMM
(
BPF_AND
,
BPF_REG_1
,
access_mask
),
BPF_JMP_REG
(
BPF_JNE
,
BPF_REG_1
,
BPF_REG_3
,
jump_nr
--
),
};
};
ret
=
bpf_program_add_instructions
(
prog
,
ins
,
ARRAY_SIZE
(
ins
));
ret
=
bpf_program_add_instructions
(
prog
,
ins
,
ARRAY_SIZE
(
ins
));
...
@@ -253,14 +263,11 @@ int bpf_program_append_device(struct bpf_program *prog, struct device_item *devi
...
@@ -253,14 +263,11 @@ int bpf_program_append_device(struct bpf_program *prog, struct device_item *devi
return
log_error_errno
(
-
1
,
errno
,
"Failed to add instructions to bpf cgroup program"
);
return
log_error_errno
(
-
1
,
errno
,
"Failed to add instructions to bpf cgroup program"
);
}
}
if
(
!
bpf_device_all_access
(
access_mask
)
)
{
if
(
device_type
>
0
)
{
struct
bpf_insn
ins
[]
=
{
struct
bpf_insn
ins
[]
=
{
BPF_MOV32_REG
(
BPF_REG_1
,
BPF_REG_3
),
BPF_JMP_IMM
(
BPF_JNE
,
BPF_REG_2
,
device_type
,
jump_nr
--
),
BPF_ALU32_IMM
(
BPF_AND
,
BPF_REG_1
,
access_mask
),
BPF_JMP_REG
(
BPF_JNE
,
BPF_REG_1
,
BPF_REG_3
,
jump_nr
),
};
};
jump_nr
-=
3
;
ret
=
bpf_program_add_instructions
(
prog
,
ins
,
ARRAY_SIZE
(
ins
));
ret
=
bpf_program_add_instructions
(
prog
,
ins
,
ARRAY_SIZE
(
ins
));
if
(
ret
)
if
(
ret
)
return
log_error_errno
(
-
1
,
errno
,
"Failed to add instructions to bpf cgroup program"
);
return
log_error_errno
(
-
1
,
errno
,
"Failed to add instructions to bpf cgroup program"
);
...
@@ -289,7 +296,7 @@ int bpf_program_append_device(struct bpf_program *prog, struct device_item *devi
...
@@ -289,7 +296,7 @@ int bpf_program_append_device(struct bpf_program *prog, struct device_item *devi
bpf_access_decision
[
0
]
=
BPF_MOV64_IMM
(
BPF_REG_0
,
device
->
allow
);
bpf_access_decision
[
0
]
=
BPF_MOV64_IMM
(
BPF_REG_0
,
device
->
allow
);
bpf_access_decision
[
1
]
=
BPF_EXIT_INSN
();
bpf_access_decision
[
1
]
=
BPF_EXIT_INSN
();
ret
=
bpf_program_add_instructions
(
prog
,
bpf_access_decision
,
ret
=
bpf_program_add_instructions
(
prog
,
bpf_access_decision
,
ARRAY_SIZE
(
bpf_access_decision
));
ARRAY_SIZE
(
bpf_access_decision
));
if
(
ret
)
if
(
ret
)
return
log_error_errno
(
-
1
,
errno
,
"Failed to add instructions to bpf cgroup program"
);
return
log_error_errno
(
-
1
,
errno
,
"Failed to add instructions to bpf cgroup program"
);
...
@@ -314,7 +321,7 @@ int bpf_program_finalize(struct bpf_program *prog)
...
@@ -314,7 +321,7 @@ int bpf_program_finalize(struct bpf_program *prog)
}
}
static
int
bpf_program_load_kernel
(
struct
bpf_program
*
prog
,
char
*
log_buf
,
static
int
bpf_program_load_kernel
(
struct
bpf_program
*
prog
,
char
*
log_buf
,
size_t
log_size
)
__u32
log_size
,
__u32
log_level
)
{
{
union
bpf_attr
attr
;
union
bpf_attr
attr
;
...
@@ -329,14 +336,15 @@ static int bpf_program_load_kernel(struct bpf_program *prog, char *log_buf,
...
@@ -329,14 +336,15 @@ static int bpf_program_load_kernel(struct bpf_program *prog, char *log_buf,
.
insn_cnt
=
prog
->
n_instructions
,
.
insn_cnt
=
prog
->
n_instructions
,
.
license
=
PTR_TO_UINT64
(
"GPL"
),
.
license
=
PTR_TO_UINT64
(
"GPL"
),
.
log_buf
=
PTR_TO_UINT64
(
log_buf
),
.
log_buf
=
PTR_TO_UINT64
(
log_buf
),
.
log_level
=
!!
log_buf
,
.
log_level
=
log_level
,
.
log_size
=
log_size
,
.
log_size
=
log_size
,
};
};
prog
->
kernel_fd
=
bpf
(
BPF_PROG_LOAD
,
&
attr
,
sizeof
(
attr
));
prog
->
kernel_fd
=
bpf
(
BPF_PROG_LOAD
,
&
attr
,
sizeof
(
attr
));
if
(
prog
->
kernel_fd
<
0
)
if
(
prog
->
kernel_fd
<
0
)
return
log_error_errno
(
-
1
,
errno
,
"Failed to load bpf program
"
);
return
log_error_errno
(
-
1
,
errno
,
"Failed to load bpf program
: %s"
,
log_buf
);
TRACE
(
"Loaded bpf program: %s"
,
log_buf
);
return
0
;
return
0
;
}
}
...
@@ -365,7 +373,7 @@ int bpf_program_cgroup_attach(struct bpf_program *prog, int type,
...
@@ -365,7 +373,7 @@ int bpf_program_cgroup_attach(struct bpf_program *prog, int type,
return
true
;
return
true
;
}
}
ret
=
bpf_program_load_kernel
(
prog
,
NULL
,
0
);
ret
=
bpf_program_load_kernel
(
prog
,
NULL
,
0
,
0
);
if
(
ret
<
0
)
if
(
ret
<
0
)
return
log_error_errno
(
-
1
,
ret
,
"Failed to load bpf program"
);
return
log_error_errno
(
-
1
,
ret
,
"Failed to load bpf program"
);
...
@@ -527,7 +535,7 @@ bool bpf_devices_cgroup_supported(void)
...
@@ -527,7 +535,7 @@ bool bpf_devices_cgroup_supported(void)
if
(
ret
<
0
)
if
(
ret
<
0
)
return
log_trace
(
false
,
"Failed to add new instructions to bpf device cgroup program"
);
return
log_trace
(
false
,
"Failed to add new instructions to bpf device cgroup program"
);
ret
=
bpf_program_load_kernel
(
prog
,
NULL
,
0
);
ret
=
bpf_program_load_kernel
(
prog
,
NULL
,
0
,
0
);
if
(
ret
<
0
)
if
(
ret
<
0
)
return
log_trace
(
false
,
"Failed to load new bpf device cgroup program"
);
return
log_trace
(
false
,
"Failed to load new bpf device cgroup program"
);
...
...
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