A small problem with source3/locking.c:traverse_fn that causes a crash if a share_mode_lock contains a delete token
Richard Sharpe
realrichardsharpe at gmail.com
Wed Nov 28 20:54:08 MST 2012
Hi folks,
Currently, the traverse_fn (which is used by smbstatus) does this to
try to deal with delete tokens:
for (i = 0; i < data->u.s.num_delete_token_entries; i++) {
uint32_t del_token_size;
memcpy(&del_token_size, del_tokens, sizeof(uint32_t));
total_del_token_size += del_token_size;
del_tokens += del_token_size;
}
It clearly thinks that there is a uint32_t length in front of each
such token. However, unparse_share_modes does this:
/* Store any delete on close tokens. */
for (pdtl = lck->delete_tokens; pdtl; pdtl = pdtl->next) {
struct security_unix_token *pdt = pdtl->delete_token;
struct security_token *pdt_nt = pdtl->delete_nt_token;
uint8_t *p = result.dptr + offset;
DATA_BLOB blob;
enum ndr_err_code ndr_err;
memcpy(p, &pdtl->name_hash, sizeof(uint32_t));
p += sizeof(uint32_t);
offset += sizeof(uint32_t);
So, it seems that the name hash should be in front of the token, and
this causes a crash if there is a token.
I thought that the following patch would fix things, but it crashes as well.
-bash-4.0$ diff -up locking.c.orig locking.c
--- locking.c.orig 2012-11-28 17:44:05.265719981 -0800
+++ locking.c 2012-11-28 19:37:04.378894979 -0800
@@ -1741,6 +1741,8 @@ static int traverse_fn(struct db_record
const char *fname;
const char *del_tokens;
uint32_t total_del_token_size = 0;
+ struct share_mode_lock *lck = TALLOC_ZERO_P(talloc_tos(),
+ struct share_mode_lock);
int i;
/* Ensure this is a locking_key record. */
@@ -1752,6 +1754,13 @@ static int traverse_fn(struct db_record
del_tokens = (const char *)rec->value.dptr + sizeof(*data) +
data->u.s.num_share_mode_entries*sizeof(*shares);
+
+ if (data->u.s.num_delete_token_entries)
+ total_del_token_size = parse_delete_tokens_list(lck,
+ data,
+ rec->value);
+ TALLOC_FREE(lck);
+#if 0
for (i = 0; i < data->u.s.num_delete_token_entries; i++) {
uint32_t del_token_size;
memcpy(&del_token_size, del_tokens, sizeof(uint32_t));
@@ -1759,6 +1768,8 @@ static int traverse_fn(struct db_record
del_tokens += del_token_size;
}
+#endif
+
sharepath = (const char *)rec->value.dptr + sizeof(*data) +
data->u.s.num_share_mode_entries*sizeof(*shares) +
total_del_token_size;
The crash is:
../librpc/ndr/ndr_basic.c:830: uid_t pull doesn't fit 0x0000820284f2a1c1
Program received signal SIGSEGV, Segmentation fault.
--
Regards,
Richard Sharpe
(何以解憂?唯有杜康。--曹操)
More information about the samba-technical
mailing list