{"schema":"libjg2-1",
"vpath":"/git/",
"avatar":"/git/avatar/",
"alang":"",
"gen_ut":1745906639,
"reponame":"cgit",
"desc":"CGI gitweb",
"owner": { "name": "Andy Green", "email": "andy@warmcat.com", "md5": "c50933ca2aa61e0fe2c43d46bb6b59cb" },"url":"https://warmcat.com/repo/cgit",
"f":3,
"items": [
{"schema":"libjg2-1",
"cid":"a0f6402bfa6dbd8851d48b339f6df1b1",
"commit": {"type":"commit",
"time": 1530115983,
"time_ofs": 120,
"oid_tree": { "oid": "fd4b868e415db4de0577495eabf48e6bf814d408", "alias": []},
"oid":{ "oid": "b31e99887b17f513289fb11227b2484504e85b6c", "alias": []},
"msg": "cache: close race window when unlocking slots",
"sig_commit": { "git_time": { "time": 1530115983, "offset": 120 }, "name": "Jason A. Donenfeld", "email": "Jason@zx2c4.com", "md5": "689e78dac56e3d77d7f74984912487d3" },
"sig_author": { "git_time": { "time": 1529472554, "offset": 120 }, "name": "John Keeping", "email": "john@keeping.me.uk", "md5": "aea7d8738c91da1cb0dfa9d86f2bbc47" }},
"body": "cache: close race window when unlocking slots\n\nWe use POSIX advisory record locks to control access to cache slots, but\nthese have an unhelpful behaviour in that they are released when any\nfile descriptor referencing the file is closed by this process.\n\nMostly this is okay, since we know we won't be opening the lock file\nanywhere else, but there is one place that it does matter: when we\nrestore stdout we dup2() over a file descriptor referring to the file,\nthus closing that descriptor.\n\nSince we restore stdout before unlocking the slot, this creates a window\nduring which the slot content can be overwritten. The fix is reasonably\nstraightforward: simply restore stdout after unlocking the slot, but the\ndiff is a bit bigger because this requires us to move the temporary\nstdout FD into struct cache_slot.\n\nSigned-off-by: John Keeping \u003cjohn@keeping.me.uk\u003e\nReviewed-by: Christian Hesse \u003cmail@eworm.de\u003e\n"
,
"diff": "diff --git a/cache.c b/cache.c\nindex 0901e6e..2c70be7 100644\n--- a/cache.c\n+++ b/cache.c\n@@ -29,6 +29,7 @@ struct cache_slot {\n \tcache_fill_fn fn;\n \tint cache_fd;\n \tint lock_fd;\n+\tint stdout_fd;\n \tconst char *cache_name;\n \tconst char *lock_name;\n \tint match;\n@@ -197,6 +198,13 @@ static int unlock_slot(struct cache_slot *slot, int replace_old_slot)\n \telse\n \t\terr \u003d unlink(slot-\u003elock_name);\n \n+\t/* Restore stdout and close the temporary FD. */\n+\tif (slot-\u003estdout_fd \u003e\u003d 0) {\n+\t\tdup2(slot-\u003estdout_fd, STDOUT_FILENO);\n+\t\tclose(slot-\u003estdout_fd);\n+\t\tslot-\u003estdout_fd \u003d -1;\n+\t}\n+\n \tif (err)\n \t\treturn errno;\n \n@@ -208,42 +216,24 @@ static int unlock_slot(struct cache_slot *slot, int replace_old_slot)\n */\n static int fill_slot(struct cache_slot *slot)\n {\n-\tint tmp;\n-\n \t/* Preserve stdout */\n-\ttmp \u003d dup(STDOUT_FILENO);\n-\tif (tmp \u003d\u003d -1)\n+\tslot-\u003estdout_fd \u003d dup(STDOUT_FILENO);\n+\tif (slot-\u003estdout_fd \u003d\u003d -1)\n \t\treturn errno;\n \n \t/* Redirect stdout to lockfile */\n-\tif (dup2(slot-\u003elock_fd, STDOUT_FILENO) \u003d\u003d -1) {\n-\t\tclose(tmp);\n+\tif (dup2(slot-\u003elock_fd, STDOUT_FILENO) \u003d\u003d -1)\n \t\treturn errno;\n-\t}\n \n \t/* Generate cache content */\n \tslot-\u003efn();\n \n \t/* Make sure any buffered data is flushed to the file */\n-\tif (fflush(stdout)) {\n-\t\tclose(tmp);\n+\tif (fflush(stdout))\n \t\treturn errno;\n-\t}\n \n \t/* update stat info */\n-\tif (fstat(slot-\u003elock_fd, \u0026slot-\u003ecache_st)) {\n-\t\tclose(tmp);\n-\t\treturn errno;\n-\t}\n-\n-\t/* Restore stdout */\n-\tif (dup2(tmp, STDOUT_FILENO) \u003d\u003d -1) {\n-\t\tclose(tmp);\n-\t\treturn errno;\n-\t}\n-\n-\t/* Close the temporary filedescriptor */\n-\tif (close(tmp))\n+\tif (fstat(slot-\u003elock_fd, \u0026slot-\u003ecache_st))\n \t\treturn errno;\n \n \treturn 0;\n@@ -393,6 +383,7 @@ int cache_process(int size, const char *path, const char *key, int ttl,\n \tstrbuf_addstr(\u0026lockname, \u0022.lock\u0022);\n \tslot.fn \u003d fn;\n \tslot.ttl \u003d ttl;\n+\tslot.stdout_fd \u003d -1;\n \tslot.cache_name \u003d filename.buf;\n \tslot.lock_name \u003d lockname.buf;\n \tslot.key \u003d key;\n","s":{"c":1745906639,"u": 792}}
],"g": 1764,"chitpc": 0,"ehitpc": 0,"indexed":0
,
"ab": 0, "si": 0, "db":0, "di":0, "sat":0, "lfc": "0000"}