[PATCH] Add client_body_temp_access configuration directive
Paul
paul at mrarm.io
Mon Oct 15 18:14:56 UTC 2018
Hello and thank you for the code review,
On 2018-10-15 16:27, Maxim Dounin wrote:
> Hello!
>
> On Fri, Oct 12, 2018 at 09:54:04PM +0200, Paul Pawlowski via
> nginx-devel wrote:
>
>> # HG changeset patch
>> # User Paul Pawlowski <paul at mrarm.io>
>> # Date 1539371172 -7200
>> # Fri Oct 12 21:06:12 2018 +0200
>> # Node ID 67cc676dbfaf56332bb6c61e635c0073c1e49907
>> # Parent 8b68d50090e4f134a35da60146fefd5e63770759
>> Add client_body_temp_access configuration directive
>
> Style: there should be a trailing dot and a reference to ticket
> you've created, and please use past tense. Also, I think that
> "client_body_access" might be a better name:
>
> Added client_body_access directive (ticket #1653).
>
>> Adds client_body_temp_access configuration directive, which sets the
>> unix permissions of the temporary files holding client request bodies.
>>
>> This makes it possible for a process running as another user to access
>> the files stored using client_body_temp_path and
>> client_body_in_file_only.
>> This is useful when using the mentioned directives in order to have
>> nginx store the request body to file and forward the file path to
>> another server running on the same machine as another user.
>
> Style: please wrap lines at 80 characters or less.
>
I've addressed the style concerns, as well as changed the name to the
suggested one.
>>
>> diff -r 8b68d50090e4 -r 67cc676dbfaf contrib/vim/syntax/nginx.vim
>> --- a/contrib/vim/syntax/nginx.vim Wed Oct 03 14:08:51 2018 +0300
>> +++ b/contrib/vim/syntax/nginx.vim Fri Oct 12 21:06:12 2018 +0200
>> @@ -155,6 +155,7 @@
>> syn keyword ngxDirective contained chunked_transfer_encoding
>> syn keyword ngxDirective contained client_body_buffer_size
>> syn keyword ngxDirective contained client_body_in_file_only
>> +syn keyword ngxDirective contained client_body_temp_access
>> syn keyword ngxDirective contained client_body_in_single_buffer
>> syn keyword ngxDirective contained client_body_temp_path
>> syn keyword ngxDirective contained client_body_timeout
>
> This list is expected to be sorted alphabetically.
>
>> diff -r 8b68d50090e4 -r 67cc676dbfaf src/http/ngx_http_core_module.c
>> --- a/src/http/ngx_http_core_module.c Wed Oct 03 14:08:51 2018 +0300
>> +++ b/src/http/ngx_http_core_module.c Fri Oct 12 21:06:12 2018 +0200
>> @@ -370,6 +370,13 @@
>> offsetof(ngx_http_core_loc_conf_t, client_body_temp_path),
>> NULL },
>>
>> + { ngx_string("client_body_temp_access"),
>> +
>> NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE123,
>> + ngx_conf_set_access_slot,
>> + NGX_HTTP_LOC_CONF_OFFSET,
>> + offsetof(ngx_http_core_loc_conf_t, client_body_temp_access),
>> + NULL },
>> +
>> { ngx_string("client_body_in_file_only"),
>>
>> NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
>> ngx_conf_set_enum_slot,
>> @@ -3373,6 +3380,7 @@
>> clcf->if_modified_since = NGX_CONF_UNSET_UINT;
>> clcf->max_ranges = NGX_CONF_UNSET_UINT;
>> clcf->client_body_in_file_only = NGX_CONF_UNSET_UINT;
>> + clcf->client_body_temp_access = NGX_CONF_UNSET_UINT;
>> clcf->client_body_in_single_buffer = NGX_CONF_UNSET;
>> clcf->internal = NGX_CONF_UNSET;
>> clcf->sendfile = NGX_CONF_UNSET;
>> @@ -3594,6 +3602,8 @@
>> ngx_conf_merge_uint_value(conf->client_body_in_file_only,
>> prev->client_body_in_file_only,
>> NGX_HTTP_REQUEST_BODY_FILE_OFF);
>> + ngx_conf_merge_uint_value(conf->client_body_temp_access,
>> + prev->client_body_temp_access, 0);
>
> Explicitly using 0600 as the default should be a better option.
I have changed the default value to 0600.
>
>> ngx_conf_merge_value(conf->client_body_in_single_buffer,
>> prev->client_body_in_single_buffer, 0);
>> ngx_conf_merge_value(conf->internal, prev->internal, 0);
>> diff -r 8b68d50090e4 -r 67cc676dbfaf src/http/ngx_http_core_module.h
>> --- a/src/http/ngx_http_core_module.h Wed Oct 03 14:08:51 2018 +0300
>> +++ b/src/http/ngx_http_core_module.h Fri Oct 12 21:06:12 2018 +0200
>> @@ -375,6 +375,7 @@
>> ngx_uint_t if_modified_since; /* if_modified_since */
>> ngx_uint_t max_ranges; /* max_ranges */
>> ngx_uint_t client_body_in_file_only; /*
>> client_body_in_file_only */
>> + ngx_uint_t client_body_temp_access; /* client_body_temp_access
>> */
>>
>> ngx_flag_t client_body_in_single_buffer;
>> /*
>> client_body_in_singe_buffer */
>> diff -r 8b68d50090e4 -r 67cc676dbfaf src/http/ngx_http_request_body.c
>> --- a/src/http/ngx_http_request_body.c Wed Oct 03 14:08:51 2018 +0300
>> +++ b/src/http/ngx_http_request_body.c Fri Oct 12 21:06:12 2018 +0200
>> @@ -450,6 +450,7 @@
>> tf->file.fd = NGX_INVALID_FILE;
>> tf->file.log = r->connection->log;
>> tf->path = clcf->client_body_temp_path;
>> + tf->access = clcf->client_body_temp_access;
>> tf->pool = r->pool;
>> tf->warn = "a client request body is buffered to a temporary
>> file";
>> tf->log_level = r->request_body_file_log_level;
>
> The following block:
>
> if (r->request_body_file_group_access) {
> tf->access = 0660;
> }
>
> raises the question on how it is expected to interact with
> r->request_body_file_group_access. I suspect that
> r->request_body_file_group_access is not currently needed and can
> be removed altogether, but this needs an additional investigation.
I've checked where is it used - the only place is the
ngx_http_dav_module, where it is used in order to set the permissions
for the temporary uploaded file in the PUT handler - however, as the
file is later moved for storage using ngx_ext_rename_file function (in
ngx_http_dav_put_handler) with permissions taken from the configuration
file (with a default value of 0600) I do not believe that the temporary
file permission matter at that stage.
The usage by third party modules also seem limited:
I've tried to do a GitHub search for it:
https://github.com/search?q=request_body_file_group_access+-filename%3Angx_http_request_body.c+-filename%3Angx_http_request.h+-filename%3Angx_http_dav_module.c&type=Code
which results in 1,123 code results. However most of these are simply
slightly altered versions of ngx_http_request_body.c, and if we exclude
the top three results we end up with 264 results:
https://github.com/search?q=request_body_file_group_access+-filename%3Angx_http_request_body.c+-filename%3Angx_http_request.h+-filename%3Angx_http_dav_module.c+-filename%3Angx_http_lua_req_body.c+-filename%3Angx_http_waf_filter_module.c+-filename%3Angx_http_spdy.c&type=Code
with most of them still largely being nginx codebase - however a few
usages can still be found including:
-
https://github.com/oscar810429/graphicsmagick_nginx_module/blob/6f171579ba7638f62f885d3d8e0687d7977f2f33/ngx_http_graphicsmagick_module.c
[I don't believe it is needed here - the file is not forwarded to other
users I believe after taking a quick look at the code]
-
https://github.com/heapsource/BlackLinks/blob/8173ba44270d65cbe50aa2865eab91af3d44f3d4/nginx-hello/ngx_http_hello_world_module.c
-
https://github.com/alacner/nginx_lua_module/blob/e194c26f96e50504540fd5830283e1c01670d170/src/ngx_http_lua_module.c
-
https://github.com/AntonRiab/ngx_pgcopy/blob/ca32432024d0677754faddbe4d8b45c5d896c79b/ngx_http_pgcopy_module.c
Even though I believe they should be replaceable, is this something
I should look into more?
I'm making the deletion of the request_body_file_group_access a separate
commit, as this touches code not directly related to the core added
functionality.
>
> Another question to consider is how this is expected to interact
> with directories created for various temp file levels. These
> directories, much like the client_body_temp_path diretory itself,
> are unconditionally created with 0700 access, and will prevent
> access to temporary files from non-nginx user as well. These can
> be pre-created with appropriate permissions - but as long as it is
> a recommended approach, this probably needs to be mentioned in the
> commit log.
This is an issue I have completely missed while writing this patch.
I have checked how do the other nginx module solve this particular
issue and figured out that probably the best option would be to use
the specified file permissions as the ones to use (using the
ngx_dir_access helper function), and this is what I've implemented.
I'm unfortunately unsure what is the proper way to E-Mail the patches in
a response mail so I'm simply attaching them to the E-Mail below
(there are two separate commits below):
# HG changeset patch
# User Paul Pawlowski <paul at mrarm.io>
# Date 1539621300 -7200
# Mon Oct 15 18:35:00 2018 +0200
# Node ID c94787463c982dab370b695e2f3ddcbc7655ead5
# Parent 8b68d50090e4f134a35da60146fefd5e63770759
Added client_body_access configuration directive (ticket #1651).
Added client_body_access configuration directive, which sets the unix
permissions of the temporary files and directories holding client
request
bodies.
This makes it possible for a process running as another user to access
the files stored using client_body_temp_path and
client_body_in_file_only.
This is useful when using the mentioned directives in order to have
nginx store
the request body to file and forward the file path to another server
running on
the same machine as another user.
diff -r 8b68d50090e4 -r c94787463c98 contrib/vim/syntax/nginx.vim
--- a/contrib/vim/syntax/nginx.vim Wed Oct 03 14:08:51 2018 +0300
+++ b/contrib/vim/syntax/nginx.vim Mon Oct 15 18:35:00 2018 +0200
@@ -153,6 +153,7 @@
syn keyword ngxDirective contained charset
syn keyword ngxDirective contained charset_types
syn keyword ngxDirective contained chunked_transfer_encoding
+syn keyword ngxDirective contained client_body_access
syn keyword ngxDirective contained client_body_buffer_size
syn keyword ngxDirective contained client_body_in_file_only
syn keyword ngxDirective contained client_body_in_single_buffer
diff -r 8b68d50090e4 -r c94787463c98 src/core/ngx_file.c
--- a/src/core/ngx_file.c Wed Oct 03 14:08:51 2018 +0300
+++ b/src/core/ngx_file.c Mon Oct 15 18:35:00 2018 +0200
@@ -146,10 +146,17 @@
uint32_t n;
ngx_err_t err;
ngx_str_t name;
+ ngx_uint_t path_access;
ngx_uint_t prefix;
ngx_pool_cleanup_t *cln;
ngx_pool_cleanup_file_t *clnf;
+ if (access != 0) {
+ path_access = ngx_dir_access(access);
+ } else {
+ path_access = 0700;
+ }
+
if (file->name.len) {
name = file->name;
levels = 0;
@@ -230,7 +237,7 @@
return NGX_ERROR;
}
- if (ngx_create_path(file, path) == NGX_ERROR) {
+ if (ngx_create_path(file, path, path_access) == NGX_ERROR) {
return NGX_ERROR;
}
}
@@ -263,7 +270,7 @@
ngx_int_t
-ngx_create_path(ngx_file_t *file, ngx_path_t *path)
+ngx_create_path(ngx_file_t *file, ngx_path_t *path, ngx_uint_t access)
{
size_t pos;
ngx_err_t err;
@@ -283,7 +290,7 @@
ngx_log_debug1(NGX_LOG_DEBUG_CORE, file->log, 0,
"temp file: \"%s\"", file->name.data);
- if (ngx_create_dir(file->name.data, 0700) == NGX_FILE_ERROR) {
+ if (ngx_create_dir(file->name.data, access) == NGX_FILE_ERROR)
{
err = ngx_errno;
if (err != NGX_EEXIST) {
ngx_log_error(NGX_LOG_CRIT, file->log, err,
diff -r 8b68d50090e4 -r c94787463c98 src/core/ngx_file.h
--- a/src/core/ngx_file.h Wed Oct 03 14:08:51 2018 +0300
+++ b/src/core/ngx_file.h Mon Oct 15 18:35:00 2018 +0200
@@ -140,7 +140,8 @@
ngx_pool_t *pool, ngx_uint_t persistent, ngx_uint_t clean,
ngx_uint_t access);
void ngx_create_hashed_filename(ngx_path_t *path, u_char *file, size_t
len);
-ngx_int_t ngx_create_path(ngx_file_t *file, ngx_path_t *path);
+ngx_int_t ngx_create_path(ngx_file_t *file, ngx_path_t *path,
+ ngx_uint_t access);
ngx_err_t ngx_create_full_path(u_char *dir, ngx_uint_t access);
ngx_int_t ngx_add_path(ngx_conf_t *cf, ngx_path_t **slot);
ngx_int_t ngx_create_paths(ngx_cycle_t *cycle, ngx_uid_t user);
diff -r 8b68d50090e4 -r c94787463c98 src/http/ngx_http_core_module.c
--- a/src/http/ngx_http_core_module.c Wed Oct 03 14:08:51 2018 +0300
+++ b/src/http/ngx_http_core_module.c Mon Oct 15 18:35:00 2018 +0200
@@ -370,6 +370,13 @@
offsetof(ngx_http_core_loc_conf_t, client_body_temp_path),
NULL },
+ { ngx_string("client_body_access"),
+
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE123,
+ ngx_conf_set_access_slot,
+ NGX_HTTP_LOC_CONF_OFFSET,
+ offsetof(ngx_http_core_loc_conf_t, client_body_access),
+ NULL },
+
{ ngx_string("client_body_in_file_only"),
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
ngx_conf_set_enum_slot,
@@ -3373,6 +3380,7 @@
clcf->if_modified_since = NGX_CONF_UNSET_UINT;
clcf->max_ranges = NGX_CONF_UNSET_UINT;
clcf->client_body_in_file_only = NGX_CONF_UNSET_UINT;
+ clcf->client_body_access = NGX_CONF_UNSET_UINT;
clcf->client_body_in_single_buffer = NGX_CONF_UNSET;
clcf->internal = NGX_CONF_UNSET;
clcf->sendfile = NGX_CONF_UNSET;
@@ -3594,6 +3602,8 @@
ngx_conf_merge_uint_value(conf->client_body_in_file_only,
prev->client_body_in_file_only,
NGX_HTTP_REQUEST_BODY_FILE_OFF);
+ ngx_conf_merge_uint_value(conf->client_body_access,
+ prev->client_body_access, 0600);
ngx_conf_merge_value(conf->client_body_in_single_buffer,
prev->client_body_in_single_buffer, 0);
ngx_conf_merge_value(conf->internal, prev->internal, 0);
diff -r 8b68d50090e4 -r c94787463c98 src/http/ngx_http_core_module.h
--- a/src/http/ngx_http_core_module.h Wed Oct 03 14:08:51 2018 +0300
+++ b/src/http/ngx_http_core_module.h Mon Oct 15 18:35:00 2018 +0200
@@ -375,6 +375,7 @@
ngx_uint_t if_modified_since; /* if_modified_since */
ngx_uint_t max_ranges; /* max_ranges */
ngx_uint_t client_body_in_file_only; /* client_body_in_file_only
*/
+ ngx_uint_t client_body_access; /* client_body_access */
ngx_flag_t client_body_in_single_buffer;
/*
client_body_in_singe_buffer */
diff -r 8b68d50090e4 -r c94787463c98 src/http/ngx_http_request_body.c
--- a/src/http/ngx_http_request_body.c Wed Oct 03 14:08:51 2018 +0300
+++ b/src/http/ngx_http_request_body.c Mon Oct 15 18:35:00 2018 +0200
@@ -450,6 +450,7 @@
tf->file.fd = NGX_INVALID_FILE;
tf->file.log = r->connection->log;
tf->path = clcf->client_body_temp_path;
+ tf->access = clcf->client_body_access;
tf->pool = r->pool;
tf->warn = "a client request body is buffered to a temporary
file";
tf->log_level = r->request_body_file_log_level;
# HG changeset patch
# User Paul Pawlowski <paul at mrarm.io>
# Date 1539623192 -7200
# Mon Oct 15 19:06:32 2018 +0200
# Node ID e6f5c3e20646abe8708db185e5acdd861c13ce35
# Parent c94787463c982dab370b695e2f3ddcbc7655ead5
Removed request_body_file_group_access from ngx_http_request_s.
request_body_file_group_access's only usage is in the
ngx_http_dav_module.
However the temporary file created by that module after a successful
upload is
moved into another directory, and the file permissions are changed to
user
specified ones. Therefore, it doesn't matter what the initial file
permissions
were and the code can be simplified.
diff -r c94787463c98 -r e6f5c3e20646
src/http/modules/ngx_http_dav_module.c
--- a/src/http/modules/ngx_http_dav_module.c Mon Oct 15 18:35:00 2018
+0200
+++ b/src/http/modules/ngx_http_dav_module.c Mon Oct 15 19:06:32 2018
+0200
@@ -170,7 +170,6 @@
r->request_body_in_file_only = 1;
r->request_body_in_persistent_file = 1;
r->request_body_in_clean_file = 1;
- r->request_body_file_group_access = 1;
r->request_body_file_log_level = 0;
rc = ngx_http_read_client_request_body(r,
ngx_http_dav_put_handler);
diff -r c94787463c98 -r e6f5c3e20646 src/http/ngx_http_request.h
--- a/src/http/ngx_http_request.h Mon Oct 15 18:35:00 2018 +0200
+++ b/src/http/ngx_http_request.h Mon Oct 15 19:06:32 2018 +0200
@@ -482,7 +482,6 @@
unsigned request_body_in_file_only:1;
unsigned
request_body_in_persistent_file:1;
unsigned request_body_in_clean_file:1;
- unsigned request_body_file_group_access:1;
unsigned request_body_file_log_level:3;
unsigned request_body_no_buffering:1;
diff -r c94787463c98 -r e6f5c3e20646 src/http/ngx_http_request_body.c
--- a/src/http/ngx_http_request_body.c Mon Oct 15 18:35:00 2018 +0200
+++ b/src/http/ngx_http_request_body.c Mon Oct 15 19:06:32 2018 +0200
@@ -457,10 +457,6 @@
tf->persistent = r->request_body_in_persistent_file;
tf->clean = r->request_body_in_clean_file;
- if (r->request_body_file_group_access) {
- tf->access = 0660;
- }
-
rb->temp_file = tf;
if (rb->bufs == NULL) {
More information about the nginx-devel
mailing list