lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite for Android: free password hash cracker in your pocket
[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Date:	Tue, 9 Sep 2008 06:03:11 +0200
From:	Willy Tarreau <w@....eu>
To:	Alain Knaff <alain@...ff.lu>
Cc:	linux-kernel@...r.kernel.org, torvalds@...ux-foundation.org,
	hpa@...or.com
Subject: Re: [update2] [PATCH] init: bzip2 or lzma -compressed kernels and initrds

On Tue, Sep 09, 2008 at 12:50:22AM +0200, Alain Knaff wrote:
> Changes since last version:
> 
> - Removed #ifdef's in head_32.S and head_64.S at the cost of a 4-byte
>   increase of LZMA-compressed kernels

4 bytes aren't that much, the code looks a lot cleaner and touches less
areas.

I may be wrong, but I think that some #ifdef NEW_CODE and #ifdef IN_MEMORY
can go too. Note that I have *not* analysed the dependency chain, it's just
that I believe they're always defined so they may go :

> --- linux.trees.git/arch/x86/boot/compressed/misc.c	2008-09-07 11:29:12.000000000 +0200
> +++ linux.trees.git.udpcast/arch/x86/boot/compressed/misc.c	2008-09-09 00:41:40.000000000 +0200
> @@ -116,71 +116,18 @@
>  /*
>   * gzip declarations
>   */
> -
> -#define OF(args)	args
>  #define STATIC		static
> +#define NEW_CODE

(...)

> +/* Decompressor should decompress in memory */
> +#define IN_MEMORY

(...)

> --- linux.trees.git/include/linux/decompress_unlzma.h	1970-01-01 01:00:00.000000000 +0100
> +++ linux.trees.git.udpcast/include/linux/decompress_unlzma.h	2008-09-08 19:56:37.000000000 +0200
> @@ -0,0 +1,15 @@
> +#ifndef DECOMPRESS_UNLZMA_H
> +#define DECOMPRESS_UNLZMA_H
> +
> +
> +int unlzma(char *, int,
> +	   int(*fill)(void*, unsigned int),
> +#ifdef IN_MEMORY
> +	   unsigned char *output,
> +#else
> +	   int(*flush)(void*, unsigned int),
> +#endif
> +	   int *
> +	);
> +
> +#endif

(...)

> +struct writer {
> +	uint8_t *buffer;
> +	uint8_t previous_byte;
> +	size_t buffer_pos;
> +#ifndef IN_MEMORY
> +	int bufsize;
> +	size_t global_pos;
> +	int(*flush)(void*, unsigned int);
> +#endif
> +	struct lzma_header *header;
> +};

(...)

> +static always_inline size_t INIT get_pos(struct writer *wr)
> +{
> +	return
> +#ifndef IN_MEMORY
> +		wr->global_pos +
> +#endif
> +		wr->buffer_pos;
> +}

(...)

> +static always_inline uint8_t INIT peek_old_byte(struct writer *wr,
> +						uint32_t offs)
> +{
> +#ifdef IN_MEMORY
> +	int32_t pos;
> +	while (offs > wr->header->dict_size)
> +		offs -= wr->header->dict_size;
> +	pos = wr->buffer_pos - offs;
> +#else
> +	uint32_t pos = wr->buffer_pos - offs;
> +	while (pos >= wr->header->dict_size)
> +		pos += wr->header->dict_size;
> +#endif
> +	return wr->buffer[pos];
> +
> +}
> +
> +static always_inline void INIT write_byte(struct writer *wr, uint8_t byte)
> +{
> +	wr->buffer[wr->buffer_pos++] = wr->previous_byte = byte;
> +#ifndef IN_MEMORY
> +	if (wr->buffer_pos == wr->header->dict_size) {
> +		wr->buffer_pos = 0;
> +		wr->global_pos += wr->header->dict_size;
> +		wr->flush((char *)wr->buffer, wr->header->dict_size);
> +	}
> +#endif
> +}

(...)

> +STATIC always_inline int INIT unlzma(char *buf, int in_len,
> +				     int(*fill)(void*, unsigned int),
> +#ifdef IN_MEMORY
> +				     unsigned char *output,
> +#else
> +				     int(*flush)(void*, unsigned int),
> +#endif
> +				     int *posp
> +)
> +{
> +	struct lzma_header header;
> +	int lc, pb, lp;
> +	uint32_t pos_state_mask;
> +	uint32_t literal_pos_mask;
> +	uint16_t *p;
> +	int num_probs;
> +	struct rc rc;
> +	int i, mi;
> +	struct writer wr;
> +	struct cstate cst;
> +	char *inbuf;
> +	int ret = -1;
> +
> +	if (buf)
> +		inbuf = buf;
> +	else
> +		inbuf = malloc(LZMA_IOBUF_SIZE);
> +	if (!inbuf) {
> +		error("Could not allocate input bufer");
> +		goto exit_0;
> +	}
> +
> +	cst.state = 0;
> +	cst.rep0 = cst.rep1 = cst.rep2 = cst.rep3 = 1;
> +
> +	wr.header = &header;
> +#ifndef IN_MEMORY
> +	wr.flush = flush;
> +	wr.global_pos = 0;
> +#endif
> +	wr.previous_byte = 0;
> +	wr.buffer_pos = 0;
> +
> +	rc_init(&rc, fill, inbuf, in_len);
> +
> +	for (i = 0; i < sizeof(header); i++) {
> +		if (rc.ptr >= rc.buffer_end)
> +			rc_read(&rc);
> +		((unsigned char *)&header)[i] = *rc.ptr++;
> +	}
> +
> +	if (header.pos >= (9 * 5 * 5))
> +		error("bad header");
> +
> +	mi = header.pos / 9;
> +	lc = header.pos % 9;
> +	pb = mi / 5;
> +	lp = mi % 5;
> +	pos_state_mask = (1 << pb) - 1;
> +	literal_pos_mask = (1 << lp) - 1;
> +
> +	ENDIAN_CONVERT(header.dict_size);
> +	ENDIAN_CONVERT(header.dst_size);
> +
> +	if (header.dict_size == 0)
> +		header.dict_size = 1;
> +
> +#ifdef IN_MEMORY
> +	wr.buffer = output;
> +#else
> +	wr.bufsize = MIN(header.dst_size, header.dict_size);
> +	wr.buffer = large_malloc(wr.bufsize);
> +#endif
> +	if (wr.buffer == NULL)
> +		goto exit_1;
> +
> +	num_probs = LZMA_BASE_SIZE + (LZMA_LIT_SIZE << (lc + lp));
> +	p = (uint16_t *) large_malloc(num_probs * sizeof(*p));
> +	if (p == 0)
> +		goto exit_2;
> +	num_probs = LZMA_LITERAL + (LZMA_LIT_SIZE << (lc + lp));
> +	for (i = 0; i < num_probs; i++)
> +		p[i] = (1 << RC_MODEL_TOTAL_BITS) >> 1;
> +
> +	rc_init_code(&rc);
> +
> +	while (get_pos(&wr) < header.dst_size) {
> +		int pos_state =	get_pos(&wr) & pos_state_mask;
> +		uint16_t *prob = p + LZMA_IS_MATCH +
> +			(cst.state << LZMA_NUM_POS_BITS_MAX) + pos_state;
> +		if (rc_is_bit_0(&rc, prob))
> +			process_bit0(&wr, &rc, &cst, p, pos_state, prob,
> +				     lc, literal_pos_mask);
> +		else {
> +			process_bit1(&wr, &rc, &cst, p, pos_state, prob);
> +			if (cst.rep0 == 0)
> +				break;
> +		}
> +	}
> +
> +	if (posp)
> +		*posp = rc.ptr-rc.buffer;
> +#ifndef IN_MEMORY
> +	wr.flush(wr.buffer, wr.buffer_pos);
> +#endif
> +	ret = 0;
> +	large_free(p);
> +exit_2:
> +#ifndef IN_MEMORY
> +	large_free(wr.buffer);
> +#endif
> +exit_1:
> +	if (!buf)
> +		free(inbuf);
> +exit_0:
> +	return ret;
> +}
> +
> +#define decompress unlzma
> diff -uNrp -X linux.trees.git.udpcast/Documentation/dontdiff linux.trees.git/lib/inflate.c linux.trees.git.udpcast/lib/inflate.c
> --- linux.trees.git/lib/inflate.c	2008-09-07 11:29:23.000000000 +0200
> +++ linux.trees.git.udpcast/lib/inflate.c	2008-09-08 22:23:36.000000000 +0200
> @@ -110,19 +110,112 @@ static char rcsid[] = "#Id: inflate.c,v 
>  
>  #ifndef STATIC
>  
> +#define NEW_CODE
> +#define NO_INFLATE_MALLOC
> +#include <linux/fs.h>
> +
>  #if defined(STDC_HEADERS) || defined(HAVE_STDLIB_H)
>  #  include <sys/types.h>
>  #  include <stdlib.h>
>  #endif
>  
> -#include "gzip.h"
> +static void __init error(char *m)
> +{
> +	printk(KERN_ERR "%s", m);
> +}
> +
> +#define INIT __init
> +#include <linux/init.h>
>  #define STATIC
> +#include <linux/inflate.h>
>  #endif /* !STATIC */
>  
>  #ifndef INIT
>  #define INIT
>  #endif
> -	
> +
> +#ifdef NEW_CODE
> +#include <linux/string.h>
> +
> +#ifndef IN_MEMORY
> +static int(*flush_cb)(void*, unsigned int);
> +#endif
(...)
etc...

Regards,
Willy

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ